diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 5e3357f87f..544765c98d 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -220,14 +220,6 @@ typedef struct MultiXactStateData MultiXactOffset oldestOffset; bool oldestOffsetKnown; - /* - * True if a multixact truncation WAL record was replayed since the last - * checkpoint. This is used to trigger 'legacy truncations', i.e. truncate - * by looking at the data directory during WAL replay, when the primary is - * too old to generate truncation records. - */ - bool sawTruncationInCkptCycle; - /* support for anti-wraparound measures */ MultiXactId multiVacLimit; MultiXactId multiWarnLimit; @@ -2381,28 +2373,7 @@ MultiXactAdvanceOldest(MultiXactId oldestMulti, Oid oldestMultiDB) Assert(InRecovery); if (MultiXactIdPrecedes(MultiXactState->oldestMultiXactId, oldestMulti)) - { - /* - * If there has been a truncation on the master, detected by seeing a - * moving oldestMulti, without a corresponding truncation record, we - * know that the primary is still running an older version of postgres - * that doesn't yet log multixact truncations. So perform the - * truncation ourselves. - */ - if (!MultiXactState->sawTruncationInCkptCycle) - { - ereport(LOG, - (errmsg("performing legacy multixact truncation"), - errdetail("Legacy truncations are sometimes performed when replaying WAL from an older primary."), - errhint("Upgrade the primary, it is susceptible to data corruption."))); - TruncateMultiXact(oldestMulti, oldestMultiDB, true); - } - SetMultiXactIdLimit(oldestMulti, oldestMultiDB); - } - - /* only looked at in the startup process, no lock necessary */ - MultiXactState->sawTruncationInCkptCycle = false; } /* @@ -2747,8 +2718,7 @@ find_multixact_start(MultiXactId multi, MultiXactOffset *result) int slotno; MultiXactOffset *offptr; - /* XXX: Remove || AmStartupProcess() after WAL page magic bump */ - Assert(MultiXactState->finishedStartup || AmStartupProcess()); + Assert(MultiXactState->finishedStartup); pageno = MultiXactIdToOffsetPage(multi); entryno = MultiXactIdToOffsetEntry(multi); @@ -2946,18 +2916,15 @@ PerformOffsetsTruncation(MultiXactId oldestMulti, MultiXactId newOldestMulti) * Remove all MultiXactOffset and MultiXactMember segments before the oldest * ones still of interest. * - * On a primary this is called as part of vacuum (via - * vac_truncate_clog()). During recovery truncation is normally done by - * replaying truncation WAL records instead of this routine; the exception is - * when replaying records from an older primary that doesn't yet generate - * truncation WAL records. In that case truncation is triggered by - * MultiXactAdvanceOldest(). + * This is only called on a primary as part of vacuum (via + * vac_truncate_clog()). During recovery truncation is done by replaying + * truncation WAL records logged here. * * newOldestMulti is the oldest currently required multixact, newOldestMultiDB * is one of the databases preventing newOldestMulti from increasing. */ void -TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB, bool in_recovery) +TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB) { MultiXactId oldestMulti; MultiXactId nextMulti; @@ -2967,13 +2934,8 @@ TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB, bool in_reco mxtruncinfo trunc; MultiXactId earliest; - /* - * Need to allow being called in recovery for backwards compatibility, - * when an updated standby replays WAL generated by a non-updated primary. - */ - Assert(in_recovery || !RecoveryInProgress()); - Assert(!in_recovery || AmStartupProcess()); - Assert(in_recovery || MultiXactState->finishedStartup); + Assert(!RecoveryInProgress()); + Assert(MultiXactState->finishedStartup); /* * We can only allow one truncation to happen at once. Otherwise parts of @@ -3086,22 +3048,15 @@ TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB, bool in_reco * Prevent checkpoints from being scheduled concurrently. This is critical * because otherwise a truncation record might not be replayed after a * crash/basebackup, even though the state of the data directory would - * require it. It's not possible (startup process doesn't have a PGXACT - * entry), and not needed, to do this during recovery, when performing an - * old-style truncation, though. There the entire scheduling depends on - * the replayed WAL records which be the same after a possible crash. + * require it. */ - if (!in_recovery) - { - Assert(!MyPgXact->delayChkpt); - MyPgXact->delayChkpt = true; - } + Assert(!MyPgXact->delayChkpt); + MyPgXact->delayChkpt = true; /* WAL log truncation */ - if (!in_recovery) - WriteMTruncateXlogRec(newOldestMultiDB, - oldestMulti, newOldestMulti, - oldestOffset, newOldestOffset); + WriteMTruncateXlogRec(newOldestMultiDB, + oldestMulti, newOldestMulti, + oldestOffset, newOldestOffset); /* * Update in-memory limits before performing the truncation, while inside @@ -3122,8 +3077,7 @@ TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB, bool in_reco /* Then offsets */ PerformOffsetsTruncation(oldestMulti, newOldestMulti); - if (!in_recovery) - MyPgXact->delayChkpt = false; + MyPgXact->delayChkpt = false; END_CRIT_SECTION(); LWLockRelease(MultiXactTruncationLock); @@ -3371,9 +3325,6 @@ multixact_redo(XLogReaderState *record) PerformOffsetsTruncation(xlrec.startTruncOff, xlrec.endTruncOff); LWLockRelease(MultiXactTruncationLock); - - /* only looked at in the startup process, no lock necessary */ - MultiXactState->sawTruncationInCkptCycle = true; } else elog(PANIC, "multixact_redo: unknown op code %u", info); diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 1ac1c0550d..22e6a21414 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -9233,10 +9233,6 @@ xlog_redo(XLogReaderState *record) 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); diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 698bb3531c..6d55148edd 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -1141,7 +1141,7 @@ vac_truncate_clog(TransactionId frozenXID, */ TruncateCLOG(frozenXID); TruncateCommitTs(frozenXID, true); - TruncateMultiXact(minMulti, minmulti_datoid, false); + TruncateMultiXact(minMulti, minmulti_datoid); /* * Update the wrap limit for GetNewTransactionId and creation of new diff --git a/src/include/access/multixact.h b/src/include/access/multixact.h index 9f9df9cda0..60457810dd 100644 --- a/src/include/access/multixact.h +++ b/src/include/access/multixact.h @@ -135,7 +135,7 @@ extern void MultiXactGetCheckptMulti(bool is_shutdown, Oid *oldestMultiDB); extern void CheckPointMultiXact(void); extern MultiXactId GetOldestMultiXactId(void); -extern void TruncateMultiXact(MultiXactId oldestMulti, Oid oldestMultiDB, bool in_recovery); +extern void TruncateMultiXact(MultiXactId oldestMulti, Oid oldestMultiDB); extern void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset); extern void MultiXactAdvanceNextMXact(MultiXactId minMulti, diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index 590bf1729a..86b532d2bd 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -31,7 +31,7 @@ /* * Each page of XLOG file has a header like this: */ -#define XLOG_PAGE_MAGIC 0xD086 /* can be used as WAL version indicator */ +#define XLOG_PAGE_MAGIC 0xD088 /* can be used as WAL version indicator */ typedef struct XLogPageHeaderData {