[master] fix core by reuse_tx race with rollbacksavepoint msg callback

This commit is contained in:
chinaxing 2023-08-04 09:18:35 +00:00 committed by ob-robot
parent 55d1e8825e
commit fe14ddd19f
3 changed files with 17 additions and 2 deletions

View File

@ -119,6 +119,7 @@ public:
#define OB_TX_ABORT_CAUSE_LIST \
_XX(PARTICIPANT_IS_CLEAN) \
_XX(TX_RESULT_INCOMPLETE) \
_XX(IN_CONSIST_STATE) \
_XX(SAVEPOINT_ROLLBACK_FAIL) \
@ -132,7 +133,6 @@ public:
enum ObTxAbortCause
{
SUCCESS = 0,
#define _XX(X) X,
OB_TX_ABORT_CAUSE_LIST
#undef _XX

View File

@ -380,6 +380,7 @@ int wait_follower_readable_(ObLS &ls,
MonotonicTs get_req_receive_mts_();
bool is_ls_dropped_(const share::ObLSID ls_id);
static bool common_retryable_error_(const int ret);
void direct_execute_commit_cb_(ObTxDesc &tx);
// include tx api refacored for future
public:
#include "ob_tx_api.h"

View File

@ -173,6 +173,11 @@ int ObTransService::reuse_tx(ObTxDesc &tx)
} else if (OB_FAIL(finalize_tx_(tx))) {
TRANS_LOG(WARN, "finalize tx fail", K(ret), K(tx.tx_id_));
} else {
// after finalize tx, the txDesc can not be fetch from TxDescMgr
// but the reference maybe hold by user, wait to be queisenct
// before we reuse it
// if reuse come from commit_cb, assume current thread hold one reference
final_ref_cnt = tx.commit_cb_lock_.self_locked() ? 2 : 1;
while (tx.get_ref() > final_ref_cnt) {
PAUSE();
@ -530,7 +535,7 @@ int ObTransService::submit_commit_tx(ObTxDesc &tx,
DEFER({
tx.lock_.unlock();
if (OB_SUCC(ret) && committed) {
tx.execute_commit_cb();
direct_execute_commit_cb_(tx);
}
});
#ifndef NDEBUG
@ -552,6 +557,15 @@ int ObTransService::submit_commit_tx(ObTxDesc &tx,
return ret;
}
// when callback exec directly, mock the general pattern
// acquire ref -> exec callback -> release ref
void ObTransService::direct_execute_commit_cb_(ObTxDesc &tx)
{
tx.inc_ref(1);
tx.execute_commit_cb();
tx_desc_mgr_.revert(tx);
}
int ObTransService::get_read_snapshot(ObTxDesc &tx,
const ObTxIsolationLevel iso_level,
const int64_t expire_ts,