diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index bb436734585..06437161135 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -9143,22 +9143,24 @@ EvictExtraBuffers(int targetNBuffers, int currentNBuffers) buf_state = pg_atomic_read_u64(&desc->state); /* - * Nobody is expected to allocate new buffers while resizing is going - * on hence unlocked precheck should be safe and saves some cycles. + * A buffer whose tag is not published carries no hash-table mapping + * that shrinking has to clean up. BM_VALID is not sufficient here: + * a buffer mid-IO has BM_TAG_VALID but not yet BM_VALID, and skipping + * it would leave an orphaned mapping in the shrunk pool. */ - if (!(buf_state & BM_VALID)) + if (!(buf_state & BM_TAG_VALID)) continue; ResourceOwnerEnlarge(CurrentResourceOwner); ReservePrivateRefCountEntry(); - LockBufHdr(desc); + buf_state = LockBufHdr(desc); /* * Now that we have locked buffer descriptor, make sure that the - * buffer without valid data has been skipped above. + * buffer without a tag has been skipped above. */ - Assert(buf_state & BM_VALID); + Assert(buf_state & BM_TAG_VALID); if (!EvictUnpinnedBufferInternal(desc, &buffer_flushed)) {