From 6e715b6bc78e3009c7b4b3b9b90f4f04bf50f59a Mon Sep 17 00:00:00 2001 From: Ashwin Agrawal Date: Thu, 30 Mar 2017 11:08:30 -0700 Subject: [PATCH] Avoid could not open file pg_subtrans/xxx situation during recovery. Initialize TransactionXmin to avoid situations where scanning pg_authid or other tables mostly in BuildFlatFiles() via SnapshotNow may try to chase down pg_subtrans for older "sub-committed" transaction. File corresponding to which may not and is not supposed to exist. Setting TransactionXmin will avoid calling SubTransGetParent() in TransactionIdDidCommit() for older XIDs. Also, along the way initialize RecentGlobalXmin as Heap access method needs it set. Repro for record of one such case: ``` CREATE ROLE foo; BEGIN; SAVEPOINT sp; DROP ROLE foo; RELEASE SAVEPOINT sp; -- this is key which marks in clog as sub-committed. kill or gpstop -air < N transactions to atleast cross pg_subtrans single file limit roughly CLOG_XACTS_PER_BYTE * BLCKSZ* SLRU_PAGES_PER_SEGMENT > restart -- errors recovery with missing pg_subtrans ``` --- src/backend/access/transam/xlog.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 12d49ac99a..3362e5feef 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6124,6 +6124,18 @@ StartupXLOG_InProduction(void) elog(LOG, "Oldest active transaction from prepared transactions %u", oldestActiveXID); + /* + * Initialize TransactionXmin to current oldestActiveXID, generally + * initialized during GetSnapshotData(). This is to avoid situations where + * scanning pg_authid or other tables mostly in BuildFlatFiles() below via + * SnapshotNow may try to chase down pg_subtrans for older "sub-committed" + * transaction, file corresponding to which may not and is not supposed to + * exist. Setting this here will avoid calling SubTransGetParent() in + * TransactionIdDidCommit() for older XIDs. Also, set RecentGlobalXmin + * since Heap access method functions needs it to have good value as well. + */ + TransactionXmin = RecentGlobalXmin = oldestActiveXID; + /* Start up the commit log and related stuff, too */ StartupCLOG(); StartupSUBTRANS(oldestActiveXID); -- GitLab