From 82296a73d48451b3c16266cb5df529ee60ffe04f Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Thu, 24 Nov 2022 12:08:38 +0000 Subject: [PATCH v1] Avoid LWLockWaitForVar() for currently held WAL insertion lock in WaitXLogInsertionsToFinish() --- src/backend/access/transam/xlog.c | 40 ++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a31fbbff78..cffcbda941 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -631,7 +631,7 @@ static TimeLineID LocalMinRecoveryPointTLI; static bool updateMinRecoveryPoint = true; /* For WALInsertLockAcquire/Release functions */ -static int MyLockNo = 0; +static int MyLockNo = -1; static bool holdingAllLocks = false; #ifdef WAL_DEBUG @@ -1321,6 +1321,8 @@ WALInsertLockAcquire(void) if (lockToTry == -1) lockToTry = MyProc->pgprocno % NUM_XLOGINSERT_LOCKS; + + Assert(MyLockNo == -1); MyLockNo = lockToTry; /* @@ -1351,6 +1353,8 @@ WALInsertLockAcquireExclusive(void) { int i; + Assert(MyLockNo == -1); + /* * When holding all the locks, all but the last lock's insertingAt * indicator is set to 0xFFFFFFFFFFFFFFFF, which is higher than any real @@ -1382,6 +1386,8 @@ WALInsertLockRelease(void) { int i; + Assert(MyLockNo == -1); + for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++) LWLockReleaseClearVar(&WALInsertLocks[i].l.lock, &WALInsertLocks[i].l.insertingAt, @@ -1394,6 +1400,8 @@ WALInsertLockRelease(void) LWLockReleaseClearVar(&WALInsertLocks[MyLockNo].l.lock, &WALInsertLocks[MyLockNo].l.insertingAt, 0); + + MyLockNo = -1; } } @@ -1406,6 +1414,8 @@ WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt) { if (holdingAllLocks) { + Assert(MyLockNo == -1); + /* * We use the last lock to mark our actual position, see comments in * WALInsertLockAcquireExclusive. @@ -1482,6 +1492,34 @@ WaitXLogInsertionsToFinish(XLogRecPtr upto) { XLogRecPtr insertingat = InvalidXLogRecPtr; + /* + * If this process is holding the current WAL insert lock, then it can + * never happen that its insertion point is behind 'upto'. When the + * process doesn't get enough WAL buffer pages for its insertion, it + * comes here requesting the older in progress insertions to finish. + * + * In this case, we avoid going the LWLockWaitForVar route and quickly + * continue. + */ + if (MyLockNo == i) + { + Assert(LWLockHeldByMe(&WALInsertLocks[i].l.lock)); + + /* + * Since we're holding the WAL insert lock, we can safely read + * insertingAt here. + */ + insertingat = WALInsertLocks[i].l.insertingAt; + + Assert(!XLogRecPtrIsInvalid(insertingat)); + Assert(insertingat >= upto); + + if (insertingat < finishedUpto) + finishedUpto = insertingat; + + continue; + } + do { /* -- 2.34.1