mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
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:
parent
4d330a61bb
commit
819b69a81d
@ -1735,6 +1735,8 @@ PinBuffer(BufferDesc *buf, BufferAccessStrategy strategy)
|
|||||||
bool result;
|
bool result;
|
||||||
PrivateRefCountEntry *ref;
|
PrivateRefCountEntry *ref;
|
||||||
|
|
||||||
|
Assert(!BufferIsLocal(b));
|
||||||
|
|
||||||
ref = GetPrivateRefCountEntry(b, true);
|
ref = GetPrivateRefCountEntry(b, true);
|
||||||
|
|
||||||
if (ref == NULL)
|
if (ref == NULL)
|
||||||
@ -1880,6 +1882,8 @@ UnpinBuffer(BufferDesc *buf)
|
|||||||
PrivateRefCountEntry *ref;
|
PrivateRefCountEntry *ref;
|
||||||
Buffer b = BufferDescriptorGetBuffer(buf);
|
Buffer b = BufferDescriptorGetBuffer(buf);
|
||||||
|
|
||||||
|
Assert(!BufferIsLocal(b));
|
||||||
|
|
||||||
/* not moving as we're likely deleting it soon anyway */
|
/* not moving as we're likely deleting it soon anyway */
|
||||||
ref = GetPrivateRefCountEntry(b, false);
|
ref = GetPrivateRefCountEntry(b, false);
|
||||||
Assert(ref != NULL);
|
Assert(ref != NULL);
|
||||||
@ -4253,6 +4257,29 @@ ConditionalLockBuffer(Buffer buffer)
|
|||||||
LW_EXCLUSIVE);
|
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
|
* LockBufferForCleanup - lock a buffer in preparation for deleting items
|
||||||
*
|
*
|
||||||
@ -4280,20 +4307,11 @@ LockBufferForCleanup(Buffer buffer)
|
|||||||
Assert(BufferIsPinned(buffer));
|
Assert(BufferIsPinned(buffer));
|
||||||
Assert(PinCountWaitBuf == NULL);
|
Assert(PinCountWaitBuf == NULL);
|
||||||
|
|
||||||
if (BufferIsLocal(buffer))
|
CheckBufferIsPinnedOnce(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* There should be exactly one local pin */
|
/* Nobody else to wait for */
|
||||||
if (GetPrivateRefCount(buffer) != 1)
|
if (BufferIsLocal(buffer))
|
||||||
elog(ERROR, "incorrect local pin count: %d",
|
return;
|
||||||
GetPrivateRefCount(buffer));
|
|
||||||
|
|
||||||
bufHdr = GetBufferDescriptor(buffer - 1);
|
bufHdr = GetBufferDescriptor(buffer - 1);
|
||||||
|
|
||||||
@ -4794,6 +4812,8 @@ LockBufHdr(BufferDesc *desc)
|
|||||||
SpinDelayStatus delayStatus;
|
SpinDelayStatus delayStatus;
|
||||||
uint32 old_buf_state;
|
uint32 old_buf_state;
|
||||||
|
|
||||||
|
Assert(!BufferIsLocal(BufferDescriptorGetBuffer(desc)));
|
||||||
|
|
||||||
init_local_spin_delay(&delayStatus);
|
init_local_spin_delay(&delayStatus);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -134,6 +134,7 @@ extern void ReleaseBuffer(Buffer buffer);
|
|||||||
extern void UnlockReleaseBuffer(Buffer buffer);
|
extern void UnlockReleaseBuffer(Buffer buffer);
|
||||||
extern void MarkBufferDirty(Buffer buffer);
|
extern void MarkBufferDirty(Buffer buffer);
|
||||||
extern void IncrBufferRefCount(Buffer buffer);
|
extern void IncrBufferRefCount(Buffer buffer);
|
||||||
|
extern void CheckBufferIsPinnedOnce(Buffer buffer);
|
||||||
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
|
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
|
||||||
BlockNumber blockNum);
|
BlockNumber blockNum);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user