| From: | Manu <manuelreyesbravo(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Cc: | Heikki Linnakangas <hlinnaka(at)iki(dot)fi>, Noah Misch <noah(at)leadboat(dot)com>, Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com> |
| Subject: | pg_upgrade stores an invalid datminmxid/relminmxid when the old cluster's newest multixact is 0xFFFFFFFF |
| Date: | 2026-10-17 07:45:01 |
| Message-ID: | 179222310109.2552144.6852303936733376629@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
While testing pg_upgrade's multixact conversion around commit 2323f03,
I ran into an adjacent, pre-existing issue.
When the old cluster's newest multixact is 0xFFFFFFFF, its checkpoint
has NextMultiXactId = 0. copy_xact_xlog_xid() maps that to
FirstMultiXactId for pg_resetwal, but set_frozenxids() writes the raw 0
into pg_database.datminmxid and pg_class.relminmxid (the code dates to
a61daa14d56, 2014).
The effect:
- on assert-enabled builds, VACUUM fails Assert(MultiXactIdIsValid(...));
- otherwise template0 keeps datminmxid = 0 (mxid_age 2147483647) and
multixact truncation is skipped ("cannot truncate up to MultiXact 0
... skipping truncation") until autovacuum vacuums template0 -- which
it does within ~60 s by default, but never with autovacuum = off.
19's new oldestMultiXid consistency check does not catch it: it uses
modular arithmetic, so 0 "follows" 0xFFFFFFFF and passes. It
reproduces with pg_upgrade 18 and master.
The attached patch applies the same adjustment in set_frozenxids(), not
in controldata.c: the raw nextMulti = 0 is still needed so the multixact
reader sees that 0xFFFFFFFF is the newest multixid -- the case 2323f03
fixed. It also adds a case to t/007_multixact_conversion.pl.
Measured on cassert builds from 14..18 across 8 offset/multixid
wraparound boundaries (40 upgrades, plus --link from 18): with the fix,
no invalid datminmxid/relminmxid and no other datminmxid change (only
template0's 0 -> 1 in the 8 affected upgrades); without it, VACUUM traps
and the two new test checks fail. check-world passes.
So the severity is low with the default autovacuum, persistent with
autovacuum off, and a hard failure on assert-enabled builds.
Regards,
Manu
| Attachment | Content-Type | Size |
|---|---|---|
| v2-0001-pg_upgrade-Don-t-store-an-invalid-datminmxid-relm.patch | text/x-patch | 4.9 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Zsolt Parragi | 2026-10-17 08:11:54 | Re: pg_upgrade stores an invalid datminmxid/relminmxid when the old cluster's newest multixact is 0xFFFFFFFF |
| Previous Message | Manu | 2026-10-17 07:31:10 | Re: [PG19] Eager aggregation runs a volatile join clause once per group |