v1-0001-Correct-the-MultiXact-autovacuum-priority-score-w.patch

application/octet-stream

Filename: v1-0001-Correct-the-MultiXact-autovacuum-priority-score-w.patch
Type: application/octet-stream
Part: 0
Message: Re: mxid_score can become Infinity in pg_stat_autovacuum_scores

Patch

Format: format-patch
Series: patch v1-0001
Subject: Correct the MultiXact autovacuum priority score when member space is high
File+
doc/src/sgml/maintenance.sgml 10 4
src/backend/postmaster/autovacuum.c 3 2
From 08a44a4c15c5187f92eb19a45c1fca7d87b0a0d9 Mon Sep 17 00:00:00 2001
From: Sami Imseih <samimseih@gmail.com>
Date: Fri, 12 Jun 2026 15:11:47 -0500
Subject: [PATCH v1 1/1] Correct the MultiXact autovacuum priority score when
 member space is high

MultiXactMemberFreezeThreshold() can return 0 when multixact member
space usage is high, causing effective_multixact_freeze_max_age to
be 0. Dividing mxid_age (cast to double) by 0 produces infinity
rather than a crash, but this results in "Infinity" appearing in
pg_stat_autovacuum_scores.mxid_score and incorrectly skews the
priority ordering.

Fix by using Max(multixact_freeze_max_age, 1) so the score
effectively equals mxid_age in this case, which is still high enough
to push the table near the top of the priority list.

Also update the documentation to explain the effect of high member
space usage on the mxid score component.
---
 doc/src/sgml/maintenance.sgml       | 14 ++++++++++----
 src/backend/postmaster/autovacuum.c |  5 +++--
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml
index 96ea84b11f2..02326e00c71 100644
--- a/doc/src/sgml/maintenance.sgml
+++ b/doc/src/sgml/maintenance.sgml
@@ -1110,10 +1110,16 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu
        multixacts of the table's
        <structname>pg_class</structname>.<structfield>relminmxid</structfield>
        field as compared to
-       <xref linkend="guc-autovacuum-multixact-freeze-max-age"/>.  Furthermore,
-       this component increases greatly once the age surpasses
-       <xref linkend="guc-vacuum-multixact-failsafe-age"/>.  The final value
-       for this component can be adjusted via
+       <xref linkend="guc-autovacuum-multixact-freeze-max-age"/>.  However,
+       when multixact member space usage is high (see
+       <xref linkend="vacuum-for-multixact-wraparound"/>), the effective
+       freeze max age is reduced below
+       <xref linkend="guc-autovacuum-multixact-freeze-max-age"/> to help
+       reclaim multixact member disk space, which can result in much higher
+       scores than normal.  Furthermore, this component increases greatly
+       once the age surpasses
+       <xref linkend="guc-vacuum-multixact-failsafe-age"/>.  The
+       final value for this component can be adjusted via
        <xref linkend="guc-autovacuum-multixact-freeze-score-weight"/>.  Note
        that increasing this parameter's value also lowers the age at which this
        component begins scaling aggressively, i.e., the scaling age is divided
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index a5a8db2ff88..509dac9c4ce 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -3194,13 +3194,14 @@ relation_needs_vacanalyze(Oid relid,
 
 	/*
 	 * To calculate the (M)XID age portion of the score, divide the age by its
-	 * respective *_freeze_max_age parameter.
+	 * respective *_freeze_max_age parameter. MultiXactMemberFreezeThreshold()
+	 * can return 0, in which case we effectively use mxid_age as the score.
 	 */
 	xid_age = TransactionIdIsNormal(relfrozenxid) ? recentXid - relfrozenxid : 0;
 	mxid_age = MultiXactIdIsValid(relminmxid) ? recentMulti - relminmxid : 0;
 
 	scores->xid = (double) xid_age / freeze_max_age;
-	scores->mxid = (double) mxid_age / multixact_freeze_max_age;
+	scores->mxid = (double) mxid_age / Max(multixact_freeze_max_age, 1);
 
 	/*
 	 * To ensure tables are given increased priority once they begin
-- 
2.50.1 (Apple Git-155)