From a67da49e1d983fc7662f7854e9eec5debbd14446 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Thu, 1 Aug 2024 10:11:06 +0530 Subject: [PATCH] Avoid duplicate table scans for cross-partition updates during logical replication. When performing a cross-partition update in the apply worker, it needlessly scans the old partition twice, resulting in noticeable overhead. This commit optimizes it by removing the redundant table scan. Author: Hou Zhijie Reviewed-by: Hayato Kuroda, Amit Kapila Discussion: https://postgr.es/m/OS0PR01MB571623E39984D94CBB5341D994AB2@OS0PR01MB5716.jpnprd01.prod.outlook.com --- src/backend/replication/logical/worker.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index ec96b5fe85e..6dc54c72838 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -2991,6 +2991,7 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, ResultRelInfo *partrelinfo_new; Relation partrel_new; bool found; + EPQState epqstate; /* Get the matching local tuple from the partition. */ found = FindReplTupleInLocalRel(edata, partrel, @@ -3021,6 +3022,9 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, newtup); MemoryContextSwitchTo(oldctx); + EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1, NIL); + ExecOpenIndices(partrelinfo, false); + /* * Does the updated tuple still satisfy the current * partition's constraint? @@ -3036,18 +3040,11 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, * work already done above to find the local tuple in the * partition. */ - EPQState epqstate; - - EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1, NIL); - ExecOpenIndices(partrelinfo, false); - EvalPlanQualSetSlot(&epqstate, remoteslot_part); TargetPrivilegesCheck(partrelinfo->ri_RelationDesc, ACL_UPDATE); ExecSimpleRelationUpdate(partrelinfo, estate, &epqstate, localslot, remoteslot_part); - ExecCloseIndices(partrelinfo); - EvalPlanQualEnd(&epqstate); } else { @@ -3091,9 +3088,9 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, RelationGetRelationName(partrel_new)); /* DELETE old tuple found in the old partition. */ - apply_handle_delete_internal(edata, partrelinfo, - localslot, - part_entry->localindexoid); + EvalPlanQualSetSlot(&epqstate, localslot); + TargetPrivilegesCheck(partrelinfo->ri_RelationDesc, ACL_DELETE); + ExecSimpleRelationDelete(partrelinfo, estate, &epqstate, localslot); /* INSERT new tuple into the new partition. */ @@ -3123,6 +3120,9 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, apply_handle_insert_internal(edata, partrelinfo_new, remoteslot_part); } + + ExecCloseIndices(partrelinfo); + EvalPlanQualEnd(&epqstate); } break; -- 2.30.2