diff --git a/mittest/mtlenv/storage/test_tablet_status_cache.cpp b/mittest/mtlenv/storage/test_tablet_status_cache.cpp index ddbe421cd..44798d097 100644 --- a/mittest/mtlenv/storage/test_tablet_status_cache.cpp +++ b/mittest/mtlenv/storage/test_tablet_status_cache.cpp @@ -179,14 +179,19 @@ TEST_F(TestTabletStatusCache, weak_read) ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_READABLE_COMMITED, 20/*snapshot*/); ASSERT_EQ(OB_SNAPSHOT_DISCARDED, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + // mode is READ_ALL_COMMITED, but snapshot is not max scn, not supported ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_ALL_COMMITED, 20/*snapshot*/); ASSERT_EQ(OB_NOT_SUPPORTED, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + // mode is READ_READABLE_COMMITED, snapshot version is bigger than create commit version, return OB_SUCCESS ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_READABLE_COMMITED, 60/*snapshot*/); ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(tablet->tablet_status_cache_.is_valid()); } TEST_F(TestTabletStatusCache, get_transfer_out_tablet) @@ -231,20 +236,26 @@ TEST_F(TestTabletStatusCache, get_transfer_out_tablet) ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); ASSERT_EQ(OB_SCHEMA_EAGAIN, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + // mode is READ_ALL_COMMITED, allow to get TRANSFER_OUT status tablet ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); tablet_handle.reset(); // read snapshot: 80. not max scn, return OB_NOT_SUPPORTED ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_ALL_COMMITED, 80/*snapshot*/); ASSERT_EQ(OB_NOT_SUPPORTED, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + // read snapshot: 80. less than transfer scn ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); // check tablet status cache { @@ -266,24 +277,32 @@ TEST_F(TestTabletStatusCache, get_transfer_out_tablet) ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + // mode is READ_ALL_COMMITED, allow to get tablet ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); tablet_handle.reset(); // mode is READ_READABLE_COMMITED, read snapshot 80 less than transfer scn 100, allow to get tablet ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_READABLE_COMMITED, 80/*snapshot*/); ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + // mode is READ_ALL_COMMITED, snapshot is not max scn, return OB_NOT_SUPPORTED ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_ALL_COMMITED, 80/*snapshot*/); ASSERT_EQ(OB_NOT_SUPPORTED, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + // mode is READ_ALL_COMMITED, allow to get tablet ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); // begin transfer out deleted transaction user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT_DELETED; @@ -309,10 +328,13 @@ TEST_F(TestTabletStatusCache, get_transfer_out_tablet) ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + // mode is READ_ALL_COMMITED, allow to get tablet whose snapshot status is transfer out ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); // transaction commit commit_scn = share::SCN::plus(min_scn, 220); @@ -322,10 +344,13 @@ TEST_F(TestTabletStatusCache, get_transfer_out_tablet) ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + // mode is READ_ALL_COMMITED, snapshot status is transfer out deleted, not allow to get ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); // begin transfer out deleted transaction user_data.tablet_status_ = ObTabletStatus::DELETED; @@ -349,6 +374,7 @@ TEST_F(TestTabletStatusCache, get_transfer_out_tablet) ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_READABLE_COMMITED, 100/*snapshot*/); ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); ObLSHandle ls_handle; ret = MTL(ObLSService*)->get_ls(LS_ID, ls_handle, ObLSGetMod::STORAGE_MOD); @@ -416,6 +442,7 @@ TEST_F(TestTabletStatusCache, get_transfer_deleted) ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_READABLE_COMMITED, 100/*snapshot*/); ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); ret = ls->get_tablet_svr()->update_tablet_to_empty_shell(tablet_id); ASSERT_EQ(OB_SUCCESS, ret); @@ -423,6 +450,78 @@ TEST_F(TestTabletStatusCache, get_transfer_deleted) ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, ObMDSGetTabletMode::READ_READABLE_COMMITED, 100/*snapshot*/); ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); +} + +TEST_F(TestTabletStatusCache, get_transfer_out_deleted) +{ + int ret = OB_SUCCESS; + // create tablet + const common::ObTabletID tablet_id(ObTimeUtility::fast_current_time() % 10000000000000); + ObTabletHandle tablet_handle; + ret = create_tablet(tablet_id, tablet_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + ObLSHandle ls_handle; + ret = MTL(ObLSService*)->get_ls(LS_ID, ls_handle, ObLSGetMod::STORAGE_MOD); + ASSERT_EQ(OB_SUCCESS, ret); + ObLS *ls = ls_handle.get_ls(); + ASSERT_NE(nullptr, ls); + + const ObTabletMapKey key(LS_ID, tablet_id); + tablet_handle.reset(); + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(tablet->tablet_status_cache_.is_valid()); + + ObTabletCreateDeleteMdsUserData user_data; + share::SCN min_scn; + min_scn.set_min(); + // set transfer scn + // create commit scn: 50 + // transfer scn: 100 + // delete commit scn: 200 + // begin transfer out deleted transaction + user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT_DELETED; + user_data.transfer_scn_ = share::SCN::plus(min_scn, 100); + user_data.transfer_ls_id_ = share::ObLSID(1010); + user_data.data_type_ = ObTabletMdsUserDataType::FINISH_TRANSFER_OUT; + user_data.create_commit_scn_ = share::SCN::plus(min_scn, 50); + user_data.create_commit_version_ = 50; + user_data.delete_commit_scn_ = share::SCN::plus(min_scn, 200); + user_data.delete_commit_version_ = 200; + + mds::MdsCtx ctx(mds::MdsWriter(transaction::ObTransID(789))); + ret = tablet->set(user_data, ctx); + ASSERT_EQ(OB_SUCCESS, ret); + share::SCN commit_scn = share::SCN::plus(min_scn, 120); + ctx.single_log_commit(commit_scn, commit_scn); + + // disable cache + { + SpinWLockGuard guard(tablet->mds_cache_lock_); + tablet->tablet_status_cache_.reset(); + } + + // mock weak read + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, 210/*snapshot*/); + ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, 100/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); + + ret = ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, 1 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED, INT64_MAX/*snapshot*/); + ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); + ASSERT_TRUE(!tablet->tablet_status_cache_.is_valid()); } TEST_F(TestTabletStatusCache, get_read_all_committed_tablet) @@ -559,6 +658,29 @@ TEST_F(TestTabletStatusCache, get_read_all_committed_tablet) ASSERT_EQ(OB_SUCCESS, ret); } +// TODO(@bowen.gbw): refactor test cases to cover all scene +/* +TEST_F(TestTabletStatusCache, transfer_src_ls_read_all_committed) +{ + +} + +TEST_F(TestTabletStatusCache, transfer_dst_ls_read_all_committed) +{ + +} + +TEST_F(TestTabletStatusCache, transfer_src_ls_read_readable_committed) +{ + +} + +TEST_F(TestTabletStatusCache, transfer_dst_ls_read_readable_committed) +{ + +} +*/ + } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_create_delete_helper.cpp b/src/storage/tablet/ob_tablet_create_delete_helper.cpp index 116cfb3d0..094183045 100755 --- a/src/storage/tablet/ob_tablet_create_delete_helper.cpp +++ b/src/storage/tablet/ob_tablet_create_delete_helper.cpp @@ -188,7 +188,11 @@ int ObTabletCreateDeleteHelper::check_status_for_new_mds( LOG_WARN("failed to check read snapshot by commit version", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(user_data)); } - if (OB_SUCC(ret) && ObTabletStatus::TRANSFER_OUT != tablet_status && user_data.is_valid()) { + if (OB_FAIL(ret)) { + } else if (ObTabletStatus::NORMAL == tablet_status + && user_data.is_valid() + && ObTabletStatus::NORMAL == user_data.tablet_status_) { + // we only set tablet status cache when current status NORMAL and create transaction is COMIITTED tablet_status_cache.set_value(user_data); } diff --git a/src/storage/tablet/ob_tablet_finish_transfer_mds_helper.cpp b/src/storage/tablet/ob_tablet_finish_transfer_mds_helper.cpp index 426870129..ae793f654 100644 --- a/src/storage/tablet/ob_tablet_finish_transfer_mds_helper.cpp +++ b/src/storage/tablet/ob_tablet_finish_transfer_mds_helper.cpp @@ -262,7 +262,6 @@ int ObTabletFinishTransferOutReplayExecutor::check_src_transfer_tablet_( ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet tx data is unexpected", K(ret), - K(ObTabletStatus::get_str(user_data.tablet_status_)), K(transfer_seq), K(user_data), KPC(tablet)); @@ -384,7 +383,6 @@ int ObTabletFinishTransferOutHelper::inner_check_transfer_out_tablet_validity_( ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet tx data is unexpected", K(ret), - K(ObTabletStatus::get_str(user_data.tablet_status_)), K(transfer_seq), K(user_data), KPC(tablet)); @@ -711,10 +709,7 @@ int ObTabletFinishTransferInReplayExecutor::check_dest_transfer_tablet_( ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet tx data is unexpected", K(ret), - K(user_data), K(scn_), - K(tablet->get_tablet_meta()), - K(ObTabletStatus::get_str(user_data.tablet_status_)), K(transfer_seq), K(user_data), KPC(tablet)); @@ -997,7 +992,6 @@ int ObTabletFinishTransferInHelper::inner_check_transfer_in_tablet_validity_( ret = OB_ERR_UNEXPECTED; LOG_ERROR("tablet tx data is unexpected", K(ret), - K(ObTabletStatus::get_str(data.tablet_status_)), K(transfer_seq), K(data), KPC(tablet)); diff --git a/src/storage/tablet/ob_tablet_status.cpp b/src/storage/tablet/ob_tablet_status.cpp index f94d18f0f..bb766c99e 100644 --- a/src/storage/tablet/ob_tablet_status.cpp +++ b/src/storage/tablet/ob_tablet_status.cpp @@ -24,6 +24,8 @@ namespace storage ObTabletStatus::ObTabletStatus() : status_(Status::MAX) { + static_assert(sizeof(status_str_array_) / sizeof(const char *) == static_cast(ObTabletStatus::MAX) + 1, + "status str array size does not equal to enum value count"); } ObTabletStatus::ObTabletStatus(const Status &status) @@ -31,24 +33,13 @@ ObTabletStatus::ObTabletStatus(const Status &status) { } -static const char *TABLET_STATUS_STRS[] = { - "CREATING", - "NORMAL", - "DELETING", - "DELETED", - "TRANSFER_OUT", - "TRANSFER_IN", - "TRANSFER_OUT_DELETED", -}; - const char *ObTabletStatus::get_str(const ObTabletStatus &status) { - const char *str = NULL; - - if (status.status_ < 0 || status.status_ >= ObTabletStatus::MAX) { + const char *str = nullptr; + if (status.status_ > ObTabletStatus::MAX) { str = "UNKNOWN"; } else { - str = TABLET_STATUS_STRS[status.status_]; + str = status_str_array_[status.status_]; } return str; } diff --git a/src/storage/tablet/ob_tablet_status.h b/src/storage/tablet/ob_tablet_status.h index c85afdfbf..9ccb8da88 100644 --- a/src/storage/tablet/ob_tablet_status.h +++ b/src/storage/tablet/ob_tablet_status.h @@ -53,8 +53,20 @@ public: int deserialize(const char *buf, const int64_t len, int64_t &pos); int64_t get_serialize_size() const; - TO_STRING_KV(K_(status)); + TO_STRING_KV("val", static_cast(status_), + "str", get_str(*this)); private: + static constexpr const char *status_str_array_[] = { + "CREATING", + "NORMAL", + "DELETING", + "DELETED", + "TRANSFER_OUT", + "TRANSFER_IN", + "TRANSFER_OUT_DELETED", + "MAX" + }; + Status status_; };