Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit376dc82

Browse files
author
Amit Kapila
committed
Add a test to verify that subscription to the standby works.
Author: Bertrand DrouvotReviewed-by: Vignesh C, Alvaro Herrera, Amit KapilaDiscussion:https://postgr.es/m/2fefa454-5a70-2174-ddbf-4a0e41537139@gmail.com
1 parentbedc1f0 commit376dc82

File tree

2 files changed

+107
-5
lines changed

2 files changed

+107
-5
lines changed

‎src/test/perl/PostgreSQL/Test/Cluster.pm

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,8 +2611,14 @@ When doing physical replication, the standby is usually identified by
26112611
passing its PostgreSQL::Test::Cluster instance. When doing logical
26122612
replication, standby_name identifies a subscription.
26132613
2614-
The default value of target_lsn is $node->lsn('write'), which ensures
2615-
that the standby has caught up to what has been committed on the primary.
2614+
When not in recovery, the default value of target_lsn is $node->lsn('write'),
2615+
which ensures that the standby has caught up to what has been committed on
2616+
the primary.
2617+
2618+
When in recovery, the default value of target_lsn is $node->lsn('replay')
2619+
instead which ensures that the cascaded standby has caught up to what has been
2620+
replayed on the standby.
2621+
26162622
If you pass an explicit value of target_lsn, it should almost always be
26172623
the primary's write LSN; so this parameter is seldom needed except when
26182624
querying some intermediate replication node rather than the primary.
@@ -2644,7 +2650,16 @@ sub wait_for_catchup
26442650
}
26452651
if (!defined($target_lsn))
26462652
{
2647-
$target_lsn =$self->lsn('write');
2653+
my$isrecovery =$self->safe_psql('postgres',"SELECT pg_is_in_recovery()");
2654+
chomp($isrecovery);
2655+
if ($isrecoveryeq't')
2656+
{
2657+
$target_lsn =$self->lsn('replay');
2658+
}
2659+
else
2660+
{
2661+
$target_lsn =$self->lsn('write');
2662+
}
26482663
}
26492664
print"Waiting for replication conn"
26502665
.$standby_name ."'s"

‎src/test/recovery/t/035_standby_logical_decoding.pl

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@
1010
use PostgreSQL::Test::Utils;
1111
use Test::More;
1212

13-
my ($stdin,$stdout,$stderr,$cascading_stdout,$cascading_stderr,$ret,$handle,$slot);
13+
my ($stdin,$stdout,$stderr,
14+
$cascading_stdout,$cascading_stderr,$subscriber_stdin,
15+
$subscriber_stdout,$subscriber_stderr,$ret,
16+
$handle,$slot);
1417

1518
my$node_primary = PostgreSQL::Test::Cluster->new('primary');
1619
my$node_standby = PostgreSQL::Test::Cluster->new('standby');
1720
my$node_cascading_standby = PostgreSQL::Test::Cluster->new('cascading_standby');
21+
my$node_subscriber = PostgreSQL::Test::Cluster->new('subscriber');
1822
my$default_timeout =$PostgreSQL::Test::Utils::timeout_default;
23+
my$psql_timeout = IPC::Run::timer($default_timeout);
1924
my$res;
2025

2126
# Name for the physical slot on primary
@@ -267,7 +272,8 @@ sub check_for_invalidation
267272
has_streaming=> 1,
268273
has_restoring=> 1);
269274
$node_standby->append_conf('postgresql.conf',
270-
qq[primary_slot_name = '$primary_slotname']);
275+
qq[primary_slot_name = '$primary_slotname'
276+
max_replication_slots = 5]);
271277
$node_standby->start;
272278
$node_primary->wait_for_replay_catchup($node_standby);
273279
$node_standby->safe_psql('testdb',qq[SELECT * FROM pg_create_physical_replication_slot('$standby_physical_slotname');]);
@@ -285,6 +291,26 @@ sub check_for_invalidation
285291
$node_cascading_standby->start;
286292
$node_standby->wait_for_replay_catchup($node_cascading_standby,$node_primary);
287293

294+
#######################
295+
# Initialize subscriber node
296+
#######################
297+
$node_subscriber->init(allows_streaming=>'logical');
298+
$node_subscriber->start;
299+
300+
my%psql_subscriber = (
301+
'subscriber_stdin'=>'',
302+
'subscriber_stdout'=>'',
303+
'subscriber_stderr'=>'');
304+
$psql_subscriber{run} = IPC::Run::start(
305+
['psql','-XA','-f','-','-d',$node_subscriber->connstr('postgres') ],
306+
'<',
307+
\$psql_subscriber{subscriber_stdin},
308+
'>',
309+
\$psql_subscriber{subscriber_stdout},
310+
'2>',
311+
\$psql_subscriber{subscriber_stderr},
312+
$psql_timeout);
313+
288314
##################################################
289315
# Test that logical decoding on the standby
290316
# behaves correctly.
@@ -365,6 +391,67 @@ sub check_for_invalidation
365391
3,
366392
'replaying logical slot from another database fails');
367393

394+
##################################################
395+
# Test that we can subscribe on the standby with the publication
396+
# created on the primary.
397+
##################################################
398+
399+
# Create a table on the primary
400+
$node_primary->safe_psql('postgres',
401+
"CREATE TABLE tab_rep (a int primary key)");
402+
403+
# Create a table (same structure) on the subscriber node
404+
$node_subscriber->safe_psql('postgres',
405+
"CREATE TABLE tab_rep (a int primary key)");
406+
407+
# Create a publication on the primary
408+
$node_primary->safe_psql('postgres',
409+
"CREATE PUBLICATION tap_pub for table tab_rep");
410+
411+
$node_primary->wait_for_replay_catchup($node_standby);
412+
413+
# Subscribe on the standby
414+
my$standby_connstr =$node_standby->connstr .' dbname=postgres';
415+
416+
# Not using safe_psql() here as it would wait for activity on the primary
417+
# and we wouldn't be able to launch pg_log_standby_snapshot() on the primary
418+
# while waiting.
419+
# psql_subscriber() allows to not wait synchronously.
420+
$psql_subscriber{subscriber_stdin} .=
421+
qq[CREATE SUBSCRIPTION tap_sub
422+
CONNECTION '$standby_connstr'
423+
PUBLICATION tap_pub
424+
WITH (copy_data = off);];
425+
$psql_subscriber{subscriber_stdin} .="\n";
426+
427+
$psql_subscriber{run}->pump_nb();
428+
429+
# Speed up the subscription creation
430+
$node_primary->safe_psql('postgres',"SELECT pg_log_standby_snapshot()");
431+
432+
# Explicitly shut down psql instance gracefully - to avoid hangs
433+
# or worse on windows
434+
$psql_subscriber{subscriber_stdin} .="\\q\n";
435+
$psql_subscriber{run}->finish;
436+
437+
$node_subscriber->wait_for_subscription_sync($node_standby,'tap_sub');
438+
439+
# Insert some rows on the primary
440+
$node_primary->safe_psql('postgres',
441+
qq[INSERT INTO tab_rep select generate_series(1,10);]);
442+
443+
$node_primary->wait_for_replay_catchup($node_standby);
444+
$node_standby->wait_for_catchup('tap_sub');
445+
446+
# Check that the subscriber can see the rows inserted in the primary
447+
$result =
448+
$node_subscriber->safe_psql('postgres',"SELECT count(*) FROM tab_rep");
449+
is($result,qq(10),'check replicated inserts after subscription on standby');
450+
451+
# We do not need the subscription and the subscriber anymore
452+
$node_subscriber->safe_psql('postgres',"DROP SUBSCRIPTION tap_sub");
453+
$node_subscriber->stop;
454+
368455
##################################################
369456
# Recovery conflict: Invalidate conflicting slots, including in-use slots
370457
# Scenario 1: hot_standby_feedback off and vacuum FULL

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp