public inbox for [email protected]
help / color / mirror / Atom feedFrom: Antonin Houska <[email protected]>
Subject: [PATCH] Distinguish properly when database-specific transaction list should be used.
Date: Wed, 6 May 2026 09:38:11 +0200
Currently, decoding session that relies on database-specific xl_running_xacts
WAL records can also use some information of cluster-wide records and vice
versa. Although this approach might reduce the total number of
xl_running_xacts records, it's simply not correct.
SnapBuildProcessRunningXacts() now decides at the very beginning whether
particular record can be used or not.
---
src/backend/replication/logical/snapbuild.c | 55 +++++++++++++--------
1 file changed, 34 insertions(+), 21 deletions(-)
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index c8309b96ed4..b9661b7d70a 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1157,6 +1157,39 @@ SnapBuildProcessRunningXacts(SnapBuild *builder, XLogRecPtr lsn, xl_running_xact
ReorderBufferTXN *txn;
TransactionId xmin;
+ /*
+ * Each decoding session should use either cluster-wide snapshots or
+ * database-specific ones, but not both. Since the latter can have more
+ * recent value of oldestRunningXid, builder->xmin could go backwards if
+ * it was followed by cluster-wide snapshot - see the ->xmin adjustment
+ * below.
+ */
+ if (!db_specific && OidIsValid(running->dbid))
+ return;
+
+ if (db_specific)
+ {
+ /*
+ * Make sure that we have the snapshots needed for startup, as well as
+ * those for regular cleanup: each time the cluster-wide snapshot is
+ * created (typically on slot creation or by checkpointer), the
+ * database-specific snapshot is requested here if the current session
+ * needs it.
+ */
+ if (!OidIsValid(running->dbid))
+ {
+ LogStandbySnapshot(MyDatabaseId);
+
+ return;
+ }
+ /*
+ * Snapshots issued for other databases do not contain the information
+ * about transactions in our database.
+ */
+ else if (running->dbid != MyDatabaseId)
+ return;
+ }
+
/*
* If we're not consistent yet, inspect the record to see whether it
* allows to get closer to being consistent. If we are consistent, dump
@@ -1171,17 +1204,7 @@ SnapBuildProcessRunningXacts(SnapBuild *builder, XLogRecPtr lsn, xl_running_xact
*/
if (db_specific)
{
- /*
- * If we must only keep track of transactions running in the
- * current database, we need transaction info from exactly that
- * database.
- */
- if (running->dbid != MyDatabaseId)
- {
- LogStandbySnapshot(MyDatabaseId);
-
- return;
- }
+ Assert(running->dbid == MyDatabaseId);
/*
* We'd better be able to check during scan if the plugin does not
@@ -1198,16 +1221,6 @@ SnapBuildProcessRunningXacts(SnapBuild *builder, XLogRecPtr lsn, xl_running_xact
else
SnapBuildSerialize(builder, lsn);
- /*
- * Database specific transaction info may exist to reach CONSISTENT state
- * faster, however the code below makes no use of it. Moreover, such
- * record might cause problems because the following normal (cluster-wide)
- * record can have lower value of oldestRunningXid. In that case, let's
- * wait with the cleanup for the next regular cluster-wide record.
- */
- if (OidIsValid(running->dbid))
- return;
-
/*
* Update range of interesting xids based on the running xacts
* information. We don't increase ->xmax using it, because once we are in
--
2.47.3
--=-=-=--
view thread (958+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH] Distinguish properly when database-specific transaction list should be used.
In-Reply-To: <no-message-id-393190@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox