mirror of
https://github.com/postgres/postgres.git
synced 2025-04-18 13:44:19 +03:00
localbuf: Track pincount in BufferDesc as well
For AIO on temporary table buffers the AIO subsystem needs to be able to ensure a pin on a buffer while AIO is going on, even if the IO issuing query errors out. Tracking the buffer in LocalRefCount does not work, as it would cause CheckForLocalBufferLeaks() to assert out. Instead, also track the refcount in BufferDesc.state, not just LocalRefCount. This also makes local buffers behave a bit more akin to shared buffers. Note that we still don't need locking, AIO completion callbacks for local buffers are executed in the issuing session (i.e. nobody else has access to the BufferDesc). Reviewed-by: Noah Misch <noah@leadboat.com> Discussion: https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
This commit is contained in:
parent
08ccd56ac7
commit
d6d8054dc7
@ -249,6 +249,13 @@ GetLocalVictimBuffer(void)
|
|||||||
pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
|
pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
|
||||||
trycounter = NLocBuffer;
|
trycounter = NLocBuffer;
|
||||||
}
|
}
|
||||||
|
else if (BUF_STATE_GET_REFCOUNT(buf_state) > 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This can be reached if the backend initiated AIO for this
|
||||||
|
* buffer and then errored out.
|
||||||
|
*/
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Found a usable buffer */
|
/* Found a usable buffer */
|
||||||
@ -570,7 +577,13 @@ InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced)
|
|||||||
|
|
||||||
buf_state = pg_atomic_read_u32(&bufHdr->state);
|
buf_state = pg_atomic_read_u32(&bufHdr->state);
|
||||||
|
|
||||||
if (check_unreferenced && LocalRefCount[bufid] != 0)
|
/*
|
||||||
|
* We need to test not just LocalRefCount[bufid] but also the BufferDesc
|
||||||
|
* itself, as the latter is used to represent a pin by the AIO subsystem.
|
||||||
|
* This can happen if AIO is initiated and then the query errors out.
|
||||||
|
*/
|
||||||
|
if (check_unreferenced &&
|
||||||
|
(LocalRefCount[bufid] != 0 || BUF_STATE_GET_REFCOUNT(buf_state) != 0))
|
||||||
elog(ERROR, "block %u of %s is still referenced (local %u)",
|
elog(ERROR, "block %u of %s is still referenced (local %u)",
|
||||||
bufHdr->tag.blockNum,
|
bufHdr->tag.blockNum,
|
||||||
relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
|
relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
|
||||||
@ -744,12 +757,13 @@ PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount)
|
|||||||
if (LocalRefCount[bufid] == 0)
|
if (LocalRefCount[bufid] == 0)
|
||||||
{
|
{
|
||||||
NLocalPinnedBuffers++;
|
NLocalPinnedBuffers++;
|
||||||
|
buf_state += BUF_REFCOUNT_ONE;
|
||||||
if (adjust_usagecount &&
|
if (adjust_usagecount &&
|
||||||
BUF_STATE_GET_USAGECOUNT(buf_state) < BM_MAX_USAGE_COUNT)
|
BUF_STATE_GET_USAGECOUNT(buf_state) < BM_MAX_USAGE_COUNT)
|
||||||
{
|
{
|
||||||
buf_state += BUF_USAGECOUNT_ONE;
|
buf_state += BUF_USAGECOUNT_ONE;
|
||||||
pg_atomic_unlocked_write_u32(&buf_hdr->state, buf_state);
|
|
||||||
}
|
}
|
||||||
|
pg_atomic_unlocked_write_u32(&buf_hdr->state, buf_state);
|
||||||
}
|
}
|
||||||
LocalRefCount[bufid]++;
|
LocalRefCount[bufid]++;
|
||||||
ResourceOwnerRememberBuffer(CurrentResourceOwner,
|
ResourceOwnerRememberBuffer(CurrentResourceOwner,
|
||||||
@ -775,7 +789,17 @@ UnpinLocalBufferNoOwner(Buffer buffer)
|
|||||||
Assert(NLocalPinnedBuffers > 0);
|
Assert(NLocalPinnedBuffers > 0);
|
||||||
|
|
||||||
if (--LocalRefCount[buffid] == 0)
|
if (--LocalRefCount[buffid] == 0)
|
||||||
|
{
|
||||||
|
BufferDesc *buf_hdr = GetLocalBufferDescriptor(buffid);
|
||||||
|
uint32 buf_state;
|
||||||
|
|
||||||
NLocalPinnedBuffers--;
|
NLocalPinnedBuffers--;
|
||||||
|
|
||||||
|
buf_state = pg_atomic_read_u32(&buf_hdr->state);
|
||||||
|
Assert(BUF_STATE_GET_REFCOUNT(buf_state) > 0);
|
||||||
|
buf_state -= BUF_REFCOUNT_ONE;
|
||||||
|
pg_atomic_unlocked_write_u32(&buf_hdr->state, buf_state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user