| From: | Noah Misch <noah(at)leadboat(dot)com> |
|---|---|
| To: | hlinnaka(at)iki(dot)fi, orlovmg(at)gmail(dot)com |
| Cc: | pgsql-hackers(at)postgresql(dot)org |
| Subject: | 64-bit MultiXactOffset vs. 9.3->9.4 upgrade, pg_resetwal, "wraparound" msg |
| Date: | 2026-08-27 23:17:57 |
| Message-ID: | 20260827231757.78.noahmisch@microsoft.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
commit bd8d9c9 wrote:
> Commit: Heikki Linnakangas <heikki(dot)linnakangas(at)iki(dot)fi>
> CommitDate: Tue Dec 9 13:53:03 2025 +0200
>
> Widen MultiXactOffset to 64 bits
> --- a/src/bin/pg_upgrade/pg_upgrade.c
> +++ b/src/bin/pg_upgrade/pg_upgrade.c
> + nxtmulti = old_cluster.controldata.chkpnt_nxtmulti;
> + if (old_cluster.controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER)
> + {
> + /* Versions 9.3 - 18: convert all multixids */
> + oldstMulti = old_cluster.controldata.chkpnt_oldstMulti;
If a cluster's upgrade history includes an upgrade from 9.3 to early 9.4, it
may have a wrong value here. Specifically, upgrades done before a61daa14
(2014-07 commit) have that hazard. We still have backend code to detect such
cases and reduce damage:
ereport(LOG,
(errmsg("cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation",
newOldestMulti)));
However, the pg_upgrade side from the v19 commit lacks such protection. If
heap tuples still reference older multixacts than the faulty control data
suggests, pg_upgrade will copy too small a range, making affected tuples
unreadable.
I also had Opus 4.8 look for defects in this change and write test cases. It
didn't find the above problem, but it had other findings. I'm attaching the
full report. I recommend fixing at least these before release:
> +| 5 | `resetwal-nextmxoff-zero` | `src/bin/pg_resetwal/pg_resetwal.c:703`, and `-O` with no zero check at 297-307 | `pg_resetwal -f` (or `-O 0`) leaves `nextMultiOffset = 0`, the reserved "invalid offset"; first multixact created afterwards is permanently unreadable: `ERROR: MultiXact 1 has invalid offset` | Yes — `src/test/modules/test_slru/t/003_multixact_offset.pl` |
> +| 7 | `members-truncation-apparent-wraparound` | `src/backend/access/transam/multixact.c:2642-2647` | When `nextOffset` lands on a members page boundary, truncation logs `could not truncate directory "pg_multixact/members": apparent wraparound` (impossible for a 64-bit counter) and reclaims nothing | Yes — `003_multixact_offset.pl` |
Others are more optional or already reported. In particular, two other
findings were already reported and apparently fixed after the Opus run, in
thread "pg_upgrade silently truncates nextMultiOffset to 32 bits":
https://www.postgresql.org/message-id/CAD21AoCvzerscfU8o4ARQ793yAGHpQ72r2x5apeC_W2-k%3DSLCQ%40mail.gmail.com
| Attachment | Content-Type | Size |
|---|---|---|
| bd8d9c9-MultiXactOffset-tests-v0.patch | text/plain | 50.8 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Henson Choi | 2026-08-28 00:12:17 | Re: Row pattern recognition |
| Previous Message | Bharath Rupireddy | 2026-08-27 22:51:35 | Re: REPACK (CONCURRENTLY) doesn't check the table AM |