Return recycled scn when tx data is not existed in sstable

This commit is contained in:
ZenoWang
2023-06-09 04:48:09 +00:00
committed by ob-robot
parent 86e6f9684e
commit 9fac17b4b2
10 changed files with 57 additions and 26 deletions

View File

@ -1818,11 +1818,12 @@ int ObTransService::get_tx_state_from_tx_table_(const share::ObLSID &lsid,
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObTxTableGuard tx_table_guard; ObTxTableGuard tx_table_guard;
int64_t _state = 0; int64_t _state = 0;
SCN recycled_scn;
if (OB_FAIL(get_tx_table_guard_(NULL, lsid, tx_table_guard))) { if (OB_FAIL(get_tx_table_guard_(NULL, lsid, tx_table_guard))) {
TRANS_LOG(WARN, "get tx table guard failed", KR(ret), K(lsid), KPC(this)); TRANS_LOG(WARN, "get tx table guard failed", KR(ret), K(lsid), KPC(this));
} else if (!tx_table_guard.is_valid()) { } else if (!tx_table_guard.is_valid()) {
TRANS_LOG(WARN, "tx table is null", KR(ret), K(lsid), KPC(this)); TRANS_LOG(WARN, "tx table is null", KR(ret), K(lsid), KPC(this));
} else if (OB_FAIL(tx_table_guard.try_get_tx_state(tx_id, _state, commit_version))) { } else if (OB_FAIL(tx_table_guard.try_get_tx_state(tx_id, _state, commit_version, recycled_scn))) {
TRANS_LOG(WARN, "get tx state failed", KR(ret), K(lsid), K(tx_id), KPC(this)); TRANS_LOG(WARN, "get tx state failed", KR(ret), K(lsid), K(tx_id), KPC(this));
} else { } else {
state = (int)_state; state = (int)_state;

View File

@ -452,7 +452,10 @@ int ObTxDataTable::insert_(ObTxData *&tx_data, ObTxDataMemtableWriteGuard &write
return ret; return ret;
} }
int ObTxDataTable::check_with_tx_data(const ObTransID tx_id, ObITxDataCheckFunctor &fn, ObTxDataGuard &tx_data_guard) int ObTxDataTable::check_with_tx_data(const ObTransID tx_id,
ObITxDataCheckFunctor &fn,
ObTxDataGuard &tx_data_guard,
SCN &recycled_scn)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (IS_NOT_INIT) { if (IS_NOT_INIT) {
@ -461,7 +464,7 @@ int ObTxDataTable::check_with_tx_data(const ObTransID tx_id, ObITxDataCheckFunct
} else if (OB_SUCC(check_tx_data_in_memtable_(tx_id, fn, tx_data_guard))) { } else if (OB_SUCC(check_tx_data_in_memtable_(tx_id, fn, tx_data_guard))) {
// successfully do check function in memtable, check done // successfully do check function in memtable, check done
STORAGE_LOG(DEBUG, "tx data table check with tx memtable data succeed", K(tx_id), K(fn)); STORAGE_LOG(DEBUG, "tx data table check with tx memtable data succeed", K(tx_id), K(fn));
} else if (OB_TRANS_CTX_NOT_EXIST == ret && OB_SUCC(check_tx_data_in_sstable_(tx_id, fn, tx_data_guard))) { } else if (OB_TRANS_CTX_NOT_EXIST == ret && OB_SUCC(check_tx_data_in_sstable_(tx_id, fn, tx_data_guard, recycled_scn))) {
// successfully do check function in sstable // successfully do check function in sstable
STORAGE_LOG(DEBUG, "tx data table check with tx sstable data succeed", K(tx_id), K(fn)); STORAGE_LOG(DEBUG, "tx data table check with tx sstable data succeed", K(tx_id), K(fn));
} else { } else {
@ -669,7 +672,8 @@ int ObTxDataTable::get_tx_data_in_memtables_cache_(const ObTransID tx_id,
int ObTxDataTable::check_tx_data_in_sstable_(const ObTransID tx_id, int ObTxDataTable::check_tx_data_in_sstable_(const ObTransID tx_id,
ObITxDataCheckFunctor &fn, ObITxDataCheckFunctor &fn,
ObTxDataGuard &tx_data_guard) ObTxDataGuard &tx_data_guard,
SCN &recycled_scn)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
tx_data_guard.reset(); tx_data_guard.reset();
@ -679,7 +683,7 @@ int ObTxDataTable::check_tx_data_in_sstable_(const ObTransID tx_id,
} else if (OB_ISNULL(tx_data_guard.tx_data())) { } else if (OB_ISNULL(tx_data_guard.tx_data())) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
STORAGE_LOG(WARN, "tx data is unexpected null", KR(ret), K(tx_data_guard)); STORAGE_LOG(WARN, "tx data is unexpected null", KR(ret), K(tx_data_guard));
} else if (OB_FAIL(get_tx_data_in_sstable_(tx_id, *tx_data_guard.tx_data()))) { } else if (OB_FAIL(get_tx_data_in_sstable_(tx_id, *tx_data_guard.tx_data(), recycled_scn))) {
STORAGE_LOG(WARN, "get tx data from sstable failed.", KR(ret), K(tx_id)); STORAGE_LOG(WARN, "get tx data from sstable failed.", KR(ret), K(tx_id));
} else { } else {
EVENT_INC(ObStatEventIds::TX_DATA_READ_TX_DATA_SSTABLE_COUNT); EVENT_INC(ObStatEventIds::TX_DATA_READ_TX_DATA_SSTABLE_COUNT);
@ -695,7 +699,7 @@ int ObTxDataTable::check_tx_data_in_sstable_(const ObTransID tx_id,
return ret; return ret;
} }
int ObTxDataTable::get_tx_data_in_sstable_(const transaction::ObTransID tx_id, ObTxData &tx_data) int ObTxDataTable::get_tx_data_in_sstable_(const transaction::ObTransID tx_id, ObTxData &tx_data, share::SCN &recycled_scn)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObTableIterParam iter_param = read_schema_.iter_param_; ObTableIterParam iter_param = read_schema_.iter_param_;
@ -711,7 +715,7 @@ int ObTxDataTable::get_tx_data_in_sstable_(const transaction::ObTransID tx_id, O
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid tablet handle", KR(ret), K(tablet_handle), K(tablet_id_)); LOG_WARN("invalid tablet handle", KR(ret), K(tablet_handle), K(tablet_id_));
} else { } else {
ObTxDataSingleRowGetter getter(iter_param, slice_allocator_); ObTxDataSingleRowGetter getter(iter_param, slice_allocator_, recycled_scn);
if (OB_FAIL(getter.init(tx_id))) { if (OB_FAIL(getter.init(tx_id))) {
STORAGE_LOG(WARN, "init ObTxDataSingleRowGetter fail.", KR(ret), KP(this), K(tablet_id_)); STORAGE_LOG(WARN, "init ObTxDataSingleRowGetter fail.", KR(ret), KP(this), K(tablet_id_));
} else if (OB_FAIL(getter.get_next_row(tx_data))) { } else if (OB_FAIL(getter.get_next_row(tx_data))) {
@ -1269,6 +1273,7 @@ int ObTxDataTable::supplement_undo_actions_if_exist(ObTxData *tx_data)
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObTxData tx_data_from_sstable; ObTxData tx_data_from_sstable;
tx_data_from_sstable.reset(); tx_data_from_sstable.reset();
SCN unused_scn;
if (IS_NOT_INIT) { if (IS_NOT_INIT) {
ret = OB_NOT_INIT; ret = OB_NOT_INIT;
@ -1276,7 +1281,7 @@ int ObTxDataTable::supplement_undo_actions_if_exist(ObTxData *tx_data)
} else if (OB_ISNULL(tx_data)) { } else if (OB_ISNULL(tx_data)) {
ret = OB_INVALID_ARGUMENT; ret = OB_INVALID_ARGUMENT;
STORAGE_LOG(ERROR, "tx data is nullptr", KR(ret), KP(this)); STORAGE_LOG(ERROR, "tx data is nullptr", KR(ret), KP(this));
} else if (OB_FAIL(get_tx_data_in_sstable_(tx_data->tx_id_, tx_data_from_sstable))) { } else if (OB_FAIL(get_tx_data_in_sstable_(tx_data->tx_id_, tx_data_from_sstable, unused_scn))) {
if (ret == OB_TRANS_CTX_NOT_EXIST) { if (ret == OB_TRANS_CTX_NOT_EXIST) {
// This transaction does not have undo actions // This transaction does not have undo actions
ret = OB_SUCCESS; ret = OB_SUCCESS;
@ -1377,8 +1382,9 @@ int ObTxDataTable::dump_tx_data_in_sstable_2_text_(const ObTransID tx_id, FILE *
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObTxData tx_data; ObTxData tx_data;
tx_data.reset(); tx_data.reset();
SCN unused_scn;
if (OB_FAIL(get_tx_data_in_sstable_(tx_id, tx_data))) { if (OB_FAIL(get_tx_data_in_sstable_(tx_id, tx_data, unused_scn))) {
STORAGE_LOG(WARN, "get tx data from sstable failed.", KR(ret), K(tx_id)); STORAGE_LOG(WARN, "get tx data from sstable failed.", KR(ret), K(tx_id));
} else { } else {
fprintf(fd, "********** Tx Data SSTable ***********\n\n"); fprintf(fd, "********** Tx Data SSTable ***********\n\n");

View File

@ -195,7 +195,10 @@ public: // ObTxDataTable
* @param[in] tx_id the tx id of the transaction to be checked * @param[in] tx_id the tx id of the transaction to be checked
* @param[in] fn the functor which is dealt with tx data * @param[in] fn the functor which is dealt with tx data
*/ */
virtual int check_with_tx_data(const transaction::ObTransID tx_id, ObITxDataCheckFunctor &fn, ObTxDataGuard &tx_data_guard); virtual int check_with_tx_data(const transaction::ObTransID tx_id,
ObITxDataCheckFunctor &fn,
ObTxDataGuard &tx_data_guard,
share::SCN &recycled_scn);
/** /**
* @brief See ObTxTable::get_recycle_scn * @brief See ObTxTable::get_recycle_scn
@ -266,11 +269,14 @@ private:
int get_tx_data_from_cache_(const transaction::ObTransID tx_id, ObTxDataGuard &tx_data_guard, bool &find); int get_tx_data_from_cache_(const transaction::ObTransID tx_id, ObTxDataGuard &tx_data_guard, bool &find);
int check_tx_data_in_sstable_(const transaction::ObTransID tx_id, ObITxDataCheckFunctor &fn, ObTxDataGuard &tx_data_guard); int check_tx_data_in_sstable_(const transaction::ObTransID tx_id,
ObITxDataCheckFunctor &fn,
ObTxDataGuard &tx_data_guard,
share::SCN &recycled_scn);
int get_tx_data_in_cache_(const transaction::ObTransID tx_id, ObTxData *&tx_data); int get_tx_data_in_cache_(const transaction::ObTransID tx_id, ObTxData *&tx_data);
int get_tx_data_in_sstable_(const transaction::ObTransID tx_id, ObTxData &tx_data); int get_tx_data_in_sstable_(const transaction::ObTransID tx_id, ObTxData &tx_data, share::SCN &recycled_scn);
int insert_(ObTxData *&tx_data, ObTxDataMemtableWriteGuard &write_guard); int insert_(ObTxData *&tx_data, ObTxDataMemtableWriteGuard &write_guard);

View File

@ -826,9 +826,10 @@ int ObTxTable::check_tx_data_in_tables_(ObReadTxDataArg &read_tx_data_arg, ObITx
} else if (OB_TRANS_CTX_NOT_EXIST == ret) { } else if (OB_TRANS_CTX_NOT_EXIST == ret) {
ObTxDataGuard tx_data_guard; ObTxDataGuard tx_data_guard;
ObTxData *tx_data = nullptr; ObTxData *tx_data = nullptr;
SCN recycled_scn;
// read tx data from tx data table and get tx data guard // read tx data from tx data table and get tx data guard
if (OB_FAIL(tx_data_table_.check_with_tx_data(read_tx_data_arg.tx_id_, fn, tx_data_guard))) { if (OB_FAIL(tx_data_table_.check_with_tx_data(read_tx_data_arg.tx_id_, fn, tx_data_guard, recycled_scn))) {
if (OB_ITER_END == ret) { if (OB_ITER_END == ret) {
ret = OB_TRANS_CTX_NOT_EXIST; ret = OB_TRANS_CTX_NOT_EXIST;
} }
@ -838,6 +839,7 @@ int ObTxTable::check_tx_data_in_tables_(ObReadTxDataArg &read_tx_data_arg, ObITx
K(ls_id_), K(ls_id_),
K(read_tx_data_arg), K(read_tx_data_arg),
K(tx_data_guard), K(tx_data_guard),
K(recycled_scn),
"state", get_state_string(state_)); "state", get_state_string(state_));
} else if (OB_NOT_NULL(tx_data = tx_data_guard.tx_data())) { } else if (OB_NOT_NULL(tx_data = tx_data_guard.tx_data())) {
// if tx data is not null, put tx data into cache // if tx data is not null, put tx data into cache
@ -947,7 +949,10 @@ int ObTxTable::get_tx_state_with_scn(ObReadTxDataArg &read_tx_data_arg,
return ret; return ret;
} }
int ObTxTable::try_get_tx_state(ObReadTxDataArg &read_tx_data_arg, int64_t &state, SCN &trans_version) int ObTxTable::try_get_tx_state(ObReadTxDataArg &read_tx_data_arg,
int64_t &state,
SCN &trans_version,
SCN &recycled_scn)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
GetTxStateWithSCNFunctor fn(SCN::max_scn(), state, trans_version); GetTxStateWithSCNFunctor fn(SCN::max_scn(), state, trans_version);
@ -956,7 +961,7 @@ int ObTxTable::try_get_tx_state(ObReadTxDataArg &read_tx_data_arg, int64_t &stat
LOG_WARN("tx table is not init.", KR(ret), K(read_tx_data_arg)); LOG_WARN("tx table is not init.", KR(ret), K(read_tx_data_arg));
} else { } else {
ObTxDataGuard tx_data_guard; ObTxDataGuard tx_data_guard;
ret = tx_data_table_.check_with_tx_data(read_tx_data_arg.tx_id_, fn, tx_data_guard); ret = tx_data_table_.check_with_tx_data(read_tx_data_arg.tx_id_, fn, tx_data_guard, recycled_scn);
if (OB_ITER_END == ret) { if (OB_ITER_END == ret) {
ret = OB_TRANS_CTX_NOT_EXIST; ret = OB_TRANS_CTX_NOT_EXIST;
} }

View File

@ -162,8 +162,9 @@ public:
* @param[in] read_epoch * @param[in] read_epoch
* @param[out] state * @param[out] state
* @param[out] trans_version * @param[out] trans_version
* @param[out] recycled_scn only if tx data is not exist, recycled_scn would be assigned
*/ */
int try_get_tx_state(ObReadTxDataArg &read_tx_data_arg, int64_t &state, share::SCN &trans_version); int try_get_tx_state(ObReadTxDataArg &read_tx_data_arg, int64_t &state, share::SCN &trans_version, share::SCN &recycled_scn);
/** /**
* @brief the txn READ_TRANS_ID use SNAPSHOT_VERSION to read the data, and check whether the data is locked, readable or unreadable by txn DATA_TRANS_ID. READ_LATEST is used to check whether read the data belong to the same txn * @brief the txn READ_TRANS_ID use SNAPSHOT_VERSION to read the data, and check whether the data is locked, readable or unreadable by txn DATA_TRANS_ID. READ_LATEST is used to check whether read the data belong to the same txn

View File

@ -72,11 +72,14 @@ int ObTxTableGuard::get_tx_state_with_scn(const transaction::ObTransID tx_id,
} }
} }
int ObTxTableGuard::try_get_tx_state(const transaction::ObTransID tx_id, int64_t &state, share::SCN &trans_version) int ObTxTableGuard::try_get_tx_state(const transaction::ObTransID tx_id,
int64_t &state,
share::SCN &trans_version,
share::SCN &recycled_scn)
{ {
if (OB_NOT_NULL(tx_table_)) { if (OB_NOT_NULL(tx_table_)) {
ObReadTxDataArg arg(tx_id, epoch_, mini_cache_); ObReadTxDataArg arg(tx_id, epoch_, mini_cache_);
return tx_table_->try_get_tx_state(arg, state, trans_version); return tx_table_->try_get_tx_state(arg, state, trans_version, recycled_scn);
} else { } else {
return OB_NOT_INIT; return OB_NOT_INIT;
} }

View File

@ -69,7 +69,10 @@ public: // dalegate functions
int64_t &state, int64_t &state,
share::SCN &trans_version); share::SCN &trans_version);
int try_get_tx_state(const transaction::ObTransID tx_id, int64_t &state, share::SCN &trans_version); int try_get_tx_state(const transaction::ObTransID tx_id,
int64_t &state,
share::SCN &trans_version,
share::SCN &recycled_scn);
int lock_for_read(const transaction::ObLockForReadArg &lock_for_read_arg, int lock_for_read(const transaction::ObLockForReadArg &lock_for_read_arg,
bool &can_read, bool &can_read,

View File

@ -430,9 +430,10 @@ int ObTxDataSingleRowGetter::get_next_row(ObTxData &tx_data)
ret = get_next_row_(sstables, tx_data); ret = get_next_row_(sstables, tx_data);
if (OB_TIMEOUT == ret || OB_DISK_HUNG == ret) { if (OB_TIMEOUT == ret || OB_DISK_HUNG == ret) {
ret = OB_EAGAIN; ret = OB_EAGAIN;
STORAGE_LOG(WARN, STORAGE_LOG(WARN, "modify ret code from OB_TIMEOUT or OB_DISK_HUNG to OB_EAGAIN", KR(ret));
"modify ret code from OB_TIMEOUT or OB_DISK_HUNG to OB_EAGAIN", } else if (OB_FAIL(ret)) {
KR(ret)); recycled_scn_ = static_cast<ObSSTable*>(sstables[0])->get_filled_tx_scn();
STORAGE_LOG(WARN, "get tx data from sstable failed", K(recycled_scn_));
} }
} }
} }

View File

@ -172,9 +172,10 @@ class ObTxDataSingleRowGetter
{ {
using SliceAllocator = ObSliceAlloc; using SliceAllocator = ObSliceAlloc;
public: public:
ObTxDataSingleRowGetter(const ObTableIterParam & iter_param, ObTxDataSingleRowGetter(const ObTableIterParam &iter_param,
SliceAllocator &slice_allocator) SliceAllocator &slice_allocator,
: iter_param_(iter_param), slice_allocator_(slice_allocator), key_datums_() {} share::SCN &recycled_scn)
: iter_param_(iter_param), slice_allocator_(slice_allocator), recycled_scn_(recycled_scn), key_datums_() {}
virtual ~ObTxDataSingleRowGetter() {} virtual ~ObTxDataSingleRowGetter() {}
/** /**
@ -198,6 +199,7 @@ private:
private: private:
const ObTableIterParam &iter_param_; const ObTableIterParam &iter_param_;
SliceAllocator &slice_allocator_; SliceAllocator &slice_allocator_;
share::SCN &recycled_scn_;
transaction::ObTransID tx_id_; transaction::ObTransID tx_id_;
ObArenaAllocator arena_allocator_; ObArenaAllocator arena_allocator_;
blocksstable::ObStorageDatum key_datums_[2]; blocksstable::ObStorageDatum key_datums_[2];

View File

@ -100,7 +100,10 @@ public:
OZ (map_.insert(tx_data->tx_id_, tx_data)); OZ (map_.insert(tx_data->tx_id_, tx_data));
return ret; return ret;
} }
virtual int check_with_tx_data(const ObTransID tx_id, ObITxDataCheckFunctor &fn, ObTxDataGuard &tx_data_guard) override virtual int check_with_tx_data(const ObTransID tx_id,
ObITxDataCheckFunctor &fn,
ObTxDataGuard &tx_data_guard,
share::SCN &recycled_scn) override
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
OZ (map_.get(tx_id, tx_data_guard)); OZ (map_.get(tx_id, tx_data_guard));