diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f825579e888..8899d5ac63d 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -888,8 +888,6 @@ RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset, MultiXactOffset *next_offptr; MultiXactOffset next_offset; - LWLockAcquire(MultiXactOffsetSLRULock, LW_EXCLUSIVE); - /* position of this multixid in the offsets SLRU area */ pageno = MultiXactIdToOffsetPage(multi); entryno = MultiXactIdToOffsetEntry(multi); @@ -907,6 +905,9 @@ RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset, * multixid was assigned. If we're replaying WAL that was generated by * such a version, the next page might not be initialized yet. Initialize * it now. + * + * This block runs before acquiring MultiXactOffsetSLRULock because + * SimpleLruWriteAll() needs to acquire the same lock internally. */ if (InRecovery && next_pageno != pageno) { @@ -951,6 +952,8 @@ RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset, { elog(DEBUG1, "next offsets page is not initialized, initializing it now"); + LWLockAcquire(MultiXactOffsetSLRULock, LW_EXCLUSIVE); + /* Create and zero the page */ slotno = SimpleLruZeroPage(MultiXactOffsetCtl, next_pageno); @@ -958,6 +961,8 @@ RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset, SimpleLruWritePage(MultiXactOffsetCtl, slotno); Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]); + LWLockRelease(MultiXactOffsetSLRULock); + /* * Remember that we initialized the page, so that we don't zero it * again at the XLOG_MULTIXACT_ZERO_OFF_PAGE record. @@ -967,6 +972,8 @@ RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset, } } + LWLockAcquire(MultiXactOffsetSLRULock, LW_EXCLUSIVE); + /* * Set the starting offset of this multixid's members. *