diff options
| author | Alvaro Herrera | 2024-01-30 17:11:17 +0000 |
|---|---|---|
| committer | Alvaro Herrera | 2024-01-30 17:11:17 +0000 |
| commit | 7b745d85b80d4492c4df8d9769592c7aad1f63d2 (patch) | |
| tree | 4e659b0cdbe3b653e4b00570e1e433c24b33ca60 /src/backend/storage | |
| parent | 776621a5e4796fa214b6b29a7ca134f6c138572a (diff) | |
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 <[email protected]>
Discussion: https://postgr.es/m/CAFiTN-vzDvNz=ExGXz6gdyjtzGixKSqs0mKHMmaQ8sOSEFZ33A@mail.gmail.com
Diffstat (limited to 'src/backend/storage')
| -rw-r--r-- | src/backend/storage/lmgr/lwlocknames.txt | 1 | ||||
| -rw-r--r-- | src/backend/storage/lmgr/predicate.c | 41 |
2 files changed, 31 insertions, 11 deletions
diff --git a/src/backend/storage/lmgr/lwlocknames.txt b/src/backend/storage/lmgr/lwlocknames.txt index a0163b21879..3d59d3646e5 100644 --- a/src/backend/storage/lmgr/lwlocknames.txt +++ b/src/backend/storage/lmgr/lwlocknames.txt @@ -57,3 +57,4 @@ WaitEventExtensionLock 48 WALSummarizerLock 49 DSMRegistryLock 50 InjectionPointLock 51 +SerialControlLock 52 diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index ee5ea1175c7..eed63a05ed8 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -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); /* |
