demo.diff
application/octet-stream
Filename: demo.diff
Type: application/octet-stream
Part: 0
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.
*