Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wh9JV-0002Jx-1P for pgsql-bugs@arkaria.postgresql.org; Tue, 07 Jul 2026 17:10:29 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wh9JT-001w0V-3C for pgsql-bugs@arkaria.postgresql.org; Tue, 07 Jul 2026 17:10:28 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wh9JT-001w0N-2J for pgsql-bugs@lists.postgresql.org; Tue, 07 Jul 2026 17:10:28 +0000 Received: from mail-vk1-xa2c.google.com ([2607:f8b0:4864:20::a2c]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wh9JR-000000004Jj-1Hjb for pgsql-bugs@lists.postgresql.org; Tue, 07 Jul 2026 17:10:28 +0000 Received: by mail-vk1-xa2c.google.com with SMTP id 71dfb90a1353d-5bc22d9977cso3014240e0c.0 for ; Tue, 07 Jul 2026 10:10:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1783444224; cv=none; d=google.com; s=arc-20260327; b=XNCsLWMaYWVhbxQYh8JctSE/X7wYa6J3GU/l9qQOXllLjjgMj8AHRkWUvaP3l8SWyY 0ut8jj1Ow/uO/bl/Ms04bY14ik2PTxzPGkqV7WyT470zfCt/VDy/0RakEwTR4+nfZO9Q EFBgvAEJSkfCw5VgtywiwuOFpxK18cJ/ki62O1ymPHMHQGNimqEbuN3wbHsb6sM2bEE1 KGiINlgUptsEp6P5PiI11L+zU0/hctZteu9QiXY1EbhXCvtZrcWHnVhdqBy86DjePbyI DpBQJ5V2/gg17N3sTymN3Mj6jElBd71s/IzjmJWG9pOM2iAB0yL1dbU/qbuByeA22BNS MtRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=swKCocLKyIIBYlXjtM8ZGY1XT3h+1Vt/Bl6oAymKLgM=; fh=PFipy9ai9/Cfm12i04v8BLUg0wzj31XQLfIVlsfl5mk=; b=RXnRve/LShTXFyxLxq5aNiDNoKRGgJdP0pGkY3YeXn31p9S10hpfNab6YdV9RW2xCF ueS2WueU5l1J1phxTU9cCz5Nv1uZ3THZarEX57+zvVOykJ1gtgpPTfWmOtKxziGEBlN4 9tps53vwjoTzdBBKdyTaSOn6IHBAl37AmvkNqvS+0yV6ggk0XyhUZakA2Ipt1A1HkAwt V0y/uEgIxRdoISEE2e+DlQufPKIfkSzraDD7dWw3QVqWjdZ2P+O3M/rFk1yj2J3o2qiv KJyjXUXPzdSozytoA0K0E6eRlZXoYz1XDgKfueTYYnWB1mu1ztfm0nZEPd8610cbh7MB 3EbA==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783444224; x=1784049024; darn=lists.postgresql.org; h=content-type:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:from:to:cc:subject:date:message-id:reply-to :content-type; bh=swKCocLKyIIBYlXjtM8ZGY1XT3h+1Vt/Bl6oAymKLgM=; b=qwQGRruSEUqRFAKgbr0OuUkfNpf+v7aRINtoggDxsC7HGfxMaadTO8ITGVhlV0KBbQ zzfZv2fihd+k+5CMyLJvjout6giB60cgghpZFyuwaSxoivXRYx03sF5aoZWaFz0ul0Ik oDZrYH/XdyNj5wC+Vdjgj1CMf08u/Lfhcmkt+GSJNYn1MWdqDELeUV8zusL4J97oKsjA yZ21WSY9RkVQO96PzDDBO7zdidNwuYWst8u1+iqL65EZKvokddxeG0frOO9GWTxtTtHV X/iSwCHQTekWprFmxYew+zDHl8q5USd6RWpD4PBic6+HbGlcwfLimZGjf4cbNrFx3ND7 jkdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783444224; x=1784049024; h=content-type:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to:content-type; bh=swKCocLKyIIBYlXjtM8ZGY1XT3h+1Vt/Bl6oAymKLgM=; b=U0YIyhjyDyTVB7qll9nfvqLrOnGoL1zPdclrmIPrlH3/kPw4h5q5Kskk4VaT/nFtPK tJcmoQ+gBBUhbQYApV+LsI3bmXxTfWgbCCMQGl8rUQnyMDi9QeXdhy2utmDmMC/Vzcvo ABV6/n1Ly3AHNApG/ZO31xXWljN0Dyz/nYbYbcR1jGVyjQclKuFvGcOpSuJHiiLEwVQu x3r70dtgj/S4yRNxlXkhN8vK0SEZufTr2nOvZsM5A+qT28VRaTlQgTPA7LxNcr8JP5i0 pbfpvIdi6wfj0u93cUqJh9D9b5Fn685IxgbTShIgXyL1YNS6LoV1CvH0EJrl7m0au4cS 0Xog== X-Forwarded-Encrypted: i=1; AHgh+RosWkDo+TfmgcbTr5p6+GqnMRTbwe5MRPKW4AQorVu29G/ZgiZuHLfdp8ldjAuq1vYTUw6pNd1beyq9@lists.postgresql.org X-Gm-Message-State: AOJu0YwOxLDcHD3VFjGxXkza7z8eBETpLvRKoEzfC7Dj/SP+KuPPOZT1 7DUCSZJLB0ep2v7BE2GDQaBiYjFO4fNj7NmXtwulmoLRNLfMaUWvpUU8nChjiUYBOv74Tk/rNj4 aq9CzFO05bwKSQNg/R5UJSawrkhCRdcY= X-Gm-Gg: AfdE7cmm8L4KbTTyusLB1y8Zqiqhfm8TvKNH07R8SaU6EBKa/4zOY+PZzBO2UPEaBc6 Otk66/Kq9uvf8Y3TuI0iepUUO2om3eqKNQlw17AJyMLslp2iXVS/NOubm7yp8S0AdaTNlYXwo/6 PmYNhvJLAUKbOx1Lx1zU03xTVlkue4dRfpPLMKDvVk/t4aVS3Y53RQdmQ7nd5Jg0h9o+qTCeUOl md+F4y1wvJw8vKecjnLkTEuHEcEyPNLjHO3uP61G1z0NMuSwVK0+D7nmBghOybeYGS6Angu8nvu thglgmWFIo/G6v6kGo+ipxHBlqhUAlXKAkt5EiqDsS13LCPmPAfoZeeN6Jefg3UQjRMpwr9uhyX BrumCogfoT+Ty8xU= X-Received: by 2002:a05:6122:e469:b0:5bd:73b5:6d25 with SMTP id 71dfb90a1353d-5be9074e753mr3806151e0c.5.1783444224246; Tue, 07 Jul 2026 10:10:24 -0700 (PDT) MIME-Version: 1.0 References: <19519-fe02d8ff679d834d@postgresql.org> In-Reply-To: From: Srinath Reddy Sadipiralla Date: Tue, 7 Jul 2026 22:40:12 +0530 X-Gm-Features: AVVi8CcfdHQ2UtWXMyO-NmclvXeRev-1sEPf62gw1CmrKBxLzL9fXy8YZjSerDg Message-ID: Subject: Re: BUG #19519: REPACK can fail due to missing chunk for toast value To: Michael Paquier Cc: Matthias van de Meent , Imran Zaheer , Alexander Lakhin , PostgreSQL mailing lists , Konstantin Knizhnik Content-Type: multipart/alternative; boundary="00000000000076882f0656087716" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000076882f0656087716 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, On Tue, Jul 7, 2026 at 10:52=E2=80=AFAM Michael Paquier wrote: > > Option 2 leads to a much nicer result overall, with the attached > passing my regression tests and Alexander's case as well (highly > concurrent thing sent yesterday). The rest of the patch is kind of > boring, where I have been trying to get a missing_ok state across the > stack to let the toast slice fetch bypass the case of missing chunks > when we are OK with it due to the rewrites. That still feels crude, > but the simplicity is appealing here, as much as the rather low > invasiveness. > > Thoughts or comments? With the initial reproducer, I originally thought this bug was driven entirely by a long-running query in another database causing a self-inflicted horizo= n drag on the rewrite operation. My theory was that the cross-database sleepe= r drags down the global xmin, which infects the snapshot held by VACUUM FULL. During ComputeXidHorizons, VACUUM FULL ends up dragging its own garbage collection horizon backward. Lazy vacuum avoids this trap because it utilizes the PROC_IN_VACUUM flag to ignore its own snapshot.Since we cannot simply apply PROC_IN_VACUUM to VACUUM FULL (it needs standard MVCC snapshots to safely evaluate index expressions), and we can't remove it from lazy vacuum (which would cause bloat), patching the rewrite operation to explicitly ignore its own snapshot during GC calculation (excludeMyself) seemed like the correct fix. The script proved that OldestXmin can be dragged backward by other processes, bypassing the patch entirely.If a completely separate process in the same database (such as a simple \d catalog lookup) requests a global snapshot, it gets "infected" by the long-running query in the other database. This new query now sits in the local ProcArray. Lazy Vacuum runs, ignores the cross-database sleeper, calculates an aggressive horizon, and physically removes the TOAST chunks.VACUUM FULL runs, sees the local carrier query, and is forced to respect its older snapshot. Its horizon is dragged backward, it assumes the main tuples are RECENTLY_DEAD, attempts to copy them, and crashes because the TOAST chunks are gone. so my initial thoughts are that until there's dependency of OldestXmin calculation on global snapshot , the rewrite horizon getting dragged back seems inevitable, so i think compared to other approaches in the thread ,your approach of ignoring the fact of missing chunks seems good. I quickly reviewed the core logic of treating the missing chunks as dead and LGTM will further look into this and test. --=20 Thanks :) Srinath Reddy Sadipiralla EDB: https://www.enterprisedb.com/ --00000000000076882f0656087716 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

On Tue, Jul 7, 2= 026 at 10:52=E2=80=AFAM Michael Paquier <michael@paquier.xyz> wrote:

Option 2 leads to a much nicer result overall, with the attached
passing my regression tests and Alexander's case as well (highly
concurrent thing sent yesterday).=C2=A0 The rest of the patch is kind of boring, where I have been trying to get a missing_ok state across the
stack to let the toast slice fetch bypass the case of missing chunks
when we are OK with it due to the rewrites.=C2=A0 That still feels crude, but the simplicity is appealing here, as much as the rather low
invasiveness.

Thoughts or comments?

With the initial reproducer, I o= riginally thought this bug was driven entirely
by a long-running query i= n another database causing a self-inflicted horizon
drag on the rewrite = operation. My theory was that the cross-database sleeper
drags down the = global xmin, which infects the snapshot held by VACUUM FULL.
During Comp= uteXidHorizons, VACUUM FULL ends up dragging its own garbage
collection = horizon backward. Lazy vacuum avoids this trap because it utilizes the
P= ROC_IN_VACUUM flag to ignore its own snapshot.Since we cannot simply apply<= br>PROC_IN_VACUUM to VACUUM FULL (it needs standard MVCC snapshots to
sa= fely evaluate index expressions), and we can't remove it from lazy vacu= um
(which would cause bloat), patching the rewrite operation to explicit= ly ignore its
own snapshot during GC calculation (excludeMyself) seemed = like the correct fix.

The script proved that OldestXmin can be dragg= ed backward by other processes,
bypassing the patch entirely.If a comple= tely separate process in the same database
(such as a simple \d catalog = lookup) requests a global snapshot, it gets "infected" by
the = long-running query in the other database. This new query now sits in the lo= cal ProcArray.
Lazy Vacuum runs, ignores the cross-database sleeper, cal= culates an aggressive horizon,
and physically removes the TOAST chunks.V= ACUUM FULL runs, sees the local carrier
query, and is forced to respect = its older snapshot. Its horizon is dragged backward, it
assumes the main= tuples are RECENTLY_DEAD, attempts to copy them, and crashes
because th= e TOAST chunks are gone.

so my initial thoughts are that until there= 's=C2=A0dependency of OldestXmin=C2=A0calculation on
global snapshot= , the rewrite horizon getting dragged back seems inevitable, so i thinkcompared to other=C2=A0approaches in the thread ,your approach of=C2=A0ignoring=C2=A0the fact of
miss= ing chunks seems good. I quickly reviewed the core logic of treating the mi= ssing
chunks as dead and LGTM will further look into this and test.

--
Thanks :)
Srinath Reddy Sadipiralla
EDB:=C2= =A0https://www.enterprisedb.com/
--00000000000076882f0656087716--