From: Drouvot, Bertrand <bertranddrouvot.pg@gmail.com>
To: Alvaro Herrera <alvherre@alvh.no-ip.org>
Cc: vignesh C <vignesh21@gmail.com>
Cc: Amit Kapila <amit.kapila16@gmail.com>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Subject: Re: Add two missing tests in 035_standby_logical_decoding.pl
Date: Wed, 26 Apr 2023 13:10:10 +0200
Message-ID: <19d8fa0d-e840-66eb-f5bc-4c3f9594ec8b@gmail.com> (raw)
In-Reply-To: <20230426102751.pkfs7gwvvrgta6p3@alvherre.pgsql>
References: <20230426102751.pkfs7gwvvrgta6p3@alvherre.pgsql>
Hi,
On 4/26/23 12:27 PM, Alvaro Herrera wrote:
>> diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm
>> index 6f7f4e5de4..819667d42a 100644
>> --- a/src/test/perl/PostgreSQL/Test/Cluster.pm
>> +++ b/src/test/perl/PostgreSQL/Test/Cluster.pm
>> @@ -2644,7 +2644,16 @@ sub wait_for_catchup
>> }
>> if (!defined($target_lsn))
>> {
>> - $target_lsn = $self->lsn('write');
>> + my $isrecovery = $self->safe_psql('postgres', "SELECT pg_is_in_recovery()");
>> + chomp($isrecovery);
>> + if ($isrecovery eq 't')
>> + {
>> + $target_lsn = $self->lsn('replay');
>> + }
>> + else
>> + {
>> + $target_lsn = $self->lsn('write');
>> + }
>
> Please modify the function's documentation to account for this code change.
>
Good point, thanks! Done in V6 attached.
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.comAttachments:v6-0001-Add-subscription-to-the-standby-test-in-035_stand.patch (text/plain, 7.0K) download
From 2a8b8bdc32671b33b2b7c0fa1a79f8d7624ae4a6 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Mon, 24 Apr 2023 05:13:23 +0000
Subject: [PATCH v6] Add subscription to the standby test in
035_standby_logical_decoding.pl
Adding one test, to verify that subscription to the standby is possible.
---
src/test/perl/PostgreSQL/Test/Cluster.pm | 21 ++++-
.../t/035_standby_logical_decoding.pl | 91 ++++++++++++++++++-
2 files changed, 107 insertions(+), 5 deletions(-)
18.8% src/test/perl/PostgreSQL/Test/
81.1% src/test/recovery/t/
diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pmindex 6f7f4e5de4..9117554c07 100644--- a/src/test/perl/PostgreSQL/Test/Cluster.pm+++ b/src/test/perl/PostgreSQL/Test/Cluster.pm@@ -2611,8 +2611,14 @@ When doing physical replication, the standby is usually identified by
passing its PostgreSQL::Test::Cluster instance. When doing logical
replication, standby_name identifies a subscription.
-The default value of target_lsn is $node->lsn('write'), which ensures-that the standby has caught up to what has been committed on the primary.+When not in recovery, the default value of target_lsn is $node->lsn('write'),+which ensures that the standby has caught up to what has been committed on+the primary.++When in recovery, the default value of target_lsn is $node->lsn('replay')+instead. This is needed when the publisher passed to wait_for_subscription_sync()+is a standby node.+
If you pass an explicit value of target_lsn, it should almost always be
the primary's write LSN; so this parameter is seldom needed except when
querying some intermediate replication node rather than the primary.
@@ -2644,7 +2650,16 @@ sub wait_for_catchup
}
if (!defined($target_lsn))
{
- $target_lsn = $self->lsn('write');+ my $isrecovery = $self->safe_psql('postgres', "SELECT pg_is_in_recovery()");+ chomp($isrecovery);+ if ($isrecovery eq 't')+ {+ $target_lsn = $self->lsn('replay');+ }+ else+ {+ $target_lsn = $self->lsn('write');+ }
}
print "Waiting for replication conn "
. $standby_name . "'s "
diff --git a/src/test/recovery/t/035_standby_logical_decoding.pl b/src/test/recovery/t/035_standby_logical_decoding.plindex b8f5311fe9..f6d6447412 100644--- a/src/test/recovery/t/035_standby_logical_decoding.pl+++ b/src/test/recovery/t/035_standby_logical_decoding.pl@@ -10,12 +10,17 @@ use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More;
-my ($stdin, $stdout, $stderr, $cascading_stdout, $cascading_stderr, $ret, $handle, $slot);+my ($stdin, $stdout, $stderr,+ $cascading_stdout, $cascading_stderr, $subscriber_stdin,+ $subscriber_stdout, $subscriber_stderr, $ret,+ $handle, $slot);
my $node_primary = PostgreSQL::Test::Cluster->new('primary');
my $node_standby = PostgreSQL::Test::Cluster->new('standby');
my $node_cascading_standby = PostgreSQL::Test::Cluster->new('cascading_standby');
+my $node_subscriber = PostgreSQL::Test::Cluster->new('subscriber');
my $default_timeout = $PostgreSQL::Test::Utils::timeout_default;
+my $psql_timeout = IPC::Run::timer($default_timeout);
my $res;
# Name for the physical slot on primary
@@ -267,7 +272,8 @@ $node_standby->init_from_backup(
has_streaming => 1,
has_restoring => 1);
$node_standby->append_conf('postgresql.conf',
- qq[primary_slot_name = '$primary_slotname']);+ qq[primary_slot_name = '$primary_slotname'+ max_replication_slots = 5]);
$node_standby->start;
$node_primary->wait_for_replay_catchup($node_standby);
$node_standby->safe_psql('testdb', qq[SELECT * FROM pg_create_physical_replication_slot('$standby_physical_slotname');]);
@@ -285,6 +291,26 @@ $node_cascading_standby->append_conf('postgresql.conf',
$node_cascading_standby->start;
$node_standby->wait_for_replay_catchup($node_cascading_standby, $node_primary);
+#######################+# Initialize subscriber node+#######################+$node_subscriber->init(allows_streaming => 'logical');+$node_subscriber->start;++my %psql_subscriber = (+ 'subscriber_stdin' => '',+ 'subscriber_stdout' => '',+ 'subscriber_stderr' => '');+$psql_subscriber{run} = IPC::Run::start(+ [ 'psql', '-XA', '-f', '-', '-d', $node_subscriber->connstr('postgres') ],+ '<',+ \$psql_subscriber{subscriber_stdin},+ '>',+ \$psql_subscriber{subscriber_stdout},+ '2>',+ \$psql_subscriber{subscriber_stderr},+ $psql_timeout);+
##################################################
# Test that logical decoding on the standby
# behaves correctly.
@@ -365,6 +391,67 @@ is( $node_primary->psql(
3,
'replaying logical slot from another database fails');
+##################################################+# Test that we can subscribe on the standby with the publication+# created on the primary.+##################################################++# Create a table on the primary+$node_primary->safe_psql('postgres',+ "CREATE TABLE tab_rep (a int primary key)");++# Create a table (same structure) on the subscriber node+$node_subscriber->safe_psql('postgres',+ "CREATE TABLE tab_rep (a int primary key)");++# Create a publication on the primary+$node_primary->safe_psql('postgres',+ "CREATE PUBLICATION tap_pub for table tab_rep");++$node_primary->wait_for_replay_catchup($node_standby);++# Subscribe on the standby+my $standby_connstr = $node_standby->connstr . ' dbname=postgres';++# Not using safe_psql() here as it would wait for activity on the primary+# and we wouldn't be able to launch pg_log_standby_snapshot() on the primary+# while waiting.+# psql_subscriber() allows to not wait synchronously.+$psql_subscriber{subscriber_stdin} .=+ qq[CREATE SUBSCRIPTION tap_sub+ CONNECTION '$standby_connstr'+ PUBLICATION tap_pub+ WITH (copy_data = off);];+$psql_subscriber{subscriber_stdin} .= "\n";++$psql_subscriber{run}->pump_nb();++# Speed up the subscription creation+$node_primary->safe_psql('postgres', "SELECT pg_log_standby_snapshot()");++# Explicitly shut down psql instance gracefully - to avoid hangs+# or worse on windows+$psql_subscriber{subscriber_stdin} .= "\\q\n";+$psql_subscriber{run}->finish;++$node_subscriber->wait_for_subscription_sync($node_standby, 'tap_sub');++# Insert some rows on the primary+$node_primary->safe_psql('postgres',+ qq[INSERT INTO tab_rep select generate_series(1,10);]);++$node_primary->wait_for_replay_catchup($node_standby);+$node_standby->wait_for_catchup('tap_sub');++# Check that the subscriber can see the rows inserted in the primary+$result =+ $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM tab_rep");+is($result, qq(10), 'check replicated inserts after subscription on standby');++# We do not need the subscription and the subscriber anymore+$node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION tap_sub");+$node_subscriber->stop;+
##################################################
# Recovery conflict: Invalidate conflicting slots, including in-use slots
# Scenario 1: hot_standby_feedback off and vacuum FULL
--
2.34.1
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: bertranddrouvot.pg@gmail.com, alvherre@alvh.no-ip.org, vignesh21@gmail.com, amit.kapila16@gmail.com, pgsql-hackers@lists.postgresql.org
Subject: Re: Add two missing tests in 035_standby_logical_decoding.pl
In-Reply-To: <19d8fa0d-e840-66eb-f5bc-4c3f9594ec8b@gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox