From 8144e7706c3e66266696109cc21a29713de28fc1 Mon Sep 17 00:00:00 2001 From: dengxuyue Date: Thu, 22 Jul 2021 21:52:26 +0800 Subject: [PATCH] Fixed partition table concurrent update issue --- src/gausskernel/optimizer/commands/trigger.cpp | 2 +- src/gausskernel/runtime/executor/execMain.cpp | 15 ++++++++++++++- .../runtime/executor/nodeModifyTable.cpp | 12 ++++++++---- src/include/executor/executor.h | 4 ++-- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/gausskernel/optimizer/commands/trigger.cpp b/src/gausskernel/optimizer/commands/trigger.cpp index 42d8de690..6b73b2163 100644 --- a/src/gausskernel/optimizer/commands/trigger.cpp +++ b/src/gausskernel/optimizer/commands/trigger.cpp @@ -2702,7 +2702,7 @@ static HeapTuple GetTupleForTrigger(EState* estate, EPQState* epqstate, ResultRe TupleTableSlot* epqslot = NULL; epqslot = EvalPlanQual( - estate, epqstate, fakeRelation, relinfo->ri_RangeTableIndex, &tmfd.ctid, tmfd.xmax); + estate, epqstate, fakeRelation, relinfo->ri_RangeTableIndex, &tmfd.ctid, tmfd.xmax, false); if (!TupIsNull(epqslot)) { *tid = tmfd.ctid; *newSlot = epqslot; diff --git a/src/gausskernel/runtime/executor/execMain.cpp b/src/gausskernel/runtime/executor/execMain.cpp index 484eb2e44..ed45b17a5 100644 --- a/src/gausskernel/runtime/executor/execMain.cpp +++ b/src/gausskernel/runtime/executor/execMain.cpp @@ -2725,7 +2725,7 @@ ExecAuxRowMark *ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist) * NULL if we determine we shouldn't process the row. */ TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate, Relation relation, Index rti, ItemPointer tid, - TransactionId priorXmax) + TransactionId priorXmax, bool partRowMoveUpdate) { TupleTableSlot *slot = NULL; HeapTuple copyTuple; @@ -2739,6 +2739,19 @@ TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate, Relation relati relation, LockTupleExclusive, tid, priorXmax); if (copyTuple == NULL) { + /* + * The tuple has been deleted or update in row movement case. + */ + if (partRowMoveUpdate) { + /* + * the may be a row movement update action which delete tuple from original + * partition and insert tuple to new partition or we can add lock on the tuple + * to be delete or updated to avoid throw exception. + */ + ereport(ERROR, (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("partition table update conflict"), + errdetail("disable row movement of table can avoid this conflict"))); + } return NULL; } diff --git a/src/gausskernel/runtime/executor/nodeModifyTable.cpp b/src/gausskernel/runtime/executor/nodeModifyTable.cpp index bcda79ebd..42e9e3b02 100644 --- a/src/gausskernel/runtime/executor/nodeModifyTable.cpp +++ b/src/gausskernel/runtime/executor/nodeModifyTable.cpp @@ -1194,7 +1194,8 @@ TupleTableSlot* ExecDelete(ItemPointer tupleid, Oid deletePartitionOid, int2 buc fake_relation, result_rel_info->ri_RangeTableIndex, &tmfd.ctid, - tmfd.xmax); + tmfd.xmax, + false); if (!TupIsNull(epqslot)) { *tupleid = tmfd.ctid; goto ldelete; @@ -1641,7 +1642,8 @@ TupleTableSlot* ExecUpdate(ItemPointer tupleid, fake_relation, result_rel_info->ri_RangeTableIndex, &tmfd.ctid, - tmfd.xmax); + tmfd.xmax, + false); if (!TupIsNull(epq_slot)) { *tupleid = tmfd.ctid; @@ -1866,7 +1868,8 @@ TupleTableSlot* ExecUpdate(ItemPointer tupleid, fake_relation, result_rel_info->ri_RangeTableIndex, &tmfd.ctid, - tmfd.xmax); + tmfd.xmax, + result_relation_desc->rd_rel->relrowmovement); if (!TupIsNull(epq_slot)) { *tupleid = tmfd.ctid; @@ -2022,7 +2025,8 @@ TupleTableSlot* ExecUpdate(ItemPointer tupleid, old_fake_relation, result_rel_info->ri_RangeTableIndex, &tmfd.ctid, - tmfd.xmax); + tmfd.xmax, + result_relation_desc->rd_rel->relrowmovement); if (!TupIsNull(epq_slot)) { *tupleid = tmfd.ctid; goto ldelete; diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index edd52e1a3..e4d727568 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -225,8 +225,8 @@ extern bool ExecContextForcesOids(PlanState* planstate, bool* hasoids); extern void ExecConstraints(ResultRelInfo* resultRelInfo, TupleTableSlot* slot, EState* estate); extern ExecRowMark* ExecFindRowMark(EState* estate, Index rti); extern ExecAuxRowMark* ExecBuildAuxRowMark(ExecRowMark* erm, List* targetlist); -extern TupleTableSlot* EvalPlanQual( - EState* estate, EPQState* epqstate, Relation relation, Index rti, ItemPointer tid, TransactionId priorXmax); +extern TupleTableSlot* EvalPlanQual(EState* estate, EPQState* epqstate, Relation relation, Index rti, + ItemPointer tid, TransactionId priorXmax, bool partRowMoveUpdate); extern HeapTuple heap_lock_updated( CommandId cid, Relation relation, int lockmode, ItemPointer tid, TransactionId priorXmax); extern void EvalPlanQualInit(EPQState* epqstate, EState* estate, Plan* subplan, List* auxrowmarks, int epqParam);