bufmgr: Add some more error checking [infrastructure] around pinning

This adds a few more assertions against a buffer being local in places we
don't expect, and extracts the check for a buffer being pinned exactly once
from LockBufferForCleanup() into its own function. Later commits will use this
function.

Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: http://postgr.es/m/419312fd-9255-078c-c3e3-f0525f911d7f@iki.fi
This commit is contained in:
Andres Freund 2023-04-05 10:42:17 -07:00
parent 4d330a61bb
commit 819b69a81d
2 changed files with 34 additions and 13 deletions

View File

@ -1735,6 +1735,8 @@ PinBuffer(BufferDesc *buf, BufferAccessStrategy strategy)
bool result;
PrivateRefCountEntry *ref;
Assert(!BufferIsLocal(b));
ref = GetPrivateRefCountEntry(b, true);
if (ref == NULL)
@ -1880,6 +1882,8 @@ UnpinBuffer(BufferDesc *buf)
PrivateRefCountEntry *ref;
Buffer b = BufferDescriptorGetBuffer(buf);
Assert(!BufferIsLocal(b));
/* not moving as we're likely deleting it soon anyway */
ref = GetPrivateRefCountEntry(b, false);
Assert(ref != NULL);
@ -4253,6 +4257,29 @@ ConditionalLockBuffer(Buffer buffer)
LW_EXCLUSIVE);
}
/*
* Verify that this backend is pinning the buffer exactly once.
*
* NOTE: Like in BufferIsPinned(), what we check here is that *this* backend
* holds a pin on the buffer. We do not care whether some other backend does.
*/
void
CheckBufferIsPinnedOnce(Buffer buffer)
{
if (BufferIsLocal(buffer))
{
if (LocalRefCount[-buffer - 1] != 1)
elog(ERROR, "incorrect local pin count: %d",
LocalRefCount[-buffer - 1]);
}
else
{
if (GetPrivateRefCount(buffer) != 1)
elog(ERROR, "incorrect local pin count: %d",
GetPrivateRefCount(buffer));
}
}
/*
* LockBufferForCleanup - lock a buffer in preparation for deleting items
*
@ -4280,20 +4307,11 @@ LockBufferForCleanup(Buffer buffer)
Assert(BufferIsPinned(buffer));
Assert(PinCountWaitBuf == NULL);
if (BufferIsLocal(buffer))
{
/* There should be exactly one pin */
if (LocalRefCount[-buffer - 1] != 1)
elog(ERROR, "incorrect local pin count: %d",
LocalRefCount[-buffer - 1]);
/* Nobody else to wait for */
return;
}
CheckBufferIsPinnedOnce(buffer);
/* There should be exactly one local pin */
if (GetPrivateRefCount(buffer) != 1)
elog(ERROR, "incorrect local pin count: %d",
GetPrivateRefCount(buffer));
/* Nobody else to wait for */
if (BufferIsLocal(buffer))
return;
bufHdr = GetBufferDescriptor(buffer - 1);
@ -4794,6 +4812,8 @@ LockBufHdr(BufferDesc *desc)
SpinDelayStatus delayStatus;
uint32 old_buf_state;
Assert(!BufferIsLocal(BufferDescriptorGetBuffer(desc)));
init_local_spin_delay(&delayStatus);
while (true)

View File

@ -134,6 +134,7 @@ extern void ReleaseBuffer(Buffer buffer);
extern void UnlockReleaseBuffer(Buffer buffer);
extern void MarkBufferDirty(Buffer buffer);
extern void IncrBufferRefCount(Buffer buffer);
extern void CheckBufferIsPinnedOnce(Buffer buffer);
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
BlockNumber blockNum);