On Thu, Sep 17, 2026 at 06:25:58PM +0300, Heikki Linnakangas wrote: > On 16/09/2026 14:33, Heikki Linnakangas wrote: > > On 28/08/2026 02:17, Noah Misch wrote: > > > commit bd8d9c9 wrote: > > > > Commit: Heikki Linnakangas <[email protected]> > > > > 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. > > > > Thanks, I'll look into this. My first reaction is that I think if > > oldstMulti is incorrectly too old, the upgrade will fail because the > > conversion routine will fail to find it. If it's too new, i.e. "in the > > future", it will also fail to find it.
Agreed, those cases fail cleanly. No concerns on those. > > The third possibility is that the bogus oldstMulti value is within the > > range of the "real" range. That's the only scenario I felt was at risk. For example, the range of MXIDs in tuple headers is [(unsigned)-100M,200M], but oldestMulti is 1. > > That can happen if multixid wraparound had > > already happened before the (broken) 9.3 -> 9.4 upgrade. In that case, > > even if the multixids are still readable on disk, you're one vacuum away > > from truncating them. In other words, the damage has already been done, > > or could be done at any minute. Okay. I briefly tried to verify how rapidly one can expect v18 to truncate the SLRUs in this scenario, but I didn't get very far. I will rely on your analysis. Thanks for studying it. > With the attached patch, you get an error message crafted specifically for > that case. > > > Converting pg_multixact files fatal > > > > Segment file containing multixid 1 does not exist. > > This can happen if an old version of pg_upgrade was used in the past > > to upgrade the cluster from version 9.3 to 9.4. If that is the cause, > > it can be fixed by running VACUUM FREEZE before upgrade. > > Failure, exiting > > I'm not sure this is worth committing though. How many clusters are there > out there that have been pg_upgraded to version 9.3.0-9.3.4, and haven't > since been running for long enough to fix the oldestMultiXid value? Having > that error message seems pretty harmless too, but if you actually hit that > case that the file is missing, it might actually be more likely that you've > hit some other bug than that old pg_upgrade issue. I wouldn't commit the more-specific error message. If it did something for the "third possibility", that might be different. I think we can consider closed the topic of how 9.3 upgrades interact with 64-bit MultiXactOffset.
