diff --git a/src/storage/ls/ob_ls_tx_service.cpp b/src/storage/ls/ob_ls_tx_service.cpp index d15b8cb10..df24a9051 100644 --- a/src/storage/ls/ob_ls_tx_service.cpp +++ b/src/storage/ls/ob_ls_tx_service.cpp @@ -267,6 +267,21 @@ int ObLSTxService::block_tx() return ret; } +int ObLSTxService::block_all() +{ + int ret = OB_SUCCESS; + bool unused_is_all_tx_clean_up = false; + if (OB_ISNULL(mgr_)) { + ret = OB_NOT_INIT; + TRANS_LOG(WARN, "not init", KR(ret), K_(ls_id)); + } else if (OB_FAIL(mgr_->block_all(unused_is_all_tx_clean_up))) { + TRANS_LOG(WARN, "block all failed", K_(ls_id)); + } else { + TRANS_LOG(INFO, "block all success", K_(ls_id)); + } + return ret; +} + int ObLSTxService::kill_all_tx(const bool graceful) { int ret = OB_SUCCESS; @@ -647,8 +662,8 @@ int ObLSTxService::prepare_offline(const int64_t start_ts) if (OB_ISNULL(mgr_)) { ret = OB_NOT_INIT; TRANS_LOG(WARN, "not init", KR(ret), K_(ls_id)); - } else if (OB_FAIL(mgr_->block_tx(unused_is_all_tx_clean_up))) { - TRANS_LOG(WARN, "block tx failed", K_(ls_id)); + } else if (OB_FAIL(mgr_->block_all(unused_is_all_tx_clean_up))) { + TRANS_LOG(WARN, "block all failed", K_(ls_id)); } else if (ObTimeUtility::current_time() > start_ts + WAIT_READONLY_REQUEST_US) { // dont care readonly request } else { @@ -673,8 +688,8 @@ int ObLSTxService::offline() if (OB_ISNULL(mgr_)) { ret = OB_NOT_INIT; TRANS_LOG(WARN, "not init", KR(ret), K_(ls_id)); - } else if (OB_FAIL(mgr_->block_tx(unused_is_all_tx_clean_up))) { - TRANS_LOG(WARN, "block tx failed", K_(ls_id)); + } else if (OB_FAIL(mgr_->block_all(unused_is_all_tx_clean_up))) { + TRANS_LOG(WARN, "block all failed", K_(ls_id)); } else if (OB_FAIL(mgr_->kill_all_tx(graceful, unused_is_all_tx_clean_up))) { TRANS_LOG(WARN, "kill_all_tx failed", K_(ls_id)); } else if (mgr_->get_tx_ctx_count() > 0) { diff --git a/src/storage/ls/ob_ls_tx_service.h b/src/storage/ls/ob_ls_tx_service.h index f5bac2aff..6bfe90e22 100644 --- a/src/storage/ls/ob_ls_tx_service.h +++ b/src/storage/ls/ob_ls_tx_service.h @@ -117,6 +117,7 @@ public: // @return other, there is something wrong or there is some readonly tx not cleaned up. int check_all_readonly_tx_clean_up() const; int block_tx(); + int block_all(); int kill_all_tx(const bool graceful); // for ddl check // Check all active and not "for_replay" tx_ctx in this ObLSTxCtxMgr diff --git a/src/storage/tx/ob_trans_ctx_mgr_v4.cpp b/src/storage/tx/ob_trans_ctx_mgr_v4.cpp index 2f8bb0664..3c81c45c1 100644 --- a/src/storage/tx/ob_trans_ctx_mgr_v4.cpp +++ b/src/storage/tx/ob_trans_ctx_mgr_v4.cpp @@ -266,22 +266,27 @@ void ObLSTxCtxMgr::print_all_tx_ctx_(const int64_t max_print, const bool verbose } // NB: BLOCK_NORMAL only block noraml tran, only leader can block normal trans -//STATE \ ACTION START LEADER_REVOKE SWL_CB_SUCC SWL_CB_FAIL LEADER_TAKEOVER RESUME_LEADER BLOCK_TX BLOCK_NORMAL STOP ONLINE UNBLOCK_NORMAL -//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -//INIT F_WORKING N N N N N N N N N N -//F_WORKING N F_WORKING N N T_PENDING R_PENDING F_TX_BLOCKED N STOPPED N N -//T_PENDING N F_WORKING L_WORKING T_PENDING N N T_TX_BLOCKED_PENDING N STOPPED N N -//R_PENDING N F_WORKING L_WORKING R_PENDING N N R_TX_BLOCKED_PENDING N STOPPED N N -//L_WORKING N F_WORKING N N N N L_TX_BLOCKED L_BLOCKED_NORMAL STOPPED N N -//F_TX_BLOCKED N F_TX_BLOCKED N N T_TX_BLOCKED_PENDING R_TX_BLOCKED_PENDING F_TX_BLOCKED N STOPPED F_WORKING N -//L_TX_BLOCKED N F_TX_BLOCKED N N N N L_TX_BLOCKED N STOPPED N N -//L_BLOCKED_NORMAL N F_WORKING N N N N L_TX_BLOCKED L_BLOCKED_NORMAL STOPPED N L_WORKING +//STATE \ ACTION START LEADER_REVOKE SWL_CB_SUCC SWL_CB_FAIL LEADER_TAKEOVER RESUME_LEADER BLOCK_TX BLOCK_NORMAL BLOCK_ALL STOP ONLINE UNBLOCK_NORMAL +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//INIT F_WORKING N N N N N N N N N N N +//F_WORKING N F_WORKING N N T_PENDING R_PENDING F_TX_BLOCKED N F_ALL_BLOCKED STOPPED N N +//T_PENDING N F_WORKING L_WORKING T_PENDING N N T_TX_BLOCKED_PENDING N T_ALL_BLOCKED_PENDING STOPPED N N +//R_PENDING N F_WORKING L_WORKING R_PENDING N N R_TX_BLOCKED_PENDING N R_ALL_BLOCKED_PENDING STOPPED N N +//L_WORKING N F_WORKING N N N N L_TX_BLOCKED L_BLOCKED_NORMAL L_ALL_BLOCKED STOPPED N N +//F_TX_BLOCKED N F_TX_BLOCKED N N T_TX_BLOCKED_PENDING R_TX_BLOCKED_PENDING F_TX_BLOCKED N F_ALL_BLOCKED STOPPED F_WORKING N +//L_TX_BLOCKED N F_TX_BLOCKED N N N N L_TX_BLOCKED N L_ALL_BLOCKED STOPPED N N +//L_BLOCKED_NORMAL N F_WORKING N N N N L_TX_BLOCKED L_BLOCKED_NORMAL L_ALL_BLOCKED STOPPED N L_WORKING // -//T_TX_BLOCKED_PENDING N F_TX_BLOCKED L_TX_BLOCKED T_TX_BLOCKED_PENDING N N T_TX_BLOCKED_PENDING N STOPPED N N -//R_TX_BLOCKED_PENDING N F_TX_BLOCKED L_TX_BLOCKED R_TX_BLOCKED_PENDING N N R_TX_BLOCKED_PENDING N STOPPED N N +//T_TX_BLOCKED_PENDING N F_TX_BLOCKED L_TX_BLOCKED T_TX_BLOCKED_PENDING N N T_TX_BLOCKED_PENDING N T_ALL_BLOCKED_PENDING STOPPED N N +//R_TX_BLOCKED_PENDING N F_TX_BLOCKED L_TX_BLOCKED R_TX_BLOCKED_PENDING N N R_TX_BLOCKED_PENDING N R_ALL_BLOCKED_PENDING STOPPED N N // -//STOPPED N STOPPED N N N N N N STOPPED N N -//END N N N N N N N N N N N +//F_ALL_BLOCKED N F_ALL_BLOCKED N N T_ALL_BLOCKED_PENDING R_ALL_BLOCKED_PENDING N N F_ALL_BLOCKED STOPPED N N +//T_ALL_BLOCKED_PENDING N F_ALL_BLOCKED L_ALL_BLOCKED T_ALL_BLOCKED_PENDING N N N N T_ALL_BLOCKED_PENDING STOPPED N N +//R_ALL_BLOCKED_PENDING N F_ALL_BLOCKED L_ALL_BLOCKED R_ALL_BLOCKED_PENDING N N N N R_ALL_BLOCKED_PENDING STOPPED N N +//L_ALL_BLOCKED N F_ALL_BLOCKED N N N N N N L_ALL_BLOCKED STOPPED N N +// +//STOPPED N STOPPED N N N N N N N STOPPED N N +//END N N N N N N N N N N N N int ObLSTxCtxMgr::StateHelper::switch_state(const int64_t op) { int ret = OB_SUCCESS; @@ -295,25 +300,36 @@ int ObLSTxCtxMgr::StateHelper::switch_state(const int64_t op) static const int64_t T_TX_BLOCKED_PENDING = State::T_TX_BLOCKED_PENDING; static const int64_t R_TX_BLOCKED_PENDING = State::R_TX_BLOCKED_PENDING; static const int64_t L_BLOCKED_NORMAL = State::L_BLOCKED_NORMAL; + + static const int64_t F_ALL_BLOCKED = State::F_ALL_BLOCKED; + static const int64_t T_ALL_BLOCKED_PENDING = State::T_ALL_BLOCKED_PENDING; + static const int64_t R_ALL_BLOCKED_PENDING = State::R_ALL_BLOCKED_PENDING; + static const int64_t L_ALL_BLOCKED = State::L_ALL_BLOCKED; + static const int64_t STOPPED = State::STOPPED; static const int64_t END = State::END; static const int64_t STATE_MAP[State::MAX][Ops::MAX] = { -// START L_REVOKE SWL_CB_SUCC SWL_CB_FAIL LEADER_TAKEOVER RESUME_LEADER BLOCK_TX BLOCK_NORMAL STOP ONLINE UNBLOCK_NORMAL - {F_WORKING, N, N, N, N, N, N, N, N, N, N}, - {N, F_WORKING, N, N, T_PENDING, R_PENDING, F_TX_BLOCKED, N, STOPPED, N, N}, - {N, F_WORKING, L_WORKING, T_PENDING, N, N, T_TX_BLOCKED_PENDING, N, STOPPED, N, N}, - {N, F_WORKING, L_WORKING, R_PENDING, N, N, R_TX_BLOCKED_PENDING, N, STOPPED, N, N}, - {N, F_WORKING, N, N, N, N, L_TX_BLOCKED, L_BLOCKED_NORMAL, STOPPED, N, N}, - {N, F_TX_BLOCKED, N, N, T_TX_BLOCKED_PENDING, R_TX_BLOCKED_PENDING, F_TX_BLOCKED, N, STOPPED, F_WORKING, N}, - {N, F_TX_BLOCKED, N, N, N, N, L_TX_BLOCKED, N, STOPPED, N, N}, - {N, F_WORKING, N, N, N, N, L_TX_BLOCKED, L_BLOCKED_NORMAL, STOPPED, N, L_WORKING}, +// START L_REVOKE SWL_CB_SUCC SWL_CB_FAIL LEADER_TAKEOVER RESUME_LEADER BLOCK_TX BLOCK_NORMAL BLOCK_ALL STOP ONLINE UNBLOCK_NORMAL + {F_WORKING, N, N, N, N, N, N, N, N, N, N, N}, + {N, F_WORKING, N, N, T_PENDING, R_PENDING, F_TX_BLOCKED, N, F_ALL_BLOCKED, STOPPED, N, N}, + {N, F_WORKING, L_WORKING, T_PENDING, N, N, T_TX_BLOCKED_PENDING, N, T_ALL_BLOCKED_PENDING, STOPPED, N, N}, + {N, F_WORKING, L_WORKING, R_PENDING, N, N, R_TX_BLOCKED_PENDING, N, R_ALL_BLOCKED_PENDING, STOPPED, N, N}, + {N, F_WORKING, N, N, N, N, L_TX_BLOCKED, L_BLOCKED_NORMAL, L_ALL_BLOCKED, STOPPED, N, N}, + {N, F_TX_BLOCKED, N, N, T_TX_BLOCKED_PENDING, R_TX_BLOCKED_PENDING, F_TX_BLOCKED, N, F_ALL_BLOCKED, STOPPED, F_WORKING, N}, + {N, F_TX_BLOCKED, N, N, N, N, L_TX_BLOCKED, N, L_ALL_BLOCKED, STOPPED, N, N}, + {N, F_WORKING, N, N, N, N, L_TX_BLOCKED, L_BLOCKED_NORMAL, L_ALL_BLOCKED, STOPPED, N, L_WORKING}, // - {N, F_TX_BLOCKED, L_TX_BLOCKED, T_TX_BLOCKED_PENDING, N, N, T_TX_BLOCKED_PENDING, N, STOPPED, N, N}, - {N, F_TX_BLOCKED, L_TX_BLOCKED, R_TX_BLOCKED_PENDING, N, N, R_TX_BLOCKED_PENDING, N, STOPPED, N, N}, + {N, F_TX_BLOCKED, L_TX_BLOCKED, T_TX_BLOCKED_PENDING, N, N, T_TX_BLOCKED_PENDING, N, T_ALL_BLOCKED_PENDING, STOPPED, N, N}, + {N, F_TX_BLOCKED, L_TX_BLOCKED, R_TX_BLOCKED_PENDING, N, N, R_TX_BLOCKED_PENDING, N, R_ALL_BLOCKED_PENDING, STOPPED, N, N}, // - {N, STOPPED, N, N, N, N, N, N, STOPPED, N, N}, - {N, N, N, N, N, N, N, N, N, N, N} + {N, F_ALL_BLOCKED, N, N, T_ALL_BLOCKED_PENDING, R_ALL_BLOCKED_PENDING, N, N, F_ALL_BLOCKED, STOPPED, F_WORKING, N}, + {N, F_ALL_BLOCKED, L_ALL_BLOCKED, T_ALL_BLOCKED_PENDING, N, N, N, N, T_ALL_BLOCKED_PENDING, STOPPED, N, N}, + {N, F_ALL_BLOCKED, L_ALL_BLOCKED, R_ALL_BLOCKED_PENDING, N, N, N, N, R_ALL_BLOCKED_PENDING, STOPPED, N, N}, + {N, F_ALL_BLOCKED, N, N, N, N, N, N, L_ALL_BLOCKED, STOPPED, N, N}, +// + {N, STOPPED, N, N, N, N, N, N, N, STOPPED, N, N}, + {N, N, N, N, N, N, N, N, N, N, N, N} }; if (OB_UNLIKELY(!Ops::is_valid(op))) { @@ -985,6 +1001,23 @@ int ObLSTxCtxMgr::block_tx(bool &is_all_tx_cleaned_up) return ret; } +int ObLSTxCtxMgr::block_all(bool &is_all_tx_cleaned_up) +{ + int ret = OB_SUCCESS; + StateHelper state_helper(ls_id_, state_); + WLockGuardWithRetryInterval guard(rwlock_, TRY_THRESOLD_US, RETRY_INTERVAL_US); + + if (is_stopped_()) { + TRANS_LOG(WARN, "ls_tx_ctx_mgr is stopped, not need block"); + } else if (OB_FAIL(state_helper.switch_state(Ops::BLOCK_ALL))) { + TRANS_LOG(WARN, "switch state error", KR(ret), "manager", *this); + } else { + is_all_tx_cleaned_up = (get_tx_ctx_count() == 0); + } + TRANS_LOG(INFO, "block ls", K(ret), "manager", *this); + return ret; +} + int ObLSTxCtxMgr::block_normal(bool &is_all_tx_cleaned_up) { int ret = OB_SUCCESS; @@ -1508,7 +1541,7 @@ int ObLSTxCtxMgr::start_readonly_request() if (IS_NOT_INIT) { TRANS_LOG(WARN, "ObLSTxCtxMgr not inited", K(this)); ret = OB_NOT_INIT; - } else if (is_tx_blocked_()) { + } else if (is_all_blocked_()) { ret = OB_PARTITION_IS_BLOCKED; // readonly read must be blocked, because trx may be killed forcely TRANS_LOG(WARN, "logstream is blocked", K(ret)); @@ -1896,6 +1929,31 @@ int ObTxCtxMgr::block_tx(const ObLSID &ls_id, bool &is_all_tx_cleaned_up) return ret; } +int ObTxCtxMgr::block_all(const ObLSID &ls_id, bool &is_all_tx_cleaned_up) +{ + int ret = OB_SUCCESS; + ObLSTxCtxMgr *ls_tx_ctx_mgr = NULL; + + if (IS_NOT_INIT) { + TRANS_LOG(WARN, "ObTxCtxMgr not inited"); + ret = OB_NOT_INIT; + } else if (OB_UNLIKELY(!ls_id.is_valid())) { + TRANS_LOG(WARN, "invalid argument", K(ls_id)); + ret = OB_INVALID_ARGUMENT; + } else if (OB_FAIL(get_ls_tx_ctx_mgr(ls_id, ls_tx_ctx_mgr))) { + TRANS_LOG(WARN, "ls_tx_ctx_mgr not exist", K(ls_id)); + ret = OB_PARTITION_NOT_EXIST; + } else { + if (OB_FAIL(ls_tx_ctx_mgr->block_all(is_all_tx_cleaned_up))) { + TRANS_LOG(WARN, "block all error", KR(ret), K(ls_id)); + } else { + TRANS_LOG(INFO, "block all success", K(ls_id), "ctx_count", ls_tx_ctx_mgr->get_tx_ctx_count()); + } + revert_ls_tx_ctx_mgr(ls_tx_ctx_mgr); + } + return ret; +} + int ObTxCtxMgr::clear_all_tx(const ObLSID &ls_id) { int ret = OB_SUCCESS; diff --git a/src/storage/tx/ob_trans_ctx_mgr_v4.h b/src/storage/tx/ob_trans_ctx_mgr_v4.h index 7ea59ea8b..23329ed90 100644 --- a/src/storage/tx/ob_trans_ctx_mgr_v4.h +++ b/src/storage/tx/ob_trans_ctx_mgr_v4.h @@ -258,6 +258,7 @@ public: // Block this ObLSTxCtxMgr, it can no longer create new tx_ctx; // @param [out] is_all_tx_cleaned_up: set it to true, when all transactions are cleaned up; int block_tx(bool &is_all_tx_cleaned_up); + int block_all(bool &is_all_tx_cleaned_up); // Block this ObLSTxCtxMgr, it can no longer create normal tx_ctx; // Allow create special tx_ctx, exp: mds_trans; @@ -577,9 +578,13 @@ private: static const int64_t L_BLOCKED_NORMAL = 7; static const int64_t T_TX_BLOCKED_PENDING = 8; static const int64_t R_TX_BLOCKED_PENDING = 9; - static const int64_t STOPPED = 10; - static const int64_t END = 11; - static const int64_t MAX = 12; + static const int64_t F_ALL_BLOCKED = 10; + static const int64_t T_ALL_BLOCKED_PENDING = 11; + static const int64_t R_ALL_BLOCKED_PENDING = 12; + static const int64_t L_ALL_BLOCKED = 13; + static const int64_t STOPPED = 14; + static const int64_t END = 15; + static const int64_t MAX = 16; public: static bool is_valid(const int64_t state) { return state > INVALID && state < MAX; } @@ -600,9 +605,15 @@ private: TCM_STATE_CASE_TO_STR(L_WORKING); TCM_STATE_CASE_TO_STR(F_TX_BLOCKED); TCM_STATE_CASE_TO_STR(L_TX_BLOCKED); + TCM_STATE_CASE_TO_STR(L_BLOCKED_NORMAL); TCM_STATE_CASE_TO_STR(T_TX_BLOCKED_PENDING); TCM_STATE_CASE_TO_STR(R_TX_BLOCKED_PENDING); - TCM_STATE_CASE_TO_STR(L_BLOCKED_NORMAL); + + TCM_STATE_CASE_TO_STR(F_ALL_BLOCKED); + TCM_STATE_CASE_TO_STR(T_ALL_BLOCKED_PENDING); + TCM_STATE_CASE_TO_STR(R_ALL_BLOCKED_PENDING); + TCM_STATE_CASE_TO_STR(L_ALL_BLOCKED); + TCM_STATE_CASE_TO_STR(STOPPED); TCM_STATE_CASE_TO_STR(END); default: @@ -625,10 +636,11 @@ private: static const int64_t RESUME_LEADER = 5; static const int64_t BLOCK_TX = 6; static const int64_t BLOCK_NORMAL = 7; - static const int64_t STOP = 8; - static const int64_t ONLINE = 9; - static const int64_t UNBLOCK_NORMAL = 10; - static const int64_t MAX = 11; + static const int64_t BLOCK_ALL = 8; + static const int64_t STOP = 9; + static const int64_t ONLINE = 10; + static const int64_t UNBLOCK_NORMAL = 11; + static const int64_t MAX = 12; public: static bool is_valid(const int64_t op) @@ -651,9 +663,10 @@ private: TCM_OP_CASE_TO_STR(RESUME_LEADER); TCM_OP_CASE_TO_STR(BLOCK_TX); TCM_OP_CASE_TO_STR(BLOCK_NORMAL); + TCM_OP_CASE_TO_STR(BLOCK_ALL); TCM_OP_CASE_TO_STR(STOP); - TCM_OP_CASE_TO_STR(UNBLOCK_NORMAL); TCM_OP_CASE_TO_STR(ONLINE); + TCM_OP_CASE_TO_STR(UNBLOCK_NORMAL); default: break; } @@ -685,13 +698,15 @@ private: inline bool is_master_(int64_t state) const { return State::L_WORKING == state || State::L_TX_BLOCKED == state || - State::L_BLOCKED_NORMAL == state; } + State::L_BLOCKED_NORMAL == state || + State::L_ALL_BLOCKED == state; } inline bool is_follower_() const { return is_follower_(ATOMIC_LOAD(&state_)); } inline bool is_follower_(int64_t state) const { return State::F_WORKING == state || - State::F_TX_BLOCKED == state; } + State::F_TX_BLOCKED == state || + State::F_ALL_BLOCKED == state; } inline bool is_tx_blocked_() const { return is_tx_blocked_(ATOMIC_LOAD(&state_)); } @@ -700,14 +715,26 @@ private: return State::F_TX_BLOCKED == state || State::L_TX_BLOCKED == state || State::T_TX_BLOCKED_PENDING == state || - State::R_TX_BLOCKED_PENDING == state; + State::R_TX_BLOCKED_PENDING == state || + State::F_ALL_BLOCKED == state || + State::T_ALL_BLOCKED_PENDING == state || + State::R_ALL_BLOCKED_PENDING == state || + State::L_ALL_BLOCKED == state; } inline bool is_normal_blocked_() const { return is_normal_blocked_(ATOMIC_LOAD(&state_)); } inline bool is_normal_blocked_(int64_t state) const + { return State::L_BLOCKED_NORMAL == state; } + + inline bool is_all_blocked_() const + { return is_all_blocked_(ATOMIC_LOAD(&state_)); } + inline bool is_all_blocked_(const int64_t state) const { - return State::L_BLOCKED_NORMAL == state; + return State::F_ALL_BLOCKED == state || + State::T_ALL_BLOCKED_PENDING == state || + State::R_ALL_BLOCKED_PENDING == state || + State::L_ALL_BLOCKED == state; } // check pending substate @@ -716,7 +743,8 @@ private: inline bool is_t_pending_(int64_t state) const { return State::T_PENDING == state || - State::T_TX_BLOCKED_PENDING == state; + State::T_TX_BLOCKED_PENDING == state || + State::T_ALL_BLOCKED_PENDING == state; } inline bool is_r_pending_() const @@ -724,7 +752,8 @@ private: inline bool is_r_pending_(int64_t state) const { return State::R_PENDING == state || - State::R_TX_BLOCKED_PENDING == state; + State::R_TX_BLOCKED_PENDING == state || + State::R_ALL_BLOCKED_PENDING == state; } inline bool is_pending_() const @@ -956,6 +985,8 @@ public: // @param [in] ls_id: the specifiied ls ID // @param [out] is_all_tx_cleaned_up, set it to true, when all transactions are cleaned up; int block_tx(const share::ObLSID &ls_id, bool &is_all_tx_cleaned_up); + // block tx and readonly request + int block_all(const share::ObLSID &ls_id, bool &is_all_tx_cleaned_up); // Traverse the specified ObLSTxCtxMgr and kill all transactions it holds; // @param [in] ls_id: the specifiied ls ID diff --git a/src/storage/tx/ob_trans_service_v4.cpp b/src/storage/tx/ob_trans_service_v4.cpp index 571844e44..3e66f2d88 100755 --- a/src/storage/tx/ob_trans_service_v4.cpp +++ b/src/storage/tx/ob_trans_service_v4.cpp @@ -2375,6 +2375,27 @@ int ObTransService::block_tx(const share::ObLSID &ls_id, bool &is_all_tx_cleaned return ret; } +int ObTransService::block_all(const share::ObLSID &ls_id, bool &is_all_tx_cleaned_up) +{ + int ret = OB_SUCCESS; + + 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 (!ls_id.is_valid()) { + TRANS_LOG(WARN, "invalid argument", K(ls_id)); + ret = OB_INVALID_ARGUMENT; + } else if (OB_FAIL(tx_ctx_mgr_.block_all(ls_id, is_all_tx_cleaned_up))) { + TRANS_LOG(WARN, "block all error", KR(ret), K(ls_id)); + } else { + TRANS_LOG(INFO, "block all success", K(ls_id), K(is_all_tx_cleaned_up)); + } + return ret; +} + int ObTransService::iterate_tx_ctx_mgr_stat(ObTxCtxMgrStatIterator &tx_ctx_mgr_stat_iter) { int ret = OB_SUCCESS; diff --git a/src/storage/tx/ob_trans_service_v4.h b/src/storage/tx/ob_trans_service_v4.h index 6c323dbe0..b3a26bc23 100644 --- a/src/storage/tx/ob_trans_service_v4.h +++ b/src/storage/tx/ob_trans_service_v4.h @@ -125,6 +125,8 @@ int kill_all_tx(const share::ObLSID &ls_id, const KillTransArg &arg, bool &is_all_tx_cleaned_up); int block_tx(const share::ObLSID &ls_id, bool &is_all_tx_cleaned_up); +// block tx and readonly request +int block_all(const share::ObLSID &ls_id, bool &is_all_tx_cleaned_up); int iterate_ls_id(ObLSIDIterator &ls_id_iter);