diff --git a/src/test/recovery/t/009_twophase.pl b/src/test/recovery/t/009_twophase.pl old mode 100644 new mode 100755 index be7f00b..d340953 --- a/src/test/recovery/t/009_twophase.pl +++ b/src/test/recovery/t/009_twophase.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 13; +use Test::More tests => 21; # Setup master node my $node_master = get_new_node("master"); @@ -320,3 +320,88 @@ $node_master->psql('postgres', " $node_master->psql('postgres', "SELECT count(*) FROM t_009_tbl", stdout => \$psql_out); is($psql_out, '6', "Check nextXid handling for prepared subtransactions"); + +############################################################################### +# Check that replay will correctly set 2PC with more than +# PGPROC_MAX_CACHED_SUBXIDS subtransations and also show data properly +# on promotion +############################################################################### +$node_master->psql('postgres', "DELETE FROM t_009_tbl"); + +# Function borrowed from src/test/regress/sql/hs_primary_extremes.sql +$node_master->psql('postgres', " + CREATE OR REPLACE FUNCTION hs_subxids (n integer) + RETURNS void + LANGUAGE plpgsql + AS \$\$ + BEGIN + IF n <= 0 THEN RETURN; END IF; + INSERT INTO t_009_tbl VALUES (n); + PERFORM hs_subxids(n - 1); + RETURN; + EXCEPTION WHEN raise_exception THEN NULL; END; + \$\$;"); +$node_master->psql('postgres', " + BEGIN; + SELECT hs_subxids(127); + PREPARE TRANSACTION 'xact_009_1';"); +$node_master->wait_for_catchup($node_slave, 'replay', $node_master->lsn('insert')); +$node_slave->psql('postgres', "SELECT coalesce(sum(id),-1) FROM t_009_tbl", + stdout => \$psql_out); +is($psql_out, '-1', "Not visible"); +$node_master->stop; +$node_slave->promote; +$node_slave->poll_query_until('postgres', + "SELECT NOT pg_is_in_recovery()") + or die "Timed out while waiting for promotion of standby"; + +$node_slave->psql('postgres', "SELECT coalesce(sum(id),-1) FROM t_009_tbl", + stdout => \$psql_out); +is($psql_out, '-1', "Not visible"); + +# restore state +($node_master, $node_slave) = ($node_slave, $node_master); +$node_slave->enable_streaming($node_master); +$node_slave->append_conf('recovery.conf', qq( +recovery_target_timeline='latest' +)); +$node_slave->start; +$psql_rc = $node_master->psql('postgres', "COMMIT PREPARED 'xact_009_1'"); +is($psql_rc, '0', "Restore of PGPROC_MAX_CACHED_SUBXIDS+ prepared transaction on promoted slave"); + +$node_master->psql('postgres', "SELECT coalesce(sum(id),-1) FROM t_009_tbl", + stdout => \$psql_out); +is($psql_out, '8128', "Visible"); + +$node_master->psql('postgres', "DELETE FROM t_009_tbl"); +$node_master->psql('postgres', " + BEGIN; + SELECT hs_subxids(201); + PREPARE TRANSACTION 'xact_009_1';"); +$node_master->wait_for_catchup($node_slave, 'replay', $node_master->lsn('insert')); +$node_slave->psql('postgres', "SELECT coalesce(sum(id),-1) FROM t_009_tbl", + stdout => \$psql_out); +is($psql_out, '-1', "Not visible"); +$node_master->stop; +$node_slave->promote; +$node_slave->poll_query_until('postgres', + "SELECT NOT pg_is_in_recovery()") + or die "Timed out while waiting for promotion of standby"; + +$node_slave->psql('postgres', "SELECT coalesce(sum(id),-1) FROM t_009_tbl", + stdout => \$psql_out); +is($psql_out, '-1', "Not visible"); + +# restore state +($node_master, $node_slave) = ($node_slave, $node_master); +$node_slave->enable_streaming($node_master); +$node_slave->append_conf('recovery.conf', qq( +recovery_target_timeline='latest' +)); +$node_slave->start; +$psql_rc = $node_master->psql('postgres', "ROLLBACK PREPARED 'xact_009_1'"); +is($psql_rc, '0', "Rollback of PGPROC_MAX_CACHED_SUBXIDS+ prepared transaction on promoted slave"); + +$node_master->psql('postgres', "SELECT coalesce(sum(id),-1) FROM t_009_tbl", + stdout => \$psql_out); +is($psql_out, '-1', "Not visible");