diff options
-rw-r--r-- | src/backend/access/transam/twophase.c | 16 | ||||
-rw-r--r-- | src/test/recovery/t/009_twophase.pl | 25 |
2 files changed, 32 insertions, 9 deletions
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index 16848fa226c..9f1616c8773 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -2156,40 +2156,40 @@ ProcessTwoPhaseBuffer(TransactionId xid, if (!fromdisk) Assert(prepare_start_lsn != InvalidXLogRecPtr); - /* Already processed? */ - if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid)) + /* Reject XID if too new */ + if (TransactionIdFollowsOrEquals(xid, origNextXid)) { if (fromdisk) { ereport(WARNING, - (errmsg("removing stale two-phase state file for transaction %u", + (errmsg("removing future two-phase state file for transaction %u", xid))); RemoveTwoPhaseFile(xid, true); } else { ereport(WARNING, - (errmsg("removing stale two-phase state from memory for transaction %u", + (errmsg("removing future two-phase state from memory for transaction %u", xid))); PrepareRedoRemove(xid, true); } return NULL; } - /* Reject XID if too new */ - if (TransactionIdFollowsOrEquals(xid, origNextXid)) + /* Already processed? */ + if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid)) { if (fromdisk) { ereport(WARNING, - (errmsg("removing future two-phase state file for transaction %u", + (errmsg("removing stale two-phase state file for transaction %u", xid))); RemoveTwoPhaseFile(xid, true); } else { ereport(WARNING, - (errmsg("removing future two-phase state from memory for transaction %u", + (errmsg("removing stale two-phase state from memory for transaction %u", xid))); PrepareRedoRemove(xid, true); } diff --git a/src/test/recovery/t/009_twophase.pl b/src/test/recovery/t/009_twophase.pl index a5686db2526..59c186a1c82 100644 --- a/src/test/recovery/t/009_twophase.pl +++ b/src/test/recovery/t/009_twophase.pl @@ -7,7 +7,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 27; +use Test::More tests => 28; my $psql_out = ''; my $psql_rc = ''; @@ -527,3 +527,26 @@ $cur_standby->psql( is( $psql_out, qq{27|issued to paris}, "Check expected t_009_tbl2 data on standby"); + +############################################################################### +# Check handling of orphaned 2PC files at recovery. +############################################################################### + +$cur_primary->teardown_node; + +# Grab location in logs of primary +my $log_offset = -s $cur_primary->logfile; + +# Create a fake file with a transaction ID large enough to be in the future, +# then check that the primary is able to start and remove this file at +# recovery. + +my $future_2pc_file = $cur_primary->data_dir . '/pg_twophase/00FFFFFF'; +append_to_file $future_2pc_file, ""; + +$cur_primary->start; +$cur_primary->log_check( + "future two-phase file removed at recovery", + $log_offset, + log_like => + [qr/removing future two-phase state file for transaction 16777215/]); |