Fixed partition table concurrent update issue

This commit is contained in:
dengxuyue 2021-07-22 21:52:26 +08:00 committed by cchen676
parent 8105a88efc
commit 7dfaa30b61
4 changed files with 25 additions and 8 deletions

View File

@ -2688,7 +2688,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;

View File

@ -2715,7 +2715,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;
@ -2729,6 +2729,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;
}

View File

@ -1061,7 +1061,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;
@ -1492,7 +1493,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;
@ -1717,7 +1719,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;
@ -1873,7 +1876,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;

View File

@ -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);