From 44c04e2731dde2b013b741bdc8f13a1ab85c296b Mon Sep 17 00:00:00 2001 From: Joao Foltran Date: Thu, 19 Mar 2026 19:05:09 -0300 Subject: [PATCH v3 2/5] Add auto_revalidate parameter to pg_create_physical_replication_slot Allow setting auto_revalidate when creating a physical replication slot via the SQL function: pg_create_physical_replication_slot(name, immediately_reserve, temporary, auto_revalidate) The flag is set after slot creation (not via ReplicationSlotCreate parameter) to avoid a cascading signature change across all 6 callers of that function. The new parameter defaults to false. --- contrib/test_decoding/expected/slot.out | 32 +++++++++++++++++++++++++ contrib/test_decoding/sql/slot.sql | 7 ++++++ src/backend/replication/slotfuncs.c | 20 +++++++++++++--- src/backend/replication/walsender.c | 1 + src/include/catalog/pg_proc.dat | 11 +++++---- src/test/recovery/meson.build | 1 + 6 files changed, 64 insertions(+), 8 deletions(-) diff --git a/contrib/test_decoding/expected/slot.out b/contrib/test_decoding/expected/slot.out index 7de03c79f6f..1834b42cd92 100644 --- a/contrib/test_decoding/expected/slot.out +++ b/contrib/test_decoding/expected/slot.out @@ -406,6 +406,38 @@ SELECT pg_drop_replication_slot('copied_slot2_notemp'); (1 row) +-- Test auto_revalidate is preserved when copying physical slots +SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot_ar', true, false, true); + ?column? +---------- + init +(1 row) + +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot_ar', 'copied_slot_ar'); + ?column? +---------- + copy +(1 row) + +SELECT slot_name, auto_revalidate FROM pg_replication_slots WHERE slot_name LIKE '%_ar' ORDER BY slot_name; + slot_name | auto_revalidate +----------------+----------------- + copied_slot_ar | t + orig_slot_ar | t +(2 rows) + +SELECT pg_drop_replication_slot('orig_slot_ar'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +SELECT pg_drop_replication_slot('copied_slot_ar'); + pg_drop_replication_slot +-------------------------- + +(1 row) + -- Test failover option of slots. SELECT 'init' FROM pg_create_logical_replication_slot('failover_true_slot', 'test_decoding', false, false, true); ?column? diff --git a/contrib/test_decoding/sql/slot.sql b/contrib/test_decoding/sql/slot.sql index 580e3ae3bef..98b349d6d60 100644 --- a/contrib/test_decoding/sql/slot.sql +++ b/contrib/test_decoding/sql/slot.sql @@ -177,6 +177,13 @@ SELECT pg_drop_replication_slot('orig_slot2'); SELECT pg_drop_replication_slot('copied_slot2_no_change'); SELECT pg_drop_replication_slot('copied_slot2_notemp'); +-- Test auto_revalidate is preserved when copying physical slots +SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot_ar', true, false, true); +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot_ar', 'copied_slot_ar'); +SELECT slot_name, auto_revalidate FROM pg_replication_slots WHERE slot_name LIKE '%_ar' ORDER BY slot_name; +SELECT pg_drop_replication_slot('orig_slot_ar'); +SELECT pg_drop_replication_slot('copied_slot_ar'); + -- Test failover option of slots. SELECT 'init' FROM pg_create_logical_replication_slot('failover_true_slot', 'test_decoding', false, false, true); SELECT 'init' FROM pg_create_logical_replication_slot('failover_false_slot', 'test_decoding', false, false, false); diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index 16fbd383735..e44ce243d22 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -46,7 +46,8 @@ static const char *SlotSyncSkipReasonNames[] = { */ static void create_physical_replication_slot(char *name, bool immediately_reserve, - bool temporary, XLogRecPtr restart_lsn) + bool temporary, XLogRecPtr restart_lsn, + bool auto_revalidate) { Assert(!MyReplicationSlot); @@ -67,6 +68,16 @@ create_physical_replication_slot(char *name, bool immediately_reserve, ReplicationSlotMarkDirty(); ReplicationSlotSave(); } + + if (auto_revalidate) + { + SpinLockAcquire(&MyReplicationSlot->mutex); + MyReplicationSlot->data.auto_revalidate = true; + SpinLockRelease(&MyReplicationSlot->mutex); + + ReplicationSlotMarkDirty(); + ReplicationSlotSave(); + } } /* @@ -79,6 +90,7 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS) Name name = PG_GETARG_NAME(0); bool immediately_reserve = PG_GETARG_BOOL(1); bool temporary = PG_GETARG_BOOL(2); + bool auto_revalidate = PG_GETARG_BOOL(3); Datum values[2]; bool nulls[2]; TupleDesc tupdesc; @@ -95,7 +107,8 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS) create_physical_replication_slot(NameStr(*name), immediately_reserve, temporary, - InvalidXLogRecPtr); + InvalidXLogRecPtr, + auto_revalidate); values[0] = NameGetDatum(&MyReplicationSlot->data.name); nulls[0] = false; @@ -758,7 +771,8 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot) create_physical_replication_slot(NameStr(*dst_name), true, temporary, - src_restart_lsn); + src_restart_lsn, + first_slot_contents.data.auto_revalidate); /* * Update the destination slot to current values of the source slot; diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 09291f7f0a6..54f05ec99ab 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -1282,6 +1282,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) if (!cmd->temporary) ReplicationSlotSave(); } + } else { diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index be157a5fbe9..34d65e40701 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -11621,11 +11621,12 @@ # replication slots { oid => '3779', descr => 'create a physical replication slot', proname => 'pg_create_physical_replication_slot', provolatile => 'v', - proparallel => 'u', prorettype => 'record', proargtypes => 'name bool bool', - proallargtypes => '{name,bool,bool,name,pg_lsn}', - proargmodes => '{i,i,i,o,o}', - proargnames => '{slot_name,immediately_reserve,temporary,slot_name,lsn}', - proargdefaults => '{false,false}', + proparallel => 'u', prorettype => 'record', + proargtypes => 'name bool bool bool', + proallargtypes => '{name,bool,bool,bool,name,pg_lsn}', + proargmodes => '{i,i,i,i,o,o}', + proargnames => '{slot_name,immediately_reserve,temporary,auto_revalidate,slot_name,lsn}', + proargdefaults => '{false,false,false}', prosrc => 'pg_create_physical_replication_slot' }, { oid => '4220', descr => 'copy a physical replication slot, changing temporality', diff --git a/src/test/recovery/meson.build b/src/test/recovery/meson.build index 9eb8ed11425..5e208ffb019 100644 --- a/src/test/recovery/meson.build +++ b/src/test/recovery/meson.build @@ -62,6 +62,7 @@ tests += { 't/051_effective_wal_level.pl', 't/052_checkpoint_segment_missing.pl', 't/053_standby_login_event_trigger.pl', + 't/054_auto_revalidate_physical_slot.pl', ], }, } -- 2.50.1 (Apple Git-155)