forked from huawei/openGauss-server
fix several bugs for enhance tuple lock
This commit is contained in:
parent
23ddd1ca38
commit
d183e96ae7
|
|
@ -4239,6 +4239,14 @@ static void transformLockingClause(ParseState* pstate, Query* qry, LockingClause
|
|||
/* make a clause we can pass down to subqueries to select all rels */
|
||||
allrels = makeNode(LockingClause);
|
||||
allrels->lockedRels = NIL; /* indicates all rels */
|
||||
/* The strength of lc is not set at old version and distribution. Set it according to forUpdate. */
|
||||
if (t_thrd.proc->workingVersionNum < ENHANCED_TUPLE_LOCK_VERSION_NUM
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
|| true
|
||||
#endif
|
||||
) {
|
||||
lc->strength = lc->forUpdate ? LCS_FORUPDATE : LCS_FORSHARE;
|
||||
}
|
||||
allrels->strength = lc->strength;
|
||||
allrels->noWait = lc->noWait;
|
||||
|
||||
|
|
@ -4404,6 +4412,7 @@ void applyLockingClause(Query* qry, Index rtindex, LockClauseStrength strength,
|
|||
* And of course pushedDown becomes false if any clause is explicit.
|
||||
*/
|
||||
rc->strength = Max(rc->strength, strength);
|
||||
rc->forUpdate = rc->strength == LCS_FORUPDATE;
|
||||
rc->noWait = rc->noWait || noWait;
|
||||
rc->pushedDown = rc->pushedDown && pushedDown;
|
||||
return;
|
||||
|
|
@ -4413,6 +4422,7 @@ void applyLockingClause(Query* qry, Index rtindex, LockClauseStrength strength,
|
|||
rc = makeNode(RowMarkClause);
|
||||
rc->rti = rtindex;
|
||||
rc->strength = strength;
|
||||
rc->forUpdate = strength == LCS_FORUPDATE;
|
||||
rc->noWait = noWait;
|
||||
rc->pushedDown = pushedDown;
|
||||
qry->rowMarks = lappend(qry->rowMarks, rc);
|
||||
|
|
|
|||
|
|
@ -212,6 +212,19 @@ Datum RI_FKey_noaction(PG_FUNCTION_ARGS);
|
|||
template <bool is_del>
|
||||
Datum RI_FKey_setdefault(PG_FUNCTION_ARGS);
|
||||
|
||||
/*
|
||||
* Since tuple lock has been enhanced, KeyShareLock is needed instead
|
||||
* of ShareLock for foreign key. But ustore table still acquires ShareLock.
|
||||
*/
|
||||
static inline bool IsShareLockForForeignKey(Relation relation)
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
return true;
|
||||
#else
|
||||
return RelationIsUstoreFormat(relation);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ----------
|
||||
* RI_FKey_check -
|
||||
*
|
||||
|
|
@ -321,13 +334,10 @@ static Datum RI_FKey_check(PG_FUNCTION_ARGS)
|
|||
* ----------
|
||||
*/
|
||||
quoteRelationName(pkrelname, pk_rel);
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
rc = snprintf_s(
|
||||
querystr, sizeof(querystr), sizeof(querystr) - 1, "SELECT 1 FROM ONLY %s x FOR SHARE OF x", pkrelname);
|
||||
#else
|
||||
|
||||
rc = snprintf_s(querystr, sizeof(querystr), sizeof(querystr) - 1,
|
||||
IsShareLockForForeignKey(trigdata->tg_relation) ? "SELECT 1 FROM ONLY %s x FOR SHARE OF x" :
|
||||
"SELECT 1 FROM ONLY %s x FOR KEY SHARE OF x", pkrelname);
|
||||
#endif
|
||||
securec_check_ss(rc, "\0", "\0");
|
||||
|
||||
/* Prepare and save the plan */
|
||||
|
|
@ -465,11 +475,9 @@ static Datum RI_FKey_check(PG_FUNCTION_ARGS)
|
|||
querysep = "AND";
|
||||
queryoids[i] = fk_type;
|
||||
}
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
appendStringInfo(&querybuf, " FOR SHARE OF x");
|
||||
#else
|
||||
appendStringInfo(&querybuf, " FOR KEY SHARE OF x");
|
||||
#endif
|
||||
|
||||
appendStringInfo(&querybuf, IsShareLockForForeignKey(trigdata->tg_relation) ? " FOR SHARE OF x" :
|
||||
" FOR KEY SHARE OF x");
|
||||
|
||||
/* Prepare and save the plan */
|
||||
qplan = ri_PlanCheck(querybuf.data, riinfo.nkeys, queryoids, &qkey, fk_rel, pk_rel, true);
|
||||
|
|
@ -617,12 +625,8 @@ static bool ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel, HeapTuple old_ro
|
|||
querysep = "AND";
|
||||
queryoids[i] = pk_type;
|
||||
}
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
appendStringInfo(&querybuf, " FOR SHARE OF x");
|
||||
#else
|
||||
appendStringInfo(&querybuf, " FOR KEY SHARE OF x");
|
||||
#endif
|
||||
|
||||
appendStringInfo(&querybuf, IsShareLockForForeignKey(pk_rel) ? " FOR SHARE OF x" : " FOR KEY SHARE OF x");
|
||||
|
||||
/* Prepare and save the plan */
|
||||
qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids, &qkey, fk_rel, pk_rel, true);
|
||||
|
|
@ -793,11 +797,9 @@ Datum RI_FKey_noaction(PG_FUNCTION_ARGS)
|
|||
querysep = "AND";
|
||||
queryoids[i] = pk_type;
|
||||
}
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
appendStringInfo(&querybuf, " FOR SHARE OF x");
|
||||
#else
|
||||
appendStringInfo(&querybuf, " FOR KEY SHARE OF x");
|
||||
#endif
|
||||
|
||||
appendStringInfo(&querybuf, IsShareLockForForeignKey(trigdata->tg_relation) ?
|
||||
" FOR SHARE OF x" : " FOR KEY SHARE OF x");
|
||||
|
||||
/* Prepare and save the plan */
|
||||
qplan = ri_PlanCheck(querybuf.data, riinfo.nkeys, queryoids, &qkey, fk_rel, pk_rel, true);
|
||||
|
|
@ -1332,11 +1334,9 @@ Datum RI_FKey_restrict(PG_FUNCTION_ARGS)
|
|||
querysep = "AND";
|
||||
queryoids[i] = pk_type;
|
||||
}
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
appendStringInfo(&querybuf, " FOR SHARE OF x");
|
||||
#else
|
||||
appendStringInfo(&querybuf, " FOR KEY SHARE OF x");
|
||||
#endif
|
||||
|
||||
appendStringInfo(&querybuf, IsShareLockForForeignKey(trigdata->tg_relation) ?
|
||||
" FOR SHARE OF x" : " FOR KEY SHARE OF x");
|
||||
|
||||
/* Prepare and save the plan */
|
||||
qplan = ri_PlanCheck(querybuf.data, riinfo.nkeys, queryoids, &qkey, fk_rel, pk_rel, true);
|
||||
|
|
|
|||
|
|
@ -4908,6 +4908,14 @@ static void preprocess_rowmarks(PlannerInfo* root)
|
|||
newrc = makeNode(PlanRowMark);
|
||||
newrc->rti = newrc->prti = rc->rti;
|
||||
newrc->rowmarkId = ++(root->glob->lastRowMarkId);
|
||||
/* The strength of lc is not set at old version and distribution. Set it according to forUpdate. */
|
||||
if (t_thrd.proc->workingVersionNum < ENHANCED_TUPLE_LOCK_VERSION_NUM
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
|| true
|
||||
#endif
|
||||
) {
|
||||
rc->strength = rc->forUpdate ? LCS_FORUPDATE : LCS_FORSHARE;
|
||||
}
|
||||
switch (rc->strength) {
|
||||
case LCS_FORUPDATE:
|
||||
newrc->markType = ROW_MARK_EXCLUSIVE;
|
||||
|
|
|
|||
|
|
@ -2892,7 +2892,7 @@ bool is_contain_crossbucket(List *defList)
|
|||
bool is_cstore_option(char relkind, Datum reloptions)
|
||||
{
|
||||
StdRdOptions* std_opt = (StdRdOptions*)heap_reloptions(relkind, reloptions, false);
|
||||
bool result = std_opt == NULL && pg_strcasecmp(ORIENTATION_COLUMN,
|
||||
bool result = std_opt != NULL && pg_strcasecmp(ORIENTATION_COLUMN,
|
||||
StdRdOptionsGetStringData(std_opt, orientation, ORIENTATION_ROW)) == 0;
|
||||
pfree_ext(std_opt);
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -5174,8 +5174,14 @@ l2:
|
|||
* If the tuple we're updating is locked, we need to preserve the locking
|
||||
* info in the old tuple's Xmax. Prepare a new Xmax value for this.
|
||||
*/
|
||||
ComputeNewXmaxInfomask(HeapTupleGetRawXmax(&oldtup), oldtup.t_data->t_infomask, oldtup.t_data->t_infomask2,
|
||||
xid, mode, true, &xmax_old_tuple, &infomask_old_tuple, &infomask2_old_tuple);
|
||||
if (t_thrd.proc->workingVersionNum >= ENHANCED_TUPLE_LOCK_VERSION_NUM) {
|
||||
ComputeNewXmaxInfomask(HeapTupleGetRawXmax(&oldtup), oldtup.t_data->t_infomask, oldtup.t_data->t_infomask2,
|
||||
xid, mode, true, &xmax_old_tuple, &infomask_old_tuple, &infomask2_old_tuple);
|
||||
} else {
|
||||
xmax_old_tuple = xid;
|
||||
infomask_old_tuple = 0;
|
||||
infomask2_old_tuple = HEAP_KEYS_UPDATED;
|
||||
}
|
||||
|
||||
/* And also prepare an Xmax value for the new copy of the tuple */
|
||||
if ((oldtup.t_data->t_infomask & HEAP_XMAX_INVALID) || (checked_lockers && !locker_remains)) {
|
||||
|
|
@ -5199,7 +5205,7 @@ l2:
|
|||
if (t_thrd.proc->workingVersionNum < ENHANCED_TUPLE_LOCK_VERSION_NUM) {
|
||||
/* if the only locker of old tuple is ourselves, xmax_new_tuple may be xid and it would be valid */
|
||||
if (TransactionIdIsValid(xmax_new_tuple) || !TransactionIdEquals(xmax_old_tuple, xid)) {
|
||||
ereport(WARNING, (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
|
||||
ereport(DEBUG2, (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
|
||||
errmsg("New MultiXact feature isn't support in this version. Please upgrade to version: %d",
|
||||
ENHANCED_TUPLE_LOCK_VERSION_NUM)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1606,6 +1606,10 @@ TM_Result UHeapamTupleUpdate(Relation relation, Relation parentRelation, ItemPoi
|
|||
TM_Result result = UHeapUpdate(relation, parentRelation, otid, (UHeapTuple)newtup, cid, crosscheck, snapshot, wait,
|
||||
oldslot, tmfd, update_indexes, modifiedIdxAttrs, allow_inplace_update);
|
||||
|
||||
/* the LockTupleMode of ustore-updating must be LockTupleExclusive now */
|
||||
if (mode != NULL) {
|
||||
*mode = LockTupleExclusive;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -680,9 +680,8 @@ static MultiXactId CreateMultiXactId(int nmembers, MultiXactMember *members)
|
|||
for (int i = 0; i < nmembers; ++i) {
|
||||
if (members[i].status != MultiXactStatusForShare) {
|
||||
ereport(ERROR, (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
|
||||
errmsg("New MultiXact feature isn't support in this version. Please upgrade to version: %d"
|
||||
"i: %d, members[i].status: %d",
|
||||
ENHANCED_TUPLE_LOCK_VERSION_NUM, i, members[i].status)));
|
||||
errmsg("New MultiXact feature isn't support in this version. Please upgrade to version: %d",
|
||||
ENHANCED_TUPLE_LOCK_VERSION_NUM)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1630,6 +1630,10 @@ static void UHeapExecuteLockTuple(Relation relation, Buffer buffer, UHeapTuple u
|
|||
TransactionId xidOnTup = InvalidTransactionId;
|
||||
TransactionId curxid = InvalidTransactionId;
|
||||
|
||||
if (mode == LockTupleKeyShare || mode == LockTupleNoKeyExclusive) {
|
||||
ereport(ERROR, (errmsg("For Key Share and For No Key Update is not support for ustore.")));
|
||||
}
|
||||
|
||||
if (mode == LockTupleExclusive) {
|
||||
xid = GetCurrentTransactionId();
|
||||
} else if (mode == LockTupleShared) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue