summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Kapila <akapila@postgresql.org>2023-09-12 09:58:50 +0530
committerAmit Kapila <akapila@postgresql.org>2023-09-12 09:58:50 +0530
commitc570bb4d61b6b1225c157252c65af538834136f2 (patch)
tree0823cfc7b03eb4b43f9ef62c5eaed4935f53c47c
parent5dc093eacef126e185656278004358d02d4dd2d0 (diff)
Fix uninitialized access to InitialRunningXacts during decoding after ERROR.
The transactions and subtransactions array that was allocated under snapshot builder memory context and recorded during decoding was not cleared in case of errors. This can result in an assertion failure if we attempt to retry logical decoding within the same session. To address this issue, we register a callback function under the snapshot builder memory context to clear the recorded transactions and subtransactions array along with the context. This problem doesn't exist in PG16 and HEAD as instead of using InitialRunningXacts, we added the list of transaction IDs and sub-transaction IDs, that have modified catalogs and are running during snapshot serialization, to the serialized snapshot (see commit 7f13ac8123). Author: Hou Zhijie Reviewed-by: Amit Kapila Backpatch-through: 11 Discussion: http://postgr.es/m/18055-ab3beed9f4b7b7d6@postgresql.org
-rw-r--r--src/backend/replication/logical/snapbuild.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index bf5f1db8565..31caad8855f 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -331,6 +331,17 @@ SnapBuildStartNextPhaseAt(SnapBuild *builder, TransactionId at)
}
/*
+ * Memory context reset callback for clearing the array of running transactions
+ * and subtransactions.
+ */
+static void
+SnapBuildResetRunningXactsCallback(void *arg)
+{
+ NInitialRunningXacts = 0;
+ InitialRunningXacts = NULL;
+}
+
+/*
* Allocate a new snapshot builder.
*
* xmin_horizon is the xid >= which we can be sure no catalog rows have been
@@ -345,6 +356,7 @@ AllocateSnapshotBuilder(ReorderBuffer *reorder,
MemoryContext context;
MemoryContext oldcontext;
SnapBuild *builder;
+ MemoryContextCallback *mcallback;
/* allocate memory in own context, to have better accountability */
context = AllocSetContextCreate(CurrentMemoryContext,
@@ -369,6 +381,10 @@ AllocateSnapshotBuilder(ReorderBuffer *reorder,
builder->start_decoding_at = start_lsn;
builder->building_full_snapshot = need_full_snapshot;
+ mcallback = palloc0(sizeof(MemoryContextCallback));
+ mcallback->func = SnapBuildResetRunningXactsCallback;
+ MemoryContextRegisterResetCallback(CurrentMemoryContext, mcallback);
+
MemoryContextSwitchTo(oldcontext);
/* The initial running transactions array must be empty. */
@@ -394,10 +410,6 @@ FreeSnapshotBuilder(SnapBuild *builder)
/* other resources are deallocated via memory context reset */
MemoryContextDelete(context);
-
- /* InitialRunningXacts is freed along with the context */
- NInitialRunningXacts = 0;
- InitialRunningXacts = NULL;
}
/*