From 8a955a031598864e1acbe88c6bac8417319d0fb7 Mon Sep 17 00:00:00 2001 From: Shveta Malik Date: Wed, 20 Dec 2023 10:54:53 +0530 Subject: [PATCH v1] Function to get invalidation cause of a replication slot. This patch implements a new system function pg_get_slot_invalidation_cause('slot_name') to get invalidation cause of a replication slot. Currently, users do not have a way to know the invalidation cause. One can only find out if the slot is invalidated or not by querying the 'conflicting' field of pg_replication_slots. This new function provides a way to query invalidation cause as well. This function returns NULL if the replication slot is not found and 0 if the replication slot is not invalidated. Possible invalidation causes returned are: 1 = required WAL has been removed. 2 = required rows have been removed. 3 = wal_level insufficient for the slot --- doc/src/sgml/func.sgml | 33 +++++++++++++++++++++++++++++ src/backend/replication/slotfuncs.c | 27 +++++++++++++++++++++++ src/include/catalog/pg_proc.dat | 4 ++++ 3 files changed, 64 insertions(+) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 20da3ed033..0826168192 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -27684,6 +27684,39 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset + + + + pg_get_slot_invalidation_cause + + pg_get_slot_invalidation_cause ( slot_name name ) + integer + + + Returns invalidation cause of the replication slot named + slot_name. Returns NULL if the replication slot + is not found and 0 if the replication slot is not invalidated. + Possible invalidation causes are: + + + + 1 = required WAL has been removed. + + + + + 2 = required rows have been removed. + + + + + 3 = wal_level insufficient for the slot + + + + + + diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index 4b694a03d0..a8643c621c 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -225,6 +225,33 @@ pg_drop_replication_slot(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } +/* + * SQL function for getting invalidation cause of a slot. + * + * Returns ReplicationSlotInvalidationCause enum value for valid slot_name; + * returns NULL if slot with given name is not found. + * + * Returns RS_INVAL_NONE if the given slot is not invalidated. + */ +Datum +pg_get_slot_invalidation_cause(PG_FUNCTION_ARGS) +{ + Name name = PG_GETARG_NAME(0); + ReplicationSlot *s; + ReplicationSlotInvalidationCause cause; + + s = SearchNamedReplicationSlot(NameStr(*name), true); + + if (s == NULL) + PG_RETURN_NULL(); + + SpinLockAcquire(&s->mutex); + cause = s->data.invalidated; + SpinLockRelease(&s->mutex); + + PG_RETURN_INT16(cause); +} + /* * pg_get_replication_slots - SQL SRF showing all replication slots * that currently exist on the database cluster. diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 77e8b13764..ce001dacb9 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -11095,6 +11095,10 @@ proname => 'pg_drop_replication_slot', provolatile => 'v', proparallel => 'u', prorettype => 'void', proargtypes => 'name', prosrc => 'pg_drop_replication_slot' }, +{ oid => '8484', descr => 'what caused the replication slot to become invalid', + proname => 'pg_get_slot_invalidation_cause', provolatile => 's', proisstrict => 't', + prorettype => 'int2', proargtypes => 'name', + prosrc => 'pg_get_slot_invalidation_cause' }, { oid => '3781', descr => 'information about replication slots currently in use', proname => 'pg_get_replication_slots', prorows => '10', proisstrict => 'f', -- 2.34.1