Skip to content

Commit

Permalink
Provide a pg_truncate_freespacemap function
Browse files Browse the repository at this point in the history
  • Loading branch information
rdunklau committed Mar 1, 2024
1 parent 212c739 commit b2a2d30
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ RPM_MINOR_VERSION_SUFFIX ?=
# Extension packaging
EXTENSION = aiven_extras
MODULE_big = aiven_extras
OBJS = src/standby_slots.o
OBJS = src/aiven_extras.o
PG_CONFIG ?= pg_config
DATA = $(filter-out $(generated),$(wildcard sql/*--*.sql))
DATA_built = $(generated)
Expand Down
6 changes: 6 additions & 0 deletions sql/aiven_extras.sql
Original file line number Diff line number Diff line change
Expand Up @@ -580,3 +580,9 @@ CREATE FUNCTION aiven_extras.pg_create_logical_replication_slot_on_standby(
OUT slot_name name, OUT lsn pg_lsn)
AS 'MODULE_PATHNAME', 'standby_slot_create'
LANGUAGE C;

DROP FUNCTION IF EXISTS aiven_extras.aiven_truncate_freespace_map(regclass);
CREATE FUNCTION aiven_extras.truncate_freespace_map(regclass)
RETURNS void
AS 'MODULE_PATHNAME', 'aiven_truncate_freespace_map'
LANGUAGE C;
69 changes: 69 additions & 0 deletions src/standby_slots.c → src/aiven_extras.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,28 @@
#include "fmgr.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "storage/freespace.h"
#include "storage/smgr.h"
#if PG_VERSION_NUM >= 160000
#include "access/relation.h"
#endif
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "access/xlogutils.h"
#include "replication/logical.h"
#include "catalog/storage_xlog.h"
#include "replication/slot.h"
#include "replication/walreceiver.h"
#if PG_VERSION_NUM >= 120000 && PG_VERSION_NUM < 130000
#include "replication/logicalfuncs.h"
#endif
#include "utils/pg_lsn.h"
#include "utils/rel.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(standby_slot_create);
PG_FUNCTION_INFO_V1(aiven_truncate_freespace_map);
Datum
standby_slot_create(PG_FUNCTION_ARGS)
{
Expand Down Expand Up @@ -120,3 +129,63 @@ standby_slot_create(PG_FUNCTION_ARGS)
ReplicationSlotRelease();
PG_RETURN_DATUM(result);
}



#if PG_VERSION_NUM >= 160000
Datum
aiven_truncate_freespace_map(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
Relation rel;
ForkNumber fork;
BlockNumber block;

rel = relation_open(relid, AccessExclusiveLock);

/* Only some relkinds have a visibility map */
if (!RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("relation \"%s\" is of wrong relation kind",
RelationGetRelationName(rel)),
errdetail_relkind_not_supported(rel->rd_rel->relkind)));


/* Forcibly reset cached file size */
RelationGetSmgr(rel)->smgr_cached_nblocks[FSM_FORKNUM] = InvalidBlockNumber;

/* Just pretend we're going to wipeout the whole rel */
block = FreeSpaceMapPrepareTruncateRel(rel, 0);

if (BlockNumberIsValid(block))
{
fork = FSM_FORKNUM;
smgrtruncate(RelationGetSmgr(rel), &fork, 1, &block);
}

if (RelationNeedsWAL(rel))
{
xl_smgr_truncate xlrec;

xlrec.blkno = 0;
xlrec.rlocator = rel->rd_locator;
xlrec.flags = SMGR_TRUNCATE_FSM;

XLogBeginInsert();
XLogRegisterData((char *) &xlrec, sizeof(xlrec));

XLogInsert(RM_SMGR_ID, XLOG_SMGR_TRUNCATE | XLR_SPECIAL_REL_UPDATE);
}

relation_close(rel, AccessExclusiveLock);

PG_RETURN_VOID();
}
#else
Datum
aiven_truncate_freespace_map(PG_FUNCTION_ARGS)
{
elog(ERROR, "aiven_truncate_freespace_map is not supported on this version.");
}
#endif

0 comments on commit b2a2d30

Please sign in to comment.