From d81d5c2a0017a9900f34f695451b0342d2673d2e Mon Sep 17 00:00:00 2001 From: chinaxing Date: Fri, 24 Feb 2023 13:30:24 +0000 Subject: [PATCH] [master] fix xa-tx free-route check alive --- src/sql/ob_sql_trans_control.cpp | 39 +++++++++++++------------ src/storage/tx/ob_tx_api.cpp | 4 ++- src/storage/tx/ob_tx_free_route_rpc.cpp | 8 +++-- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/sql/ob_sql_trans_control.cpp b/src/sql/ob_sql_trans_control.cpp index 73bebd3521..7935a167b1 100644 --- a/src/sql/ob_sql_trans_control.cpp +++ b/src/sql/ob_sql_trans_control.cpp @@ -337,29 +337,33 @@ int ObSqlTransControl::kill_tx(ObSQLSessionInfo *session, int cause) auto session_id = session->get_sessid(); LOG_INFO("begin to kill tx", K(cause), K(session_id), KPC(session)); int ret = OB_SUCCESS; - if (session->is_in_transaction() && !session->is_txn_free_route_temp()) { + if (session->is_in_transaction()) { transaction::ObTxDesc *tx_desc = session->get_tx_desc(); auto tx_tenant_id = tx_desc->get_tenant_id(); const ObTransID tx_id = tx_desc->get_tx_id(); + auto tx_free_route_tmp = session->is_txn_free_route_temp(); MTL_SWITCH(tx_tenant_id) { - if (tx_desc->is_xa_trans()) { + if (tx_free_route_tmp) { + // if XA-txn is on this server, we have acquired its ref, release ref + // and disassocate with session + if (tx_desc->is_xa_trans() && tx_desc->get_addr() == GCONF.self_addr_) { + auto txs = MTL(transaction::ObTransService*); + CK (OB_NOT_NULL(txs)); + OZ (txs->release_tx_ref(*tx_desc)); + OX (session->get_tx_desc() = NULL); + } + } else if (tx_desc->is_xa_trans()) { const transaction::ObXATransID xid = session->get_xid(); const transaction::ObGlobalTxType global_tx_type = tx_desc->get_global_tx_type(xid); + auto xas = MTL(transaction::ObXAService *); + CK (OB_NOT_NULL(xas)); if (transaction::ObGlobalTxType::XA_TRANS == global_tx_type) { - if (OB_FAIL(MTL(transaction::ObXAService *)->handle_terminate_for_xa_branch( - session->get_xid(), tx_desc, session->get_xa_end_timeout_seconds()))) { - LOG_WARN("rollback xa trans fail", K(ret), K(xid), K(global_tx_type), K(session_id), - K(tx_id)); - } else { - // currently, tx_desc is NULL - } + OZ (xas->handle_terminate_for_xa_branch(session->get_xid(), tx_desc, session->get_xa_end_timeout_seconds()), + xid, global_tx_type, session_id, tx_id); + // currently, tx_desc is NULL } else if (transaction::ObGlobalTxType::DBLINK_TRANS == global_tx_type) { - if (OB_FAIL(MTL(transaction::ObXAService *)->rollback_for_dblink_trans(tx_desc))) { - LOG_WARN("fail to rollback for dblink trans", K(ret), K(xid), K(global_tx_type), - K(tx_id)); - } else { - // currently, tx_desc is NULL - } + OZ (xas->rollback_for_dblink_trans(tx_desc), ret, xid, global_tx_type, tx_id); + // currently, tx_desc is NULL } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected global trans type", K(ret), K(xid), K(global_tx_type), K(tx_id)); @@ -367,12 +371,11 @@ int ObSqlTransControl::kill_tx(ObSQLSessionInfo *session, int cause) session->get_tx_desc() = NULL; } else { transaction::ObTransService *txs = NULL; - CK(OB_NOT_NULL(txs = MTL_WITH_CHECK_TENANT(transaction::ObTransService*, - tx_tenant_id))); + CK(OB_NOT_NULL(txs = MTL_WITH_CHECK_TENANT(transaction::ObTransService*, tx_tenant_id))); OZ(txs->abort_tx(*tx_desc, cause), *session, tx_desc->get_tx_id()); } // NOTE that the tx_desc is set to NULL in xa case, DO NOT print anything in tx_desc - LOG_INFO("kill tx done", K(ret), K(cause), K(session_id), K(tx_id)); + LOG_INFO("kill tx done", K(ret), K(cause), K(session_id), K(tx_id), K(tx_free_route_tmp)); } } return ret; diff --git a/src/storage/tx/ob_tx_api.cpp b/src/storage/tx/ob_tx_api.cpp index fef6f01db4..ed7e2ead37 100644 --- a/src/storage/tx/ob_tx_api.cpp +++ b/src/storage/tx/ob_tx_api.cpp @@ -1774,7 +1774,9 @@ int ObTransService::sql_stmt_start_hook(const ObXATransID &xid, ObTxDesc &tx, co TRANS_LOG(WARN, "need rollback", K(ret), K(global_tx_type), K(xid)); } } - } else { + } else if (tx.is_xa_tightly_couple()) { + // loosely couple mode txn-route use session_id to detect xa-start node's alive + // so, can not overwrite session_id tx.set_sessid(session_id); } if (OB_FAIL(ret) && registed) { diff --git a/src/storage/tx/ob_tx_free_route_rpc.cpp b/src/storage/tx/ob_tx_free_route_rpc.cpp index b800890a92..543b5226e4 100644 --- a/src/storage/tx/ob_tx_free_route_rpc.cpp +++ b/src/storage/tx/ob_tx_free_route_rpc.cpp @@ -80,6 +80,7 @@ int ObTxFreeRouteCheckAliveRespP::kill_session_() sql::ObSQLSessionInfo *session = NULL; if (OB_SUCC(guard.get_session(session))) { if (session->get_is_in_retry()) { + // TODO: only kill session when it is idle } else if (OB_FAIL(GCTX.session_mgr_->kill_session(*session))) { TRANS_LOG(WARN, "kill session fail", K(ret)); } @@ -95,9 +96,10 @@ int ObTxFreeRouteCheckAliveRespP::release_session_tx_() if (OB_FAIL(guard.get_session(session))) { } else if (session->get_is_in_retry()) { // skip quit txn if session in Query Retry + } else if (OB_FAIL(session->try_lock_query())) { + } else if (OB_FAIL(session->try_lock_thread_data())) { + session->unlock_query(); } else { - sql::ObSQLSessionInfo::LockGuard query_lock_guard(session->get_query_lock()); - sql::ObSQLSessionInfo::LockGuard data_lock_guard(session->get_thread_data_lock()); auto &ctx = session->get_txn_free_route_ctx(); auto &tx_desc = session->get_tx_desc(); if (ctx.get_local_version() != arg_.request_id_) { @@ -124,6 +126,8 @@ int ObTxFreeRouteCheckAliveRespP::release_session_tx_() TRANS_LOG(INFO, "[txn free route] release tx success"); } } + session->unlock_query(); + session->unlock_thread_data(); } return ret; }