v2-0002-add-test-for-pg_recvlogical-reconnection.patch
application/octet-stream
Filename: v2-0002-add-test-for-pg_recvlogical-reconnection.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v2-0002
Subject: add test for pg_recvlogical reconnection
| File | + | − |
|---|---|---|
| src/bin/pg_basebackup/t/030_pg_recvlogical.pl | 71 | 0 |
From 187dc28154581746d82f10065cb3911215f11a1c Mon Sep 17 00:00:00 2001
From: Fujii Masao <fujii@postgresql.org>
Date: Fri, 28 Nov 2025 10:50:02 +0900
Subject: [PATCH v2 2/2] add test for pg_recvlogical reconnection
---
src/bin/pg_basebackup/t/030_pg_recvlogical.pl | 71 +++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
index 1b7a6f6f43f..0588f052786 100644
--- a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
+++ b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
@@ -151,4 +151,75 @@ my $result = $node->safe_psql('postgres',
);
is($result, 't', "failover is enabled for the new slot");
+# Test that when pg_recvlogical reconnects, it does not write duplicate
+# records to the output file
+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');
+
+# Insert the first record for this test
+$node->safe_psql('postgres', 'INSERT INTO test_table VALUES (1)');
+
+my ($stdout, $stderr);
+my $recv = IPC::Run::start(
+ [
+ 'pg_recvlogical',
+ '--slot' => 'reconnect_test',
+ '--dbname' => $node->connstr('postgres'),
+ '--start',
+ '--file' => $outfile,
+ '--fsync-interval' => '1',
+ '--status-interval' => '100',
+ '--verbose'
+ ],
+ '>' => \$stdout,
+ '2>' => \$stderr);
+
+# Wait for pg_recvlogical to receive and write the first INSERT
+$node->poll_query_until('postgres',
+ "SELECT pg_read_file('$outfile') ~ 'INSERT'")
+ or die "Timed out while waiting for pg_recvlogical to receive first INSERT";
+
+# Terminate the walsender to force pg_recvlogical to reconnect
+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 pg_recvlogical to establish a new connection
+$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'"
+) or die "Timed out while waiting for pg_recvlogical to reconnect";
+
+# Insert the second record for this test
+$node->safe_psql('postgres', 'INSERT INTO test_table VALUES (2)');
+
+# Wait for pg_recvlogical to receive and write both INSERT
+$node->poll_query_until('postgres',
+ "SELECT pg_read_file('$outfile') ~ 'INSERT.*INSERT'")
+ or die "Timed out while waiting for pg_recvlogical to receive both INSERT";
+
+$recv->signal('TERM');
+$recv->finish();
+
+my $outfiledata = slurp_file("$outfile");
+my $count = (() = $outfiledata =~ /INSERT/g);
+cmp_ok($count, '==', 2, 'pg_recvlogical has received and written two INSERT');
+
+$node->command_ok(
+ [
+ 'pg_recvlogical',
+ '--slot' => 'reconnect_test',
+ '--dbname' => $node->connstr('postgres'),
+ '--drop-slot'
+ ],
+ 'reconnect_test slot dropped');
+
done_testing();
--
2.51.2