From a781dd3676a51a210d37be9943b53bbf186823c6 Mon Sep 17 00:00:00 2001 From: obdev Date: Fri, 24 Feb 2023 14:10:44 +0000 Subject: [PATCH] [DeadLock] unregister detector if tx implicit aborted in first write sql --- src/share/deadlock/ob_deadlock_detector_rpc.h | 6 +++--- .../deadlock/ob_lcl_scheme/ob_lcl_node.cpp | 1 - src/sql/ob_sql_trans_control.cpp | 13 ++++++++++++- src/storage/tx/ob_trans_deadlock_adapter.cpp | 17 ++++++++++------- src/storage/tx/ob_trans_deadlock_adapter.h | 3 +++ 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/share/deadlock/ob_deadlock_detector_rpc.h b/src/share/deadlock/ob_deadlock_detector_rpc.h index 5f37456926..b16b344d1d 100644 --- a/src/share/deadlock/ob_deadlock_detector_rpc.h +++ b/src/share/deadlock/ob_deadlock_detector_rpc.h @@ -33,13 +33,13 @@ class ObDetectorRpcProxy : public ObRpcProxy { public: DEFINE_TO(ObDetectorRpcProxy); - RPC_AP(PR5 post_lcl_message, + RPC_AP(PR9 post_lcl_message, OB_DETECTOR_LCL_MESSAGE, (share::detector::ObLCLMessage), Int64); - RPC_AP(PR5 post_collect_info_message, + RPC_AP(PR9 post_collect_info_message, OB_DETECTOR_COLLECT_INFO_MESSAGE, (share::detector::ObDeadLockCollectInfoMessage), Int64); - RPC_AP(PR5 post_notify_parent_message, + RPC_AP(PR9 post_notify_parent_message, OB_DETECTOR_NOTIFY_PARENT_MESSAGE, (share::detector::ObDeadLockNotifyParentMessage), Int64) }; diff --git a/src/share/deadlock/ob_lcl_scheme/ob_lcl_node.cpp b/src/share/deadlock/ob_lcl_scheme/ob_lcl_node.cpp index 9c86114d55..c7ccea5388 100644 --- a/src/share/deadlock/ob_lcl_scheme/ob_lcl_node.cpp +++ b/src/share/deadlock/ob_lcl_scheme/ob_lcl_node.cpp @@ -519,7 +519,6 @@ int ObLCLNode::process_lcl_message(const ObLCLMessage &lcl_msg) int64_t diff = current_ts - lcl_msg.get_send_ts(); if (diff > PHASE_TIME / 3) { DETECT_LOG_(WARN, "phase not match", K(diff), K(current_ts), K(*this)); - ret = OB_ERR_UNEXPECTED; } } else { { diff --git a/src/sql/ob_sql_trans_control.cpp b/src/sql/ob_sql_trans_control.cpp index 7935a167b1..6be94b4f80 100644 --- a/src/sql/ob_sql_trans_control.cpp +++ b/src/sql/ob_sql_trans_control.cpp @@ -837,8 +837,10 @@ int ObSqlTransControl::end_stmt(ObExecContext &exec_ctx, const bool rollback) OZ (get_tx_service(session, txs), *session); // plain select stmt don't require txn descriptor if (OB_SUCC(ret) && !is_plain_select) { - ObTransDeadlockDetectorAdapter::maintain_deadlock_info_when_end_stmt(exec_ctx, rollback); CK (OB_NOT_NULL(tx_desc)); + ObTransID tx_id_before_rollback; + OX (tx_id_before_rollback = tx_desc->get_tx_id()); + OX (ObTransDeadlockDetectorAdapter::maintain_deadlock_info_when_end_stmt(exec_ctx, rollback)); auto &tx_result = session->get_trans_result(); if (OB_FAIL(ret)) { } else if (tx_result.is_incomplete()) { @@ -854,6 +856,15 @@ int ObSqlTransControl::end_stmt(ObExecContext &exec_ctx, const bool rollback) OZ (txs->rollback_to_implicit_savepoint(*tx_desc, savepoint, stmt_expire_ts, &touched_ls), savepoint, stmt_expire_ts, touched_ls); } + // this may happend cause tx may implicit aborted + // (for example: first write sql of implicit started trans meet lock conflict) + // and if associated detector is created, must clean it also + if (OB_NOT_NULL(tx_desc) && tx_desc->get_tx_id() != tx_id_before_rollback) { + ObTransDeadlockDetectorAdapter:: + unregister_from_deadlock_detector(tx_id_before_rollback, + ObTransDeadlockDetectorAdapter:: + UnregisterPath::TX_ROLLBACK_IN_END_STMT); + } } // call end stmt hook if (OB_NOT_NULL(tx_desc) && OB_NOT_NULL(txs) && OB_NOT_NULL(session)) { diff --git a/src/storage/tx/ob_trans_deadlock_adapter.cpp b/src/storage/tx/ob_trans_deadlock_adapter.cpp index 4df58e2cb6..9ce2c9d406 100644 --- a/src/storage/tx/ob_trans_deadlock_adapter.cpp +++ b/src/storage/tx/ob_trans_deadlock_adapter.cpp @@ -354,7 +354,7 @@ int ObTransDeadlockDetectorAdapter::register_remote_execution_to_deadlock_detect on_detect_op, on_collect_op, ~session_guard->get_tx_desc()->get_active_ts(), - 500_ms))) { + 3_s))) { DETECT_LOG(WARN, "fail to register deadlock", PRINT_WRAPPER); } else { MTL(ObDeadLockDetectorMgr*)->set_timeout(self_tx_id, query_timeout); @@ -640,14 +640,14 @@ int ObTransDeadlockDetectorAdapter::maintain_deadlock_info_when_end_stmt(sql::Ob ret = OB_BAD_NULL_ERROR; DETECT_LOG(ERROR, "session is NULL", PRINT_WRAPPER); } else if (session->is_inner()) { - // inner session no need register to deadlock + DETECT_LOG(INFO, "inner session no need register to deadlock", PRINT_WRAPPER); } else if (memtable::TLOCAL_NEED_WAIT_IN_LOCK_WAIT_MGR) { - // will call post_process() in lock_wait_mgr, will register deadlock info there, no need process here + DETECT_LOG(INFO, "thread local flag marked local execution, no need register to deadlock here", PRINT_WRAPPER); } else if (OB_ISNULL(desc = session->get_tx_desc())) { ret = OB_BAD_NULL_ERROR; DETECT_LOG(ERROR, "desc in session is NULL", PRINT_WRAPPER); } else if (!desc->is_valid()) { - // no trans opened, for example:read-only trans + DETECT_LOG(INFO, "invalid tx desc no need register to deadlock", PRINT_WRAPPER); } else if (is_rollback) {// statment is failed, maybe will try again, check if need register to deadlock detector if (session->get_query_timeout_ts() < ObClockGenerator::getCurrentTime()) { unregister_from_deadlock_detector(desc->tid(), UnregisterPath::END_STMT_TIMEOUT); @@ -665,13 +665,16 @@ int ObTransDeadlockDetectorAdapter::maintain_deadlock_info_when_end_stmt(sql::Ob conflict_txs))) { DETECT_LOG(WARN, "register or replace list failed", PRINT_WRAPPER); } else { - desc->reset_conflict_txs(); - DETECT_LOG(TRACE, "maintain deadlock info when end_stmt", PRINT_WRAPPER); + // do nothing, register success or keep retrying } } else {// statment is done, will not try again, all related deadlock info should be resetted unregister_from_deadlock_detector(desc->tid(), UnregisterPath::END_STMT_DONE); - DETECT_LOG(TRACE, "unregister from deadlock detector", KR(ret), K(desc->tid())); + DETECT_LOG(INFO, "try unregister from deadlock detector", KR(ret), K(desc->tid())); } + if (OB_NOT_NULL(desc)) {// whether registered or not, clean conflict info anyway + desc->reset_conflict_txs(); + } + DETECT_LOG(INFO, "maintain deadlock info", PRINT_WRAPPER); return ret; #undef PRINT_WRAPPER } diff --git a/src/storage/tx/ob_trans_deadlock_adapter.h b/src/storage/tx/ob_trans_deadlock_adapter.h index 5378fd9fd3..35ae161c15 100644 --- a/src/storage/tx/ob_trans_deadlock_adapter.h +++ b/src/storage/tx/ob_trans_deadlock_adapter.h @@ -78,6 +78,7 @@ class ObTransDeadlockDetectorAdapter END_STMT_TIMEOUT, REPLACE_MEET_TOTAL_DIFFERENT_LIST, DO_END_TRANS, + TX_ROLLBACK_IN_END_STMT, }; static const char* to_string(const UnregisterPath path) { @@ -102,6 +103,8 @@ class ObTransDeadlockDetectorAdapter return "REPLACE_MEET_TOTAL_DIFFERENT_LIST"; case UnregisterPath::DO_END_TRANS: return "DO_END_TRANS"; + case UnregisterPath::TX_ROLLBACK_IN_END_STMT: + return "TX_ROLLBACK_IN_END_STMT"; default: return "UNKNOWN"; }