diff --git a/src/storage/memtable/ob_memtable.h b/src/storage/memtable/ob_memtable.h index f45680084c..949627e3ae 100644 --- a/src/storage/memtable/ob_memtable.h +++ b/src/storage/memtable/ob_memtable.h @@ -630,6 +630,7 @@ int ObMemtable::save_multi_source_data_unit(const T *const multi_source_data_uni TRANS_LOG(INFO, "unsync_cnt_for_multi_data inc for rollback", K(key_.tablet_id_), K(type), KPC(multi_source_data_unit)); } } else { + const share::SCN start_scn = get_start_scn(); if (scn > get_start_scn() && scn < share::ObScnRange::MAX_SCN) { if (OB_FAIL(ret)) { } @@ -637,6 +638,12 @@ int ObMemtable::save_multi_source_data_unit(const T *const multi_source_data_uni else if ((!for_replay || !is_callback) && OB_FAIL(set_max_end_scn(scn))) { TRANS_LOG(WARN, "failed to set max_end_scn", K(ret), K(scn), KPC(this)); + } + // commit log is replayed to empty memtable whitch is frozen after clog switch to follower gracefully, commit status mds will be lost. + // so push max_end_scn to start_scn + 1 + else if (start_scn == get_end_scn() + && OB_FAIL(set_end_scn(share::SCN::scn_inc(start_scn)))) { + TRANS_LOG(WARN, "failed to set max_end_scn", K(ret), K(scn), KPC(this)); } else if (OB_FAIL(set_rec_scn(scn))) { TRANS_LOG(WARN, "failed to set rec_scn", K(ret), K(scn), KPC(this)); } diff --git a/unittest/storage/memtable/test_memtable_basic.cpp b/unittest/storage/memtable/test_memtable_basic.cpp index 06cb163887..b65bbfe563 100644 --- a/unittest/storage/memtable/test_memtable_basic.cpp +++ b/unittest/storage/memtable/test_memtable_basic.cpp @@ -33,6 +33,7 @@ #include "storage/tx_storage/ob_ls_map.h" #include "share/schema/ob_column_schema.h" #include "storage/ob_storage_schema.h" +#include "storage/tablet/ob_tablet_multi_source_data.h" namespace oceanbase { @@ -525,6 +526,29 @@ TEST_F(TestMemtable, test_unsync_cnt_for_multi_data) ASSERT_EQ(0, storage_schema.get_unsync_cnt_for_multi_data()); } +TEST_F(TestMemtable, test_mds_commit_to_empty_memtable) +{ + ObMemtable memtable; + EXPECT_EQ(OB_SUCCESS, init_memtable(memtable)); + ObTabletTxMultiSourceDataUnit tablet_status; + tablet_status.tablet_status_ = ObTabletStatus::NORMAL; + bool is_callback = true; + bool for_replay = true; + share::SCN scn; + scn.set_max(); + + + ASSERT_EQ(OB_SUCCESS, memtable.save_multi_source_data_unit(&tablet_status, scn, !for_replay, memtable::MemtableRefOp::INC_REF, !is_callback)); + memtable.key_.scn_range_.start_scn_.convert_for_gts(100); + memtable.key_.scn_range_.end_scn_.convert_for_gts(100); + ASSERT_EQ(1, tablet_status.get_unsync_cnt_for_multi_data()); + ASSERT_EQ(OB_SUCCESS, scn.convert_for_gts(102)); + ASSERT_EQ(OB_SUCCESS, memtable.save_multi_source_data_unit(&tablet_status, scn, for_replay, memtable::MemtableRefOp::DEC_REF, is_callback)); + ASSERT_EQ(0, tablet_status.get_unsync_cnt_for_multi_data()); + ASSERT_EQ(OB_SUCCESS, scn.convert_for_gts(101)); + ASSERT_EQ(scn, memtable.get_end_scn()); +} + }// end of oceanbase