diff options
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 53 |
1 files changed, 16 insertions, 37 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a87f09ee47f..1ac1c0550dd 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6330,7 +6330,6 @@ StartupXLOG(void) SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB); SetCommitTsLimit(checkPoint.oldestCommitTs, checkPoint.newestCommitTs); - MultiXactSetSafeTruncate(checkPoint.oldestMulti); XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch; XLogCtl->ckptXid = checkPoint.nextXid; @@ -6347,10 +6346,8 @@ StartupXLOG(void) StartupReorderBuffer(); /* - * Startup MultiXact. We need to do this early for two reasons: one is - * that we might try to access multixacts when we do tuple freezing, and - * the other is we need its state initialized because we attempt - * truncation during restartpoints. + * Startup MultiXact. We need to do this early to be able to replay + * truncations. */ StartupMultiXact(); @@ -8508,12 +8505,6 @@ CreateCheckPoint(int flags) END_CRIT_SECTION(); /* - * Now that the checkpoint is safely on disk, we can update the point to - * which multixact can be truncated. - */ - MultiXactSetSafeTruncate(checkPoint.oldestMulti); - - /* * Let smgr do post-checkpoint cleanup (eg, deleting old files). */ smgrpostckpt(); @@ -8552,11 +8543,6 @@ CreateCheckPoint(int flags) if (!RecoveryInProgress()) TruncateSUBTRANS(GetOldestXmin(NULL, false)); - /* - * Truncate pg_multixact too. - */ - TruncateMultiXact(); - /* Real work is done, but log and update stats before releasing lock. */ LogCheckpointEnd(false); @@ -8887,21 +8873,6 @@ CreateRestartPoint(int flags) } /* - * Due to a historical accident multixact truncations are not WAL-logged, - * but just performed everytime the mxact horizon is increased. So, unless - * we explicitly execute truncations on a standby it will never clean out - * /pg_multixact which obviously is bad, both because it uses space and - * because we can wrap around into pre-existing data... - * - * We can only do the truncation here, after the UpdateControlFile() - * above, because we've now safely established a restart point. That - * guarantees we will not need to access those multis. - * - * It's probably worth improving this. - */ - TruncateMultiXact(); - - /* * Truncate pg_subtrans if possible. We can throw away all data before * the oldest XMIN of any running transaction. No future transaction will * attempt to reference any pg_subtrans entry older than that (see Asserts @@ -9261,9 +9232,14 @@ xlog_redo(XLogReaderState *record) LWLockRelease(OidGenLock); MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset); + + /* + * NB: This may perform multixact truncation when replaying WAL + * generated by an older primary. + */ + MultiXactAdvanceOldest(checkPoint.oldestMulti, + checkPoint.oldestMultiDB); SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB); - SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB); - MultiXactSetSafeTruncate(checkPoint.oldestMulti); /* * If we see a shutdown checkpoint while waiting for an end-of-backup @@ -9353,14 +9329,17 @@ xlog_redo(XLogReaderState *record) LWLockRelease(OidGenLock); MultiXactAdvanceNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset); + + /* + * NB: This may perform multixact truncation when replaying WAL + * generated by an older primary. + */ + MultiXactAdvanceOldest(checkPoint.oldestMulti, + checkPoint.oldestMultiDB); if (TransactionIdPrecedes(ShmemVariableCache->oldestXid, checkPoint.oldestXid)) SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB); - MultiXactAdvanceOldest(checkPoint.oldestMulti, - checkPoint.oldestMultiDB); - MultiXactSetSafeTruncate(checkPoint.oldestMulti); - /* ControlFile->checkPointCopy always tracks the latest ckpt XID */ ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch; ControlFile->checkPointCopy.nextXid = checkPoint.nextXid; |