From bd2e29c7a9d46ccc8e3bc2fbdc1e22663da0675c Mon Sep 17 00:00:00 2001 From: YangEfei Date: Wed, 19 Jun 2024 07:04:46 +0000 Subject: [PATCH] [OB_LOCKS] fix the deadlock when get session_id by tx_id --- src/storage/ls/ob_ls.h | 5 +++++ src/storage/ls/ob_ls_tx_service.cpp | 29 +++++++++++++++++++++++++++++ src/storage/ls/ob_ls_tx_service.h | 1 + src/storage/tx/ob_trans_service.cpp | 16 ++++++++-------- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/storage/ls/ob_ls.h b/src/storage/ls/ob_ls.h index 7444684900..42363f0101 100644 --- a/src/storage/ls/ob_ls.h +++ b/src/storage/ls/ob_ls.h @@ -826,6 +826,11 @@ public: // @param [out] scheduler: scheduler of this tx_id // int get_tx_scheduler(const transaction::ObTransID &tx_id, ObAddr &scheduler) const; CONST_DELEGATE_WITH_RET(ls_tx_svr_, get_tx_scheduler, int); + // get tx start session_id in ls tx service + // @param [in] tx_id: wish to get this tx_id start session_id + // @param [out] session_id: session_id of this tx_id + // int get_tx_start_session_id(const transaction::ObTransID &tx_id, uint32_t &session_id) const; + CONST_DELEGATE_WITH_RET(ls_tx_svr_, get_tx_start_session_id, int); // iterate the obj lock op at tx service. // int iterate_tx_obj_lock_op(ObLockOpIterator &iter) const; CONST_DELEGATE_WITH_RET(ls_tx_svr_, iterate_tx_obj_lock_op, int); diff --git a/src/storage/ls/ob_ls_tx_service.cpp b/src/storage/ls/ob_ls_tx_service.cpp index 9b1192d73e..30f00737de 100644 --- a/src/storage/ls/ob_ls_tx_service.cpp +++ b/src/storage/ls/ob_ls_tx_service.cpp @@ -128,6 +128,35 @@ int ObLSTxService::get_tx_scheduler(const transaction::ObTransID &tx_id, return ret; } +int ObLSTxService::get_tx_start_session_id(const transaction::ObTransID &tx_id, uint32_t &session_id) const +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + if (OB_ISNULL(mgr_)) { + ret = OB_NOT_INIT; + TRANS_LOG(WARN, "not init", K(ret)); + } else { + ObPartTransCtx *ctx; + if (OB_FAIL(mgr_->get_tx_ctx_directly_from_hash_map(tx_id, ctx))) { + if (OB_TRANS_CTX_NOT_EXIST == ret) { + ret = OB_SUCCESS; + TRANS_LOG(INFO, "ctx not existed on this LS", K(tx_id), K(ls_id_)); + } else { + TRANS_LOG(WARN, "get ctx failed", K(ret), K(tx_id), K(ls_id_)); + } + } else if (OB_ISNULL(ctx)) { + ret = OB_BAD_NULL_ERROR; + TRANS_LOG(WARN, "get ctx is null", K(ret), K(tx_id), K(ls_id_)); + } else { + session_id = ctx->get_session_id(); + if (OB_TMP_FAIL(mgr_->revert_tx_ctx(ctx))) { + TRANS_LOG(ERROR, "fail to revert tx", K(ret), K(tmp_ret), K(tx_id), KPC(ctx)); + } + } + } + return ret; +} + int ObLSTxService::revert_tx_ctx(ObTransCtx *ctx) const { int ret = OB_SUCCESS; diff --git a/src/storage/ls/ob_ls_tx_service.h b/src/storage/ls/ob_ls_tx_service.h index af1111399a..279912af0c 100644 --- a/src/storage/ls/ob_ls_tx_service.h +++ b/src/storage/ls/ob_ls_tx_service.h @@ -97,6 +97,7 @@ public: const int64_t lock_timeout) const; int get_tx_scheduler(const transaction::ObTransID &tx_id, ObAddr &scheduler) const; + int get_tx_start_session_id(const transaction::ObTransID &tx_id, uint32_t &session_id) const; int revert_tx_ctx(transaction::ObTransCtx *ctx) const; int get_read_store_ctx(const transaction::ObTxReadSnapshot &snapshot, const bool read_latest, diff --git a/src/storage/tx/ob_trans_service.cpp b/src/storage/tx/ob_trans_service.cpp index b96e1c108e..13152d433c 100644 --- a/src/storage/tx/ob_trans_service.cpp +++ b/src/storage/tx/ob_trans_service.cpp @@ -443,22 +443,22 @@ int ObTransService::get_trans_start_session_id(const share::ObLSID &ls_id, const { int ret = OB_SUCCESS; transaction::ObPartTransCtx *part_ctx = nullptr; + ObLSHandle ls_handle; + session_id = ObBasicSessionInfo::INVALID_SESSID; if (IS_NOT_INIT) { TRANS_LOG(WARN, "ObTransService not inited"); ret = OB_NOT_INIT; } else if (OB_UNLIKELY(!is_running_)) { TRANS_LOG(WARN, "ObTransService is not running"); ret = OB_NOT_RUNNING; - } else if (OB_FAIL(tx_ctx_mgr_.get_tx_ctx(ls_id, tx_id, false, part_ctx))) { + } else if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::TRANS_MOD))) { + TRANS_LOG(WARN, "get ls failed", K(ret), K(ls_id), K(tx_id)); + } else if (!ls_handle.is_valid()) { + ret = OB_INVALID_ARGUMENT; + TRANS_LOG(WARN, "ls is null in ObLSHandle", K(ret), K(ls_id), K(tx_id)); + } else if (OB_FAIL(ls_handle.get_ls()->get_tx_start_session_id(tx_id, session_id))) { TRANS_LOG(WARN, "get ObPartTransCtx by ls_id and tx_id failed", K(ls_id), K(tx_id)); - } else if (OB_ISNULL(part_ctx)) { - ret = OB_ERR_UNEXPECTED; - TRANS_LOG(WARN, "ObPartTransCtx is null", K(ls_id), K(tx_id)); - } else { - session_id = part_ctx->get_session_id(); - tx_ctx_mgr_.revert_tx_ctx(part_ctx); } - return ret; }