enhance tuple lock

This commit is contained in:
chenxiaobin19
2021-12-16 20:37:27 +08:00
parent 2417964517
commit 899cd4a36c
92 changed files with 4402 additions and 1177 deletions

View File

@ -317,7 +317,7 @@ void standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
switch (queryDesc->operation) {
case CMD_SELECT:
/*
* SELECT FOR UPDATE/SHARE and modifying CTEs need to mark tuples
* SELECT FOR [KEY] UPDATE/SHARE and modifying CTEs need to mark tuples
*/
if (queryDesc->plannedstmt->rowMarks != NIL || queryDesc->plannedstmt->hasModifyingCTE) {
estate->es_output_cid = GetCurrentCommandId(true);
@ -1241,7 +1241,7 @@ void InitPlan(QueryDesc *queryDesc, int eflags)
}
/*
* Similarly, we have to lock relations selected FOR UPDATE/FOR SHARE
* Similarly, we have to lock relations selected FOR [KEY] UPDATE/SHARE
* before we initialize the plan tree, else we'd be risking lock upgrades.
* While we are at it, build the ExecRowMark list.
*/
@ -1264,7 +1264,9 @@ void InitPlan(QueryDesc *queryDesc, int eflags)
*/
switch (rc->markType) {
case ROW_MARK_EXCLUSIVE:
case ROW_MARK_NOKEYEXCLUSIVE:
case ROW_MARK_SHARE:
case ROW_MARK_KEYSHARE:
if (IS_PGXC_COORDINATOR || u_sess->pgxc_cxt.PGXCNodeId < 0 ||
bms_is_member(u_sess->pgxc_cxt.PGXCNodeId, rc->bms_nodeids)) {
relid = getrelid(rc->rti, rangeTable);
@ -1979,7 +1981,7 @@ static void ExecEndPlan(PlanState *planstate, EState *estate)
}
/*
* close any relations selected FOR UPDATE/FOR SHARE, again keeping locks
* close any relations selected FOR [KEY] UPDATE/SHARE, again keeping locks
*/
foreach (l, estate->es_rowMarks) {
ExecRowMark *erm = (ExecRowMark *)lfirst(l);
@ -2773,6 +2775,7 @@ TupleTableSlot *EvalPlanQualUHeap(EState *estate, EPQState *epqstate, Relation r
* epqstate - state for EvalPlanQual rechecking
* relation - table containing tuple
* rti - rangetable index of table containing tuple
* lockmode - requested tuple lock mode
* *tid - t_ctid from the outdated tuple (ie, next updated version)
* priorXmax - t_xmax from the outdated tuple
*
@ -2781,9 +2784,12 @@ TupleTableSlot *EvalPlanQualUHeap(EState *estate, EPQState *epqstate, Relation r
*
* Returns a slot containing the new candidate update/delete tuple, or
* NULL if we determine we shouldn't process the row.
*
* Note: properly, lockmode should be declared as enum LockTupleMode,
* but we use "int" to avoid having to include heapam.h in executor.h.
*/
TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate, Relation relation, Index rti, ItemPointer tid,
TransactionId priorXmax, bool partRowMoveUpdate)
TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate, Relation relation, Index rti, int lockmode,
ItemPointer tid, TransactionId priorXmax, bool partRowMoveUpdate)
{
TupleTableSlot *slot = NULL;
Tuple copyTuple;
@ -2793,7 +2799,7 @@ TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate, Relation relati
/*
* Get and lock the updated version of the row; if fail, return NULL.
*/
copyTuple = tableam_tuple_lock_updated(estate->es_output_cid, relation, LockTupleExclusive, tid, priorXmax,
copyTuple = tableam_tuple_lock_updated(estate->es_output_cid, relation, lockmode, tid, priorXmax,
estate->es_snapshot);
if (copyTuple == NULL) {
@ -3073,7 +3079,7 @@ HeapTuple heap_lock_updated(CommandId cid, Relation relation, int lockmode, Item
/* updated, so look at the updated row */
tuple.t_self = tuple.t_data->t_ctid;
/* updated row should have xmin matching this xmax */
priorXmax = HeapTupleGetRawXmax(&tuple);
priorXmax = HeapTupleGetUpdateXid(&tuple);
ReleaseBuffer(buffer);
/* loop back to fetch next in chain */
}