Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7b745d8

Browse files
committed
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
1 parent 776621a commit 7b745d8

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

src/backend/storage/lmgr/lwlocknames.txt

+1
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,4 @@ WaitEventExtensionLock 48
5757
WALSummarizerLock 49
5858
DSMRegistryLock 50
5959
InjectionPointLock 51
60+
SerialControlLock 52

src/backend/storage/lmgr/predicate.c

+30-11
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@
134134
* SerializableXactHashLock
135135
* - Protects both PredXact and SerializableXidHash.
136136
*
137+
* SerialControlLock
138+
* - Protects SerialControlData members
139+
*
140+
* SerialSLRULock
141+
* - Protects SerialSlruCtl
137142
*
138143
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
139144
* Portions Copyright (c) 1994, Regents of the University of California
@@ -828,9 +833,11 @@ SerialInit(void)
828833
/*
829834
* Set control information to reflect empty SLRU.
830835
*/
836+
LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
831837
serialControl->headPage = -1;
832838
serialControl->headXid = InvalidTransactionId;
833839
serialControl->tailXid = InvalidTransactionId;
840+
LWLockRelease(SerialControlLock);
834841
}
835842
}
836843

@@ -852,7 +859,12 @@ SerialAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
852859

853860
targetPage = SerialPage(xid);
854861

855-
LWLockAcquire(SerialSLRULock, LW_EXCLUSIVE);
862+
/*
863+
* In this routine, we must hold both SerialControlLock and SerialSLRULock
864+
* simultaneously while making the SLRU data catch up with the new state
865+
* that we determine.
866+
*/
867+
LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
856868

857869
/*
858870
* If no serializable transactions are active, there shouldn't be anything
@@ -886,6 +898,8 @@ SerialAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
886898
if (isNewPage)
887899
serialControl->headPage = targetPage;
888900

901+
LWLockAcquire(SerialSLRULock, LW_EXCLUSIVE);
902+
889903
if (isNewPage)
890904
{
891905
/* Initialize intervening pages. */
@@ -903,6 +917,7 @@ SerialAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
903917
SerialSlruCtl->shared->page_dirty[slotno] = true;
904918

905919
LWLockRelease(SerialSLRULock);
920+
LWLockRelease(SerialControlLock);
906921
}
907922

908923
/*
@@ -920,10 +935,10 @@ SerialGetMinConflictCommitSeqNo(TransactionId xid)
920935

921936
Assert(TransactionIdIsValid(xid));
922937

923-
LWLockAcquire(SerialSLRULock, LW_SHARED);
938+
LWLockAcquire(SerialControlLock, LW_SHARED);
924939
headXid = serialControl->headXid;
925940
tailXid = serialControl->tailXid;
926-
LWLockRelease(SerialSLRULock);
941+
LWLockRelease(SerialControlLock);
927942

928943
if (!TransactionIdIsValid(headXid))
929944
return 0;
@@ -954,7 +969,7 @@ SerialGetMinConflictCommitSeqNo(TransactionId xid)
954969
static void
955970
SerialSetActiveSerXmin(TransactionId xid)
956971
{
957-
LWLockAcquire(SerialSLRULock, LW_EXCLUSIVE);
972+
LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
958973

959974
/*
960975
* When no sxacts are active, nothing overlaps, set the xid values to
@@ -966,7 +981,7 @@ SerialSetActiveSerXmin(TransactionId xid)
966981
{
967982
serialControl->tailXid = InvalidTransactionId;
968983
serialControl->headXid = InvalidTransactionId;
969-
LWLockRelease(SerialSLRULock);
984+
LWLockRelease(SerialControlLock);
970985
return;
971986
}
972987

@@ -984,7 +999,7 @@ SerialSetActiveSerXmin(TransactionId xid)
984999
{
9851000
serialControl->tailXid = xid;
9861001
}
987-
LWLockRelease(SerialSLRULock);
1002+
LWLockRelease(SerialControlLock);
9881003
return;
9891004
}
9901005

@@ -993,7 +1008,7 @@ SerialSetActiveSerXmin(TransactionId xid)
9931008

9941009
serialControl->tailXid = xid;
9951010

996-
LWLockRelease(SerialSLRULock);
1011+
LWLockRelease(SerialControlLock);
9971012
}
9981013

9991014
/*
@@ -1007,12 +1022,12 @@ CheckPointPredicate(void)
10071022
{
10081023
int truncateCutoffPage;
10091024

1010-
LWLockAcquire(SerialSLRULock, LW_EXCLUSIVE);
1025+
LWLockAcquire(SerialControlLock, LW_EXCLUSIVE);
10111026

10121027
/* Exit quickly if the SLRU is currently not in use. */
10131028
if (serialControl->headPage < 0)
10141029
{
1015-
LWLockRelease(SerialSLRULock);
1030+
LWLockRelease(SerialControlLock);
10161031
return;
10171032
}
10181033

@@ -1072,9 +1087,13 @@ CheckPointPredicate(void)
10721087
serialControl->headPage = -1;
10731088
}
10741089

1075-
LWLockRelease(SerialSLRULock);
1090+
LWLockRelease(SerialControlLock);
10761091

1077-
/* Truncate away pages that are no longer required */
1092+
/*
1093+
* Truncate away pages that are no longer required. Note that no
1094+
* additional locking is required, because this is only called as part of
1095+
* a checkpoint, and the validity limits have already been determined.
1096+
*/
10781097
SimpleLruTruncate(SerialSlruCtl, truncateCutoffPage);
10791098

10801099
/*

src/backend/utils/activity/wait_event_names.txt

+1
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ WaitEventExtension "Waiting to read or update custom wait events information for
331331
WALSummarizer "Waiting to read or update WAL summarization state."
332332
DSMRegistry "Waiting to read or update the dynamic shared memory registry."
333333
InjectionPoint "Waiting to read or update information related to injection points."
334+
SerialControl "Waiting to read or update shared <filename>pg_serial</filename> state."
334335

335336
#
336337
# END OF PREDEFINED LWLOCKS (DO NOT CHANGE THIS LINE)

0 commit comments

Comments
 (0)