diff options
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index abc5682e7f9..e5640793eb8 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6264,6 +6264,7 @@ StartupXLOG(void) MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset); SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB); SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB); + MultiXactSetSafeTruncate(checkPoint.oldestMulti); XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch; XLogCtl->ckptXid = checkPoint.nextXid; @@ -8273,6 +8274,12 @@ 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(); @@ -8305,6 +8312,11 @@ 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); @@ -8579,21 +8591,6 @@ CreateRestartPoint(int flags) LWLockRelease(ControlFileLock); /* - * Due to an 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 need to access those multis. - * - * It's probably worth improving this. - */ - TruncateMultiXact(lastCheckPoint.oldestMulti); - - /* * Delete old log files (those no longer needed even for previous * checkpoint/restartpoint) to prevent the disk holding the xlog from * growing full. @@ -8652,6 +8649,21 @@ CreateRestartPoint(int flags) } /* + * Due to an 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 @@ -9117,6 +9129,7 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) checkPoint.nextMultiOffset); 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 @@ -9217,6 +9230,7 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) checkPoint.oldestXidDB); MultiXactAdvanceOldest(checkPoint.oldestMulti, checkPoint.oldestMultiDB); + MultiXactSetSafeTruncate(checkPoint.oldestMulti); /* ControlFile->checkPointCopy always tracks the latest ckpt XID */ ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch; |