mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Replace buffer I/O locks with condition variables.
1. Backends waiting for buffer I/O are now interruptible. 2. If something goes wrong in a backend that is currently performing I/O, waiting backends no longer wake up until that backend reaches AbortBufferIO() and broadcasts on the CV. Previously, any waiters would wake up (because the I/O lock was automatically released) and then busy-loop until AbortBufferIO() cleared BM_IO_IN_PROGRESS. 3. LWLockMinimallyPadded is removed, as it would now be unused. Author: Robert Haas <robertmhaas@gmail.com> Reviewed-by: Thomas Munro <thomas.munro@gmail.com> Reviewed-by: Julien Rouhaud <rjuju123@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> (earlier version, 2016) Discussion: https://postgr.es/m/CA%2BhUKGJ8nBFrjLuCTuqKN0pd2PQOwj9b_jnsiGFFMDvUxahj_A%40mail.gmail.com Discussion: https://postgr.es/m/CA+Tgmoaj2aPti0yho7FeEf2qt-JgQPRWb0gci_o1Hfr=C56Xng@mail.gmail.com
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
|
||||
BufferDescPadded *BufferDescriptors;
|
||||
char *BufferBlocks;
|
||||
LWLockMinimallyPadded *BufferIOLWLockArray = NULL;
|
||||
ConditionVariableMinimallyPadded *BufferIOCVArray;
|
||||
WritebackContext BackendWritebackContext;
|
||||
CkptSortItem *CkptBufferIds;
|
||||
|
||||
@@ -68,7 +68,7 @@ InitBufferPool(void)
|
||||
{
|
||||
bool foundBufs,
|
||||
foundDescs,
|
||||
foundIOLocks,
|
||||
foundIOCV,
|
||||
foundBufCkpt;
|
||||
|
||||
/* Align descriptors to a cacheline boundary. */
|
||||
@@ -81,11 +81,11 @@ InitBufferPool(void)
|
||||
ShmemInitStruct("Buffer Blocks",
|
||||
NBuffers * (Size) BLCKSZ, &foundBufs);
|
||||
|
||||
/* Align lwlocks to cacheline boundary */
|
||||
BufferIOLWLockArray = (LWLockMinimallyPadded *)
|
||||
ShmemInitStruct("Buffer IO Locks",
|
||||
NBuffers * (Size) sizeof(LWLockMinimallyPadded),
|
||||
&foundIOLocks);
|
||||
/* Align condition variables to cacheline boundary. */
|
||||
BufferIOCVArray = (ConditionVariableMinimallyPadded *)
|
||||
ShmemInitStruct("Buffer IO Condition Variables",
|
||||
NBuffers * sizeof(ConditionVariableMinimallyPadded),
|
||||
&foundIOCV);
|
||||
|
||||
/*
|
||||
* The array used to sort to-be-checkpointed buffer ids is located in
|
||||
@@ -98,10 +98,10 @@ InitBufferPool(void)
|
||||
ShmemInitStruct("Checkpoint BufferIds",
|
||||
NBuffers * sizeof(CkptSortItem), &foundBufCkpt);
|
||||
|
||||
if (foundDescs || foundBufs || foundIOLocks || foundBufCkpt)
|
||||
if (foundDescs || foundBufs || foundIOCV || foundBufCkpt)
|
||||
{
|
||||
/* should find all of these, or none of them */
|
||||
Assert(foundDescs && foundBufs && foundIOLocks && foundBufCkpt);
|
||||
Assert(foundDescs && foundBufs && foundIOCV && foundBufCkpt);
|
||||
/* note: this path is only taken in EXEC_BACKEND case */
|
||||
}
|
||||
else
|
||||
@@ -131,8 +131,7 @@ InitBufferPool(void)
|
||||
LWLockInitialize(BufferDescriptorGetContentLock(buf),
|
||||
LWTRANCHE_BUFFER_CONTENT);
|
||||
|
||||
LWLockInitialize(BufferDescriptorGetIOLock(buf),
|
||||
LWTRANCHE_BUFFER_IO);
|
||||
ConditionVariableInit(BufferDescriptorGetIOCV(buf));
|
||||
}
|
||||
|
||||
/* Correct last entry of linked list */
|
||||
@@ -169,16 +168,9 @@ BufferShmemSize(void)
|
||||
/* size of stuff controlled by freelist.c */
|
||||
size = add_size(size, StrategyShmemSize());
|
||||
|
||||
/*
|
||||
* It would be nice to include the I/O locks in the BufferDesc, but that
|
||||
* would increase the size of a BufferDesc to more than one cache line,
|
||||
* and benchmarking has shown that keeping every BufferDesc aligned on a
|
||||
* cache line boundary is important for performance. So, instead, the
|
||||
* array of I/O locks is allocated in a separate tranche. Because those
|
||||
* locks are not highly contended, we lay out the array with minimal
|
||||
* padding.
|
||||
*/
|
||||
size = add_size(size, mul_size(NBuffers, sizeof(LWLockMinimallyPadded)));
|
||||
/* size of I/O condition variables */
|
||||
size = add_size(size, mul_size(NBuffers,
|
||||
sizeof(ConditionVariableMinimallyPadded)));
|
||||
/* to allow aligning the above */
|
||||
size = add_size(size, PG_CACHE_LINE_SIZE);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user