|
|
|
@ -23,7 +23,7 @@ sub configure_and_reload |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Set up two nodes, which will alternately be master and replication standby. |
|
|
|
|
# Set up two nodes, which will alternately be primary and replication standby. |
|
|
|
|
|
|
|
|
|
# Setup london node |
|
|
|
|
my $node_london = get_new_node("london"); |
|
|
|
@ -46,13 +46,13 @@ $node_paris->start; |
|
|
|
|
configure_and_reload($node_london, "synchronous_standby_names = 'paris'"); |
|
|
|
|
configure_and_reload($node_paris, "synchronous_standby_names = 'london'"); |
|
|
|
|
|
|
|
|
|
# Set up nonce names for current master and standby nodes |
|
|
|
|
note "Initially, london is master and paris is standby"; |
|
|
|
|
my ($cur_master, $cur_standby) = ($node_london, $node_paris); |
|
|
|
|
my $cur_master_name = $cur_master->name; |
|
|
|
|
# Set up nonce names for current primary and standby nodes |
|
|
|
|
note "Initially, london is primary and paris is standby"; |
|
|
|
|
my ($cur_primary, $cur_standby) = ($node_london, $node_paris); |
|
|
|
|
my $cur_primary_name = $cur_primary->name; |
|
|
|
|
|
|
|
|
|
# Create table we'll use in the test transactions |
|
|
|
|
$cur_master->psql('postgres', "CREATE TABLE t_009_tbl (id int, msg text)"); |
|
|
|
|
$cur_primary->psql('postgres', "CREATE TABLE t_009_tbl (id int, msg text)"); |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
|
# Check that we can commit and abort transaction after soft restart. |
|
|
|
@ -61,25 +61,25 @@ $cur_master->psql('postgres', "CREATE TABLE t_009_tbl (id int, msg text)"); |
|
|
|
|
# files. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (1, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (1, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (2, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (2, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_1'; |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (3, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (3, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (4, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (4, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_2';"); |
|
|
|
|
$cur_master->stop; |
|
|
|
|
$cur_master->start; |
|
|
|
|
$cur_primary->stop; |
|
|
|
|
$cur_primary->start; |
|
|
|
|
|
|
|
|
|
$psql_rc = $cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_1'"); |
|
|
|
|
$psql_rc = $cur_primary->psql('postgres', "COMMIT PREPARED 'xact_009_1'"); |
|
|
|
|
is($psql_rc, '0', 'Commit prepared transaction after restart'); |
|
|
|
|
|
|
|
|
|
$psql_rc = $cur_master->psql('postgres', "ROLLBACK PREPARED 'xact_009_2'"); |
|
|
|
|
$psql_rc = $cur_primary->psql('postgres', "ROLLBACK PREPARED 'xact_009_2'"); |
|
|
|
|
is($psql_rc, '0', 'Rollback prepared transaction after restart'); |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
@ -88,50 +88,50 @@ is($psql_rc, '0', 'Rollback prepared transaction after restart'); |
|
|
|
|
# transaction using dedicated WAL records. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
CHECKPOINT; |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (5, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (5, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (6, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (6, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_3'; |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (7, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (7, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (8, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (8, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_4';"); |
|
|
|
|
$cur_master->teardown_node; |
|
|
|
|
$cur_master->start; |
|
|
|
|
$cur_primary->teardown_node; |
|
|
|
|
$cur_primary->start; |
|
|
|
|
|
|
|
|
|
$psql_rc = $cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_3'"); |
|
|
|
|
$psql_rc = $cur_primary->psql('postgres', "COMMIT PREPARED 'xact_009_3'"); |
|
|
|
|
is($psql_rc, '0', 'Commit prepared transaction after teardown'); |
|
|
|
|
|
|
|
|
|
$psql_rc = $cur_master->psql('postgres', "ROLLBACK PREPARED 'xact_009_4'"); |
|
|
|
|
$psql_rc = $cur_primary->psql('postgres', "ROLLBACK PREPARED 'xact_009_4'"); |
|
|
|
|
is($psql_rc, '0', 'Rollback prepared transaction after teardown'); |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
|
# Check that WAL replay can handle several transactions with same GID name. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
CHECKPOINT; |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (9, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (9, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (10, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (10, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_5'; |
|
|
|
|
COMMIT PREPARED 'xact_009_5'; |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (11, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (11, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (12, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (12, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_5';"); |
|
|
|
|
$cur_master->teardown_node; |
|
|
|
|
$cur_master->start; |
|
|
|
|
$cur_primary->teardown_node; |
|
|
|
|
$cur_primary->start; |
|
|
|
|
|
|
|
|
|
$psql_rc = $cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_5'"); |
|
|
|
|
$psql_rc = $cur_primary->psql('postgres', "COMMIT PREPARED 'xact_009_5'"); |
|
|
|
|
is($psql_rc, '0', 'Replay several transactions with same GID'); |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
@ -139,39 +139,39 @@ is($psql_rc, '0', 'Replay several transactions with same GID'); |
|
|
|
|
# while replaying transaction commits. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (13, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (13, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (14, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (14, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_6'; |
|
|
|
|
COMMIT PREPARED 'xact_009_6';"); |
|
|
|
|
$cur_master->teardown_node; |
|
|
|
|
$cur_master->start; |
|
|
|
|
$psql_rc = $cur_master->psql( |
|
|
|
|
$cur_primary->teardown_node; |
|
|
|
|
$cur_primary->start; |
|
|
|
|
$psql_rc = $cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (15, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (15, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (16, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (16, 'issued to ${cur_primary_name}'); |
|
|
|
|
-- This prepare can fail due to conflicting GID or locks conflicts if |
|
|
|
|
-- replay did not fully cleanup its state on previous commit. |
|
|
|
|
PREPARE TRANSACTION 'xact_009_7';"); |
|
|
|
|
is($psql_rc, '0', "Cleanup of shared memory state for 2PC commit"); |
|
|
|
|
|
|
|
|
|
$cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_7'"); |
|
|
|
|
$cur_primary->psql('postgres', "COMMIT PREPARED 'xact_009_7'"); |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
|
# Check that WAL replay will cleanup its shared memory state on running standby. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (17, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (17, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (18, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (18, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_8'; |
|
|
|
|
COMMIT PREPARED 'xact_009_8';"); |
|
|
|
|
$cur_standby->psql( |
|
|
|
@ -186,15 +186,15 @@ is($psql_out, '0', |
|
|
|
|
# prepare and commit to use on-disk twophase files. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (19, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (19, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (20, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (20, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_9';"); |
|
|
|
|
$cur_standby->psql('postgres', "CHECKPOINT"); |
|
|
|
|
$cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_9'"); |
|
|
|
|
$cur_primary->psql('postgres', "COMMIT PREPARED 'xact_009_9'"); |
|
|
|
|
$cur_standby->psql( |
|
|
|
|
'postgres', |
|
|
|
|
"SELECT count(*) FROM pg_prepared_xacts", |
|
|
|
@ -206,114 +206,114 @@ is($psql_out, '0', |
|
|
|
|
# Check that prepared transactions can be committed on promoted standby. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (21, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (21, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (22, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (22, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_10';"); |
|
|
|
|
$cur_master->teardown_node; |
|
|
|
|
$cur_primary->teardown_node; |
|
|
|
|
$cur_standby->promote; |
|
|
|
|
|
|
|
|
|
# change roles |
|
|
|
|
note "Now paris is master and london is standby"; |
|
|
|
|
($cur_master, $cur_standby) = ($node_paris, $node_london); |
|
|
|
|
$cur_master_name = $cur_master->name; |
|
|
|
|
note "Now paris is primary and london is standby"; |
|
|
|
|
($cur_primary, $cur_standby) = ($node_paris, $node_london); |
|
|
|
|
$cur_primary_name = $cur_primary->name; |
|
|
|
|
|
|
|
|
|
# because london is not running at this point, we can't use syncrep commit |
|
|
|
|
# on this command |
|
|
|
|
$psql_rc = $cur_master->psql('postgres', |
|
|
|
|
$psql_rc = $cur_primary->psql('postgres', |
|
|
|
|
"SET synchronous_commit = off; COMMIT PREPARED 'xact_009_10'"); |
|
|
|
|
is($psql_rc, '0', "Restore of prepared transaction on promoted standby"); |
|
|
|
|
|
|
|
|
|
# restart old master as new standby |
|
|
|
|
$cur_standby->enable_streaming($cur_master); |
|
|
|
|
# restart old primary as new standby |
|
|
|
|
$cur_standby->enable_streaming($cur_primary); |
|
|
|
|
$cur_standby->start; |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
|
# Check that prepared transactions are replayed after soft restart of standby |
|
|
|
|
# while master is down. Since standby knows that master is down it uses a |
|
|
|
|
# while primary is down. Since standby knows that primary is down it uses a |
|
|
|
|
# different code path on startup to ensure that the status of transactions is |
|
|
|
|
# consistent. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (23, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (23, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (24, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (24, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_11';"); |
|
|
|
|
$cur_master->stop; |
|
|
|
|
$cur_primary->stop; |
|
|
|
|
$cur_standby->restart; |
|
|
|
|
$cur_standby->promote; |
|
|
|
|
|
|
|
|
|
# change roles |
|
|
|
|
note "Now london is master and paris is standby"; |
|
|
|
|
($cur_master, $cur_standby) = ($node_london, $node_paris); |
|
|
|
|
$cur_master_name = $cur_master->name; |
|
|
|
|
note "Now london is primary and paris is standby"; |
|
|
|
|
($cur_primary, $cur_standby) = ($node_london, $node_paris); |
|
|
|
|
$cur_primary_name = $cur_primary->name; |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', |
|
|
|
|
"SELECT count(*) FROM pg_prepared_xacts", |
|
|
|
|
stdout => \$psql_out); |
|
|
|
|
is($psql_out, '1', |
|
|
|
|
"Restore prepared transactions from files with master down"); |
|
|
|
|
"Restore prepared transactions from files with primary down"); |
|
|
|
|
|
|
|
|
|
# restart old master as new standby |
|
|
|
|
$cur_standby->enable_streaming($cur_master); |
|
|
|
|
# restart old primary as new standby |
|
|
|
|
$cur_standby->enable_streaming($cur_primary); |
|
|
|
|
$cur_standby->start; |
|
|
|
|
|
|
|
|
|
$cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_11'"); |
|
|
|
|
$cur_primary->psql('postgres', "COMMIT PREPARED 'xact_009_11'"); |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
|
# Check that prepared transactions are correctly replayed after standby hard |
|
|
|
|
# restart while master is down. |
|
|
|
|
# restart while primary is down. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (25, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (25, 'issued to ${cur_primary_name}'); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl VALUES (26, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl VALUES (26, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_12'; |
|
|
|
|
"); |
|
|
|
|
$cur_master->stop; |
|
|
|
|
$cur_primary->stop; |
|
|
|
|
$cur_standby->teardown_node; |
|
|
|
|
$cur_standby->start; |
|
|
|
|
$cur_standby->promote; |
|
|
|
|
|
|
|
|
|
# change roles |
|
|
|
|
note "Now paris is master and london is standby"; |
|
|
|
|
($cur_master, $cur_standby) = ($node_paris, $node_london); |
|
|
|
|
$cur_master_name = $cur_master->name; |
|
|
|
|
note "Now paris is primary and london is standby"; |
|
|
|
|
($cur_primary, $cur_standby) = ($node_paris, $node_london); |
|
|
|
|
$cur_primary_name = $cur_primary->name; |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', |
|
|
|
|
"SELECT count(*) FROM pg_prepared_xacts", |
|
|
|
|
stdout => \$psql_out); |
|
|
|
|
is($psql_out, '1', |
|
|
|
|
"Restore prepared transactions from records with master down"); |
|
|
|
|
"Restore prepared transactions from records with primary down"); |
|
|
|
|
|
|
|
|
|
# restart old master as new standby |
|
|
|
|
$cur_standby->enable_streaming($cur_master); |
|
|
|
|
# restart old primary as new standby |
|
|
|
|
$cur_standby->enable_streaming($cur_primary); |
|
|
|
|
$cur_standby->start; |
|
|
|
|
|
|
|
|
|
$cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_12'"); |
|
|
|
|
$cur_primary->psql('postgres', "COMMIT PREPARED 'xact_009_12'"); |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
|
# Check for a lock conflict between prepared transaction with DDL inside and |
|
|
|
|
# replay of XLOG_STANDBY_LOCK wal record. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
CREATE TABLE t_009_tbl2 (id int, msg text); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl2 VALUES (27, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl2 VALUES (27, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_13'; |
|
|
|
|
-- checkpoint will issue XLOG_STANDBY_LOCK that can conflict with lock |
|
|
|
|
-- held by 'create table' statement |
|
|
|
@ -321,10 +321,10 @@ $cur_master->psql( |
|
|
|
|
COMMIT PREPARED 'xact_009_13';"); |
|
|
|
|
|
|
|
|
|
# Ensure that last transaction is replayed on standby. |
|
|
|
|
my $cur_master_lsn = |
|
|
|
|
$cur_master->safe_psql('postgres', "SELECT pg_current_wal_lsn()"); |
|
|
|
|
my $cur_primary_lsn = |
|
|
|
|
$cur_primary->safe_psql('postgres', "SELECT pg_current_wal_lsn()"); |
|
|
|
|
my $caughtup_query = |
|
|
|
|
"SELECT '$cur_master_lsn'::pg_lsn <= pg_last_wal_replay_lsn()"; |
|
|
|
|
"SELECT '$cur_primary_lsn'::pg_lsn <= pg_last_wal_replay_lsn()"; |
|
|
|
|
$cur_standby->poll_query_until('postgres', $caughtup_query) |
|
|
|
|
or die "Timed out while waiting for standby to catch up"; |
|
|
|
|
|
|
|
|
@ -336,69 +336,69 @@ is($psql_out, '1', "Replay prepared transaction with DDL"); |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
|
# Check recovery of prepared transaction with DDL inside after a hard restart |
|
|
|
|
# of the master. |
|
|
|
|
# of the primary. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
CREATE TABLE t_009_tbl3 (id int, msg text); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl3 VALUES (28, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl3 VALUES (28, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_14'; |
|
|
|
|
BEGIN; |
|
|
|
|
CREATE TABLE t_009_tbl4 (id int, msg text); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl4 VALUES (29, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl4 VALUES (29, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_15';"); |
|
|
|
|
|
|
|
|
|
$cur_master->teardown_node; |
|
|
|
|
$cur_master->start; |
|
|
|
|
$cur_primary->teardown_node; |
|
|
|
|
$cur_primary->start; |
|
|
|
|
|
|
|
|
|
$psql_rc = $cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_14'"); |
|
|
|
|
$psql_rc = $cur_primary->psql('postgres', "COMMIT PREPARED 'xact_009_14'"); |
|
|
|
|
is($psql_rc, '0', 'Commit prepared transaction after teardown'); |
|
|
|
|
|
|
|
|
|
$psql_rc = $cur_master->psql('postgres', "ROLLBACK PREPARED 'xact_009_15'"); |
|
|
|
|
$psql_rc = $cur_primary->psql('postgres', "ROLLBACK PREPARED 'xact_009_15'"); |
|
|
|
|
is($psql_rc, '0', 'Rollback prepared transaction after teardown'); |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
|
# Check recovery of prepared transaction with DDL inside after a soft restart |
|
|
|
|
# of the master. |
|
|
|
|
# of the primary. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', " |
|
|
|
|
BEGIN; |
|
|
|
|
CREATE TABLE t_009_tbl5 (id int, msg text); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl5 VALUES (30, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl5 VALUES (30, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_16'; |
|
|
|
|
BEGIN; |
|
|
|
|
CREATE TABLE t_009_tbl6 (id int, msg text); |
|
|
|
|
SAVEPOINT s1; |
|
|
|
|
INSERT INTO t_009_tbl6 VALUES (31, 'issued to ${cur_master_name}'); |
|
|
|
|
INSERT INTO t_009_tbl6 VALUES (31, 'issued to ${cur_primary_name}'); |
|
|
|
|
PREPARE TRANSACTION 'xact_009_17';"); |
|
|
|
|
|
|
|
|
|
$cur_master->stop; |
|
|
|
|
$cur_master->start; |
|
|
|
|
$cur_primary->stop; |
|
|
|
|
$cur_primary->start; |
|
|
|
|
|
|
|
|
|
$psql_rc = $cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_16'"); |
|
|
|
|
$psql_rc = $cur_primary->psql('postgres', "COMMIT PREPARED 'xact_009_16'"); |
|
|
|
|
is($psql_rc, '0', 'Commit prepared transaction after restart'); |
|
|
|
|
|
|
|
|
|
$psql_rc = $cur_master->psql('postgres', "ROLLBACK PREPARED 'xact_009_17'"); |
|
|
|
|
$psql_rc = $cur_primary->psql('postgres', "ROLLBACK PREPARED 'xact_009_17'"); |
|
|
|
|
is($psql_rc, '0', 'Rollback prepared transaction after restart'); |
|
|
|
|
|
|
|
|
|
############################################################################### |
|
|
|
|
# Verify expected data appears on both servers. |
|
|
|
|
############################################################################### |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', |
|
|
|
|
"SELECT count(*) FROM pg_prepared_xacts", |
|
|
|
|
stdout => \$psql_out); |
|
|
|
|
is($psql_out, '0', "No uncommitted prepared transactions on master"); |
|
|
|
|
is($psql_out, '0', "No uncommitted prepared transactions on primary"); |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', |
|
|
|
|
"SELECT * FROM t_009_tbl ORDER BY id", |
|
|
|
|
stdout => \$psql_out); |
|
|
|
@ -424,15 +424,15 @@ is( $psql_out, qq{1|issued to london |
|
|
|
|
24|issued to paris |
|
|
|
|
25|issued to london |
|
|
|
|
26|issued to london}, |
|
|
|
|
"Check expected t_009_tbl data on master"); |
|
|
|
|
"Check expected t_009_tbl data on primary"); |
|
|
|
|
|
|
|
|
|
$cur_master->psql( |
|
|
|
|
$cur_primary->psql( |
|
|
|
|
'postgres', |
|
|
|
|
"SELECT * FROM t_009_tbl2", |
|
|
|
|
stdout => \$psql_out); |
|
|
|
|
is( $psql_out, |
|
|
|
|
qq{27|issued to paris}, |
|
|
|
|
"Check expected t_009_tbl2 data on master"); |
|
|
|
|
"Check expected t_009_tbl2 data on primary"); |
|
|
|
|
|
|
|
|
|
$cur_standby->psql( |
|
|
|
|
'postgres', |
|
|
|
|