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;
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;
}
/*
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);
* 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;
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
* 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
/* Then offsets */
PerformOffsetsTruncation(oldestMulti, newOldestMulti);
- if (!in_recovery)
- MyPgXact->delayChkpt = false;
+ MyPgXact->delayChkpt = false;
END_CRIT_SECTION();
LWLockRelease(MultiXactTruncationLock);
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);