diff --git a/mittest/mtlenv/storage/test_tablet_status_cache.cpp b/mittest/mtlenv/storage/test_tablet_status_cache.cpp index 2a47669dd..b802c8ab8 100644 --- a/mittest/mtlenv/storage/test_tablet_status_cache.cpp +++ b/mittest/mtlenv/storage/test_tablet_status_cache.cpp @@ -241,7 +241,7 @@ TEST_F(TestTabletStatusCache, get_transfer_out_tablet) ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1_s, ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); //ASSERT_EQ(OB_SCHEMA_EAGAIN, ret); - ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + ASSERT_EQ(OB_ERR_UNEXPECTED, ret); // not committed but user_data.transfer_scn_ has valid_value ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); // mode is READ_ALL_COMMITED, allow to get TRANSFER_OUT status tablet @@ -757,6 +757,47 @@ TEST_F(TestTabletStatusCache, read_all_committed) ASSERT_EQ(OB_SUCCESS, ret); } +TEST_F(TestTabletStatusCache, transfer_out_not_commited_read_from_src_ls) +{ + int ret = OB_SUCCESS; + + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + const ObTabletMapKey key(LS_ID, tablet_id); + ObTabletHandle tablet_handle; + ret = create_tablet(tablet_id, tablet_handle, ObTabletStatus::MAX, share::SCN::invalid_scn()); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + // disable cache + { + SpinWLockGuard guard(tablet->mds_cache_lock_); + tablet->tablet_status_cache_.reset(); + } + + ObTabletCreateDeleteMdsUserData user_data; + share::SCN min_scn; + min_scn.set_min(); + share::SCN commit_scn; + + // start transfer in not commited + user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT; + user_data.data_type_ = ObTabletMdsUserDataType::START_TRANSFER_OUT; + user_data.create_commit_scn_.set_min(); + user_data.create_commit_version_ = ObTransVersion::INVALID_TRANS_VERSION; + user_data.transfer_scn_.set_min(); + + mds::MdsCtx ctx3(mds::MdsWriter(transaction::ObTransID(2023062803))); + ret = tablet->set(user_data, ctx3); + ASSERT_EQ(OB_SUCCESS, ret); + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1_s, + ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); +} + // TODO(@gaishun.gs): refactor test cases to cover all scene /* TEST_F(TestTabletStatusCache, transfer_src_ls_read_all_committed) diff --git a/src/storage/tablet/ob_tablet_create_delete_helper.cpp b/src/storage/tablet/ob_tablet_create_delete_helper.cpp index daa166eaf..18e42e46b 100644 --- a/src/storage/tablet/ob_tablet_create_delete_helper.cpp +++ b/src/storage/tablet/ob_tablet_create_delete_helper.cpp @@ -427,10 +427,12 @@ int ObTabletCreateDeleteHelper::check_read_snapshot_for_transfer_out( LOG_WARN("invalid args", K(ret), K(ls_id), K(tablet_id), K(user_data)); } else if (OB_FAIL(read_snapshot.convert_for_tx(snapshot_version))) { LOG_WARN("failed to convert from int64_t to SCN", K(ret), K(snapshot_version)); + } else if (!is_committed && !transfer_scn.is_min()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("if not committed, transfer_scn should not has value", KR(ret), K(is_committed), K(transfer_scn), K(tablet)); + } else if (transfer_scn.is_min()) { + // noop, before on_redo() } else if (read_snapshot >= transfer_scn) { - // TODO(@gaishun.gs): TEMP SOLUTION, - // return OB_TABLET_NOT_EXIST if read snapshot is no smaller than transfer scn, - // no matter start transfer out transaction is committed or not. ret = OB_TABLET_NOT_EXIST; LOG_WARN("read snapshot is no smaller than transfer scn under transfer out status, should retry on dst ls", K(ret), K(read_snapshot), K(transfer_scn), K(tablet_status));