fix tx desc reference leak

This commit is contained in:
obdev
2023-02-24 13:14:19 +00:00
committed by ob-robot
parent 50329218dc
commit 5ef5dd6fae

View File

@ -263,6 +263,7 @@ int ObTransService::register_commit_retry_task_(ObTxDesc &tx, int64_t max_delay)
{ {
const int64_t MIN_DELAY = 50 * 1000;// 50ms const int64_t MIN_DELAY = 50 * 1000;// 50ms
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
int saved_ret = OB_SUCCESS;
max_delay = max_delay == INT64_MAX ? ObTransCtx::MAX_TRANS_2PC_TIMEOUT_US : max_delay; max_delay = max_delay == INT64_MAX ? ObTransCtx::MAX_TRANS_2PC_TIMEOUT_US : max_delay;
int64_t now = ObClockGenerator::getClock(); int64_t now = ObClockGenerator::getClock();
int64_t expire_after = std::min(tx.expire_ts_ - now, tx.commit_expire_ts_ - now); int64_t expire_after = std::min(tx.expire_ts_ - now, tx.commit_expire_ts_ - now);
@ -278,6 +279,11 @@ int ObTransService::register_commit_retry_task_(ObTxDesc &tx, int64_t max_delay)
if (OB_FAIL(timer_.register_timeout_task(tx.commit_task_, delay))) { if (OB_FAIL(timer_.register_timeout_task(tx.commit_task_, delay))) {
TRANS_LOG(WARN, "register tx retry task fail", KR(ret), K(delay), K(tx)); TRANS_LOG(WARN, "register tx retry task fail", KR(ret), K(delay), K(tx));
tx_desc_mgr_.revert(tx); tx_desc_mgr_.revert(tx);
if (OB_TIMER_TASK_HAS_SCHEDULED == ret) {
saved_ret = ret;
// rewrite ret
ret = OB_SUCCESS;
}
} }
} }
#ifndef NDEBUG #ifndef NDEBUG
@ -288,7 +294,8 @@ int ObTransService::register_commit_retry_task_(ObTxDesc &tx, int64_t max_delay)
} }
#endif #endif
ObTransTraceLog &tlog = tx.get_tlog(); ObTransTraceLog &tlog = tx.get_tlog();
REC_TRANS_TRACE_EXT(&tlog, register_timeout_task, OB_Y(ret), REC_TRANS_TRACE_EXT(&tlog, register_timeout_task,
OB_ID(ret), OB_SUCCESS != ret ? ret : saved_ret,
OB_ID(arg), delay, OB_ID(arg), delay,
OB_ID(ref), tx.get_ref()); OB_ID(ref), tx.get_ref());
return ret; return ret;
@ -336,16 +343,13 @@ int ObTransService::handle_tx_commit_timeout(ObTxDesc &tx, const int64_t delay)
int32_t ref_cnt = 0; int32_t ref_cnt = 0;
// remember tx_id because tx maybe cleanout and reused // remember tx_id because tx maybe cleanout and reused
// in this function's following steps. // in this function's following steps.
tx.lock_.lock();
auto tx_id = tx.tx_id_; auto tx_id = tx.tx_id_;
int64_t now = ObClockGenerator::getClock(); int64_t now = ObClockGenerator::getClock();
bool cb_executed = false; bool cb_executed = false;
if (OB_FAIL(tx.lock_.lock(5000000))) {
TRANS_LOG(WARN, "failed to acquire lock in specified time", K(tx));
// FIXME: how to handle it without lock protection
} else {
if (!tx.commit_task_.is_registered()){ if (!tx.commit_task_.is_registered()){
TRANS_LOG(INFO, "task canceled", K(tx)); TRANS_LOG(INFO, "task canceled", K(tx));
} else if (FALSE_IT(timer_.unregister_timeout_task(tx.commit_task_))) { } else if (FALSE_IT(tx.commit_task_.set_registered(false))) {
} else if (tx.flags_.RELEASED_) { } else if (tx.flags_.RELEASED_) {
TRANS_LOG(INFO, "tx released, cancel commit retry", K(tx)); TRANS_LOG(INFO, "tx released, cancel commit retry", K(tx));
} else if (tx.state_ != ObTxDesc::State::IN_TERMINATE) { } else if (tx.state_ != ObTxDesc::State::IN_TERMINATE) {
@ -378,7 +382,6 @@ int ObTransService::handle_tx_commit_timeout(ObTxDesc &tx, const int64_t delay)
ref_cnt = tx.get_ref(); ref_cnt = tx.get_ref();
tx.lock_.unlock(); tx.lock_.unlock();
cb_executed = tx.execute_commit_cb(); cb_executed = tx.execute_commit_cb();
}
// NOTE: // NOTE:
// it not safe and meaningless to access tx after commit_cb // it not safe and meaningless to access tx after commit_cb
// has been called, the tx may has been reused or release // has been called, the tx may has been reused or release