Re: 64-bit MultiXactOffset vs. 9.3->9.4 upgrade, pg_resetwal, "wraparound" msg

From: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
To: Noah Misch <noah(at)leadboat(dot)com>
Cc: orlovmg(at)gmail(dot)com, pgsql-hackers(at)postgresql(dot)org
Subject: Re: 64-bit MultiXactOffset vs. 9.3->9.4 upgrade, pg_resetwal, "wraparound" msg
Date: 2026-09-18 18:15:38
Message-ID: a432f851-deb1-4f24-80cb-9348cb6cd98a@iki.fi
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 17/09/2026 19:21, Noah Misch wrote:
> 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 <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.
>>>
>>> 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.

Thinking about this some more, you were right originally, there is
danger here:

If you're in that situation, where oldestMulti is higher than
min(datminmxid), VACUUM will _not_ truncate the slrus. That was the
whole idea of commit 78db307bb2, to refrain from truncating. So you're
not in much danger, unless you consume so many multixids that you start
to overwrite the tail.

But v19 pg_upgrade would indeed effectively truncate them away, by not
converting them to the new format.

A better fix here is to add a pre-check that oldestMulti <
min(datminmxid). That seems like a good sanity check anyway, and it will
catch that ancient 9.3 scenario.

Barring objections, I'll commit the attached to add that check. I didn't
include a hint about that 9.3 upgrade bug, since I don't think you're
very likely to hit that anymore. But it's good to have the check to
prevent damage if you do manage to hit it, or some other bug.

- Heikki

Attachment Content-Type Size
0001-Check-that-oldestXID-and-oldestMulti-are-consistent-.patch text/x-patch 7.3 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Bharath Rupireddy 2026-09-18 18:23:37 Re: Report index currently being vacuumed in pg_stat_progress_vacuum
Previous Message Jeff Davis 2026-09-18 18:08:43 Re: Regression tests failures due to concurrent grants