mirror of
https://github.com/postgres/postgres.git
synced 2025-06-04 00:02:37 -04: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:
parent
776621a5e4
commit
7b745d85b8
@ -57,3 +57,4 @@ WaitEventExtensionLock 48
|
||||
WALSummarizerLock 49
|
||||
DSMRegistryLock 50
|
||||
InjectionPointLock 51
|
||||
SerialControlLock 52
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -331,6 +331,7 @@ WaitEventExtension "Waiting to read or update custom wait events information for
|
||||
WALSummarizer "Waiting to read or update WAL summarization state."
|
||||
DSMRegistry "Waiting to read or update the dynamic shared memory registry."
|
||||
InjectionPoint "Waiting to read or update information related to injection points."
|
||||
SerialControl "Waiting to read or update shared <filename>pg_serial</filename> state."
|
||||
|
||||
#
|
||||
# END OF PREDEFINED LWLOCKS (DO NOT CHANGE THIS LINE)
|
||||
|
Loading…
x
Reference in New Issue
Block a user