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.98.2) (envelope-from ) id 1xCINu-00000003hyj-0Lcx for pgsql-bugs@arkaria.postgresql.org; Thu, 01 Oct 2026 15:07:46 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1xCINt-00000007dCS-0RKM for pgsql-bugs@arkaria.postgresql.org; Thu, 01 Oct 2026 15:07:45 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1xCINs-00000007dCJ-39JE for pgsql-bugs@lists.postgresql.org; Thu, 01 Oct 2026 15:07:44 +0000 Received: from mail.w14.tutanota.de ([185.205.69.214]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1xCINq-00000002DSA-3Ekp for pgsql-bugs@lists.postgresql.org; Thu, 01 Oct 2026 15:07:43 +0000 Received: from tutadb.w10.tutanota.de (w10.api.tuta.com [IPv6:fd:ac::d:10]) by mail.w14.tutanota.de (Postfix) with ESMTP id C720D18DDFDA4 for ; Thu, 1 Oct 2026 17:07:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1790867260; s=s1; d=rhyadav.dev; h=From:From:To:To:Subject:Subject:Content-Description:Content-ID:Content-Type:Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:In-Reply-To:In-Reply-To:MIME-Version:MIME-Version:Message-ID:Message-ID:Reply-To:References:References:Sender; bh=tQuW7ejY5ZW318CNmu5EMq2Tzxz5KQAHJC2P8BSEtYg=; b=E6+D2LP0M0ae3IW56jr5g7zqYfwd9p6GcunNii86AOueqYVBGs3Aujbx0rQ/xgaJ Sw6P66rYV8bQTdoHl3NUOcA5CAGSAi6+CH2KzGWPuNR1jz/q3vQiVnHn+nYMylOuuga PTKgPfXBvkGwb0/DNWrvTtE14zRyt6/omwR82XmLpYIqP9g6MJeQvTmanjAEs2L54Ys vfuakOMJFHWz7GUF1vmmQWqXIwI4LTG74KF0FnHJkxZJWzHVqO2JJCm/X5o08dA3+3g CIOVOXyAesU1r9DHolMoUYeyS6ELwxnI0u6IuFH7qhnH45W958XXWZsNOJREbzDuMgM Qtn4fW1wmA== Date: Thu, 1 Oct 2026 17:07:40 +0200 (CEST) From: rahul@rhyadav.dev To: shihao zhong Cc: Kirill Reshke , Nktpro , Pgsql Bugs , Melanie Plageman Message-ID: In-Reply-To: References: Subject: Re: PostgreSQL 18.6/17.11: standby PANIC on restart after VM truncation MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_42854_300863161.1790867260810" Feedback-ID: 01f8c5108c48fea26a092a077590a8fcdbfcdbb733bc38e3db5db9540fc242b99227bb05256e786b1fc713cdb05f073377d63f8aec9e32cbf77d26f42c5d89118b:TurnOnPrivacy!:tutamail List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ------=_Part_42854_300863161.1790867260810 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi, On Mon, 28 Sep 2026, shihao zhong wrote: > Melanie's v2-0002 in the VM clear thread [1] is the same change as > candidate (a), and it fixes this report too. I tested Melanie's v2 series as posted (0001-0003, which apply to REL_19_STABLE) and candidate (a) on REL_18_STABLE, using the steps from Shihao's test: full_page_writes =3D off and a plain standby restart.=C2=A0 Both were debug builds with assertions, and the fix works: - Unpatched, 18 and 19 fail to restart with "WAL contains references =C2=A0 to invalid pages" after "page 0 of relation ..._vm does not exist" =C2=A0 for each table. - Patched, the standby restarts and its VM forks end up truncated =C2=A0 again. - On 18, reverting any one of the three RBM_ZERO_ON_ERROR changes =C2=A0 brings the PANIC back, so the test covers each of them. However, with wal_consistency_checking =3D all on the primary, the patched standby still fails to restart: =C2=A0 FATAL:=C2=A0 invalid page pd_lower 0 pd_upper 0 pd_special 0 =C2=A0 CONTEXT:=C2=A0 WAL redo at 0/03A80068 for Heap/DELETE: ...; =C2=A0 blkref #1: rel 1663/5/16384, fork 2, blk 0 FPW RBM_ZERO_ON_ERROR recreates the truncated VM page as all zeros. verifyBackupPageConsistency() then masks it with heap_mask(), and mask_unused_space() rejects a page with pd_lower 0. heap_xlog_prune_freeze() and heap_xlog_multi_insert() already initialize a VM page that was read as zeros, and doing the same at the three VM clear sites fixes it.=C2=A0 The attached diff applies on top of v2 on REL_19_STABLE; with it, the standby restarts with and without wal_consistency_checking.=C2=A0 On 18, candidate (b) alone also passes with wal_consistency_checking, since it never recreates the page. This only matters with wal_consistency_checking, but buildfarm animals that use it could trip over Shihao's test once it's in. Also, v2-0002 applies only on top of v2-0001 on REL_19_STABLE.=C2=A0 On master it doesn't apply after master-v2-0001, 18 needs its own version (candidate (a) applies there as is), and in 17 the redo code is in heapam.c. [1] https://postgr.es/m/CAAKRu_bApoksLDb-HX0GYciU3uLWqA1JagntaV8GP0%3D%2Bid= ehHw%40mail.gmail.com Regards, Rahul Yadav ------=_Part_42854_300863161.1790867260810 Content-Type: text/plain; charset=us-ascii; name=initialize-zeroed-vm-pages-on-v2.txt Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=initialize-zeroed-vm-pages-on-v2.txt diff --git a/src/backend/access/heap/heapam_xlog.c b/src/backend/access/heap/heapam_xlog.c index 4d99d99080..b87f38befc 100644 --- a/src/backend/access/heap/heapam_xlog.c +++ b/src/backend/access/heap/heapam_xlog.c @@ -89,6 +89,10 @@ heap_xlog_vm_clear(XLogReaderState *record, RBM_ZERO_ON_ERROR, false, &vmbuffer) == BLK_NEEDS_REDO) { + /* initialize the page if it was read as zeros */ + if (PageIsNew(BufferGetPage(vmbuffer))) + PageInit(BufferGetPage(vmbuffer), BLCKSZ, 0); + if (visibilitymap_clear(reln, heap_blkno, vmbuffer, flags)) PageSetLSN(BufferGetPage(vmbuffer), lsn); } @@ -855,6 +859,10 @@ heap_xlog_update(XLogReaderState *record, bool hot_update) RBM_ZERO_ON_ERROR, false, &vmbuffer_new) == BLK_NEEDS_REDO) { + /* initialize the page if it was read as zeros */ + if (PageIsNew(BufferGetPage(vmbuffer_new))) + PageInit(BufferGetPage(vmbuffer_new), BLCKSZ, 0); + /* * If both the old and new heap pages were all-visible and their * VM bits are on the same VM page, that single VM page is @@ -894,6 +902,10 @@ heap_xlog_update(XLogReaderState *record, bool hot_update) RBM_ZERO_ON_ERROR, false, &vmbuffer_old) == BLK_NEEDS_REDO) { + /* initialize the page if it was read as zeros */ + if (PageIsNew(BufferGetPage(vmbuffer_old))) + PageInit(BufferGetPage(vmbuffer_old), BLCKSZ, 0); + if (visibilitymap_clear(reln, oldblk, vmbuffer_old, VISIBILITYMAP_VALID_BITS)) PageSetLSN(BufferGetPage(vmbuffer_old), lsn); ------=_Part_42854_300863161.1790867260810--