pg.ddx.io  pgsql-committers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
pgsql: Revert GetTransactionSnapshot() to return historic snapshot duri
2+ messages / 1 participants
[nested] [flat]

* pgsql: Revert GetTransactionSnapshot() to return historic snapshot duri
@ 2025-08-22 10:21  Heikki Linnakangas <heikki.linnakangas@iki.fi>
  0 siblings, 0 replies; 2+ messages in thread

From: Heikki Linnakangas @ 2025-08-22 10:21 UTC (permalink / raw)
  To: pgsql-committers@lists.postgresql.org

Revert GetTransactionSnapshot() to return historic snapshot during LR

Commit 1585ff7387 changed GetTransactionSnapshot() to throw an error
if it's called during logical decoding, instead of returning the
historic snapshot. I made that change for extra protection, because a
historic snapshot can only be used to access catalog tables while
GetTransactionSnapshot() is usually called when you're executing
arbitrary queries. You might get very subtle visibility problems if
you tried to use the historic snapshot for arbitrary queries.

There's no built-in code in PostgreSQL that calls
GetTransactionSnapshot() during logical decoding, but it turns out
that the pglogical extension does just that, to evaluate row filter
expressions. You would get weird results if the row filter runs
arbitrary queries, but it is sane as long as you don't access any
non-catalog tables. Even though there are no checks to enforce that in
pglogical, a typical row filter expression does not access any tables
and works fine. Accessing tables marked with the user_catalog_table =
true option is also OK.

To fix pglogical with row filters, and any other extensions that might
do similar things, revert GetTransactionSnapshot() to return a
historic snapshot during logical decoding.

To try to still catch the unsafe usage of historic snapshots, add
checks in heap_beginscan() and index_beginscan() to complain if you
try to use a historic snapshot to scan a non-catalog table. We're very
close to the version 18 release however, so add those new checks only
in master.

Backpatch-through: 18
Reported-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Noah Misch <noah@leadboat.com>
Discussion: https://www.postgresql.org/message-id/20250809222338.cc.nmisch@google.com

Branch
------
REL_18_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/27f20441c5e7193bd0d16b0d34be58ed6a310f38

Modified Files
--------------
src/backend/utils/time/snapmgr.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)



^ permalink  raw  reply  [nested|flat] 2+ messages in thread

* pgsql: Revert GetTransactionSnapshot() to return historic snapshot duri
@ 2025-08-22 10:21  Heikki Linnakangas <heikki.linnakangas@iki.fi>
  0 siblings, 0 replies; 2+ messages in thread

From: Heikki Linnakangas @ 2025-08-22 10:21 UTC (permalink / raw)
  To: pgsql-committers@lists.postgresql.org

Revert GetTransactionSnapshot() to return historic snapshot during LR

Commit 1585ff7387 changed GetTransactionSnapshot() to throw an error
if it's called during logical decoding, instead of returning the
historic snapshot. I made that change for extra protection, because a
historic snapshot can only be used to access catalog tables while
GetTransactionSnapshot() is usually called when you're executing
arbitrary queries. You might get very subtle visibility problems if
you tried to use the historic snapshot for arbitrary queries.

There's no built-in code in PostgreSQL that calls
GetTransactionSnapshot() during logical decoding, but it turns out
that the pglogical extension does just that, to evaluate row filter
expressions. You would get weird results if the row filter runs
arbitrary queries, but it is sane as long as you don't access any
non-catalog tables. Even though there are no checks to enforce that in
pglogical, a typical row filter expression does not access any tables
and works fine. Accessing tables marked with the user_catalog_table =
true option is also OK.

To fix pglogical with row filters, and any other extensions that might
do similar things, revert GetTransactionSnapshot() to return a
historic snapshot during logical decoding.

To try to still catch the unsafe usage of historic snapshots, add
checks in heap_beginscan() and index_beginscan() to complain if you
try to use a historic snapshot to scan a non-catalog table. We're very
close to the version 18 release however, so add those new checks only
in master.

Backpatch-through: 18
Reported-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Noah Misch <noah@leadboat.com>
Discussion: https://www.postgresql.org/message-id/20250809222338.cc.nmisch@google.com

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/50f770c3d92cfb2d62724d8c810d37c1f6249a11

Modified Files
--------------
src/backend/access/heap/heapam.c   |  9 +++++++++
src/backend/access/index/indexam.c |  8 ++++++++
src/backend/utils/time/snapmgr.c   | 19 +++++++++++++++----
src/include/utils/snapmgr.h        |  3 +++
4 files changed, 35 insertions(+), 4 deletions(-)



^ permalink  raw  reply  [nested|flat] 2+ messages in thread


end of thread, other threads:[~2025-08-22 10:21 UTC | newest]

Thread overview: 2+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2025-08-22 10:21 pgsql: Revert GetTransactionSnapshot() to return historic snapshot duri Heikki Linnakangas <heikki.linnakangas@iki.fi>
2025-08-22 10:21 pgsql: Revert GetTransactionSnapshot() to return historic snapshot duri Heikki Linnakangas <heikki.linnakangas@iki.fi>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox