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 1vyCDP-00HWjO-0b for pgsql-hackers@arkaria.postgresql.org; Thu, 05 Mar 2026 17:10:23 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vyCDM-000Teq-2R for pgsql-hackers@arkaria.postgresql.org; Thu, 05 Mar 2026 17:10:21 +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 1vyCDL-000Teh-2g for pgsql-hackers@lists.postgresql.org; Thu, 05 Mar 2026 17:10:20 +0000 Received: from fout-b4-smtp.messagingengine.com ([202.12.124.147]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1vyCDI-00000000y3u-2tse for pgsql-hackers@postgresql.org; Thu, 05 Mar 2026 17:10:19 +0000 Received: from phl-compute-03.internal (phl-compute-03.internal [10.202.2.43]) by mailfout.stl.internal (Postfix) with ESMTP id EDD191D00251; Thu, 5 Mar 2026 12:10:13 -0500 (EST) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-03.internal (MEProxy); Thu, 05 Mar 2026 12:10:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anarazel.de; h= cc:cc:content-type:content-type:date:date:from:from:in-reply-to :message-id:mime-version:reply-to:subject:subject:to:to; s=fm1; t=1772730613; x=1772817013; bh=7jTjcVrpHQF7DNBhliFYFKUrdvAMifXX +FU18uNwj+c=; b=md29kgdKusynJ5wL2+OiDIF53888qmfZDrAPwKF69BzezKsn J0i2ggH3Hn8F9lmb9Z28LX7C1qmco9bbEFBloQEq36/4kLU2kWZ2psOom408Jhmo VrRAhOvI+S285Q+qZpDkhxvvtRDGVoZ3KOjhKfB3MSMTlzXZu9CgjoL4rE+p6muR wff5VgBL6BrFo8PYotN8L9tn86m3F2egNv69/1RB/e5eYcd79E43SGKdMbFTOfYr KZY+Iy0+kdTcQprsEbbCMK1jl0dMl4bymjBgictxtrpGeZVi351ExmyE+7gThOhm wFGK2yiWwYViCpGxNe6dCYjys1EujIplPoeibg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:message-id :mime-version:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1772730613; x= 1772817013; bh=7jTjcVrpHQF7DNBhliFYFKUrdvAMifXX+FU18uNwj+c=; b=u UkshR20jZcBNOKVkateTR4ufaI3aGX2+6QWyUJM9K9GlSt2LLdXzdKQZzXxTnlF8 buUA/lA2FkdIWGKEmK17eI8Gi6G43UBb4HuLX9x2/FI4v3RzSSkmU0QcOh9Sa89e uLXVWaT+TaCr6EltuqC9VwHq1D3slqdTCT1Or3N8Ol1zRiLLygWC1lvwoHgJEAW0 bXEZ0uBP80eF8eyYaJK9RkfyxzLvAZYYkwpM7k5PU7NawzXPFmm9jdS2v3qZSqjc abQgq7LD61l1uOUv+SKtHLO81o/W1hOrLHueEoHPoGKKno5dSIrvwlRiexgn4QqF 2pPzk3KKQsoqzf7Zy8sew== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddvieeileegucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepfffhvfevuffkgggtugesthdtsfdttddtvdenucfhrhhomheptehnughrvghsucfh rhgvuhhnugcuoegrnhgurhgvshesrghnrghrrgiivghlrdguvgeqnecuggftrfgrthhtvg hrnhepleffkefhleetheegueegveelledtgeeiudehteetvdeiheduffegleelteeukeff necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprghnug hrvghssegrnhgrrhgriigvlhdruggvpdhnsggprhgtphhtthhopeegpdhmohguvgepshhm thhpohhuthdprhgtphhtthhopehpghessghofihtrdhivgdprhgtphhtthhopehtvhesfh huiiiihidrtgiipdhrtghpthhtohepnhhorghhsehlvggruggsohgrthdrtghomhdprhgt phhtthhopehpghhsqhhlqdhhrggtkhgvrhhssehpohhsthhgrhgvshhqlhdrohhrgh X-ME-Proxy: Feedback-ID: id4a34324:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 5 Mar 2026 12:10:12 -0500 (EST) Date: Thu, 5 Mar 2026 12:10:11 -0500 From: Andres Freund To: pgsql-hackers@postgresql.org, Noah Misch Cc: Tomas Vondra , Peter Geoghegan Subject: gistGetFakeLSN() can return incorrect LSNs Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, Tomas encountered a crash with the index prefetching patchset. One of the patches included therein is a generalization of the gistGetFakeLSN() mechanism, which is then used by other indexes as well. That triggered an occasional, hard to locally reproduce, ERROR or PANIC in CI, about ERROR: xlog flush request 0/01BD2018 is not satisfied --- flushed only to 0/01BD2000 A bunch of debugging later, it turns out that this is a pre-existing issue. XLogRecPtr gistGetFakeLSN(Relation rel) { ... else if (RelationIsPermanent(rel)) { /* * WAL-logging on this relation will start after commit, so its LSNs * must be distinct numbers smaller than the LSN at the next commit. * Emit a dummy WAL record if insert-LSN hasn't advanced after the * last call. */ static XLogRecPtr lastlsn = InvalidXLogRecPtr; XLogRecPtr currlsn = GetXLogInsertRecPtr(); /* Shouldn't be called for WAL-logging relations */ Assert(!RelationNeedsWAL(rel)); /* No need for an actual record if we already have a distinct LSN */ if (XLogRecPtrIsValid(lastlsn) && lastlsn == currlsn) currlsn = gistXLogAssignLSN(); lastlsn = currlsn; XLogFlush(currlsn); return currlsn; } The problem is that GetXLogInsertRecPtr() returns the start of the next record. That's *most* of the time the same as what XLogInsert() would return (i.e. one byte past the end of the last record), but not reliably so: If the last record ends directly at a page boundary, XLogInsert() returns an LSN directly to the start of the page, but GetXLogInsertRecPtr() will return an LSN that points to just after the xlog page header. If you look at the error from above, that's exactly what's happening - the flush is only up to 0/01BD2000 (0x2000 is 8192, i.e. an 8kB boundary). But the flush request is to 0/01BD2018, where 0x18 is the size of XLogPageHeaderData. To be safe, this code would need to use a version of GetXLogInsertRecPtr() that does use XLogBytePosToEndRecPtr() instead of XLogBytePosToRecPtr(). It's probably not easy to trigger this outside of aggressive test scenarios, due to needing to avoid the gistXLogAssingLSN() path and having to encounter a "reason" to flush the buffer immediately after. However, if I put an XLogFlush() into gistGetFakeLSN() and use wal_level=minimal, it's a lot easier. It looks like this was introduced in commit c6b92041d38 Author: Noah Misch Date: 2020-04-04 12:25:34 -0700 Skip WAL for new relfilenodes, under wal_level=minimal. Greetings, Andres Freund