本文已参与「新人创作礼」活动,一起开启掘金创作之路
pg_dropcache可以用来清空shared_buffer,但由于pg多版本的特性,脏页也会直接drop, 所以可能会导致数据不一致,所以不建议在生产环境随便使用。
不过有的时候我们做一些测试的时候可能需要清空缓存,那倒是可以用pg_dropcache来试试。
但是比较可惜,这个插件只支持到pg12,pg13开始就不支持了,因为在pg13中DropRelFileNodeBuffers这个函数做了调整。
PG12:
extern void DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum,
BlockNumber firstDelBlock);
PG13:
extern void DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber *forkNum,
int nforks, BlockNumber *firstDelBlock);
我们可以自己修改下这个插件,让其支持pg13版本。
例如:
使用pg_dropcache来清空t3表的缓存:
完整patch如下:
--- pg_dropcache.c 2018-04-24 16:15:48.000000000 +0800
+++ pg_dropcache_bak.c 2021-10-29 16:01:11.000000000 +0800
@@ -22,7 +22,9 @@
pg_drop_rel_cache(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
- int forkNum;
+ ForkNumber forkNum[5];
+ int nforks=MAX_FORKNUM;
+ BlockNumber firstDelBlock[] = {0};
HeapTuple tp;
RelFileNodeBackend rnode;
@@ -30,7 +32,7 @@
if (HeapTupleIsValid(tp))
{
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
-
+
rnode.node.relNode = reltup->relfilenode;
rnode.node.spcNode = (reltup->reltablespace == InvalidOid) ?
MyDatabaseTableSpace :
@@ -46,9 +48,9 @@
PG_RETURN_VOID();
}
- forkNum = PG_ARGISNULL(1) ? 0 : forkname_to_number(text_to_cstring(PG_GETARG_TEXT_P(1)));
- for (; forkNum <= MAX_FORKNUM; ++forkNum)
- DropRelFileNodeBuffers(rnode, forkNum, 0);
+ *forkNum = PG_ARGISNULL(1) ? 0 : forkname_to_number(text_to_cstring(PG_GETARG_TEXT_P(1)));
+ DropRelFileNodeBuffers(rnode, forkNum, nforks,firstDelBlock);
PG_RETURN_VOID();
}
+