[DeadLock] unregister detector if tx implicit aborted in first write sql
This commit is contained in:
@ -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)
|
||||
};
|
||||
|
@ -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 {
|
||||
{
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
||||
|
Reference in New Issue
Block a user