Skip retain ctx when record min_start_scn in ctx
This commit is contained in:
@ -100,6 +100,14 @@ int ObCtxTxData::insert_into_tx_table()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ObCtxTxData::is_decided() const
|
||||||
|
{
|
||||||
|
// ATTENTION! : decided means the callback function of commit_log/abort_log has been called and the tx_data has been
|
||||||
|
// inserted into TxDataTable. The read_only_ flag is set as true after inserting into tx data table.
|
||||||
|
RLockGuard guard(lock_);
|
||||||
|
return read_only_;
|
||||||
|
}
|
||||||
|
|
||||||
int ObCtxTxData::recover_tx_data(ObTxData *tmp_tx_data)
|
int ObCtxTxData::recover_tx_data(ObTxData *tmp_tx_data)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
|
|||||||
@ -38,6 +38,7 @@ public:
|
|||||||
|
|
||||||
bool is_read_only() const { return read_only_; }
|
bool is_read_only() const { return read_only_; }
|
||||||
bool has_recovered_from_tx_table() const { return recovered_from_tx_table_; }
|
bool has_recovered_from_tx_table() const { return recovered_from_tx_table_; }
|
||||||
|
bool is_decided() const;
|
||||||
share::SCN get_max_replayed_rollback_scn() const { return max_replayed_rollback_scn_; }
|
share::SCN get_max_replayed_rollback_scn() const { return max_replayed_rollback_scn_; }
|
||||||
void set_max_replayed_rollback_scn(const share::SCN &scn) { max_replayed_rollback_scn_ = scn; }
|
void set_max_replayed_rollback_scn(const share::SCN &scn) { max_replayed_rollback_scn_ = scn; }
|
||||||
int insert_into_tx_table();
|
int insert_into_tx_table();
|
||||||
|
|||||||
@ -1143,14 +1143,15 @@ int ObLSTxCtxMgr::check_scheduler_status(SCN &min_start_scn, MinStartScnStatus &
|
|||||||
IteratePartCtxAskSchedulerStatusFunctor functor;
|
IteratePartCtxAskSchedulerStatusFunctor functor;
|
||||||
if (OB_FAIL(ls_tx_ctx_map_.for_each(functor))) {
|
if (OB_FAIL(ls_tx_ctx_map_.for_each(functor))) {
|
||||||
TRANS_LOG(WARN, "for each transaction context error", KR(ret), "manager", *this);
|
TRANS_LOG(WARN, "for each transaction context error", KR(ret), "manager", *this);
|
||||||
|
} else if (!min_start_scn.is_valid()) {
|
||||||
|
// The default min_start_scn must be valid, or skip writting HAS_CTX/NO_CTX CLOG
|
||||||
|
status = MinStartScnStatus::UNKOWN;
|
||||||
} else {
|
} else {
|
||||||
if (0 == ls_tx_ctx_map_.count()) {
|
// use smaller one between max_decided_scn and min_start_scn of all tx ctx
|
||||||
min_start_scn.reset();
|
TRANS_LOG(DEBUG, "set min start scn", K(min_start_scn), K(functor.get_min_start_scn()));
|
||||||
status = MinStartScnStatus::NO_CTX;
|
min_start_scn = std::min(min_start_scn, functor.get_min_start_scn());
|
||||||
} else {
|
|
||||||
min_start_scn = functor.get_min_start_scn();
|
status = functor.get_min_start_status();
|
||||||
status = functor.get_min_start_status();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@ -1378,6 +1378,8 @@ public:
|
|||||||
IteratePartCtxAskSchedulerStatusFunctor()
|
IteratePartCtxAskSchedulerStatusFunctor()
|
||||||
{
|
{
|
||||||
SET_EXPIRED_LIMIT(100 * 1000 /*100ms*/, 3 * 1000 * 1000 /*3s*/);
|
SET_EXPIRED_LIMIT(100 * 1000 /*100ms*/, 3 * 1000 * 1000 /*3s*/);
|
||||||
|
first_err_code_ = OB_SUCCESS;
|
||||||
|
has_start_scn_ctx_cnt_ = 0;
|
||||||
min_start_scn_.set_max();
|
min_start_scn_.set_max();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1390,24 +1392,29 @@ public:
|
|||||||
ret = OB_INVALID_ARGUMENT;
|
ret = OB_INVALID_ARGUMENT;
|
||||||
TRANS_LOG(WARN, "invalid argument", KR(ret), K(tx_id), "ctx", OB_P(tx_ctx));
|
TRANS_LOG(WARN, "invalid argument", KR(ret), K(tx_id), "ctx", OB_P(tx_ctx));
|
||||||
} else {
|
} else {
|
||||||
share::SCN ctx_start_scn = tx_ctx->get_start_log_ts();
|
// logic for get min_start_scn
|
||||||
if (!ctx_start_scn.is_valid()) {
|
if (tx_ctx->is_decided()) {
|
||||||
ctx_start_scn.set_max();
|
TRANS_LOG(DEBUG, "skip record committed tx", KPC(tx_ctx));
|
||||||
|
} else if (tx_ctx->get_start_log_ts().is_valid()) {
|
||||||
|
has_start_scn_ctx_cnt_++;
|
||||||
|
min_start_scn_ = MIN(min_start_scn_, tx_ctx->get_start_log_ts());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OB_FALSE_IT(min_start_scn_ = MIN(min_start_scn_, ctx_start_scn))) {
|
// logic for gc tx ctx
|
||||||
// do nothing
|
int tmp_ret = OB_SUCCESS;
|
||||||
} else if (OB_FAIL(tx_ctx->check_scheduler_status())) {
|
if (OB_TMP_FAIL(tx_ctx->check_scheduler_status())) {
|
||||||
TRANS_LOG(WARN, "check scheduler status error", KR(ret), "ctx", *tx_ctx);
|
TRANS_LOG(WARN, "check scheduler status error", KR(tmp_ret), "ctx", *tx_ctx);
|
||||||
} else {
|
|
||||||
// do nothing
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
min_start_scn_.reset();
|
min_start_scn_.reset();
|
||||||
|
has_start_scn_ctx_cnt_ = 0;
|
||||||
|
if (OB_SUCCESS == first_err_code_) {
|
||||||
|
// record first error code if exist
|
||||||
|
first_err_code_ = ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1417,15 +1424,29 @@ public:
|
|||||||
{
|
{
|
||||||
MinStartScnStatus start_status = MinStartScnStatus::HAS_CTX;
|
MinStartScnStatus start_status = MinStartScnStatus::HAS_CTX;
|
||||||
|
|
||||||
if (!min_start_scn_.is_valid()) {
|
if (OB_SUCCESS != first_err_code_) {
|
||||||
start_status = MinStartScnStatus::UNKOWN;
|
start_status = MinStartScnStatus::UNKOWN;
|
||||||
} else if (min_start_scn_.is_max()) {
|
} else if (!min_start_scn_.is_valid()) {
|
||||||
|
start_status = MinStartScnStatus::UNKOWN;
|
||||||
|
} else if (0 == has_start_scn_ctx_cnt_ || min_start_scn_.is_max()) {
|
||||||
start_status = MinStartScnStatus::NO_CTX;
|
start_status = MinStartScnStatus::NO_CTX;
|
||||||
|
if ((0 == has_start_scn_ctx_cnt_) && (!min_start_scn_.is_max())) {
|
||||||
|
TRANS_LOG_RET(WARN, OB_ERR_UNEXPECTED, "unexpected values pair", K(has_start_scn_ctx_cnt_), K(min_start_scn_));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRANS_LOG(DEBUG,
|
||||||
|
"get min start status",
|
||||||
|
K(first_err_code_),
|
||||||
|
K(has_start_scn_ctx_cnt_),
|
||||||
|
K(min_start_scn_),
|
||||||
|
K(start_status));
|
||||||
return start_status;
|
return start_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int first_err_code_;
|
||||||
|
int64_t has_start_scn_ctx_cnt_;
|
||||||
share::SCN min_start_scn_;
|
share::SCN min_start_scn_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -352,6 +352,7 @@ public:
|
|||||||
// ========================================================
|
// ========================================================
|
||||||
// newly added for 4.0
|
// newly added for 4.0
|
||||||
|
|
||||||
|
bool is_decided() const { return ctx_tx_data_.is_decided(); }
|
||||||
int retry_dup_trx_before_prepare(
|
int retry_dup_trx_before_prepare(
|
||||||
const share::SCN &before_prepare_version,
|
const share::SCN &before_prepare_version,
|
||||||
const ObDupTableBeforePrepareRequest::BeforePrepareScnSrc before_prepare_src);
|
const ObDupTableBeforePrepareRequest::BeforePrepareScnSrc before_prepare_src);
|
||||||
|
|||||||
@ -156,8 +156,8 @@ int ObTxLoopWorker::scan_all_ls_(bool can_tx_gc, bool can_gc_retain_ctx)
|
|||||||
iter_ret = OB_SUCCESS;
|
iter_ret = OB_SUCCESS;
|
||||||
cur_ls_ptr = nullptr;
|
cur_ls_ptr = nullptr;
|
||||||
while (OB_SUCCESS == (iter_ret = iter_ptr->get_next(cur_ls_ptr))) {
|
while (OB_SUCCESS == (iter_ret = iter_ptr->get_next(cur_ls_ptr))) {
|
||||||
|
SCN min_start_scn = SCN::invalid_scn();
|
||||||
SCN min_start_scn;
|
SCN max_decided_scn = SCN::invalid_scn();
|
||||||
MinStartScnStatus status = MinStartScnStatus::UNKOWN;
|
MinStartScnStatus status = MinStartScnStatus::UNKOWN;
|
||||||
common::ObRole role;
|
common::ObRole role;
|
||||||
int64_t base_proposal_id, proposal_id;
|
int64_t base_proposal_id, proposal_id;
|
||||||
@ -173,6 +173,14 @@ int ObTxLoopWorker::scan_all_ls_(bool can_tx_gc, bool can_gc_retain_ctx)
|
|||||||
if (can_tx_gc) {
|
if (can_tx_gc) {
|
||||||
// TODO shanyan.g close ctx gc temporarily because of logical bug
|
// TODO shanyan.g close ctx gc temporarily because of logical bug
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// ATTENTION : get_max_decided_scn must before iterating all trans ctx.
|
||||||
|
// set max_decided_scn as default value
|
||||||
|
if (OB_TMP_FAIL(cur_ls_ptr->get_log_handler()->get_max_decided_scn(max_decided_scn))) {
|
||||||
|
TRANS_LOG(WARN, "get max decided scn failed", KR(tmp_ret), K(min_start_scn));
|
||||||
|
max_decided_scn.set_invalid();
|
||||||
|
}
|
||||||
|
min_start_scn = max_decided_scn;
|
||||||
do_tx_gc_(cur_ls_ptr, min_start_scn, status);
|
do_tx_gc_(cur_ls_ptr, min_start_scn, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user