diff --git a/mittest/mtlenv/storage/test_tablet_create_delete_helper.cpp b/mittest/mtlenv/storage/test_tablet_create_delete_helper.cpp index f2fdcea69c..fc6b862974 100644 --- a/mittest/mtlenv/storage/test_tablet_create_delete_helper.cpp +++ b/mittest/mtlenv/storage/test_tablet_create_delete_helper.cpp @@ -3095,7 +3095,7 @@ TEST_F(TestTabletCreateDeleteHelper, empty_memtable_replay_commit) ASSERT_EQ(OB_SUCCESS, ret); share::SCN left_scn; left_scn.convert_for_gts(101); - share::SCN right_scn = ((memtable::ObMemtable*)new_memtable)->get_end_scn(); + share::SCN right_scn = ((memtable::ObMemtable*)new_memtable)->get_max_end_scn(); ASSERT_EQ(left_scn, right_scn); } } // namespace storage diff --git a/src/storage/memtable/ob_memtable.cpp b/src/storage/memtable/ob_memtable.cpp index 4c59ac6eec..bf2ac89a0f 100644 --- a/src/storage/memtable/ob_memtable.cpp +++ b/src/storage/memtable/ob_memtable.cpp @@ -1794,6 +1794,30 @@ int ObMemtable::set_max_end_scn(const SCN scn) return ret; } +// the difference from set_max_end_scn is not to check memtable range +int ObMemtable::set_max_end_scn_to_inc_start_scn() +{ + int ret = OB_SUCCESS; + const share::SCN scn = share::SCN::scn_inc(get_start_scn()); + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + TRANS_LOG(WARN, "not inited", K(ret)); + } else { + SCN old_max_end_scn; + SCN new_max_end_scn = get_max_end_scn(); + while ((old_max_end_scn = new_max_end_scn) < scn) { + if ((new_max_end_scn = + max_end_scn_.atomic_vcas(old_max_end_scn, scn)) + == old_max_end_scn) { + new_max_end_scn = scn; + } + } + } + + return ret; +} + bool ObMemtable::rec_scn_is_stable() { int ret = OB_SUCCESS; diff --git a/src/storage/memtable/ob_memtable.h b/src/storage/memtable/ob_memtable.h index 6c33c26d31..5863e3f226 100644 --- a/src/storage/memtable/ob_memtable.h +++ b/src/storage/memtable/ob_memtable.h @@ -415,6 +415,7 @@ public: int set_start_scn(const share::SCN start_ts); int set_end_scn(const share::SCN freeze_ts); int set_max_end_scn(const share::SCN scn); + int set_max_end_scn_to_inc_start_scn(); inline int set_logging_blocked() { logging_blocked_start_time = common::ObTimeUtility::current_time(); @@ -646,10 +647,10 @@ int ObMemtable::save_multi_source_data_unit(const T *const multi_source_data_uni // commit log is replayed to empty memtable which is frozen after clog switch to follower gracefully, commit status mds will be lost. // so push end_scn to start_scn + 1 else if (get_max_end_scn().is_min() && get_end_scn().is_max()) { - TRANS_LOG(INFO, "empty memtable push end_scn to start_scn + 1", K(ret), K(scn), KPC(this)); - if (OB_FAIL(set_end_scn(share::SCN::scn_inc(start_scn)))) { + if (OB_FAIL(set_max_end_scn_to_inc_start_scn())) { TRANS_LOG(WARN, "failed to set max_end_scn", K(ret), K(scn), KPC(this)); } + TRANS_LOG(INFO, "empty memtable push end_scn to start_scn + 1", K(ret), K(scn), KPC(this)); } if (OB_FAIL(ret)) { } else if (OB_FAIL(set_rec_scn(scn))) {