diff --git a/Makefile b/Makefile index d20d92e..d686126 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,12 @@ -# contrib/pg_dropcache/Makefile +# pg_dropcache Makefile MODULE_big = pg_dropcache OBJS = pg_dropcache.o $(WIN32RES) EXTENSION = pg_dropcache -DATA = pg_dropcache--0.1.sql +DATA = pg_dropcache--0.2.sql PGFILEDESC = "pg_dropcache - clears buffer cache" -ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) -else -subdir = contrib/pg_dropcache -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global -include $(top_srcdir)/contrib/contrib-global.mk -endif diff --git a/pg_dropcache--0.2.sql b/pg_dropcache--0.2.sql new file mode 100644 index 0000000..f344591 --- /dev/null +++ b/pg_dropcache--0.2.sql @@ -0,0 +1,11 @@ +\echo Use "CREATE EXTENSION pg_dropcache" to load this file. \quit + +CREATE OR REPLACE FUNCTION pg_dropcache() +RETURNS VOID +AS 'pg_dropcache', 'pg_dropcache' +LANGUAGE C; + +CREATE OR REPLACE FUNCTION pg_drop_rel_cache(relation regclass, fork text default null) +RETURNS VOID +AS 'pg_dropcache', 'pg_drop_rel_cache' +LANGUAGE C; diff --git a/pg_dropcache.c b/pg_dropcache.c index a28a449..f5c6a68 100644 --- a/pg_dropcache.c +++ b/pg_dropcache.c @@ -1,3 +1,18 @@ + +/*------------------------------------------------------------------------- + * + * pg_dropcache.c + * + * + * Portions Copyright (c) 2018, Ildar Musin + * https://github.com/zilder/pg_dropcache + * + * + * Portions Copyright (c) 2025, Pierre Forstmann + * + *------------------------------------------------------------------------- + */ + #include "postgres.h" #include "storage/bufmgr.h" #include "utils/syscache.h" @@ -5,6 +20,7 @@ #include "access/htup_details.h" #include "miscadmin.h" #include "catalog/pg_class.h" +#include "storage/smgr.h" PG_MODULE_MAGIC; @@ -22,20 +38,23 @@ Datum pg_drop_rel_cache(PG_FUNCTION_ARGS) { Oid relid = PG_GETARG_OID(0); - int forkNum; HeapTuple tp; - RelFileNodeBackend rnode; + RelFileLocatorBackend rnode; + BlockNumber nblocks = 0; + ForkNumber forks[MAX_FORKNUM]; + SMgrRelation srel; + int nforks = 0; tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (HeapTupleIsValid(tp)) { Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp); - rnode.node.relNode = reltup->relfilenode; - rnode.node.spcNode = (reltup->reltablespace == InvalidOid) ? + rnode.locator.relNumber = reltup->relfilenode; + rnode.locator.spcOid = (reltup->reltablespace == InvalidOid) ? MyDatabaseTableSpace : reltup->reltablespace; - rnode.node.dbNode = MyDatabaseId; + rnode.locator.dbOid = MyDatabaseId; rnode.backend = InvalidBackendId; ReleaseSysCache(tp); @@ -46,9 +65,19 @@ pg_drop_rel_cache(PG_FUNCTION_ARGS) 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); + /* + * see RelationTruncate (storage.c) + * -> smgrtruncate (smgr.c) + * -> DropRelationBuffers (bufmgr.c) + */ + forks[nforks] = MAIN_FORKNUM; + nforks = 1; + /* + * TO DO: take into account FSM and visibility map + */ + srel = smgropen(rnode.locator, InvalidBackendId); + DropRelationBuffers(srel, forks, nforks, &nblocks); + PG_RETURN_VOID(); } diff --git a/pg_dropcache.control b/pg_dropcache.control index 3ad4f1f..fa8e9a1 100644 --- a/pg_dropcache.control +++ b/pg_dropcache.control @@ -1,5 +1,5 @@ # pg_dropcache extension comment = 'clears buffer cache' -default_version = '0.1' +default_version = '0.2' module_pathname = '$libdir/pg_dropcache' relocatable = true