1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Make on-access pruning pin visibility map before locking heap page

b46e1e54d0 pinned the VM after acquiring a cleanup lock on the heap
page when on-access pruning. This was not correct, as pinning the VM may
require I/O. Pin the VM before acquiring the lock. This could mean
occasional unneeded pinning when the buffer is under contention, but
that should be rare.

Reported-by: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAAKRu_aR6e2mNVo-DNHDUfBE5i0cbE4%3Du%3D_Qi9%2Bv573qiGtBig%40mail.gmail.com
Backpatch-through: 19
This commit is contained in:
Melanie Plageman
2026-09-11 20:37:53 -04:00
parent e31766933a
commit b3609cd2db

View File

@@ -325,6 +325,14 @@ heap_page_prune_opt(Relation relation, Buffer buffer, Buffer *vmbuffer,
bool record_free_space = false;
Size freespace = 0;
/*
* Pin the VM page before taking the heap cleanup lock. This may
* occasionally lead to an unnecessary pin when the buffer is
* contended, but the same VM page covers many heap pages, so there is
* a good chance for the work to be reusable.
*/
visibilitymap_pin(relation, BufferGetBlockNumber(buffer), vmbuffer);
/* OK, try to get exclusive buffer lock */
if (!ConditionalLockBufferForCleanup(buffer))
return;
@@ -340,9 +348,6 @@ heap_page_prune_opt(Relation relation, Buffer buffer, Buffer *vmbuffer,
PruneFreezeResult presult;
PruneFreezeParams params;
visibilitymap_pin(relation, BufferGetBlockNumber(buffer),
vmbuffer);
params.relation = relation;
params.buffer = buffer;
params.vmbuffer = *vmbuffer;