*** a/src/backend/access/transam/clog.c --- b/src/backend/access/transam/clog.c *************** *** 489,494 **** StartupCLOG(void) --- 489,513 ---- */ ClogCtl->shared->latest_page_number = pageno; + LWLockRelease(CLogControlLock); + } + + /* + * This must be called ONCE at the end of startup/recovery. + */ + void + TrimCLOG(void) + { + TransactionId xid = ShmemVariableCache->nextXid; + int pageno = TransactionIdToPage(xid); + + LWLockAcquire(CLogControlLock, LW_EXCLUSIVE); + + /* + * Re-Initialize our idea of the latest page number. + */ + ClogCtl->shared->latest_page_number = pageno; + /* * Zero out the remainder of the current clog page. Under normal * circumstances it should be zeroes already, but it seems at least *** a/src/backend/access/transam/multixact.c --- b/src/backend/access/transam/multixact.c *************** *** 1567,1573 **** StartupMultiXact(void) /* * Zero out the remainder of the current members page. See notes in ! * StartupCLOG() for motivation. */ entryno = MXOffsetToMemberEntry(offset); if (entryno != 0) --- 1567,1573 ---- /* * Zero out the remainder of the current members page. See notes in ! * TrimCLOG() for motivation. */ entryno = MXOffsetToMemberEntry(offset); if (entryno != 0) *** a/src/backend/access/transam/xlog.c --- b/src/backend/access/transam/xlog.c *************** *** 6410,6419 **** StartupXLOG(void) oldestActiveXID = checkPoint.oldestActiveXid; Assert(TransactionIdIsValid(oldestActiveXID)); ! /* Startup commit log and related stuff */ StartupCLOG(); StartupSUBTRANS(oldestActiveXID); - StartupMultiXact(); /* * If we're beginning at a shutdown checkpoint, we know that --- 6410,6421 ---- oldestActiveXID = checkPoint.oldestActiveXid; Assert(TransactionIdIsValid(oldestActiveXID)); ! /* ! * Startup commit log and subtrans only. Other SLRUs are not ! * maintained during recovery and need not be started yet. ! */ StartupCLOG(); StartupSUBTRANS(oldestActiveXID); /* * If we're beginning at a shutdown checkpoint, we know that *************** *** 6914,6929 **** StartupXLOG(void) TransactionIdRetreat(ShmemVariableCache->latestCompletedXid); /* ! * Start up the commit log and related stuff, too. In hot standby mode we ! * did this already before WAL replay. */ if (standbyState == STANDBY_DISABLED) { StartupCLOG(); StartupSUBTRANS(oldestActiveXID); - StartupMultiXact(); } /* Reload shared-memory state for prepared transactions */ RecoverPreparedTransactions(); --- 6916,6936 ---- TransactionIdRetreat(ShmemVariableCache->latestCompletedXid); /* ! * Start up the commit log and subtrans, if not already done for ! * hot standby. */ if (standbyState == STANDBY_DISABLED) { StartupCLOG(); StartupSUBTRANS(oldestActiveXID); } + /* + * Perform end of recovery actions for any SLRUs that need it. + */ + StartupMultiXact(); + TrimCLOG(); + /* Reload shared-memory state for prepared transactions */ RecoverPreparedTransactions(); *** a/src/include/access/clog.h --- b/src/include/access/clog.h *************** *** 40,45 **** extern Size CLOGShmemSize(void); --- 40,46 ---- extern void CLOGShmemInit(void); extern void BootStrapCLOG(void); extern void StartupCLOG(void); + extern void TrimCLOG(void); extern void ShutdownCLOG(void); extern void CheckPointCLOG(void); extern void ExtendCLOG(TransactionId newestXact);