From 25940eed0e79a0d7d6ea6dd18fa28109454e6fa6 Mon Sep 17 00:00:00 2001 From: Hou Zhijie Date: Thu, 17 Aug 2023 19:29:34 +0800 Subject: [PATCH v3] cleanup decoding context and slots in error cases Some of the management functions for logical decoding didn't clean up the decoding context and slots when an error occurs during decoding. This can result in accessing unfreed resources and assert failure the next time we call these functions. Fix it by cleaning up the decoding context and slots in error cases. --- src/backend/replication/logical/logicalfuncs.c | 18 ++++++++---------- src/backend/replication/slotfuncs.c | 13 ++++++------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c index 55a24c02c9..129d47faed 100644 --- a/src/backend/replication/logical/logicalfuncs.c +++ b/src/backend/replication/logical/logicalfuncs.c @@ -109,7 +109,7 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin MemoryContext per_query_ctx; MemoryContext oldcontext; XLogRecPtr end_of_wal; - LogicalDecodingContext *ctx; + LogicalDecodingContext *volatile ctx = NULL; ResourceOwner old_resowner = CurrentResourceOwner; ArrayType *arr; Size ndim; @@ -297,19 +297,17 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin */ ReplicationSlotMarkDirty(); } - - /* free context, call shutdown callback */ - FreeDecodingContext(ctx); - - ReplicationSlotRelease(); - InvalidateSystemCaches(); } - PG_CATCH(); + PG_FINALLY(); { + /* Free the context and call shutdown callback if necessary */ + if (ctx != NULL) + FreeDecodingContext(ctx); + + ReplicationSlotRelease(); + /* clear all timetravel entries */ InvalidateSystemCaches(); - - PG_RE_THROW(); } PG_END_TRY(); diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index 6035cf4816..cc83a1e6f2 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -470,7 +470,7 @@ pg_physical_replication_slot_advance(XLogRecPtr moveto) static XLogRecPtr pg_logical_replication_slot_advance(XLogRecPtr moveto) { - LogicalDecodingContext *ctx; + LogicalDecodingContext *volatile ctx = NULL; ResourceOwner old_resowner = CurrentResourceOwner; XLogRecPtr retlsn; @@ -559,17 +559,16 @@ pg_logical_replication_slot_advance(XLogRecPtr moveto) retlsn = MyReplicationSlot->data.confirmed_flush; - /* free context, call shutdown callback */ - FreeDecodingContext(ctx); - InvalidateSystemCaches(); } - PG_CATCH(); + PG_FINALLY(); { + /* Free the context and call shutdown callback if necessary */ + if (ctx != NULL) + FreeDecodingContext(ctx); + /* clear all timetravel entries */ InvalidateSystemCaches(); - - PG_RE_THROW(); } PG_END_TRY(); -- 2.30.0.windows.2