From 349df8eada0d3eae63b009e34691240aad8cf258 Mon Sep 17 00:00:00 2001 From: Shlok Kyal Date: Tue, 4 Feb 2025 14:58:32 +0530 Subject: [PATCH v1] Restrict copying of invalidated replication slots Currently we can copy an invalidated slot using function 'pg_copy_logical_replication_slot'. With this patch we will throw an error in such case. --- src/backend/replication/slotfuncs.c | 8 ++++++++ src/test/recovery/t/035_standby_logical_decoding.pl | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index 8be4b8c65b..f83a890c50 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -604,6 +604,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot) ReplicationSlot second_slot_contents; XLogRecPtr src_restart_lsn; bool src_islogical; + bool src_isinvalidated; bool temporary; char *plugin; Datum values[2]; @@ -661,6 +662,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot) src_restart_lsn = first_slot_contents.data.restart_lsn; temporary = (first_slot_contents.data.persistency == RS_TEMPORARY); plugin = logical_slot ? NameStr(first_slot_contents.data.plugin) : NULL; + src_isinvalidated = (first_slot_contents.data.invalidated != RS_INVAL_NONE); /* Check type of replication slot */ if (src_islogical != logical_slot) @@ -678,6 +680,12 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot) (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("cannot copy a replication slot that doesn't reserve WAL"))); + /* We should not copy invalidated replication slots */ + if (src_isinvalidated) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot copy an invalidated replication slot"))); + /* Overwrite params from optional arguments */ if (PG_NARGS() >= 3) temporary = PG_GETARG_BOOL(2); diff --git a/src/test/recovery/t/035_standby_logical_decoding.pl b/src/test/recovery/t/035_standby_logical_decoding.pl index 505e85d1eb..efebf72bd6 100644 --- a/src/test/recovery/t/035_standby_logical_decoding.pl +++ b/src/test/recovery/t/035_standby_logical_decoding.pl @@ -553,6 +553,14 @@ $handle = check_pg_recvlogical_stderr($handle, "can no longer access replication slot \"vacuum_full_activeslot\""); +# Attempting to copy an invalidated slot +($result, $stdout, $stderr) = $node_standby->psql( + 'postgres', + qq[select pg_copy_logical_replication_slot('vacuum_full_inactiveslot', 'vacuum_full_inactiveslot_copy');], + replication => 'database'); +ok($stderr =~ /ERROR: cannot copy an invalidated replication slot/, + "invalidated slot cannot be copied"); + # Turn hot_standby_feedback back on change_hot_standby_feedback_and_wait_for_xmins(1, 1); -- 2.34.1