diff options
Diffstat (limited to 'src/backend/access/transam/multixact.c')
-rw-r--r-- | src/backend/access/transam/multixact.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 1cb3dfab375..d2a3a7fbf58 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -827,6 +827,10 @@ GetNewMultiXactId(int nxids, MultiXactOffset *offset) /* MultiXactIdSetOldestMember() must have been called already */ Assert(MultiXactIdIsValid(OldestMemberMXactId[MyBackendId])); + /* safety check, we should never get this far in a HS slave */ + if (RecoveryInProgress()) + elog(ERROR, "cannot assign MultiXactIds during recovery"); + LWLockAcquire(MultiXactGenLock, LW_EXCLUSIVE); /* Handle wraparound of the nextMXact counter */ @@ -914,6 +918,10 @@ GetMultiXactIdMembers(MultiXactId multi, TransactionId **xids) Assert(MultiXactIdIsValid(multi)); + /* safety check, we should never get this far in a HS slave */ + if (RecoveryInProgress()) + elog(ERROR, "cannot GetMultiXactIdMembers() during recovery"); + /* See if the MultiXactId is in the local cache */ length = mXactCacheGetById(multi, xids); if (length >= 0) @@ -1513,11 +1521,8 @@ ZeroMultiXactMemberPage(int pageno, bool writeXlog) * This must be called ONCE during postmaster or standalone-backend startup. * * StartupXLOG has already established nextMXact/nextOffset by calling - * MultiXactSetNextMXact and/or MultiXactAdvanceNextMXact. Note that we - * may already have replayed WAL data into the SLRU files. - * - * We don't need any locks here, really; the SLRU locks are taken - * only because slru.c expects to be called with locks held. + * MultiXactSetNextMXact and/or MultiXactAdvanceNextMXact, but we haven't yet + * replayed WAL. */ void StartupMultiXact(void) @@ -1525,13 +1530,39 @@ StartupMultiXact(void) MultiXactId multi = MultiXactState->nextMXact; MultiXactOffset offset = MultiXactState->nextOffset; int pageno; + + /* + * Initialize our idea of the latest page number. + */ + pageno = MultiXactIdToOffsetPage(multi); + MultiXactOffsetCtl->shared->latest_page_number = pageno; + + /* + * Initialize our idea of the latest page number. + */ + pageno = MXOffsetToMemberPage(offset); + MultiXactMemberCtl->shared->latest_page_number = pageno; +} + +/* + * This must be called ONCE at the end of startup/recovery. + * + * We don't need any locks here, really; the SLRU locks are taken only because + * slru.c expects to be called with locks held. + */ +void +TrimMultiXact(void) +{ + MultiXactId multi = MultiXactState->nextMXact; + MultiXactOffset offset = MultiXactState->nextOffset; + int pageno; int entryno; /* Clean up offsets state */ LWLockAcquire(MultiXactOffsetControlLock, LW_EXCLUSIVE); /* - * Initialize our idea of the latest page number. + * (Re-)Initialize our idea of the latest page number. */ pageno = MultiXactIdToOffsetPage(multi); MultiXactOffsetCtl->shared->latest_page_number = pageno; @@ -1561,7 +1592,7 @@ StartupMultiXact(void) LWLockAcquire(MultiXactMemberControlLock, LW_EXCLUSIVE); /* - * Initialize our idea of the latest page number. + * (Re-)Initialize our idea of the latest page number. */ pageno = MXOffsetToMemberPage(offset); MultiXactMemberCtl->shared->latest_page_number = pageno; @@ -1640,14 +1671,9 @@ CheckPointMultiXact(void) /* * Truncate the SLRU files. This could be done at any time, but - * checkpoint seems a reasonable place for it. There is one exception: if - * we are called during xlog recovery, then shared->latest_page_number - * isn't valid (because StartupMultiXact hasn't been called yet) and so - * SimpleLruTruncate would get confused. It seems best not to risk - * removing any data during recovery anyway, so don't truncate. + * checkpoint seems a reasonable place for it. */ - if (!RecoveryInProgress()) - TruncateMultiXact(); + TruncateMultiXact(); TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_DONE(true); } |