Hi all

The attached patch adds a test to the TAP logical decoding suite to show
that pg_replication_slot_advance() works on a server in standby mode.

I didn't add a full demonstration of how to do failover with logical slots
because we're still missing a way to "sync" a logical slot from a primary
to a standby, or a way to directly create such a slot safely on a standby
in a way that enforces a safe catalog_xmin etc.

You can't replay from the slot unless the server is promoted, so I don't
test that.

I'm not sure if anyone's going to find it worth committing, but it's here
so searchers can find it at least.
From 218c607b64db493b975bb398528d6a952beeb32f Mon Sep 17 00:00:00 2001
From: Craig Ringer <craig.rin...@2ndquadrant.com>
Date: Tue, 10 Nov 2020 13:06:41 +0800
Subject: [PATCH] Extend TAP test for pg_replication_slot_advance() to cover
 standby

Show that pg_replication_slot_advance() works on a standby server
too.
---
 src/test/recovery/t/006_logical_decoding.pl | 37 +++++++++++++++------
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/src/test/recovery/t/006_logical_decoding.pl 
b/src/test/recovery/t/006_logical_decoding.pl
index ffc3e77f83..46d521a6a0 100644
--- a/src/test/recovery/t/006_logical_decoding.pl
+++ b/src/test/recovery/t/006_logical_decoding.pl
@@ -7,7 +7,7 @@ use strict;
 use warnings;
 use PostgresNode;
 use TestLib;
-use Test::More tests => 14;
+use Test::More tests => 17;
 use Config;
 
 # Initialize primary node
@@ -185,19 +185,34 @@ chomp($logical_restart_lsn_post);
 ok(($logical_restart_lsn_pre cmp $logical_restart_lsn_post) == 0,
        "logical slot advance persists across restarts");
 
-# done with the node
+# Show that advancing the slot is supported when in recovery (standby)
 $node_primary->stop;
-
-$node_primary->append_conf('postgresql.conf',qq[
-hot_standby = on
-primary_conninfo = 'bogus'
-]);
-
+$node_primary->set_standby_mode();
 $node_primary->start;
 is($node_primary->safe_psql('postgres', 'SELECT 
pg_is_in_recovery();'),'t','started up in recovery');
-$current_lsn = $node_primary->lsn('insert');
+$current_lsn = $node_primary->lsn('replay');
 ($result, $stdout, $stderr) = $node_primary->psql('postgres',
-       "SELECT pg_replication_slot_advance('$logical_slot', 
'$current_lsn'::pg_lsn);"
+       "SELECT end_lsn FROM pg_replication_slot_advance('$logical_slot', 
'$current_lsn'::pg_lsn);"
 );
-ok($result, "pg_replication_slot_advance() on standby succeeded");
+chomp($result);
+is($result, 0, "pg_replication_slot_advance() on standby succeeded");
 is($stderr, '', "pg_replication_slot_advance() on standby produced no stderr");
+
+# The slot actually advanced
+is($node_primary->safe_psql('postgres', "SELECT pg_lsn '$result' >= pg_lsn 
'$current_lsn';"),
+   't', 'pg_replication_slot_advance() reported slot moved forwards');
+is($node_primary->safe_psql('postgres',
+         "SELECT confirmed_flush_lsn = pg_lsn '$current_lsn' from 
pg_replication_slots WHERE slot_name = '$logical_slot';"),
+   't', 'pg_replication_slot_advance() return value matches 
pg_replication_slots on standby');
+
+# Slot advance should persist across clean restarts on standby too
+$node_primary->restart;
+$logical_restart_lsn_post = $node_primary->safe_psql('postgres',
+       "SELECT restart_lsn from pg_replication_slots WHERE slot_name = 
'$logical_slot';"
+);
+chomp($logical_restart_lsn_post);
+ok(($logical_restart_lsn_pre cmp $logical_restart_lsn_post) == 0,
+       "logical slot advance persists across restarts");
+
+# done with the node
+$node_primary->stop;
-- 
2.26.2

Reply via email to