1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-28 11:55:03 +03:00

Use an LWLock instead of a spinlock in waitlsn.c

This should prevent busy-waiting when number of waiting processes is high.

Discussion: https://postgr.es/m/202404030658.hhj3vfxeyhft%40alvherre.pgsql
Author: Alvaro Herrera
This commit is contained in:
Alexander Korotkov
2024-04-07 00:31:43 +03:00
parent 1577081e96
commit 25f42429e2
4 changed files with 10 additions and 12 deletions

View File

@@ -58,7 +58,6 @@ WaitLSNShmemInit(void)
&found);
if (!found)
{
SpinLockInit(&waitLSN->waitersHeapMutex);
pg_atomic_init_u64(&waitLSN->minWaitedLSN, PG_UINT64_MAX);
pairingheap_initialize(&waitLSN->waitersHeap, lsn_cmp, NULL);
memset(&waitLSN->procInfos, 0, MaxBackends * sizeof(WaitLSNProcInfo));
@@ -115,13 +114,13 @@ addLSNWaiter(XLogRecPtr lsn)
procInfo->procnum = MyProcNumber;
procInfo->waitLSN = lsn;
SpinLockAcquire(&waitLSN->waitersHeapMutex);
LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE);
pairingheap_add(&waitLSN->waitersHeap, &procInfo->phNode);
procInfo->inHeap = true;
updateMinWaitedLSN();
SpinLockRelease(&waitLSN->waitersHeapMutex);
LWLockRelease(WaitLSNLock);
}
/*
@@ -132,11 +131,11 @@ deleteLSNWaiter(void)
{
WaitLSNProcInfo *procInfo = &waitLSN->procInfos[MyProcNumber];
SpinLockAcquire(&waitLSN->waitersHeapMutex);
LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE);
if (!procInfo->inHeap)
{
SpinLockRelease(&waitLSN->waitersHeapMutex);
LWLockRelease(WaitLSNLock);
return;
}
@@ -144,7 +143,7 @@ deleteLSNWaiter(void)
procInfo->inHeap = false;
updateMinWaitedLSN();
SpinLockRelease(&waitLSN->waitersHeapMutex);
LWLockRelease(WaitLSNLock);
}
/*
@@ -160,7 +159,7 @@ WaitLSNSetLatches(XLogRecPtr currentLSN)
wakeUpProcNums = palloc(sizeof(int) * MaxBackends);
SpinLockAcquire(&waitLSN->waitersHeapMutex);
LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE);
/*
* Iterate the pairing heap of waiting processes till we find LSN not yet
@@ -182,7 +181,7 @@ WaitLSNSetLatches(XLogRecPtr currentLSN)
updateMinWaitedLSN();
SpinLockRelease(&waitLSN->waitersHeapMutex);
LWLockRelease(WaitLSNLock);
/*
* Set latches for processes, whose waited LSNs are already replayed. This