diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index 95aa8be9c53..330d2a5c9ec 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -2183,26 +2183,6 @@ ProcessTwoPhaseBuffer(TransactionId xid, if (!fromdisk) Assert(prepare_start_lsn != InvalidXLogRecPtr); - /* Already processed? */ - if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid)) - { - if (fromdisk) - { - ereport(WARNING, - (errmsg("removing stale 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", - xid))); - PrepareRedoRemove(xid, true); - } - return NULL; - } - /* Reject XID if too new */ if (TransactionIdFollowsOrEquals(xid, origNextXid)) { @@ -2223,6 +2203,26 @@ ProcessTwoPhaseBuffer(TransactionId xid, return NULL; } + /* Already processed? */ + if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid)) + { + if (fromdisk) + { + ereport(WARNING, + (errmsg("removing stale 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", + xid))); + PrepareRedoRemove(xid, true); + } + return NULL; + } + if (fromdisk) { /* Read and validate file */ diff --git a/src/test/recovery/t/009_twophase.pl b/src/test/recovery/t/009_twophase.pl index fe7e8e79802..7642e4f0b3c 100644 --- a/src/test/recovery/t/009_twophase.pl +++ b/src/test/recovery/t/009_twophase.pl @@ -528,4 +528,27 @@ 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/]); + done_testing();