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 1w141L-002Wfg-1x for pgsql-hackers@arkaria.postgresql.org; Fri, 13 Mar 2026 15:01:47 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w141J-004fns-3D for pgsql-hackers@arkaria.postgresql.org; Fri, 13 Mar 2026 15:01:46 +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.96) (envelope-from ) id 1w141J-004fnk-1f for pgsql-hackers@lists.postgresql.org; Fri, 13 Mar 2026 15:01:46 +0000 Received: from mail-wm1-x329.google.com ([2a00:1450:4864:20::329]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w141H-00000001y5p-1WF2 for pgsql-hackers@postgresql.org; Fri, 13 Mar 2026 15:01:45 +0000 Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-4852fdb36a8so25865375e9.2 for ; Fri, 13 Mar 2026 08:01:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec.at; s=google; t=1773414102; x=1774018902; darn=postgresql.org; h=message-id:date:mime-version:comments:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=3j/xgfHATREQsQmTIvxOTZTqbhyyvaIOBCxO1zwk+eg=; b=nr4+Qk1cwLS26A+G1hJVRE3DVkCXCqR0JhzU81y0iJKFY6pd79QbQ2m0dnhoGg2+Gi se9FE+3lMnVVdncWEV+TXgK3sFp6QFi5dZV376oOPLY/WPV9/vAadLF6GI9Es+gStg1g KYcwOQRT9gobGHg+1Z9TU2zmBMCHmoF4GeF7dT2rsqNJLWbSUUcwJ43rfiG5VO70hfuC ygM8J3m0hHGfBGz6Sr8En4FyZkbMJS56Nu8IQzyAr32n+p1lzP3uOYQ1Gsm5yVCAhR9v DB3fl7FrFPuPuGd1OhV/L5z261D6MHBBJDs/gIfZ9RmQ4bYw6jgNDPF0iq6genha6IcC JRKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773414102; x=1774018902; h=message-id:date:mime-version:comments:references:in-reply-to :subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=3j/xgfHATREQsQmTIvxOTZTqbhyyvaIOBCxO1zwk+eg=; b=l03tGtIjtHojaZKbhwjpESvdbqI8UdTVp3yn6/FRe+WroQjAo3gYs+XcQifQD2jvUy x6MLEDrNT8cZ/5WPz9U+GDxJYSXhF6kvYYyAYUOKG+Pe5ZMAMD/2sL48NTs3I/hW3UZT UXdME/7TmFL3cIbyfh3EEmcGhVtko7hVnzX1VqNPWpKbjvgmrVTUVEgX8TSao/emBvF/ OTmIDR+H8ddaFm9MoZYFgiylIqIlFs0hgmvowXYwzGUlhM9fvb78XAQ3WV9pQByBZIbO YsHpsOELUfMclGQ2O/ES7jxKTE0O2XzBznI+jVmWrvXS6s9BhmxgaLmU9fj7Z/8QeRLK 5hxg== X-Forwarded-Encrypted: i=1; AJvYcCXujqseLL6u2A07N5y+fFvc3GbxLxlOVNbHV5QKGFCbKPjj9jnDugwEnODxbpAfjdinCS/Rcg6c2wgdsVd4@postgresql.org X-Gm-Message-State: AOJu0YyZubWSeQrjodCnXagTTMh9gDXrplsyuH7VI8WyO0+sKyjEM75u RRXhZpOLquk/b9F1xes5mdAHK9L2V0g6iFYv1wHKP9sQDWj2id/6EvE5M4V4wioOkaU= X-Gm-Gg: ATEYQzwjZpoTGuornZDn08WBnYl0LRmV9uybikRPuqsxo1FOnxzIyvBckAaFErUI0y5 z+6s2R7hCmdz0tvQSJq5oxUPhB3YO40M5yNa+VB9AKLh5jb39LJJ5Rn+P6lzq6jJQTrYv7NquWs uNgHzvLtJ6NQJQGBKkzZ7ZfOVQfFNGWPEiKYfcweUi40h9v8rAt4fYptd5TrU/hTbSw0QejEL5K P0MXf1hJvvEaPFbMVByDMbmMGzuWfCnP2yovd0fRkNkTqh+RTbyLaQsmxxhrvx9z+k5Sl4fetyV sBvswFdpeDMFCj3qTnXPcy23n0HrLXH/5CQ60dYClZtTy9WCrWFHj2iPjr/Yff/Ttz+1fsU/cgY XcnKFtWIJsxNay2KMO/NMYg/vj7NawL26oDJ/zedasQSojaSZJZLHvNgN8Yi+nCN/3FhhyfxABo XMgFPR6o9pXLr5FiCjDe3YXilLLvGB5GfNVcdN X-Received: by 2002:a05:600d:4453:20b0:477:a54a:acba with SMTP id 5b1f17b1804b1-485567031a2mr45489015e9.17.1773414101847; Fri, 13 Mar 2026 08:01:41 -0700 (PDT) Received: from localhost (109-81-168-142.rct.o2.cz. [109.81.168.142]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48557777105sm40407635e9.4.2026.03.13.08.01.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Mar 2026 08:01:41 -0700 (PDT) From: Antonin Houska To: Andres Freund cc: Kirill Reshke , Heikki Linnakangas , Melanie Plageman , Matthias van de Meent , pgsql-hackers@postgresql.org, Thomas Munro , Noah Misch , Robert Haas , Michael Paquier Subject: Re: Buffer locking is special (hints, checksums, AIO writes) In-reply-to: References: <4csodkvvfbfloxxjlkgsnl2lgfv2mtzdl7phqzd4jxjadxm4o5@usw7feyb5bzf> <61812.1770637345@localhost> <19720.1770709587@localhost> <196082.1770892568@localhost> Comments: In-reply-to Andres Freund message dated "Wed, 11 Mar 2026 19:09:26 -0400." X-Mailer: MH-E 8.6+git; nmh 1.8; GNU Emacs 28.3 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Date: Fri, 13 Mar 2026 16:01:40 +0100 Message-ID: <38845.1773414100@localhost> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --=-=-= Content-Type: text/plain Andres Freund wrote: > Probably need to update the comments a bit. What about something like > > > /* > * Is the snapshot implemented as an MVCC snapshot (i.e. it uses > * SNAPSHOT_MVCC). If so, there will be at most be one visible row in a chain > * of updated tuples, and each visible tuple will be seen exactly once. > */ > #define IsMVCCSnapshot(snapshot) \ The ", and each visible tuple ..." part seemed to me redundant, so I omitted it. If you think I'm wrong, please add it yourself when committing the patch. I also added a comment to the IsHistoricMVCCSnapshot(), trying to explain what "historic" means. -- Antonin Houska Web: https://www.cybertec-postgresql.com --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=v2-Refine-checking-of-snapshot-type.patch From 6c391d437ec61ff16b2a459a799d2030142e656f Mon Sep 17 00:00:00 2001 From: Antonin Houska Date: Thu, 12 Feb 2026 11:14:00 +0100 Subject: [PATCH] Refine checking of snapshot type. It appears to be confusing if IsMVCCSnapshot() evaluates to true for both "regular" and "historic" MVCC snapshot. This patch restricts the meaning of the macro to the "regular" MVCC snapshot, and introduces a new macro IsMVCCLikeSnapshot() to recognize both types. IsMVCCLikeSnapshot() is only used in functions that can (supposedly) be called during logical decoding. --- src/backend/access/heap/heapam_handler.c | 2 +- src/backend/access/index/indexam.c | 2 +- src/backend/access/nbtree/nbtree.c | 2 +- src/include/utils/snapmgr.h | 21 ++++++++++++++++++--- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 5137d2510ea..2d1ee9ac95d 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -159,7 +159,7 @@ heapam_index_fetch_tuple(struct IndexFetchTableData *scan, * Only in a non-MVCC snapshot can more than one member of the HOT * chain be visible. */ - *call_again = !IsMVCCSnapshot(snapshot); + *call_again = !IsMVCCLikeSnapshot(snapshot); slot->tts_tableOid = RelationGetRelid(scan->rel); ExecStoreBufferHeapTuple(&bslot->base.tupdata, slot, hscan->xs_cbuf); diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 43f64a0e721..5eb7e99ad3e 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -445,7 +445,7 @@ index_markpos(IndexScanDesc scan) void index_restrpos(IndexScanDesc scan) { - Assert(IsMVCCSnapshot(scan->xs_snapshot)); + Assert(IsMVCCLikeSnapshot(scan->xs_snapshot)); SCAN_CHECKS; CHECK_SCAN_PROCEDURE(amrestrpos); diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 6d0a6f27f3f..cdd81d147cc 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -423,7 +423,7 @@ btrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, * Note: so->dropPin should never change across rescans. */ so->dropPin = (!scan->xs_want_itup && - IsMVCCSnapshot(scan->xs_snapshot) && + IsMVCCLikeSnapshot(scan->xs_snapshot) && RelationNeedsWAL(scan->indexRelation) && scan->heapRelation != NULL); diff --git a/src/include/utils/snapmgr.h b/src/include/utils/snapmgr.h index b8c01a291a1..4f1e910bc75 100644 --- a/src/include/utils/snapmgr.h +++ b/src/include/utils/snapmgr.h @@ -51,14 +51,29 @@ extern PGDLLIMPORT SnapshotData SnapshotToastData; ((snapshotdata).snapshot_type = SNAPSHOT_NON_VACUUMABLE, \ (snapshotdata).vistest = (vistestp)) -/* This macro encodes the knowledge of which snapshots are MVCC-safe */ +/* + * Is the snapshot implemented as an MVCC snapshot (i.e. it uses + * SNAPSHOT_MVCC)? If so, there will be at most one visible tuple in a chain + * of updated tuples. + */ #define IsMVCCSnapshot(snapshot) \ - ((snapshot)->snapshot_type == SNAPSHOT_MVCC || \ - (snapshot)->snapshot_type == SNAPSHOT_HISTORIC_MVCC) + ((snapshot)->snapshot_type == SNAPSHOT_MVCC) +/* + * Special kind of MVCC snapshot, to be used during logical decoding. The + * visibility is checked from the perspective of an already committed + * transaction, which we're trying to decode. + */ #define IsHistoricMVCCSnapshot(snapshot) \ ((snapshot)->snapshot_type == SNAPSHOT_HISTORIC_MVCC) +/* + * Is the snapshot either an MVCC snapshot or has equivalent visibility + * semantics (see IsMVCCSnapshot())? + */ +#define IsMVCCLikeSnapshot(snapshot) \ + (IsMVCCSnapshot(snapshot) || IsHistoricMVCCSnapshot(snapshot)) + extern Snapshot GetTransactionSnapshot(void); extern Snapshot GetLatestSnapshot(void); extern void SnapshotSetCommandId(CommandId curcid); -- 2.47.3 --=-=-=--