[TABLELOCK] Fix bug about calling release_all_locks when session doesn't hold any locks
This commit is contained in:
parent
e4bf916318
commit
e76485f957
@ -408,6 +408,8 @@ int ObExprReleaseLock::release_lock(const ObExpr &expr, ObEvalCtx &ctx, ObDatum
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
ObDatum *lock_name = NULL;
|
||||
int64_t release_cnt = ObLockFuncExecutor::INVALID_RELEASE_CNT;
|
||||
|
||||
if (!proxy_is_support(ctx.exec_ctx_)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("obproxy is not support mysql lock function", K(ret));
|
||||
@ -425,24 +427,19 @@ int ObExprReleaseLock::release_lock(const ObExpr &expr, ObEvalCtx &ctx, ObDatum
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument, lock name should not be null", K(ret));
|
||||
} else if (OB_FAIL(executor.execute(ctx.exec_ctx_,
|
||||
lock_name_str))) {
|
||||
lock_name_str,
|
||||
release_cnt))) {
|
||||
LOG_WARN("release lock failed", K(ret), K(lock_name_str));
|
||||
}
|
||||
}
|
||||
|
||||
// 1 release success
|
||||
if (OB_SUCC(ret)) {
|
||||
result.set_int(1);
|
||||
} else if (OB_EMPTY_RESULT == ret) {
|
||||
// 2 there is no lock
|
||||
ret = OB_SUCCESS;
|
||||
result.set_null();
|
||||
} else if (OB_OBJ_LOCK_NOT_EXIST == ret) {
|
||||
// 3 the lock is not belong to current client session
|
||||
ret = OB_SUCCESS;
|
||||
result.set_int(0);
|
||||
if (release_cnt < 0) {
|
||||
result.set_null();
|
||||
} else {
|
||||
result.set_int(release_cnt);
|
||||
}
|
||||
} else {
|
||||
// 4 some thing error.
|
||||
result.set_null();
|
||||
}
|
||||
|
||||
@ -483,11 +480,14 @@ int ObExprReleaseAllLocks::release_all_locks(const ObExpr &expr,
|
||||
} else {
|
||||
ret = executor.execute(ctx.exec_ctx_, release_cnt);
|
||||
}
|
||||
// 1. release all locks success.
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
result.set_int(release_cnt);
|
||||
if (release_cnt < 0) {
|
||||
result.set_null();
|
||||
} else {
|
||||
result.set_int(release_cnt);
|
||||
}
|
||||
} else {
|
||||
// 2. some thing error.
|
||||
result.set_null();
|
||||
}
|
||||
return ret;
|
||||
|
@ -977,7 +977,8 @@ int ObGetLockExecutor::get_sql_port_(ObLockFuncContext &ctx,
|
||||
}
|
||||
|
||||
int ObReleaseLockExecutor::execute(ObExecContext &ctx,
|
||||
const ObString &lock_name)
|
||||
const ObString &lock_name,
|
||||
int64_t &release_cnt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
@ -989,6 +990,8 @@ int ObReleaseLockExecutor::execute(ObExecContext &ctx,
|
||||
bool lock_id_existed = false;
|
||||
ObLockID tmp_lock_id;
|
||||
|
||||
release_cnt = INVALID_RELEASE_CNT; // means not release successfully
|
||||
|
||||
OZ (ObLockFuncContext::valid_execute_context(ctx));
|
||||
if (OB_SUCC(ret)) {
|
||||
SMART_VAR(ObLockFuncContext, stack_ctx) {
|
||||
@ -1001,8 +1004,8 @@ int ObReleaseLockExecutor::execute(ObExecContext &ctx,
|
||||
ObTxParam tx_param;
|
||||
ObUnLockObjsRequest arg;
|
||||
ObTableLockOwnerID lock_owner;
|
||||
// 1. check client_session_id is valid
|
||||
// 2. get lock id from inner table
|
||||
// 1. get lock id from inner table
|
||||
// 2. check client_session_id is valid
|
||||
// 3. unlock obj
|
||||
// 4. modify inner table
|
||||
// 4.1 lock table: dec cnt if the cnt is greater than 1, else remove the record.
|
||||
@ -1011,11 +1014,17 @@ int ObReleaseLockExecutor::execute(ObExecContext &ctx,
|
||||
// lock id, remove the record at lock name-id table.
|
||||
// 4.3 session table: check the lock table if there is no lock of the same
|
||||
// client session, remove the record of the same client session id.
|
||||
OZ (query_lock_id_(lock_name, lock_id));
|
||||
if (OB_EMPTY_RESULT == ret) {
|
||||
release_cnt = LOCK_NOT_EXIST_RELEASE_CNT;
|
||||
}
|
||||
if (ctx.get_my_session()->is_obproxy_mode()) {
|
||||
OZ (check_client_ssid_(stack_ctx, client_session_id, client_session_create_ts));
|
||||
if (OB_EMPTY_RESULT == ret) {
|
||||
release_cnt = LOCK_NOT_OWN_RELEASE_CNT;
|
||||
}
|
||||
}
|
||||
OZ (lock_owner.convert_from_client_sessid(client_session_id, client_session_create_ts));
|
||||
OZ (query_lock_id_(lock_name, lock_id));
|
||||
OZ (ObInnerConnectionLockUtil::build_tx_param(session, tx_param));
|
||||
|
||||
OZ (tmp_lock_id.set(ObLockOBJType::OBJ_TYPE_MYSQL_LOCK_FUNC, lock_id));
|
||||
@ -1031,11 +1040,14 @@ int ObReleaseLockExecutor::execute(ObExecContext &ctx,
|
||||
if (OB_SUCC(ret) && need_remove_from_lock_table) {
|
||||
OZ (unlock_obj_(tx_desc, tx_param, arg));
|
||||
OZ (remove_session_record_(stack_ctx, client_session_id, client_session_create_ts));
|
||||
OX (release_cnt = 1);
|
||||
} else if (OB_EMPTY_RESULT == ret) {
|
||||
if (OB_TMP_FAIL(check_lock_exist_(stack_ctx, lock_id, lock_id_existed))) {
|
||||
LOG_WARN("check lock_id existed failed", K(tmp_ret), K(lock_id));
|
||||
} else if (lock_id_existed) {
|
||||
ret = OB_OBJ_LOCK_NOT_EXIST; // when lock is hold by other session, return 0 as result
|
||||
release_cnt = LOCK_NOT_OWN_RELEASE_CNT;
|
||||
} else {
|
||||
release_cnt = LOCK_NOT_EXIST_RELEASE_CNT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1046,6 +1058,11 @@ int ObReleaseLockExecutor::execute(ObExecContext &ctx,
|
||||
}
|
||||
}
|
||||
}
|
||||
// if release_cnt is valid, means we have tried to release,
|
||||
// and have not encountered any failures before
|
||||
if (INVALID_RELEASE_CNT != release_cnt) {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1111,6 +1128,7 @@ int ObReleaseAllLockExecutor::execute_(ObExecContext &ctx,
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
bool is_rollback = false;
|
||||
ObTableLockOwnerID owner_id;
|
||||
release_cnt = INVALID_RELEASE_CNT; // means not release successfully
|
||||
OZ (ObLockFuncContext::valid_execute_context(ctx));
|
||||
if (OB_SUCC(ret)) {
|
||||
SMART_VAR(ObLockFuncContext, stack_ctx) {
|
||||
@ -1121,6 +1139,9 @@ int ObReleaseAllLockExecutor::execute_(ObExecContext &ctx,
|
||||
ObTxParam tx_param;
|
||||
if (ctx.get_my_session()->is_obproxy_mode()) {
|
||||
OZ (check_client_ssid_(stack_ctx, client_session_id, client_session_create_ts));
|
||||
if (OB_EMPTY_RESULT == ret) {
|
||||
release_cnt = LOCK_NOT_OWN_RELEASE_CNT;
|
||||
}
|
||||
}
|
||||
OZ (ObInnerConnectionLockUtil::build_tx_param(session, tx_param));
|
||||
OZ (owner_id.convert_from_client_sessid(client_session_id, client_session_create_ts));
|
||||
@ -1138,6 +1159,11 @@ int ObReleaseAllLockExecutor::execute_(ObExecContext &ctx,
|
||||
}
|
||||
}
|
||||
}
|
||||
// if release_cnt is valid, means we have tried to release,
|
||||
// and have not encountered any failures before
|
||||
if (INVALID_RELEASE_CNT != release_cnt) {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,10 @@ public:
|
||||
static constexpr int64_t MAX_LOCK_HANDLE_ID = 1999999999;
|
||||
static constexpr int64_t DEFAULT_EXPIRATION_US = 60 * 1000 * 1000L; // 1min
|
||||
|
||||
static constexpr int64_t INVALID_RELEASE_CNT = -2;
|
||||
static constexpr int64_t LOCK_NOT_EXIST_RELEASE_CNT = -1;
|
||||
static constexpr int64_t LOCK_NOT_OWN_RELEASE_CNT = 0;
|
||||
|
||||
public:
|
||||
int check_lock_exist_(const uint64_t &lock_id);
|
||||
int check_lock_exist_(ObLockFuncContext &ctx,
|
||||
@ -216,7 +220,8 @@ class ObReleaseLockExecutor : public ObLockFuncExecutor
|
||||
{
|
||||
public:
|
||||
int execute(sql::ObExecContext &ctx,
|
||||
const ObString &lock_name);
|
||||
const ObString &lock_name,
|
||||
int64_t &release_cnt);
|
||||
};
|
||||
|
||||
class ObReleaseAllLockExecutor : public ObLockFuncExecutor
|
||||
|
Loading…
x
Reference in New Issue
Block a user