From 71d668ee94571693283e2be1a57bf43400fc7ace Mon Sep 17 00:00:00 2001 From: Hou Zhijie Date: Thu, 25 Jul 2024 15:36:47 +0800 Subject: [PATCH v1 1/2] avoid duplicate table scan for cross partition update When performing a cross-partition update action in apply worker, it accidentally scans the old partition twice, resulting in noticeable overhead. This commit optimizes it by removing the redundant table scan. --- src/backend/replication/logical/worker.c | 27 ++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index ec96b5fe85..9a61679130 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 { @@ -3090,10 +3087,15 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, get_namespace_name(RelationGetNamespace(partrel_new)), RelationGetRelationName(partrel_new)); - /* DELETE old tuple found in the old partition. */ - apply_handle_delete_internal(edata, partrelinfo, - localslot, - part_entry->localindexoid); + /* + * Simply DELETE old tuple found in the old partition. We + * don't call apply_handle_delete_internal() here to avoid + * repeating some work already done above to find the + * local tuple in the partition. + */ + EvalPlanQualSetSlot(&epqstate, localslot); + TargetPrivilegesCheck(partrelinfo->ri_RelationDesc, ACL_DELETE); + ExecSimpleRelationDelete(partrelinfo, estate, &epqstate, localslot); /* INSERT new tuple into the new partition. */ @@ -3123,6 +3125,9 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, apply_handle_insert_internal(edata, partrelinfo_new, remoteslot_part); } + + ExecCloseIndices(partrelinfo); + EvalPlanQualEnd(&epqstate); } break; -- 2.31.1