1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-03 09:13:20 +03:00

Split use of SerialSLRULock, creating SerialControlLock

predicate.c has been using SerialSLRULock (the control lock for its SLRU
structure) to coordinate access to SerialControlData, another of its
numerous shared memory structures; this is unnecessary and confuses
further SLRU scalability work.  Create a separate LWLock to cover
SerialControlData.

Extracted from a larger patch from the same author, and some additional
changes by Álvaro.

Author: Dilip Kumar <dilip.kumar@enterprisedb.com>
Discussion: https://postgr.es/m/CAFiTN-vzDvNz=ExGXz6gdyjtzGixKSqs0mKHMmaQ8sOSEFZ33A@mail.gmail.com
This commit is contained in:
Alvaro Herrera
2024-01-30 18:11:17 +01:00
parent 776621a5e4
commit 7b745d85b8
3 changed files with 32 additions and 11 deletions

View File

@@ -57,3 +57,4 @@ WaitEventExtensionLock 48
WALSummarizerLock 49
DSMRegistryLock 50
InjectionPointLock 51
SerialControlLock 52

View File

@@ -134,6 +134,11 @@
* 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
@@ -828,9 +833,11 @@ SerialInit(void)
/*
* Set control information to reflect empty SLRU.
*/
LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
serialControl->headPage = -1;
serialControl->headXid = InvalidTransactionId;
serialControl->tailXid = InvalidTransactionId;
LWLockRelease(SerialControlLock);
}
}
@@ -852,7 +859,12 @@ SerialAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
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
@@ -886,6 +898,8 @@ SerialAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
if (isNewPage)
serialControl->headPage = targetPage;
LWLockAcquire(SerialSLRULock, LW_EXCLUSIVE);
if (isNewPage)
{
/* Initialize intervening pages. */
@@ -903,6 +917,7 @@ SerialAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
SerialSlruCtl->shared->page_dirty[slotno] = true;
LWLockRelease(SerialSLRULock);
LWLockRelease(SerialControlLock);
}
/*
@@ -920,10 +935,10 @@ SerialGetMinConflictCommitSeqNo(TransactionId xid)
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;
@@ -954,7 +969,7 @@ SerialGetMinConflictCommitSeqNo(TransactionId xid)
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
@@ -966,7 +981,7 @@ SerialSetActiveSerXmin(TransactionId xid)
{
serialControl->tailXid = InvalidTransactionId;
serialControl->headXid = InvalidTransactionId;
LWLockRelease(SerialSLRULock);
LWLockRelease(SerialControlLock);
return;
}
@@ -984,7 +999,7 @@ SerialSetActiveSerXmin(TransactionId xid)
{
serialControl->tailXid = xid;
}
LWLockRelease(SerialSLRULock);
LWLockRelease(SerialControlLock);
return;
}
@@ -993,7 +1008,7 @@ SerialSetActiveSerXmin(TransactionId xid)
serialControl->tailXid = xid;
LWLockRelease(SerialSLRULock);
LWLockRelease(SerialControlLock);
}
/*
@@ -1007,12 +1022,12 @@ CheckPointPredicate(void)
{
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;
}
@@ -1072,9 +1087,13 @@ CheckPointPredicate(void)
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);
/*