mxid_score can become Infinity in pg_stat_autovacuum_scores

Masahiko Sawada <sawada.mshk@gmail.com>

From: Masahiko Sawada <sawada.mshk@gmail.com>
To: PostgreSQL-development <pgsql-hackers@postgresql.org>
Date: 2026-06-12T18:19:31Z
Lists: pgsql-hackers
Hi all,

While testing the autovacuum score, I noticed that scores->mxid could
be infinity by the following calculation in
relation_needs_vacanalyze():

scores->mxid = (double) mxid_age / multixact_freeze_max_age;

The variable multixact_freeze_max_age originates from
effective_multixact_freeze_max_age, which is determined by
MultiXactMemberFreezeThreshold(). As noted in the comments for
MultiXactMemberFreezeThreshold(), it can return 0 under certain
conditions:

/* fraction could be > 1.0, but lowest possible freeze age is zero */
if (fraction >= 1.0)
    return 0;

Since mxid_age is cast to a double before the division, this does not
trigger a division-by-zero error or cause a server crash. However,
scores->mxid results in 'inf', which displays as "Infinity" in the
mxid_score column of the pg_stat_autovacuum_scores view. While this
might not be intentional, it seems better to prevent mxid_score from
becoming infinity by doing something like this:

- scores->mxid = (double) mxid_age / multixact_freeze_max_age;
+ scores->mxid = (double) mxid_age / Max(multixact_freeze_max_age, 1);

Any thoughts on this?

Regards,

-- 
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com



Commits

  1. Avoid division-by-zero when calculating autovacuum MXID score.

  2. Widen MultiXactOffset to 64 bits