* SerializableXactHashLock
* - Protects both PredXact and SerializableXidHash.
*
+ * SerialControlLock
+ * - Protects SerialControlData members
+ *
+ * SerialSLRULock
+ * - Protects SerialSlruCtl
*
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
/*
* Set control information to reflect empty SLRU.
*/
+ LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
serialControl->headPage = -1;
serialControl->headXid = InvalidTransactionId;
serialControl->tailXid = InvalidTransactionId;
+ LWLockRelease(SerialControlLock);
}
}
targetPage = SerialPage(xid);
- LWLockAcquire(SerialSLRULock, LW_EXCLUSIVE);
+ /*
+ * In this routine, we must hold both SerialControlLock and SerialSLRULock
+ * simultaneously while making the SLRU data catch up with the new state
+ * that we determine.
+ */
+ LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
/*
* If no serializable transactions are active, there shouldn't be anything
if (isNewPage)
serialControl->headPage = targetPage;
+ LWLockAcquire(SerialSLRULock, LW_EXCLUSIVE);
+
if (isNewPage)
{
/* Initialize intervening pages. */
SerialSlruCtl->shared->page_dirty[slotno] = true;
LWLockRelease(SerialSLRULock);
+ LWLockRelease(SerialControlLock);
}
/*
Assert(TransactionIdIsValid(xid));
- LWLockAcquire(SerialSLRULock, LW_SHARED);
+ LWLockAcquire(SerialControlLock, LW_SHARED);
headXid = serialControl->headXid;
tailXid = serialControl->tailXid;
- LWLockRelease(SerialSLRULock);
+ LWLockRelease(SerialControlLock);
if (!TransactionIdIsValid(headXid))
return 0;
static void
SerialSetActiveSerXmin(TransactionId xid)
{
- LWLockAcquire(SerialSLRULock, LW_EXCLUSIVE);
+ LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
/*
* When no sxacts are active, nothing overlaps, set the xid values to
{
serialControl->tailXid = InvalidTransactionId;
serialControl->headXid = InvalidTransactionId;
- LWLockRelease(SerialSLRULock);
+ LWLockRelease(SerialControlLock);
return;
}
{
serialControl->tailXid = xid;
}
- LWLockRelease(SerialSLRULock);
+ LWLockRelease(SerialControlLock);
return;
}
serialControl->tailXid = xid;
- LWLockRelease(SerialSLRULock);
+ LWLockRelease(SerialControlLock);
}
/*
{
int truncateCutoffPage;
- LWLockAcquire(SerialSLRULock, LW_EXCLUSIVE);
+ LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
/* Exit quickly if the SLRU is currently not in use. */
if (serialControl->headPage < 0)
{
- LWLockRelease(SerialSLRULock);
+ LWLockRelease(SerialControlLock);
return;
}
serialControl->headPage = -1;
}
- LWLockRelease(SerialSLRULock);
+ LWLockRelease(SerialControlLock);
- /* Truncate away pages that are no longer required */
+ /*
+ * Truncate away pages that are no longer required. Note that no
+ * additional locking is required, because this is only called as part of
+ * a checkpoint, and the validity limits have already been determined.
+ */
SimpleLruTruncate(SerialSlruCtl, truncateCutoffPage);
/*