From: Nathan Bossart Date: Thu, 18 Jun 2026 15:18:25 +0000 (-0500) Subject: Avoid division-by-zero when calculating autovacuum MXID score. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f2297b548794a0fec502a9fc70c9970d96b09c4;p=thirdparty%2Fpostgresql.git Avoid division-by-zero when calculating autovacuum MXID score. In some cases, effective_multixact_freeze_max_age can be 0, which presents a division-by-zero hazard for the multixact ID age score calculation. To fix, bump it to 1 in that case so that we use the multixact ID age as the score. While at it, also document that this component score scales due to high multixact member space usage. Reported-by: Masahiko Sawada Author: Sami Imseih Reviewed-by: Bharath Rupireddy Discussion: https://postgr.es/m/CAD21AoC6nKeYAjTvJ9dmBea03GZK9222h_O%3DONmcVuxfyO88Bg%40mail.gmail.com --- diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 96ea84b11f2..e341f165efd 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -1112,8 +1112,10 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu field as compared to . Furthermore, this component increases greatly once the age surpasses - . The final value - for this component can be adjusted via + or when the number + of multixact member entries created exceeds approximately 2 billion + entries (see ). The + final value for this component can be adjusted via . 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..e9aaf24c1be 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -3048,7 +3048,10 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, * One exception to the previous paragraph is for tables nearing wraparound, * i.e., those that have surpassed the effective failsafe ages. In that case, * the relfrozenxid/relminmxid-based score is scaled aggressively so that the - * table has a decent chance of sorting to the front of the list. + * table has a decent chance of sorting to the front of the list. Furthermore, + * the relminmxid-based score is scaled aggressively as + * effective_multixact_freeze_max_age is lowered due to high multixact member + * space usage. * * To adjust how strongly each component contributes to the score, the * following parameters can be adjusted from their default of 1.0 to anywhere @@ -3194,13 +3197,15 @@ 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. The multixact_freeze_max_age + * variable might be 0 here (i.e., a division-by-zero hazard), so in that + * case we use the mxid_age as the MXID 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(1, multixact_freeze_max_age); /* * To ensure tables are given increased priority once they begin