0002-Vacuum-do-a-partial-FSM-vacuum-at-the-beginning.patch
text/x-patch
Filename: 0002-Vacuum-do-a-partial-FSM-vacuum-at-the-beginning.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch 0002
Subject: Vacuum: do a partial FSM vacuum at the beginning
| File | + | − |
|---|---|---|
| src/backend/commands/vacuumlazy.c | 24 | 0 |
From 0a980794c90973383e5a63f64839616a79542260 Mon Sep 17 00:00:00 2001
From: Claudio Freire <klaussfreire@gmail.com>
Date: Thu, 8 Feb 2018 12:39:15 -0300
Subject: [PATCH 2/2] Vacuum: do a partial FSM vacuum at the beginning
A partial FSM vacuum right at the start of the vacuum process
helps ameliorate issues with cancelled autovacuums never updating
the FSM.
---
src/backend/commands/vacuumlazy.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index 9ad0f34..2965204 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -103,6 +103,19 @@
*/
#define PREFETCH_SIZE ((BlockNumber) 32)
+/*
+ * If autovacuums get regularly cancelled, the FSM may never be
+ * vacuumed. To work around that, we perform an initial partial
+ * FSM vacuum at the beginning of the vacuum process, to quickly
+ * make existing unmarked free space visible. To avoid useless
+ * redundant work, however, we avoid recursing into branches
+ * that already have a set amount of free space, we only try
+ * to discover unmarked free space. This value controls how
+ * much free space is enough free space in that context. The
+ * value is in the terms of the FSM map.
+ */
+#define INITIAL_PARTIAL_FSM_VACUUM_THRESHOLD 64
+
typedef struct LVRelStats
{
/* hasindex = true means two-pass strategy; false means one-pass */
@@ -250,6 +263,17 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params,
vacrelstats->pages_removed = 0;
vacrelstats->lock_waiter_detected = false;
+ /*
+ * Vacuum the Free Space Map partially before we start.
+ * If an earlier vacuum was canceled, and that's likely in
+ * highly contended tables, we may need to finish up. If we do
+ * it now, we make the space visible to other backends regardless
+ * of whether we succeed in finishing this time around.
+ * Don't bother checking branches that already have usable space,
+ * though.
+ */
+ FreeSpaceMapVacuum(onerel, INITIAL_PARTIAL_FSM_VACUUM_THRESHOLD);
+
/* Open all indexes of the relation */
vac_open_indexes(onerel, RowExclusiveLock, &nindexes, &Irel);
vacrelstats->hasindex = (nindexes > 0);
--
1.8.4.5