diff --git a/src/test/recovery/t/035_standby_logical_decoding.pl b/src/test/recovery/t/035_standby_logical_decoding.pl index e2c46a6bf6..561dcd33c3 100644 --- a/src/test/recovery/t/035_standby_logical_decoding.pl +++ b/src/test/recovery/t/035_standby_logical_decoding.pl @@ -51,16 +51,23 @@ sub wait_for_xmins # Create the required logical slots on standby. sub create_logical_slots { - my ($node) = @_; - $node->create_logical_slot_on_standby($node_primary, 'inactiveslot', 'testdb'); - $node->create_logical_slot_on_standby($node_primary, 'activeslot', 'testdb'); + my ($node, $slot_prefix) = @_; + + my $active_slot = $slot_prefix . 'activeslot'; + my $inactive_slot = $slot_prefix . 'inactiveslot'; + $node->create_logical_slot_on_standby($node_primary, qq($inactive_slot), 'testdb'); + $node->create_logical_slot_on_standby($node_primary, qq($active_slot), 'testdb'); } # Drop the logical slots on standby. sub drop_logical_slots { - $node_standby->psql('postgres', q[SELECT pg_drop_replication_slot('inactiveslot')]); - $node_standby->psql('postgres', q[SELECT pg_drop_replication_slot('activeslot')]); + my ($slot_prefix) = @_; + my $active_slot = $slot_prefix . 'activeslot'; + my $inactive_slot = $slot_prefix . 'inactiveslot'; + + $node_standby->psql('postgres', qq[SELECT pg_drop_replication_slot('$inactive_slot')]); + $node_standby->psql('postgres', qq[SELECT pg_drop_replication_slot('$active_slot')]); } # Acquire one of the standby logical slots created by create_logical_slots(). @@ -68,16 +75,17 @@ sub drop_logical_slots # If wait is not true it means we are testing a known failure scenario. sub make_slot_active { - my ($node, $wait, $to_stdout, $to_stderr) = @_; + my ($node, $slot_prefix, $wait, $to_stdout, $to_stderr) = @_; my $slot_user_handle; - $slot_user_handle = IPC::Run::start(['pg_recvlogical', '-d', $node->connstr('testdb'), '-S', 'activeslot', '-o', 'include-xids=0', '-o', 'skip-empty-xacts=1', '--no-loop', '--start', '-f', '-'], '>', $to_stdout, '2>', $to_stderr); + my $active_slot = $slot_prefix . 'activeslot'; + $slot_user_handle = IPC::Run::start(['pg_recvlogical', '-d', $node->connstr('testdb'), '-S', qq($active_slot), '-o', 'include-xids=0', '-o', 'skip-empty-xacts=1', '--no-loop', '--start', '-f', '-'], '>', $to_stdout, '2>', $to_stderr); if ($wait) { # make sure activeslot is in use $node->poll_query_until('testdb', - "SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'activeslot' AND active_pid IS NOT NULL)" + qq[SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = '$active_slot' AND active_pid IS NOT NULL)] ) or die "slot never became active"; } return $slot_user_handle; @@ -104,10 +112,10 @@ sub check_pg_recvlogical_stderr # that was acquired by make_slot_active(), and the non-active 'inactiveslot'. sub check_slots_dropped { - my ($slot_user_handle) = @_; + my ($slot_prefix, $slot_user_handle) = @_; - is($node_standby->slot('inactiveslot')->{'slot_type'}, '', 'inactiveslot on standby dropped'); - is($node_standby->slot('activeslot')->{'slot_type'}, '', 'activeslot on standby dropped'); + is($node_standby->slot($slot_prefix . 'inactiveslot')->{'slot_type'}, '', 'inactiveslot on standby dropped'); + is($node_standby->slot($slot_prefix . 'activeslot')->{'slot_type'}, '', 'activeslot on standby dropped'); check_pg_recvlogical_stderr($slot_user_handle, "conflict with recovery"); } @@ -170,6 +178,51 @@ sub check_slots_conflicting_status } } +# Drop the slots, re-create them, change hot_standby_feedback, +# check xmin and catalog_xmin values, make slot active and reset stat. +sub reactive_slots_change_hfs_and_wait_for_xmins +{ + my ($previous_slot_prefix, $slot_prefix, $hsf, $invalidated) = @_; + + # drop the logical slots + drop_logical_slots($previous_slot_prefix); + + # create the logical slots + create_logical_slots($node_standby, $slot_prefix); + + change_hot_standby_feedback_and_wait_for_xmins($hsf, $invalidated); + + $handle = make_slot_active($node_standby, $slot_prefix, 1, \$stdout, \$stderr); + + # reset stat: easier to check for confl_active_logicalslot in pg_stat_database_conflicts + $node_standby->psql('testdb', q[select pg_stat_reset();]); +} + +# Check invalidation in the logfile and in pg_stat_database_conflicts +sub check_for_invalidation +{ + my ($slot_prefix, $log_start, $test_name) = @_; + + my $active_slot = $slot_prefix . 'activeslot'; + my $inactive_slot = $slot_prefix . 'inactiveslot'; + + # message should be issued + ok( find_in_log( + $node_standby, + "invalidating obsolete replication slot \"$inactive_slot\"", $log_start), + "inactiveslot slot invalidation is logged $test_name"); + + ok( find_in_log( + $node_standby, + "invalidating obsolete replication slot \"$active_slot\"", $log_start), + "activeslot slot invalidation is logged $test_name"); + + # Verify that pg_stat_database_conflicts.confl_active_logicalslot has been updated + ok( $node_standby->poll_query_until( + 'postgres', + "select (confl_active_logicalslot = 1) from pg_stat_database_conflicts where datname = 'testdb'", 't'), + 'confl_active_logicalslot updated') or die "Timed out waiting confl_active_logicalslot to be updated"; +} ######################## # Initialize primary node ######################## @@ -233,7 +286,7 @@ $node_standby->wait_for_replay_catchup($node_cascading_standby, $node_primary); ################################################## # create the logical slots -create_logical_slots($node_standby); +create_logical_slots($node_standby, 'behaves_ok_'); $node_primary->safe_psql('testdb', qq[CREATE TABLE decoding_test(x integer, y text);]); $node_primary->safe_psql('testdb', qq[INSERT INTO decoding_test(x,y) SELECT s, s::text FROM generate_series(1,10) s;]); @@ -241,7 +294,7 @@ $node_primary->safe_psql('testdb', qq[INSERT INTO decoding_test(x,y) SELECT s, s $node_primary->wait_for_replay_catchup($node_standby); my $result = $node_standby->safe_psql('testdb', - qq[SELECT pg_logical_slot_get_changes('activeslot', NULL, NULL);]); + qq[SELECT pg_logical_slot_get_changes('behaves_ok_activeslot', NULL, NULL);]); # test if basic decoding works is(scalar(my @foobar = split /^/m, $result), @@ -263,13 +316,13 @@ COMMIT}; $node_primary->wait_for_replay_catchup($node_standby); my $stdout_sql = $node_standby->safe_psql('testdb', - qq[SELECT data FROM pg_logical_slot_peek_changes('activeslot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');] + qq[SELECT data FROM pg_logical_slot_peek_changes('behaves_ok_activeslot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');] ); is($stdout_sql, $expected, 'got expected output from SQL decoding session'); my $endpos = $node_standby->safe_psql('testdb', - "SELECT lsn FROM pg_logical_slot_peek_changes('activeslot', NULL, NULL) ORDER BY lsn DESC LIMIT 1;" + "SELECT lsn FROM pg_logical_slot_peek_changes('behaves_ok_activeslot', NULL, NULL) ORDER BY lsn DESC LIMIT 1;" ); # Insert some rows after $endpos, which we won't read. @@ -280,7 +333,7 @@ $node_primary->safe_psql('testdb', $node_primary->wait_for_catchup($node_standby); my $stdout_recv = $node_standby->pg_recvlogical_upto( - 'testdb', 'activeslot', $endpos, $default_timeout, + 'testdb', 'behaves_ok_activeslot', $endpos, $default_timeout, 'include-xids' => '0', 'skip-empty-xacts' => '1'); chomp($stdout_recv); @@ -288,11 +341,11 @@ is($stdout_recv, $expected, 'got same expected output from pg_recvlogical decoding session'); $node_standby->poll_query_until('testdb', - "SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'activeslot' AND active_pid IS NULL)" + "SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'behaves_ok_activeslot' AND active_pid IS NULL)" ) or die "slot never became inactive"; $stdout_recv = $node_standby->pg_recvlogical_upto( - 'testdb', 'activeslot', $endpos, $default_timeout, + 'testdb', 'behaves_ok_activeslot', $endpos, $default_timeout, 'include-xids' => '0', 'skip-empty-xacts' => '1'); chomp($stdout_recv); @@ -302,28 +355,20 @@ $node_primary->safe_psql('postgres', 'CREATE DATABASE otherdb'); is( $node_primary->psql( 'otherdb', - "SELECT lsn FROM pg_logical_slot_peek_changes('activeslot', NULL, NULL) ORDER BY lsn DESC LIMIT 1;" + "SELECT lsn FROM pg_logical_slot_peek_changes('behaves_ok_activeslot', NULL, NULL) ORDER BY lsn DESC LIMIT 1;" ), 3, 'replaying logical slot from another database fails'); -# drop the logical slots -drop_logical_slots(); - ################################################## # Recovery conflict: Invalidate conflicting slots, including in-use slots # Scenario 1: hot_standby_feedback off and vacuum FULL ################################################## -# create the logical slots -create_logical_slots($node_standby); - # One way to produce recovery conflict is to create/drop a relation and # launch a vacuum full on pg_class with hot_standby_feedback turned off on # the standby. -change_hot_standby_feedback_and_wait_for_xmins(0,1); - -$handle = make_slot_active($node_standby, 1, \$stdout, \$stderr); +reactive_slots_change_hfs_and_wait_for_xmins('behaves_ok_', 'vacuum_full_', 0, 1); # This should trigger the conflict $node_primary->safe_psql('testdb', qq[CREATE TABLE conflict_test(x integer, y text);]); @@ -332,34 +377,33 @@ $node_primary->safe_psql('testdb', 'VACUUM full pg_class;'); $node_primary->wait_for_replay_catchup($node_standby); -# message should be issued -ok( find_in_log( - $node_standby, - "invalidating obsolete replication slot \"inactiveslot\""), - 'inactiveslot slot invalidation is logged with vacuum FULL on pg_class'); - -ok( find_in_log( - $node_standby, - "invalidating obsolete replication slot \"activeslot\""), - 'activeslot slot invalidation is logged with vacuum FULL on pg_class'); - -# Verify that pg_stat_database_conflicts.confl_active_logicalslot has been updated -ok( $node_standby->poll_query_until( - 'postgres', - "select (confl_active_logicalslot = 1) from pg_stat_database_conflicts where datname = 'testdb'", 't'), - 'confl_active_logicalslot updated') or die "Timed out waiting confl_active_logicalslot to be updated"; +# Check invalidation in the logfile and in pg_stat_database_conflicts +check_for_invalidation('vacuum_full_', 1, 'with vacuum FULL on pg_class'); # Verify slots are reported as conflicting in pg_replication_slots check_slots_conflicting_status(1); -$handle = make_slot_active($node_standby, 0, \$stdout, \$stderr); +$handle = make_slot_active($node_standby, 'vacuum_full_', 0, \$stdout, \$stderr); # We are not able to read from the slot as it has been invalidated -check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot \"activeslot\""); +check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot \"vacuum_full_activeslot\""); # Turn hot_standby_feedback back on change_hot_standby_feedback_and_wait_for_xmins(1,1); +################################################## +# Verify that invalidated logical slots stay invalidated across a restart. +################################################## +$node_standby->restart; + +# Verify slots are reported as conflicting in pg_replication_slots +check_slots_conflicting_status(1); + +################################################## +# Verify that invalidated logical slots do not lead to retaining WAL +################################################## +# XXXXX TODO + ################################################## # Recovery conflict: Invalidate conflicting slots, including in-use slots # Scenario 2: conflict due to row removal with hot_standby_feedback off. @@ -368,17 +412,9 @@ change_hot_standby_feedback_and_wait_for_xmins(1,1); # get the position to search from in the standby logfile my $logstart = -s $node_standby->logfile; -# drop the logical slots -drop_logical_slots(); - -# create the logical slots -create_logical_slots($node_standby); - # One way to produce recovery conflict is to create/drop a relation and # launch a vacuum on pg_class with hot_standby_feedback turned off on the standby. -change_hot_standby_feedback_and_wait_for_xmins(0,1); - -$handle = make_slot_active($node_standby, 1, \$stdout, \$stderr); +reactive_slots_change_hfs_and_wait_for_xmins('vacuum_full_', 'row_removal_', 0, 1); # This should trigger the conflict $node_primary->safe_psql('testdb', qq[CREATE TABLE conflict_test(x integer, y text);]); @@ -387,31 +423,16 @@ $node_primary->safe_psql('testdb', 'VACUUM pg_class;'); $node_primary->wait_for_replay_catchup($node_standby); -# message should be issued -ok( find_in_log( - $node_standby, - "invalidating obsolete replication slot \"inactiveslot\"", $logstart), - 'inactiveslot slot invalidation is logged with vacuum on pg_class'); - -ok( find_in_log( - $node_standby, - "invalidating obsolete replication slot \"activeslot\"", $logstart), - 'activeslot slot invalidation is logged with vacuum on pg_class'); - -# Verify that pg_stat_database_conflicts.confl_active_logicalslot has been updated -# we now expect 2 conflicts reported as the counter persist across reloads -ok( $node_standby->poll_query_until( - 'postgres', - "select (confl_active_logicalslot = 2) from pg_stat_database_conflicts where datname = 'testdb'", 't'), - 'confl_active_logicalslot updated') or die "Timed out waiting confl_active_logicalslot to be updated"; +# Check invalidation in the logfile and in pg_stat_database_conflicts +check_for_invalidation('row_removal_', $logstart, 'with vacuum on pg_class'); # Verify slots are reported as conflicting in pg_replication_slots check_slots_conflicting_status(1); -$handle = make_slot_active($node_standby, 0, \$stdout, \$stderr); +$handle = make_slot_active($node_standby, 'row_removal_', 0, \$stdout, \$stderr); # We are not able to read from the slot as it has been invalidated -check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot \"activeslot\""); +check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot \"row_removal_activeslot\""); ################################################## # Recovery conflict: Same as Scenario 2 but on a shared catalog table @@ -421,17 +442,9 @@ check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot # get the position to search from in the standby logfile $logstart = -s $node_standby->logfile; -# drop the logical slots -drop_logical_slots(); - -# create the logical slots -create_logical_slots($node_standby); - # One way to produce recovery conflict is to create/drop a relation and # launch a vacuum on pg_class with hot_standby_feedback turned off on the standby. -change_hot_standby_feedback_and_wait_for_xmins(0,1); - -$handle = make_slot_active($node_standby, 1, \$stdout, \$stderr); +reactive_slots_change_hfs_and_wait_for_xmins('row_removal_', 'shared_row_removal_', 0, 1); # Trigger the conflict. The txid_current() is to ensure there's some WAL # record associated with the database, otherwise the wait below does not work @@ -445,31 +458,16 @@ $node_primary->safe_psql('testdb', 'VACUUM pg_authid;'); $node_primary->wait_for_replay_catchup($node_standby); -# message should be issued -ok( find_in_log( - $node_standby, - "invalidating obsolete replication slot \"inactiveslot\"", $logstart), - 'inactiveslot slot invalidation is logged with vacuum on pg_authid'); - -ok( find_in_log( - $node_standby, - "invalidating obsolete replication slot \"activeslot\"", $logstart), - 'activeslot slot invalidation is logged with vacuum on pg_authid'); - -# Verify that pg_stat_database_conflicts.confl_active_logicalslot has been updated -# we now expect 2 conflicts reported as the counter persist across reloads -ok( $node_standby->poll_query_until( - 'postgres', - "select (confl_active_logicalslot = 3) from pg_stat_database_conflicts where datname = 'testdb'", 't'), - 'confl_active_logicalslot updated') or die "Timed out waiting confl_active_logicalslot to be updated"; +# Check invalidation in the logfile and in pg_stat_database_conflicts +check_for_invalidation('shared_row_removal_', $logstart, 'with vacuum on pg_authid'); # Verify slots are reported as conflicting in pg_replication_slots check_slots_conflicting_status(1); -$handle = make_slot_active($node_standby, 0, \$stdout, \$stderr); +$handle = make_slot_active($node_standby, 'shared_row_removal_', 0, \$stdout, \$stderr); # We are not able to read from the slot as it has been invalidated -check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot \"activeslot\""); +check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot \"shared_row_removal_activeslot\""); ################################################## # Recovery conflict: Same as Scenario 2 but on a non catalog table @@ -479,41 +477,30 @@ check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot # get the position to search from in the standby logfile $logstart = -s $node_standby->logfile; -# drop the logical slots -drop_logical_slots(); - -# create the logical slots -create_logical_slots($node_standby); - -# put hot standby feedback to off -change_hot_standby_feedback_and_wait_for_xmins(0,1); - -$handle = make_slot_active($node_standby, 1, \$stdout, \$stderr); +reactive_slots_change_hfs_and_wait_for_xmins('shared_row_removal_', 'no_conflict_', 0, 1); # This should not trigger a conflict -$node_primary->safe_psql('testdb', qq[CREATE TABLE conflict_test(x integer, y text);]); -$node_primary->safe_psql('testdb', qq[INSERT INTO conflict_test(x,y) SELECT s, s::text FROM generate_series(1,4) s;]); -$node_primary->safe_psql('testdb', qq[UPDATE conflict_test set x=1, y=1;]); -$node_primary->safe_psql('testdb', 'VACUUM conflict_test;'); - +$node_primary->safe_psql('testdb', qq[CREATE TABLE conflict_test(x integer, y text); + INSERT INTO conflict_test(x,y) SELECT s, s::text FROM generate_series(1,4) s; + UPDATE conflict_test set x=1, y=1; + VACUUM conflict_test;]); $node_primary->wait_for_replay_catchup($node_standby); # message should not be issued ok( !find_in_log( $node_standby, - "invalidating obsolete slot \"inactiveslot\"", $logstart), + "invalidating obsolete slot \"no_conflict_inactiveslot\"", $logstart), 'inactiveslot slot invalidation is not logged with vacuum on conflict_test'); ok( !find_in_log( $node_standby, - "invalidating obsolete slot \"activeslot\"", $logstart), + "invalidating obsolete slot \"no_conflict_activeslot\"", $logstart), 'activeslot slot invalidation is not logged with vacuum on conflict_test'); # Verify that pg_stat_database_conflicts.confl_active_logicalslot has not been updated -# we now still expect 2 conflicts reported as the counter persist across reloads ok( $node_standby->poll_query_until( 'postgres', - "select (confl_active_logicalslot = 3) from pg_stat_database_conflicts where datname = 'testdb'", 't'), + "select (confl_active_logicalslot = 0) from pg_stat_database_conflicts where datname = 'testdb'", 't'), 'confl_active_logicalslot not updated') or die "Timed out waiting confl_active_logicalslot to be updated"; # Verify slots are reported as non conflicting in pg_replication_slots @@ -522,6 +509,9 @@ check_slots_conflicting_status(0); # Turn hot_standby_feedback back on change_hot_standby_feedback_and_wait_for_xmins(1, 0); +# Restart the standby node to ensure no slots are still active +$node_standby->restart; + ################################################## # Recovery conflict: Invalidate conflicting slots, including in-use slots # Scenario 4: conflict due to on-access pruning. @@ -530,17 +520,9 @@ change_hot_standby_feedback_and_wait_for_xmins(1, 0); # get the position to search from in the standby logfile $logstart = -s $node_standby->logfile; -# drop the logical slots -drop_logical_slots(); - -# create the logical slots -create_logical_slots($node_standby); - # One way to produce recovery conflict is to trigger an on-access pruning # on a relation marked as user_catalog_table. -change_hot_standby_feedback_and_wait_for_xmins(0,0); - -$handle = make_slot_active($node_standby, 1, \$stdout, \$stderr); +reactive_slots_change_hfs_and_wait_for_xmins('no_conflict_', 'pruning_', 0, 0); # This should trigger the conflict $node_primary->safe_psql('testdb', qq[CREATE TABLE prun(id integer, s char(2000)) WITH (fillfactor = 75, user_catalog_table = true);]); @@ -552,31 +534,16 @@ $node_primary->safe_psql('testdb', qq[UPDATE prun SET s = 'E';]); $node_primary->wait_for_replay_catchup($node_standby); -# message should be issued -ok( find_in_log( - $node_standby, - "invalidating obsolete replication slot \"inactiveslot\"", $logstart), - 'inactiveslot slot invalidation is logged with on-access pruning'); - -ok( find_in_log( - $node_standby, - "invalidating obsolete replication slot \"activeslot\"", $logstart), - 'activeslot slot invalidation is logged with on-access pruning'); - -# Verify that pg_stat_database_conflicts.confl_active_logicalslot has been updated -# we now expect 3 conflicts reported as the counter persist across reloads -ok( $node_standby->poll_query_until( - 'postgres', - "select (confl_active_logicalslot = 4) from pg_stat_database_conflicts where datname = 'testdb'", 't'), - 'confl_active_logicalslot updated') or die "Timed out waiting confl_active_logicalslot to be updated"; +# Check invalidation in the logfile and in pg_stat_database_conflicts +check_for_invalidation('pruning_', $logstart, 'with on-access pruning'); # Verify slots are reported as conflicting in pg_replication_slots check_slots_conflicting_status(1); -$handle = make_slot_active($node_standby, 0, \$stdout, \$stderr); +$handle = make_slot_active($node_standby, 'pruning_', 0, \$stdout, \$stderr); # We are not able to read from the slot as it has been invalidated -check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot \"activeslot\""); +check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot \"pruning_activeslot\""); # Turn hot_standby_feedback back on change_hot_standby_feedback_and_wait_for_xmins(1, 1); @@ -590,12 +557,15 @@ change_hot_standby_feedback_and_wait_for_xmins(1, 1); $logstart = -s $node_standby->logfile; # drop the logical slots -drop_logical_slots(); +drop_logical_slots('pruning_'); # create the logical slots -create_logical_slots($node_standby); +create_logical_slots($node_standby, 'wal_level_'); + +$handle = make_slot_active($node_standby, 'wal_level_', 1, \$stdout, \$stderr); -$handle = make_slot_active($node_standby, 1, \$stdout, \$stderr); +# reset stat: easier to check for confl_active_logicalslot in pg_stat_database_conflicts +$node_standby->psql('testdb', q[select pg_stat_reset();]); # Make primary wal_level replica. This will trigger slot conflict. $node_primary->append_conf('postgresql.conf',q[ @@ -605,28 +575,13 @@ $node_primary->restart; $node_primary->wait_for_replay_catchup($node_standby); -# message should be issued -ok( find_in_log( - $node_standby, - "invalidating obsolete replication slot \"inactiveslot\"", $logstart), - 'inactiveslot slot invalidation is logged due to wal_level'); - -ok( find_in_log( - $node_standby, - "invalidating obsolete replication slot \"activeslot\"", $logstart), - 'activeslot slot invalidation is logged due to wal_level'); - -# Verify that pg_stat_database_conflicts.confl_active_logicalslot has been updated -# we now expect 5 conflicts reported as the counter persist across reloads -ok( $node_standby->poll_query_until( - 'postgres', - "select (confl_active_logicalslot = 5) from pg_stat_database_conflicts where datname = 'testdb'", 't'), - 'confl_active_logicalslot updated') or die "Timed out waiting confl_active_logicalslot to be updated"; +# Check invalidation in the logfile and in pg_stat_database_conflicts +check_for_invalidation('wal_level_', $logstart, 'due to wal_level'); # Verify slots are reported as conflicting in pg_replication_slots check_slots_conflicting_status(1); -$handle = make_slot_active($node_standby, 0, \$stdout, \$stderr); +$handle = make_slot_active($node_standby, 'wal_level_', 0, \$stdout, \$stderr); # We are not able to read from the slot as it requires wal_level at least logical on the primary server check_pg_recvlogical_stderr($handle, "logical decoding on standby requires wal_level to be at least logical on the primary server"); @@ -637,21 +592,22 @@ wal_level = 'logical' $node_primary->restart; $node_primary->wait_for_replay_catchup($node_standby); -$handle = make_slot_active($node_standby, 0, \$stdout, \$stderr); +$handle = make_slot_active($node_standby, 'wal_level_', 0, \$stdout, \$stderr); # as the slot has been invalidated we should not be able to read -check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot \"activeslot\""); +check_pg_recvlogical_stderr($handle, "cannot read from logical replication slot \"wal_level_activeslot\""); ################################################## # DROP DATABASE should drops it's slots, including active slots. ################################################## # drop the logical slots -drop_logical_slots(); +drop_logical_slots('wal_level_'); # create the logical slots -create_logical_slots($node_standby); +create_logical_slots($node_standby, 'drop_db_'); + +$handle = make_slot_active($node_standby, 'drop_db_', 1, \$stdout, \$stderr); -$handle = make_slot_active($node_standby, 1, \$stdout, \$stderr); # Create a slot on a database that would not be dropped. This slot should not # get dropped. $node_standby->create_logical_slot_on_standby($node_primary, 'otherslot', 'postgres'); @@ -665,7 +621,7 @@ is($node_standby->safe_psql('postgres', q[SELECT EXISTS(SELECT 1 FROM pg_database WHERE datname = 'testdb')]), 'f', 'database dropped on standby'); -check_slots_dropped($handle); +check_slots_dropped('drop_db', $handle); is($node_standby->slot('otherslot')->{'slot_type'}, 'logical', 'otherslot on standby not dropped'); @@ -684,14 +640,14 @@ $node_primary->psql('postgres', q[CREATE DATABASE testdb]); $node_primary->safe_psql('testdb', qq[CREATE TABLE decoding_test(x integer, y text);]); # create the logical slots -create_logical_slots($node_standby); +create_logical_slots($node_standby, 'promotion_'); # create the logical slots on the cascading standby too -create_logical_slots($node_cascading_standby); +create_logical_slots($node_cascading_standby, 'promotion_'); # Make slots actives -$handle = make_slot_active($node_standby, 1, \$stdout, \$stderr); -my $cascading_handle = make_slot_active($node_cascading_standby, 1, \$cascading_stdout, \$cascading_stderr); +$handle = make_slot_active($node_standby, 'promotion_', 1, \$stdout, \$stderr); +my $cascading_handle = make_slot_active($node_cascading_standby, 'promotion_', 1, \$cascading_stdout, \$cascading_stderr); # Insert some rows before the promotion $node_primary->safe_psql('testdb', @@ -727,7 +683,7 @@ COMMIT}; # check that we are decoding pre and post promotion inserted rows $stdout_sql = $node_standby->safe_psql('testdb', - qq[SELECT data FROM pg_logical_slot_peek_changes('inactiveslot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');] + qq[SELECT data FROM pg_logical_slot_peek_changes('promotion_inactiveslot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');] ); is($stdout_sql, $expected, 'got expected output from SQL decoding session on promoted standby'); @@ -746,7 +702,7 @@ is($stdout, $expected, # check that we are decoding pre and post promotion inserted rows on the cascading standby $stdout_sql = $node_cascading_standby->safe_psql('testdb', - qq[SELECT data FROM pg_logical_slot_peek_changes('inactiveslot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');] + qq[SELECT data FROM pg_logical_slot_peek_changes('promotion_inactiveslot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');] ); is($stdout_sql, $expected, 'got expected output from SQL decoding session on cascading standby');