PostgreSQL pg_dropcache修改(兼容pg13)

276 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

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();
 }
+