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
This commit is contained in:
Amit Kapila 2024-08-01 10:11:06 +05:30
parent a7f107df2b
commit a67da49e1d
1 changed files with 10 additions and 10 deletions

View File

@ -2991,6 +2991,7 @@ apply_handle_tuple_routing(ApplyExecutionData *edata,
ResultRelInfo *partrelinfo_new; ResultRelInfo *partrelinfo_new;
Relation partrel_new; Relation partrel_new;
bool found; bool found;
EPQState epqstate;
/* Get the matching local tuple from the partition. */ /* Get the matching local tuple from the partition. */
found = FindReplTupleInLocalRel(edata, partrel, found = FindReplTupleInLocalRel(edata, partrel,
@ -3021,6 +3022,9 @@ apply_handle_tuple_routing(ApplyExecutionData *edata,
newtup); newtup);
MemoryContextSwitchTo(oldctx); MemoryContextSwitchTo(oldctx);
EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1, NIL);
ExecOpenIndices(partrelinfo, false);
/* /*
* Does the updated tuple still satisfy the current * Does the updated tuple still satisfy the current
* partition's constraint? * partition's constraint?
@ -3036,18 +3040,11 @@ apply_handle_tuple_routing(ApplyExecutionData *edata,
* work already done above to find the local tuple in the * work already done above to find the local tuple in the
* partition. * partition.
*/ */
EPQState epqstate;
EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1, NIL);
ExecOpenIndices(partrelinfo, false);
EvalPlanQualSetSlot(&epqstate, remoteslot_part); EvalPlanQualSetSlot(&epqstate, remoteslot_part);
TargetPrivilegesCheck(partrelinfo->ri_RelationDesc, TargetPrivilegesCheck(partrelinfo->ri_RelationDesc,
ACL_UPDATE); ACL_UPDATE);
ExecSimpleRelationUpdate(partrelinfo, estate, &epqstate, ExecSimpleRelationUpdate(partrelinfo, estate, &epqstate,
localslot, remoteslot_part); localslot, remoteslot_part);
ExecCloseIndices(partrelinfo);
EvalPlanQualEnd(&epqstate);
} }
else else
{ {
@ -3091,9 +3088,9 @@ apply_handle_tuple_routing(ApplyExecutionData *edata,
RelationGetRelationName(partrel_new)); RelationGetRelationName(partrel_new));
/* DELETE old tuple found in the old partition. */ /* DELETE old tuple found in the old partition. */
apply_handle_delete_internal(edata, partrelinfo, EvalPlanQualSetSlot(&epqstate, localslot);
localslot, TargetPrivilegesCheck(partrelinfo->ri_RelationDesc, ACL_DELETE);
part_entry->localindexoid); ExecSimpleRelationDelete(partrelinfo, estate, &epqstate, localslot);
/* INSERT new tuple into the new partition. */ /* INSERT new tuple into the new partition. */
@ -3123,6 +3120,9 @@ apply_handle_tuple_routing(ApplyExecutionData *edata,
apply_handle_insert_internal(edata, partrelinfo_new, apply_handle_insert_internal(edata, partrelinfo_new,
remoteslot_part); remoteslot_part);
} }
ExecCloseIndices(partrelinfo);
EvalPlanQualEnd(&epqstate);
} }
break; break;