v1-0001-Add-test-for-pg_recvlogical-reconnection.patch

text/plain

Filename: v1-0001-Add-test-for-pg_recvlogical-reconnection.patch
Type: text/plain
Part: 0
Message: Re: pg_recvlogical: Prevent flushed data from being re-sent after restarting replication
From 908983e7b9d5d8924a2ee3f2a45bd8302f494880 Mon Sep 17 00:00:00 2001
From: Mircea Cadariu <cadariu.mircea@gmail.com>
Date: Mon, 24 Nov 2025 08:49:10 +0000
Subject: [PATCH v1] Add test for pg_recvlogical reconnection

---
 src/bin/pg_basebackup/t/030_pg_recvlogical.pl | 65 ++++++++++++++
 ...test-for-pg_recvlogical-reconnection.patch | 86 +++++++++++++++++++
 2 files changed, 151 insertions(+)
 create mode 100644 v1-0001-Add-test-for-pg_recvlogical-reconnection.patch

diff --git a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
index 1b7a6f6f43..726941943a 100644
--- a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
+++ b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
@@ -151,4 +151,69 @@ my $result = $node->safe_psql('postgres',
 );
 is($result, 't', "failover is enabled for the new slot");
 
+use IPC::Run qw(start);
+
+my $outfile = $node->basedir . '/reconnect.out';
+  
+$node->command_ok(
+    [
+        'pg_recvlogical',
+        '--slot' => 'reconnect_test',
+        '--dbname' => $node->connstr('postgres'),
+        '--create-slot',
+    ],
+    'slot created for reconnection test');
+
+$node->safe_psql('postgres', 'CREATE TABLE t(x int);');
+$node->safe_psql('postgres', 'INSERT INTO t VALUES (1);');
+
+my $recv = start [
+    'pg_recvlogical',
+    '--slot', 'reconnect_test',
+    '--dbname', $node->connstr('postgres'),
+    '--start',
+    '--file', $outfile,
+    '--fsync-interval', '1',
+    '--status-interval', '1',
+    '--verbose'
+], '>', \my $out, '2>', \my $err;
+
+# Wait only for initial connection
+$node->poll_query_until('postgres',
+    "SELECT active_pid IS NOT NULL FROM pg_replication_slots WHERE slot_name = 'reconnect_test'");
+
+# Terminate the backend
+my $backend_pid = $node->safe_psql('postgres',
+    "SELECT active_pid FROM pg_replication_slots WHERE slot_name = 'reconnect_test'");
+$node->safe_psql('postgres', "SELECT pg_terminate_backend($backend_pid)");
+
+# Wait for reconnection
+$node->poll_query_until('postgres',
+    "SELECT active_pid IS NOT NULL AND active_pid != $backend_pid FROM pg_replication_slots WHERE slot_name = 'reconnect_test'");
+
+# Insert after reconnection
+$node->safe_psql('postgres', 'INSERT INTO t VALUES (2);');
+
+# Wait for file to contain both inserts
+$node->poll_query_until('postgres',
+    "SELECT (SELECT pg_read_file('$outfile') ~ 'INSERT.*INSERT') AS has_both");
+
+$recv->signal('TERM');
+$recv->finish();
+
+open(my $file, '<', $outfile);
+my $count = () = do { local $/; <$file> } =~ /INSERT/g;
+close($file);
+
+cmp_ok($count, '==', 2, 'two INSERTs');
+
+$node->command_ok(
+    [
+        'pg_recvlogical',
+        '--slot' => 'reconnect_test',
+        '--dbname' => $node->connstr('postgres'),
+        '--drop-slot'
+    ],
+    'reconnect_test slot dropped');
+
 done_testing();
diff --git a/v1-0001-Add-test-for-pg_recvlogical-reconnection.patch b/v1-0001-Add-test-for-pg_recvlogical-reconnection.patch
new file mode 100644
index 0000000000..f9f9b355b5
--- /dev/null
+++ b/v1-0001-Add-test-for-pg_recvlogical-reconnection.patch
@@ -0,0 +1,86 @@
+From 2e2a0a8c91cd4452b0b9457f04285a7c1c2e9b36 Mon Sep 17 00:00:00 2001
+From: Mircea Cadariu <cadariu.mircea@gmail.com>
+Date: Mon, 24 Nov 2025 08:49:10 +0000
+Subject: [PATCH v1] Add test for pg_recvlogical reconnection
+
+---
+ src/bin/pg_basebackup/t/030_pg_recvlogical.pl | 65 +++++++++++++++++++
+ 1 file changed, 65 insertions(+)
+
+diff --git a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
+index 1b7a6f6f43..6dd96ec095 100644
+--- a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
++++ b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
+@@ -151,4 +151,69 @@ my $result = $node->safe_psql('postgres',
+ );
+ is($result, 't', "failover is enabled for the new slot");
+ 
++use IPC::Run qw(start);
++
++my $outfile = $node->basedir . '/reconnect.out';
++  
++$node->command_ok(
++    [
++        'pg_recvlogical',
++        '--slot' => 'reconnect_test',
++        '--dbname' => $node->connstr('postgres'),
++        '--create-slot',
++    ],
++    'slot created for reconnection test');
++
++$node->safe_psql('postgres', 'CREATE TABLE t(x int);');
++$node->safe_psql('postgres', 'INSERT INTO t VALUES (1);');
++
++my $recv = start [
++    'pg_recvlogical',
++    '--slot', 'reconnect_test',
++    '--dbname', $node->connstr('postgres'),
++    '--start',
++    '--file', $outfile,
++    '--fsync-interval', '1',
++    '--status-interval', '1',
++    '--verbose'
++], '>', \my $out, '2>', \my $err;
++
++# Wait only for initial connection
++$node->poll_query_until('postgres',
++    "SELECT active_pid IS NOT NULL FROM pg_replication_slots WHERE slot_name = 'reconnect_test'");
++
++# Terminate the backend
++my $backend_pid = $node->safe_psql('postgres',
++    "SELECT active_pid FROM pg_replication_slots WHERE slot_name = 'reconnect_test'");
++$node->safe_psql('postgres', "SELECT pg_terminate_backend($backend_pid)");
++
++# Wait for reconnection
++$node->poll_query_until('postgres',
++    "SELECT active_pid IS NOT NULL AND active_pid != $backend_pid FROM pg_replication_slots WHERE slot_name = 'reconnect_test'");
++
++# Insert after reconnection
++$node->safe_psql('postgres', 'INSERT INTO t VALUES (2);');
++
++# Wait for file to contain both inserts
++$node->poll_query_until('postgres',
++    "SELECT (SELECT pg_read_file('$outfile') ~ 'INSERT.*INSERT') AS has_both");
++
++$recv->signal('TERM');
++$recv->finish();
++
++open(my $file, '<', $outfile);
++my $count = () = do { local $/; <$file> } =~ /INSERT/g;
++close($file);
++
++cmp_ok($count, '==', 2, 'at least two INSERTs');
++
++$node->command_ok(
++    [
++        'pg_recvlogical',
++        '--slot' => 'reconnect_test',
++        '--dbname' => $node->connstr('postgres'),
++        '--drop-slot'
++    ],
++    'reconnect_test slot dropped');
++
+ done_testing();
+-- 
+2.39.5 (Apple Git-154)
+
-- 
2.39.5 (Apple Git-154)