8000 Fix uninitialized access to InitialRunningXacts during decoding after… · postgres/postgres@feb4e21 · GitHub
[go: up one dir, main page]

Skip to content

Commit feb4e21

Browse files
author
Amit Kapila
committed
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 7f13ac8). Author: Hou Zhijie Reviewed-by: Amit Kapila Backpatch-through: 11 Discussion: http://postgr.es/m/18055-ab3beed9f4b7b7d6@postgresql.org
1 parent 0aeadb4 commit feb4e21

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

src/backend/replication/logical/snapbuild.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,17 @@ SnapBuildStartNextPhaseAt(SnapBuild *builder, TransactionId at)
336336
builder->was_running.was_xmax = at;
337337
}
338338

339+
/*
340+
* Memory context reset callback for clearing the array of running transactions
341+
* and subtransactions.
342+
*/
343+
static void
344+
SnapBuildResetRunningXactsCallback(void *arg)
345+
{
346+
NInitialRunningXacts = 0;
347+
InitialRunningXacts = NULL;
348+
}
349+
339350
/*
340351
* Allocate a new snapshot builder.
341352
*
@@ -351,6 +362,7 @@ AllocateSnapshotBuilder(ReorderBuffer *reorder,
351362
MemoryContext context;
352363
MemoryContext oldcontext;
353364
SnapBuild *builder;
365+
MemoryContextCallback *mcallback;
354366

355367
/* allocate memory in own context, to have better accountability */
356368
context = AllocSetContextCreate(CurrentMemoryContext,
@@ -375,6 +387,10 @@ AllocateSnapshotBuilder(ReorderBuffer *reorder,
375387
builder->start_decoding_at = start_lsn;
376388
builder->building_full_snapshot = need_full_snapshot;
377389

390+
mcallback = palloc0(sizeof(MemoryContextCallback));
391+
mcallback->func = SnapBuildResetRunningXactsCallback;
392+
MemoryContextRegisterResetCallback(CurrentMemoryContext, mcallback);
393+
378394
MemoryContextSwitchTo(oldcontext);
379395

380396
/* The initial running transactions array must be empty. */
@@ -400,10 +416,6 @@ FreeSnapshotBuilder(SnapBuild *builder)
400416

401417
/* other resources are deallocated via memory context reset */
402418
MemoryContextDelete(context);
403-
404-
/* InitialRunningXacts is freed along with the context */
405-
NInitialRunningXacts = 0;
406-
InitialRunningXacts = NULL;
407419
}
408420

409421
/*

0 commit comments

Comments
 (0)
0