fix create memtable during replay corner case

This commit is contained in:
Handora 2024-08-26 06:39:16 +00:00 committed by ob-robot
parent ae6a932613
commit 56af8cfa43
10 changed files with 127 additions and 96 deletions

View File

@ -109,7 +109,7 @@ int ObLSTabletService::insert_tablet_rows(
return ret;
}
int ObStorageTableGuard::refresh_and_protect_table(ObRelativeTable &relative_table)
int ObStorageTableGuard::refresh_and_protect_memtable_for_write(ObRelativeTable &relative_table)
{
int ret = OB_SUCCESS;
ObTabletTableIterator &iter = relative_table.tablet_iter_;

View File

@ -5148,7 +5148,7 @@ int ObLSTabletService::check_row_locked_by_myself(
K(relative_table), K(store_ctx), K(rowkey));
} else {
ObStorageTableGuard guard(tablet, store_ctx, true);
if (OB_FAIL(guard.refresh_and_protect_table(relative_table))) {
if (OB_FAIL(guard.refresh_and_protect_memtable_for_write(relative_table))) {
LOG_WARN("fail to protect table", K(ret), K(tablet_handle));
} else if (OB_FAIL(tablet->check_row_locked_by_myself(relative_table, store_ctx, rowkey, locked))) {
LOG_WARN("fail to check row locked, ", K(ret), K(rowkey));

View File

@ -95,10 +95,9 @@ int ObITabletMemtable::resolve_left_boundary_for_active_memtable_()
{
int ret = OB_SUCCESS;
storage::ObTabletMemtableMgr *memtable_mgr = get_memtable_mgr();
const SCN new_start_scn = MAX(get_end_scn(), get_migration_clog_checkpoint_scn());
if (OB_NOT_NULL(memtable_mgr)) {
if (OB_FAIL(memtable_mgr->resolve_left_boundary_for_active_memtable(this, new_start_scn))) {
if (OB_FAIL(memtable_mgr->resolve_left_boundary_for_active_memtable(this, get_end_scn()))) {
TRANS_LOG(WARN, "fail to resolve left boundary for active memtable", K(ret), K(ls_id_), KPC(this));
}
}
@ -142,23 +141,6 @@ int ObITabletMemtable::set_freezer(ObFreezer *handler)
return ret;
}
int ObITabletMemtable::set_migration_clog_checkpoint_scn(const SCN &clog_checkpoint_scn)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_inited())) {
ret = OB_NOT_INIT;
TRANS_LOG(WARN, "not inited", K(ret));
} else if (clog_checkpoint_scn <= ObScnRange::MIN_SCN) {
ret = OB_SCN_OUT_OF_BOUND;
TRANS_LOG(WARN, "invalid clog_checkpoint_ts", K(ret));
} else {
(void)migration_clog_checkpoint_scn_.atomic_store(clog_checkpoint_scn);
}
return ret;
}
int ObITabletMemtable::set_rec_scn(const SCN rec_scn)
{
int ret = OB_SUCCESS;

View File

@ -209,14 +209,12 @@ public:
unsubmitted_cnt_(0),
logging_blocked_start_time_(0),
write_ref_cnt_(0),
migration_clog_checkpoint_scn_(),
freeze_state_(TabletMemtableFreezeState::INVALID),
memtable_mgr_handle_()
{
max_end_scn_.set_min();
rec_scn_.set_max();
freeze_scn_.set_max();
migration_clog_checkpoint_scn_.set_min();
}
void reset()
@ -241,7 +239,6 @@ public:
max_end_scn_.set_min();
rec_scn_.set_max();
freeze_scn_.set_max();
migration_clog_checkpoint_scn_.set_min();
freezer_ = nullptr;
memtable_mgr_handle_.reset();
mt_stat_.reset();
@ -257,7 +254,6 @@ public:
int dec_unsubmitted_cnt();
int set_freezer(ObFreezer *handler);
int set_rec_scn(const share::SCN rec_scn);
int set_migration_clog_checkpoint_scn(const share::SCN &clog_checkpoint_scn);
int resolve_left_boundary(share::SCN end_scn) { return set_start_scn(end_scn); }
int resolve_right_boundary();
int replay_schema_version_change_log(const int64_t schema_version);
@ -374,7 +370,6 @@ public:
const ObMtStat &get_mt_stat() const { return mt_stat_; }
share::SCN get_max_end_scn() const { return max_end_scn_.atomic_get(); }
share::SCN get_rec_scn() { return rec_scn_.atomic_get(); }
share::SCN get_migration_clog_checkpoint_scn() { return migration_clog_checkpoint_scn_.atomic_get(); }
ObTabletMemtableMgr *get_memtable_mgr();
// *************** getter *****************
@ -399,7 +394,6 @@ public:
K(max_end_scn_),
K(rec_scn_),
K(freeze_scn_),
K(migration_clog_checkpoint_scn_),
KP(freezer_),
K(memtable_mgr_handle_),
K(mt_stat_.frozen_time_),
@ -477,7 +471,6 @@ private:
int64_t unsubmitted_cnt_;
int64_t logging_blocked_start_time_; // record the start time of logging blocked
int64_t write_ref_cnt_ CACHE_ALIGNED;
share::SCN migration_clog_checkpoint_scn_;
TabletMemtableFreezeState freeze_state_;
ObMemtableMgrHandle memtable_mgr_handle_;
};

View File

@ -37,8 +37,7 @@ ObStorageTableGuard::ObStorageTableGuard(
ObStoreCtx &store_ctx,
const bool need_control_mem,
const bool for_replay,
const SCN replay_scn,
const bool for_multi_source_data)
const SCN replay_scn)
: tablet_(tablet),
store_ctx_(store_ctx),
need_control_mem_(need_control_mem),
@ -46,8 +45,7 @@ ObStorageTableGuard::ObStorageTableGuard(
retry_count_(0),
last_ts_(0),
for_replay_(for_replay),
replay_scn_(replay_scn),
for_multi_source_data_(for_multi_source_data)
replay_scn_(replay_scn)
{
init_ts_ = ObClockGenerator::getClock();
share::memstore_throttled_alloc() = 0;
@ -105,7 +103,7 @@ void ObStorageTableGuard::throttle_if_needed_()
}
}
int ObStorageTableGuard::refresh_and_protect_table(ObRelativeTable &relative_table)
int ObStorageTableGuard::refresh_and_protect_memtable_for_write(ObRelativeTable &relative_table)
{
int ret = OB_SUCCESS;
ObTabletTableIterator &iter = relative_table.tablet_iter_;
@ -142,7 +140,7 @@ int ObStorageTableGuard::refresh_and_protect_table(ObRelativeTable &relative_tab
return ret;
}
int ObStorageTableGuard::refresh_and_protect_memtable()
int ObStorageTableGuard::refresh_and_protect_memtable_for_replay()
{
const int64_t DEFAULT_REFRESH_WARN_INTERVAL = 10LL * 1000LL; // 10 ms
const int64_t FIND_DIRECT_LOAD_MT_WARN_INTERVAL = 10LL * 1000LL * 1000LL; // 10 seconds
@ -163,7 +161,7 @@ int ObStorageTableGuard::refresh_and_protect_memtable()
if (OB_FAIL(tablet_->get_boundary_memtable_from_memtable_mgr(handle))) {
// if there is no memtable, create a new one
if (OB_ENTRY_NOT_EXIST == ret) {
ret = create_data_memtable_(ls_id, tablet_id, need_retry);
ret = create_data_memtable_for_replay_(ls_id, tablet_id, need_retry);
} else { // OB_ENTRY_NOT_EXIST != ret
LOG_WARN("fail to get boundary memtable", K(ret), K(ls_id), K(tablet_id));
}
@ -172,7 +170,7 @@ int ObStorageTableGuard::refresh_and_protect_memtable()
} else if (tablet_memtable->is_direct_load_memtable()) {
// set warn interval to 1 second because freeze direct load memtable is an async task
warn_interval = FIND_DIRECT_LOAD_MT_WARN_INTERVAL;
ret = create_data_memtable_(ls_id, tablet_id, need_retry);
ret = create_data_memtable_for_replay_(ls_id, tablet_id, need_retry);
} else if (OB_FAIL(check_freeze_to_inc_write_ref(static_cast<ObMemtable*>(tablet_memtable), need_retry))) {
if (OB_EAGAIN == ret) {
} else if (OB_MINOR_FREEZE_NOT_ALLOW != ret) {
@ -201,9 +199,9 @@ int ObStorageTableGuard::refresh_and_protect_memtable()
return ret;
}
int ObStorageTableGuard::create_data_memtable_(const share::ObLSID &ls_id,
const common::ObTabletID &tablet_id,
bool &need_retry)
int ObStorageTableGuard::create_data_memtable_for_replay_(const share::ObLSID &ls_id,
const common::ObTabletID &tablet_id,
bool &need_retry)
{
int ret = OB_SUCCESS;
LOG_DEBUG("there is no boundary memtable", K(ret), K(ls_id), K(tablet_id));
@ -229,13 +227,43 @@ int ObStorageTableGuard::create_data_memtable_(const share::ObLSID &ls_id,
tablet_id, 0 /* schema version */, false /* for_direct_load */, for_replay_, clog_checkpoint_scn))) {
LOG_WARN("fail to create a boundary memtable", K(ret), K(ls_id), K(tablet_id));
}
} else {
// replay_log_scn_ <= clog_checkpoint_scn. no need to create a boundary memtable
need_retry = false;
// In situation that replay_log_scn_ <= clog_checkpoint_scn, we have no need
// to create the memtable. While we need double check to decide whether
// another thread has created the memtable that we need replay. And if it
// does, we must replay on the memtable.
} else if (OB_FAIL(double_check_get_memtable_for_replay_(replay_scn_, need_retry))) {
LOG_WARN("fail to double check replay memtable", K(ret), K(ls_id), K(tablet_id),
K(replay_scn_), K(clog_checkpoint_scn));
}
return ret;
}
int ObStorageTableGuard::double_check_get_memtable_for_replay_(const share::SCN replay_scn,
bool &need_retry)
{
int ret = OB_SUCCESS;
ObTableHandleV2 handle;
ObProtectedMemtableMgrHandle *protected_handle = NULL;
if (OB_FAIL(tablet_->get_protected_memtable_mgr_handle(protected_handle))) {
LOG_WARN("failed to get_protected_memtable_mgr_handle", K(ret), KPC(tablet_));
} else if (OB_FAIL(protected_handle->get_memtable_for_replay(replay_scn_, handle))) {
if (OB_NO_NEED_UPDATE == ret) {
// no need to replay the log
need_retry = false;
ret = OB_SUCCESS;
} else if (OB_ENTRY_NOT_EXIST == ret) {
// memtable_mgr not exist, it means nothing need replay
need_retry = false;
ret = OB_SUCCESS;
} else {
LOG_WARN("fail to get memtable for replay", K(ret), K(need_retry), K(replay_scn));
}
}
return ret;
}
void ObStorageTableGuard::reset()
{
if (NULL != memtable_) {
@ -302,7 +330,7 @@ int ObStorageTableGuard::check_freeze_to_inc_write_ref(ObMemtable *memtable, boo
} else if (memtable->is_active_memtable()) {
// the most recent memtable is active
// no need to create a new memtable
if (for_replay_ || for_multi_source_data_) {
if (for_replay_) {
// filter memtables for replay or multi_source_data according to scn
ObTableHandleV2 handle;
if (OB_FAIL(tablet_->get_protected_memtable_mgr_handle(protected_handle))) {
@ -334,7 +362,6 @@ int ObStorageTableGuard::check_freeze_to_inc_write_ref(ObMemtable *memtable, boo
if (0 == write_ref) {
SCN clog_checkpoint_scn;
bool need_create_memtable = true;
SCN migration_clog_checkpoint_scn;
ObTabletHandle tmp_handle;
ObLSHandle ls_handle;
if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) {
@ -343,15 +370,13 @@ int ObStorageTableGuard::check_freeze_to_inc_write_ref(ObMemtable *memtable, boo
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected error, invalid ls handle", K(ret), K(need_retry), K(ls_handle), K(ls_id), K(tablet_id));
} else if (OB_FAIL(ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id,
tmp_handle, 0, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) {
tmp_handle,
0,
ObMDSGetTabletMode::READ_WITHOUT_CHECK))) {
LOG_WARN("fail to get tablet", K(ret), K(ls_id), K(tablet_id));
} else if (FALSE_IT(clog_checkpoint_scn = tmp_handle.get_obj()->get_tablet_meta().clog_checkpoint_scn_)) {
} else if (FALSE_IT(migration_clog_checkpoint_scn = memtable->get_migration_clog_checkpoint_scn())) {
} else if (for_replay_ && !migration_clog_checkpoint_scn.is_min()) {
memtable->resolve_right_boundary();
if (replay_scn_ <= clog_checkpoint_scn) {
need_create_memtable = false;
}
} else if (for_replay_ && replay_scn_ <= clog_checkpoint_scn) {
need_create_memtable = false;
}
// create a new memtable if no write in the old memtable
@ -368,6 +393,26 @@ int ObStorageTableGuard::check_freeze_to_inc_write_ref(ObMemtable *memtable, boo
LOG_WARN("fail to create new memtable for freeze", K(ret), K(need_retry), K(ls_id), K(tablet_id));
}
}
} else if (for_replay_) {
ObTableHandleV2 handle;
if (OB_FAIL(tablet_->get_protected_memtable_mgr_handle(protected_handle))) {
LOG_WARN("failed to get_protected_memtable_mgr_handle", K(ret), KPC(tablet_));
} else if (OB_FAIL(protected_handle->get_memtable_for_replay(replay_scn_, handle))) {
if (OB_NO_NEED_UPDATE == ret) {
// no need to replay the log
need_retry = false;
ret = OB_SUCCESS;
} else {
LOG_WARN("fail to get memtable for replay", K(ret), K(need_retry), K(ls_id), K(tablet_id));
}
} else if (OB_FAIL(handle.get_data_memtable(memtable))) {
LOG_WARN("fail to get memtable from ObTableHandle", K(ret), K(need_retry), K(ls_id), K(tablet_id));
} else {
if (memtable != old_memtable) {
is_tablet_freeze = memtable->get_is_tablet_freeze();
}
double_check_inc_write_ref(old_freeze_flag, is_tablet_freeze, memtable, need_retry);
}
}
}
}

View File

@ -49,21 +49,21 @@ public:
ObStoreCtx &store_ctx,
const bool need_control_mem,
const bool for_replay = false,
const share::SCN replay_scn = share::SCN(),
const bool for_multi_source_data = false);
const share::SCN replay_scn = share::SCN());
~ObStorageTableGuard();
ObStorageTableGuard(const ObStorageTableGuard&) = delete;
ObStorageTableGuard &operator=(const ObStorageTableGuard&) = delete;
public:
int refresh_and_protect_table(ObRelativeTable &relative_table);
int refresh_and_protect_memtable();
// refresh and get/create the memtable for write
int refresh_and_protect_memtable_for_write(ObRelativeTable &relative_table);
// refresh and get/create the memtable for replay
int refresh_and_protect_memtable_for_replay();
int get_memtable_for_replay(ObIMemtable *&memtable);
TO_STRING_KV(KP(tablet_),
K(need_control_mem_),
K(for_replay_),
K(for_multi_source_data_),
K(replay_scn_),
KP(memtable_),
K(retry_count_),
@ -78,10 +78,12 @@ private:
memtable::ObMemtable *memtable,
bool &bool_ret);
int check_freeze_to_inc_write_ref(memtable::ObMemtable *table, bool &bool_ret);
int create_data_memtable_(const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, bool &no_need_create);
int create_data_memtable_for_replay_(const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, bool &no_need_create);
bool need_to_refresh_table(ObTableStoreIterator &iter);
void check_if_need_log_(bool &need_log, bool &need_log_error);
void throttle_if_needed_();
int double_check_get_memtable_for_replay_(const share::SCN replay_scn,
bool &need_retry);
private:
static const int64_t LOG_INTERVAL_US = 10 * 1000 * 1000; // 10s
@ -99,7 +101,6 @@ private:
int64_t init_ts_;
bool for_replay_;
share::SCN replay_scn_;
bool for_multi_source_data_;
};
} // namespace storage
} // namespace oceanbase

View File

@ -261,7 +261,7 @@ int ObSingleRowGetter::open(const ObDatumRowkey &rowkey, bool use_fuse_row_cache
} else {
{
ObStorageTableGuard guard(tablet_, *store_ctx_, false);
if (OB_FAIL(guard.refresh_and_protect_table(*relative_table_))) {
if (OB_FAIL(guard.refresh_and_protect_memtable_for_write(*relative_table_))) {
STORAGE_LOG(WARN, "fail to protect table", K(ret));
}
}

View File

@ -3656,7 +3656,7 @@ int ObTablet::lock_row(
} else if (OB_UNLIKELY(relative_table.get_tablet_id() != tablet_meta_.tablet_id_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tablet id doesn't match", K(ret), K(relative_table.get_tablet_id()), K(tablet_meta_.tablet_id_));
} else if (OB_FAIL(guard.refresh_and_protect_table(relative_table))) {
} else if (OB_FAIL(guard.refresh_and_protect_memtable_for_write(relative_table))) {
LOG_WARN("fail to protect table", K(ret), "tablet_id", tablet_meta_.tablet_id_);
}
if (OB_SUCC(ret)) {
@ -3696,7 +3696,7 @@ int ObTablet::lock_row(
} else if (OB_UNLIKELY(relative_table.get_tablet_id() != tablet_meta_.tablet_id_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tablet id doesn't match", K(ret), K(relative_table.get_tablet_id()), K(tablet_meta_.tablet_id_));
} else if (OB_FAIL(guard.refresh_and_protect_table(relative_table))) {
} else if (OB_FAIL(guard.refresh_and_protect_memtable_for_write(relative_table))) {
LOG_WARN("fail to protect table", K(ret));
} else {
ObArenaAllocator allocator(common::ObMemAttr(MTL_ID(), ObModIds::OB_STORE_ROW_LOCK_CHECKER));
@ -4127,7 +4127,7 @@ int ObTablet::update_row(
} else if (OB_UNLIKELY(relative_table.get_tablet_id() != tablet_meta_.tablet_id_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tablet id doesn't match", K(ret), K(relative_table.get_tablet_id()), K(tablet_meta_.tablet_id_));
} else if (OB_FAIL(guard.refresh_and_protect_table(relative_table))) {
} else if (OB_FAIL(guard.refresh_and_protect_memtable_for_write(relative_table))) {
LOG_WARN("fail to protect table", K(ret));
} else if (OB_FAIL(prepare_memtable(relative_table, store_ctx, write_memtable))) {
LOG_WARN("prepare write memtable fail", K(ret), K(relative_table));
@ -4182,7 +4182,7 @@ int ObTablet::insert_rows(
} else if (OB_UNLIKELY(relative_table.get_tablet_id() != tablet_meta_.tablet_id_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("Tablet id doesn't match", K(ret), K(relative_table.get_tablet_id()), K(tablet_meta_.tablet_id_));
} else if (OB_FAIL(guard.refresh_and_protect_table(relative_table))) {
} else if (OB_FAIL(guard.refresh_and_protect_memtable_for_write(relative_table))) {
LOG_WARN("Failed to protect table", K(ret));
} else if (OB_FAIL(prepare_memtable(relative_table, store_ctx, write_memtable))) {
LOG_WARN("Failed to prepare write memtable", K(ret), K(relative_table));
@ -4231,7 +4231,7 @@ int ObTablet::insert_row_without_rowkey_check(
} else if (OB_UNLIKELY(relative_table.get_tablet_id() != tablet_meta_.tablet_id_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tablet id doesn't match", K(ret), K(relative_table.get_tablet_id()), K(tablet_meta_.tablet_id_));
} else if (OB_FAIL(guard.refresh_and_protect_table(relative_table))) {
} else if (OB_FAIL(guard.refresh_and_protect_memtable_for_write(relative_table))) {
LOG_WARN("fail to protect table", K(ret));
} else if (OB_FAIL(prepare_memtable(relative_table, store_ctx, write_memtable))) {
LOG_WARN("prepare write memtable fail", K(ret), K(relative_table));
@ -4393,7 +4393,7 @@ int ObTablet::rowkey_exists(
} else {
{
ObStorageTableGuard guard(this, store_ctx, false);
if (OB_FAIL(guard.refresh_and_protect_table(relative_table))) {
if (OB_FAIL(guard.refresh_and_protect_memtable_for_write(relative_table))) {
LOG_WARN("fail to protect table", K(ret));
}
}
@ -4445,7 +4445,7 @@ int ObTablet::rowkeys_exists(
} else {
{
ObStorageTableGuard guard(this, store_ctx, false);
if (OB_FAIL(guard.refresh_and_protect_table(relative_table))) {
if (OB_FAIL(guard.refresh_and_protect_memtable_for_write(relative_table))) {
LOG_WARN("fail to protect table", K(ret));
}
}
@ -4683,7 +4683,11 @@ int ObTablet::create_memtable(
ObTimeGuard time_guard("ObTablet::create_memtable", 10 * 1000);
common::SpinWLockGuard guard(memtables_lock_);
time_guard.click("lock");
const SCN new_clog_checkpoint_scn = clog_checkpoint_scn.is_min() ? tablet_meta_.clog_checkpoint_scn_ : clog_checkpoint_scn;
// we use the parameter clog_checkpoint_scn to double check whether the
// clog_checkpoint_scn has been changed during memtable replay check.
// So we complement the input_clog_checkpoint_scn for other scenario.
const SCN input_clog_checkpoint_scn = clog_checkpoint_scn.is_min() ?
tablet_meta_.clog_checkpoint_scn_ : clog_checkpoint_scn;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
@ -4692,11 +4696,14 @@ int ObTablet::create_memtable(
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid schema version", K(ret), K(schema_version));
} else if (FALSE_IT(time_guard.click("prepare_memtables"))) {
} else if (OB_FAIL(inner_create_memtable(new_clog_checkpoint_scn, schema_version, for_direct_load, for_replay))) {
} else if (OB_FAIL(inner_create_memtable(input_clog_checkpoint_scn,
schema_version,
for_direct_load,
for_replay))) {
if (OB_ENTRY_EXIST == ret) {
ret = OB_SUCCESS;
} else if (OB_MINOR_FREEZE_NOT_ALLOW != ret) {
LOG_WARN("failed to create memtable", K(ret), K(clog_checkpoint_scn),
LOG_WARN("failed to create memtable", K(ret), K(input_clog_checkpoint_scn),
K(schema_version), K(for_replay));
}
} else {
@ -4729,14 +4736,14 @@ int ObTablet::create_memtable(
STORAGE_LOG(DEBUG,
"Tablet finish create memtable",
K(schema_version),
K(clog_checkpoint_scn),
K(input_clog_checkpoint_scn),
K(for_replay),
K(lbt()));
return ret;
}
int ObTablet::inner_create_memtable(
const SCN clog_checkpoint_scn,
const SCN input_clog_checkpoint_scn,
const int64_t schema_version,
const bool for_direct_load,
const bool for_replay)
@ -4744,12 +4751,12 @@ int ObTablet::inner_create_memtable(
int ret = OB_SUCCESS;
const share::ObLSID &ls_id = tablet_meta_.ls_id_;
const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_;
const SCN new_clog_checkpoint_scn = tablet_meta_.clog_checkpoint_scn_;
const SCN latest_clog_checkpoint_scn = tablet_meta_.clog_checkpoint_scn_;
ObProtectedMemtableMgrHandle *protected_handle = NULL;
if (OB_UNLIKELY(!clog_checkpoint_scn.is_valid_and_not_min()) || OB_UNLIKELY(schema_version < 0)) {
if (OB_UNLIKELY(!input_clog_checkpoint_scn.is_valid_and_not_min()) || OB_UNLIKELY(schema_version < 0)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid args", K(ret), K(clog_checkpoint_scn), K(schema_version));
LOG_WARN("invalid args", K(ret), K(input_clog_checkpoint_scn), K(schema_version));
} else if (OB_UNLIKELY(MAX_MEMSTORE_CNT == memtable_count_)) {
ret = OB_MINOR_FREEZE_NOT_ALLOW;
if (TC_REACH_TIME_INTERVAL(1_s)) {
@ -4760,16 +4767,17 @@ int ObTablet::inner_create_memtable(
LOG_WARN("failed to get_protected_memtable_mgr_handle", K(ret), KPC(this));
} else if (OB_FAIL(protected_handle->create_memtable(tablet_meta_,
CreateMemtableArg(schema_version,
clog_checkpoint_scn,
new_clog_checkpoint_scn,
input_clog_checkpoint_scn,
latest_clog_checkpoint_scn,
for_replay,
for_direct_load)))) {
if (OB_ENTRY_EXIST != ret && OB_MINOR_FREEZE_NOT_ALLOW != ret) {
LOG_WARN("failed to create memtable", K(ret), K(ls_id), K(tablet_id), KPC(this));
}
} else {
LOG_INFO("succeeded to create memtable for tablet", K(ret), K(ls_id), K(tablet_id),
K(clog_checkpoint_scn), K(schema_version), K(for_replay));
LOG_INFO("succeeded to create memtable for tablet", K(ret), K(tablet_id),
K(ls_id), K(schema_version), K(for_replay), K(for_direct_load),
K(input_clog_checkpoint_scn), K(latest_clog_checkpoint_scn));
}
return ret;

View File

@ -189,12 +189,13 @@ int ObTabletMemtableMgr::try_resolve_boundary_on_create_memtable_for_leader_(
} else if (can_resolve) {
SCN new_start_scn;
last_frozen_tablet_memtable->resolve_right_boundary();
last_frozen_tablet_memtable->set_resolved_active_memtable_left_boundary();
if (new_tablet_memtable != last_frozen_tablet_memtable) {
new_start_scn = MAX(last_frozen_tablet_memtable->get_end_scn(),
last_frozen_tablet_memtable->get_migration_clog_checkpoint_scn());
new_tablet_memtable->get_start_scn());
if (OB_FAIL(new_tablet_memtable->resolve_left_boundary(new_start_scn))) {
TRANS_LOG(ERROR, "resolve left boundary failed", KR(ret), K(new_start_scn), KPC(new_tablet_memtable));
} else {
last_frozen_tablet_memtable->set_resolved_active_memtable_left_boundary();
}
}
TRANS_LOG(INFO, "[resolve_right_boundary] in create_memtable on leader", K(ret),
@ -271,9 +272,10 @@ int ObTabletMemtableMgr::check_boundary_memtable_(const uint32_t logstream_freez
} else if (tablet_memtable->is_direct_load_memtable()) {
if (tablet_memtable->get_end_scn().is_max()) {
PAUSE();
// if end_scn of direct load memtable has not decided, return OB_ENTRY_EXIST and Tablet will reset it to
// OB_SUCCESS. Then refresh_and_protect_table(refresh_and_protect_memtable) in StorageTableGuard will retry create
// memtable
// if end_scn of direct load memtable has not decided, return
// OB_ENTRY_EXIST and Tablet will reset it to OB_SUCCESS. Then
// refresh_and_protect_memtable_for_write(refresh_and_protect_memtable_for_replay)
// in StorageTableGuard will retry create memtable
ret = OB_ENTRY_EXIST;
}
} else if (tablet_memtable->is_data_memtable()) {
@ -389,19 +391,19 @@ int ObTabletMemtableMgr::resolve_data_memtable_boundary_(ObITabletMemtable *froz
{
int ret = OB_SUCCESS;
if (arg.for_replay_) {
SCN new_memtable_start_scn;
frozen_tablet_memtable->resolve_right_boundary();
if (new_tablet_memtable != frozen_tablet_memtable) {
new_memtable_start_scn =
MAX(frozen_tablet_memtable->get_end_scn(), frozen_tablet_memtable->get_migration_clog_checkpoint_scn());
if (OB_FAIL(new_tablet_memtable->resolve_left_boundary(new_memtable_start_scn))) {
TRANS_LOG(WARN, "resolve left boundary fail", K(ret), K(new_tablet_memtable));
if (OB_FAIL(new_tablet_memtable->resolve_left_boundary(
MAX(frozen_tablet_memtable->get_end_scn(),
new_tablet_memtable->get_start_scn())))) {
TRANS_LOG(WARN, "resolve left boundary fail", K(ret), K(arg),
KPC(new_tablet_memtable), KPC(frozen_tablet_memtable));
}
}
TRANS_LOG(INFO, "[resolve_right_boundary] in create_memtable on replay", KPC(frozen_tablet_memtable));
}
// for leader, decide the right boundary of frozen memtable
else if (OB_FAIL(try_resolve_boundary_on_create_memtable_for_leader_(frozen_tablet_memtable, new_tablet_memtable))) {
TRANS_LOG(INFO, "[resolve_right_boundary] in create_memtable on replay",
KPC(frozen_tablet_memtable), KPC(new_tablet_memtable), K(arg));
} else if (OB_FAIL(try_resolve_boundary_on_create_memtable_for_leader_(
frozen_tablet_memtable, new_tablet_memtable))) {
TRANS_LOG(WARN, "try resolve boundary fail", K(ret));
}
return ret;
@ -420,7 +422,7 @@ int ObTabletMemtableMgr::resolve_direct_load_memtable_boundary_(ObITabletMemtabl
STORAGE_LOG(ERROR, "frozen direct load memtable must have a valid end_scn", KPC(frozen_tablet_memtable));
} else if (active_tablet_memtable != frozen_tablet_memtable) {
new_memtable_start_scn =
MAX(frozen_tablet_memtable->get_end_scn(), frozen_tablet_memtable->get_migration_clog_checkpoint_scn());
MAX(frozen_tablet_memtable->get_end_scn(), active_tablet_memtable->get_start_scn());
if (OB_FAIL(active_tablet_memtable->resolve_left_boundary(new_memtable_start_scn))) {
STORAGE_LOG(ERROR, "fail to resolve left boundary", KPC(active_tablet_memtable));
} else {
@ -622,8 +624,8 @@ int ObTabletMemtableMgr::resolve_left_boundary_for_active_memtable(ObITabletMemt
} else if (OB_FAIL(handle.get_tablet_memtable(active_tablet_memtable))) {
LOG_WARN("fail to get active memtable", K(ret));
} else {
// set the start_scn of the new memtable
int tmp_ret = active_tablet_memtable->resolve_left_boundary(start_scn);
int tmp_ret = active_tablet_memtable->resolve_left_boundary(
MAX(start_scn, active_tablet_memtable->get_start_scn()));
if (OB_SUCCESS != tmp_ret) {
TRANS_LOG(ERROR, "resolve left boundary failed", K(start_scn), KPC(active_tablet_memtable), KPC(tablet_memtable));
}

View File

@ -783,7 +783,7 @@ int ObTxReplayExecutor::prepare_memtable_replay_(ObStorageTableGuard &w_guard,
ObIMemtable *&mem_ptr)
{
int ret = OB_SUCCESS;
if (OB_FAIL(w_guard.refresh_and_protect_memtable())) {
if (OB_FAIL(w_guard.refresh_and_protect_memtable_for_replay())) {
TRANS_LOG(WARN, "[Replay Tx] refresh and protect memtable error", K(ret));
} else if (OB_FAIL(w_guard.get_memtable_for_replay(mem_ptr))) {
// OB_NO_NEED_UPDATE => don't need to replay