aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2023-11-17 11:02:52 -0800
committerAndres Freund <andres@anarazel.de>2023-11-17 12:46:55 -0800
commitb2e237afddc56a4826121169a693412d8683d940 (patch)
tree9aad78eabab778c5d7b3e8be639ccfffd1380d22
parentf7816aec23eed1dc1da5f9a53cb6507d30b7f0a2 (diff)
downloadpostgresql-b2e237afddc56a4826121169a693412d8683d940.tar.gz
postgresql-b2e237afddc56a4826121169a693412d8683d940.zip
Release lock on heap buffer before vacuuming FSM
When there are no indexes on a table, we vacuum each heap block after pruning it and then update the freespace map. Periodically, we also vacuum the freespace map. This was done while unnecessarily holding a lock on the heap page. Release the lock before calling FreeSpaceMapVacuumRange() and, while we're at it, ensure the range includes the heap block we just vacuumed. There are no known deadlocks or other similar issues, therefore don't backpatch. It's certainly not good to do all this work under a lock, but it's not frequently reached, making it not worth the risk of backpatching. Author: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/CAAKRu_YiL%3D44GvGnt1dpYouDSSoV7wzxVoXs8m3p311rp-TVQQ%40mail.gmail.com
-rw-r--r--src/backend/access/heap/vacuumlazy.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 6985d299b26..59f51f40e1b 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1047,18 +1047,6 @@ lazy_scan_heap(LVRelState *vacrel)
dead_items->num_items = 0;
/*
- * Periodically perform FSM vacuuming to make newly-freed
- * space visible on upper FSM pages. Note we have not yet
- * performed FSM processing for blkno.
- */
- if (blkno - next_fsm_block_to_vacuum >= VACUUM_FSM_EVERY_PAGES)
- {
- FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum,
- blkno);
- next_fsm_block_to_vacuum = blkno;
- }
-
- /*
* Now perform FSM processing for blkno, and move on to next
* page.
*
@@ -1071,6 +1059,24 @@ lazy_scan_heap(LVRelState *vacrel)
UnlockReleaseBuffer(buf);
RecordPageWithFreeSpace(vacrel->rel, blkno, freespace);
+
+ /*
+ * Periodically perform FSM vacuuming to make newly-freed
+ * space visible on upper FSM pages. FreeSpaceMapVacuumRange()
+ * vacuums the portion of the freespace map covering heap
+ * pages from start to end - 1. Include the block we just
+ * vacuumed by passing it blkno + 1. Overflow isn't an issue
+ * because MaxBlockNumber + 1 is InvalidBlockNumber which
+ * causes FreeSpaceMapVacuumRange() to vacuum freespace map
+ * pages covering the remainder of the relation.
+ */
+ if (blkno - next_fsm_block_to_vacuum >= VACUUM_FSM_EVERY_PAGES)
+ {
+ FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum,
+ blkno + 1);
+ next_fsm_block_to_vacuum = blkno + 1;
+ }
+
continue;
}