Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e358425

Browse files
committed
Fix handling of orphaned 2PC files in the future at recovery
Before 728bd99, that has improved the support for 2PC files during recovery, the initial logic scanning files in pg_twophase was done so as files in the future of the transaction ID horizon were checked first, followed by a check if a transaction ID is aborted or committed which could involve a pg_xact lookup. After this commit, these checks have been done in reverse order. Files detected as in the future do not have a state that can be checked in pg_xact, hence this caused recovery to fail abruptly should an orphaned 2PC file in the future of the transaction ID horizon exist in pg_twophase at the beginning of recovery. A test is added to check for this scenario, using an empty 2PC with a transaction ID large enough to be in the future when running the test. This test is added in 16 and older versions for now. 17 and newer versions are impacted by a second bug caused by the addition of the epoch in the 2PC file names. An equivalent test will be added in these branches in a follow-up commit, once the second set of issues reported are fixed. Author: Vitaly Davydov, Michael Paquier Discussion: https://postgr.es/m/11e597-676ab680-8d-374f23c0@145466129 Backpatch-through: 13
1 parent 68ff25e commit e358425

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

src/backend/access/transam/twophase.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -2206,40 +2206,40 @@ ProcessTwoPhaseBuffer(TransactionId xid,
22062206
if (!fromdisk)
22072207
Assert(prepare_start_lsn != InvalidXLogRecPtr);
22082208

2209-
/* Already processed? */
2210-
if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid))
2209+
/* Reject XID if too new */
2210+
if (TransactionIdFollowsOrEquals(xid, origNextXid))
22112211
{
22122212
if (fromdisk)
22132213
{
22142214
ereport(WARNING,
2215-
(errmsg("removing stale two-phase state file for transaction %u",
2215+
(errmsg("removing future two-phase state file for transaction %u",
22162216
xid)));
22172217
RemoveTwoPhaseFile(xid, true);
22182218
}
22192219
else
22202220
{
22212221
ereport(WARNING,
2222-
(errmsg("removing stale two-phase state from memory for transaction %u",
2222+
(errmsg("removing future two-phase state from memory for transaction %u",
22232223
xid)));
22242224
PrepareRedoRemove(xid, true);
22252225
}
22262226
return NULL;
22272227
}
22282228

2229-
/* Reject XID if too new */
2230-
if (TransactionIdFollowsOrEquals(xid, origNextXid))
2229+
/* Already processed? */
2230+
if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid))
22312231
{
22322232
if (fromdisk)
22332233
{
22342234
ereport(WARNING,
2235-
(errmsg("removing future two-phase state file for transaction %u",
2235+
(errmsg("removing stale two-phase state file for transaction %u",
22362236
xid)));
22372237
RemoveTwoPhaseFile(xid, true);
22382238
}
22392239
else
22402240
{
22412241
ereport(WARNING,
2242-
(errmsg("removing future two-phase state from memory for transaction %u",
2242+
(errmsg("removing stale two-phase state from memory for transaction %u",
22432243
xid)));
22442244
PrepareRedoRemove(xid, true);
22452245
}

0 commit comments

Comments
 (0)