From 0d2822773daed18c5d24170652fc584141369de3 Mon Sep 17 00:00:00 2001 From: Nisha Moond Date: Wed, 2 Sep 2026 19:54:47 +0530 Subject: [PATCH v2 1/2] Avoid re-creating the conflict slot on retry in FindConflictTuple() FindConflictTuple() created a new tuple table slot on each retry when table_tuple_lock() returned TM_Updated, leaving the previous slot holding a buffer pin until the apply transaction ended. Since these slots were not registered in es_tupleTable, they were not released by ExecResetTupleTable(). Create the slot on first use and reuse it on subsequent retries. Re-storing the tuple in the same slot releases the previous buffer pin, avoiding the accumulation of pinned buffers during repeated retries. Oversight in commit 9758174e2e5. Backpatch-through: 18 --- src/backend/executor/execReplication.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index b2ca5cbf117..a4b5e16bf1a 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -742,7 +742,13 @@ retry: return false; } - *conflictslot = table_slot_create(rel, NULL); + /* + * Create the slot only once and reuse it on retries. Re-storing the tuple + * in the same slot releases the buffer pin held for the previously stored + * tuple. + */ + if (*conflictslot == NULL) + *conflictslot = table_slot_create(rel, NULL); PushActiveSnapshot(GetLatestSnapshot()); -- 2.50.1 (Apple Git-155)