From 58caa336f2add0f47343a1a3e315491a24342906 Mon Sep 17 00:00:00 2001 From: JiahuaChen Date: Wed, 28 Jun 2023 10:12:15 +0000 Subject: [PATCH] READ_ALL_COMMITED should not return not created tablet --- .../storage/test_tablet_status_cache.cpp | 135 ++++++++++++++++++ src/storage/tablet/ob_tablet.cpp | 17 +++ src/storage/tablet/ob_tablet.h | 1 + .../tablet/ob_tablet_create_delete_helper.cpp | 5 +- src/storage/tablet/ob_tablet_status.cpp | 53 ------- src/storage/tablet/ob_tablet_status.h | 2 - 6 files changed, 155 insertions(+), 58 deletions(-) diff --git a/mittest/mtlenv/storage/test_tablet_status_cache.cpp b/mittest/mtlenv/storage/test_tablet_status_cache.cpp index 1c6bf4ef4f..ddbe421cda 100644 --- a/mittest/mtlenv/storage/test_tablet_status_cache.cpp +++ b/mittest/mtlenv/storage/test_tablet_status_cache.cpp @@ -424,6 +424,141 @@ TEST_F(TestTabletStatusCache, get_transfer_deleted) ObMDSGetTabletMode::READ_READABLE_COMMITED, 100/*snapshot*/); ASSERT_EQ(OB_TABLET_NOT_EXIST, ret); } + +TEST_F(TestTabletStatusCache, get_read_all_committed_tablet) +{ + 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); + 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; + share::SCN commit_scn; + + // creation not commited + user_data.tablet_status_ = ObTabletStatus::MAX; + min_scn.set_min(); + user_data.data_type_ = ObTabletMdsUserDataType::CREATE_TABLET; + user_data.create_commit_scn_ = share::SCN::plus(min_scn, 50); + user_data.create_commit_version_ = 50; + mds::MdsCtx ctx1(mds::MdsWriter(transaction::ObTransID(2023062801))); + ret = tablet->set(user_data, ctx1); + ASSERT_EQ(OB_SUCCESS, ret); + commit_scn = share::SCN::plus(min_scn, 100); + ctx1.single_log_commit(commit_scn, commit_scn); + + tablet_handle.reset(); + 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_TABLET_NOT_EXIST, ret); + + // creation commited + user_data.tablet_status_ = ObTabletStatus::NORMAL; + user_data.data_type_ = ObTabletMdsUserDataType::CREATE_TABLET; + user_data.create_commit_scn_ = share::SCN::plus(min_scn, 50); + user_data.create_commit_version_ = 50; + mds::MdsCtx ctx2(mds::MdsWriter(transaction::ObTransID(2023062802))); + ret = tablet->set(user_data, ctx2); + ASSERT_EQ(OB_SUCCESS, ret); + commit_scn = share::SCN::plus(min_scn, 200); + ctx2.single_log_commit(commit_scn, commit_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); + + // start transfer in not commited + user_data.tablet_status_ = ObTabletStatus::TRANSFER_IN; + user_data.data_type_ = ObTabletMdsUserDataType::START_TRANSFER_IN; + user_data.create_commit_scn_ = share::SCN::plus(min_scn, 50); + user_data.create_commit_version_ = 50; + 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 * 1000 * 1000/*timeout_us*/, + ObMDSGetTabletMode::READ_ALL_COMMITED, ObTransVersion::MAX_TRANS_VERSION/*snapshot*/); + ASSERT_EQ(OB_SUCCESS, ret); + + // start transfer in commited + commit_scn = share::SCN::plus(min_scn, 300); + ctx3.single_log_commit(commit_scn, commit_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); + + // finish transfer in not commited + user_data.tablet_status_ = ObTabletStatus::NORMAL; + user_data.data_type_ = ObTabletMdsUserDataType::FINISH_TRANSFER_IN; + user_data.create_commit_scn_ = share::SCN::plus(min_scn, 50); + user_data.create_commit_version_ = 50; + mds::MdsCtx ctx4(mds::MdsWriter(transaction::ObTransID(2023062804))); + ret = tablet->set(user_data, ctx4); + ASSERT_EQ(OB_SUCCESS, ret); + 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); + + // finish transfer in commited + commit_scn = share::SCN::plus(min_scn, 400); + ctx4.single_log_commit(commit_scn, commit_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); + + // start transfer out not commited + user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT; + user_data.data_type_ = ObTabletMdsUserDataType::START_TRANSFER_OUT; + user_data.create_commit_scn_ = share::SCN::plus(min_scn, 50); + user_data.create_commit_version_ = 50; + mds::MdsCtx ctx5(mds::MdsWriter(transaction::ObTransID(2023062805))); + ret = tablet->set(user_data, ctx5); + ASSERT_EQ(OB_SUCCESS, ret); + 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); + + // start transfer out commited + commit_scn = share::SCN::plus(min_scn, 500); + ctx5.single_log_commit(commit_scn, commit_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); + + // finish transfer out not commited + user_data.tablet_status_ = ObTabletStatus::TRANSFER_OUT_DELETED; + 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; + mds::MdsCtx ctx6(mds::MdsWriter(transaction::ObTransID(2023062806))); + ret = tablet->set(user_data, ctx6); + ASSERT_EQ(OB_SUCCESS, ret); + 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); + + // finish transfer out commited + commit_scn = share::SCN::plus(min_scn, 600); + ctx6.single_log_commit(commit_scn, commit_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); +} + } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet.cpp b/src/storage/tablet/ob_tablet.cpp index 586b4f8513..6a627b0711 100755 --- a/src/storage/tablet/ob_tablet.cpp +++ b/src/storage/tablet/ob_tablet.cpp @@ -5729,6 +5729,23 @@ int ObTablet::check_new_mds_with_cache( return ret; } +int ObTablet::check_tablet_status_for_read_all_committed() +{ + int ret = OB_SUCCESS; + const ObTabletID &tablet_id = get_tablet_meta().tablet_id_; + const ObLSID &ls_id = get_tablet_meta().ls_id_; + ObTabletCreateDeleteMdsUserData user_data; + // first make sure tablet is in any committed state + // then check if it is a empty shell + if (OB_FAIL(get_tablet_status(share::SCN::max_scn(), user_data, 0/*timeout*/))) { + LOG_WARN("failed to get tablet status", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_UNLIKELY(!user_data.tablet_status_.is_valid() || is_empty_shell())) { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("tablet does not exist", K(ret), K(ls_id), K(tablet_id), K(user_data)); + } + return ret; +} + int ObTablet::set_tablet_status( const ObTabletCreateDeleteMdsUserData &tablet_status, mds::MdsCtx &ctx) diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h index eb87d45b01..edde1c6f20 100755 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -487,6 +487,7 @@ public: mds::MdsDumpKV *&kv); int check_new_mds_with_cache(const int64_t snapshot_version, const int64_t timeout); + int check_tablet_status_for_read_all_committed(); int check_schema_version_with_cache(const int64_t schema_version, const int64_t timeout); int check_snapshot_readable_with_cache(const int64_t snapshot_version, const int64_t timeout); int set_tablet_status( diff --git a/src/storage/tablet/ob_tablet_create_delete_helper.cpp b/src/storage/tablet/ob_tablet_create_delete_helper.cpp index ef1f123298..116cfb3d06 100755 --- a/src/storage/tablet/ob_tablet_create_delete_helper.cpp +++ b/src/storage/tablet/ob_tablet_create_delete_helper.cpp @@ -114,9 +114,8 @@ int ObTabletCreateDeleteHelper::check_and_get_tablet( if (OB_UNLIKELY(snapshot_version != ObTransVersion::MAX_TRANS_VERSION)) { ret = OB_NOT_SUPPORTED; LOG_WARN("read all committed mode should only pass max scn", K(ret), K(key), K(mode), K(snapshot_version)); - } else if (OB_UNLIKELY(tablet->is_empty_shell())) { - ret = OB_TABLET_NOT_EXIST; - LOG_WARN("tablet is empty shell", K(ret), K(tablet->get_tablet_meta())); + } else if (OB_FAIL(tablet->check_tablet_status_for_read_all_committed())) { + LOG_WARN("failed to check tablet status", K(ret), K(key)); } } else if (ObMDSGetTabletMode::READ_READABLE_COMMITED == mode) { if (OB_FAIL(tablet->check_new_mds_with_cache(snapshot_version, timeout_us))) { diff --git a/src/storage/tablet/ob_tablet_status.cpp b/src/storage/tablet/ob_tablet_status.cpp index 2a8e71afe2..f94d18f0f8 100644 --- a/src/storage/tablet/ob_tablet_status.cpp +++ b/src/storage/tablet/ob_tablet_status.cpp @@ -95,58 +95,5 @@ int64_t ObTabletStatus::get_serialize_size() const { return serialization::encoded_length_i8(static_cast(status_)); } - -bool ObTabletStatus::is_valid_status(const Status current_status, const Status target_status) -{ - bool b_ret = true; - - switch (current_status) { - case CREATING: - if (target_status != NORMAL && target_status != DELETED) { - b_ret = false; - } - break; - case NORMAL: - if (target_status != DELETING && target_status != NORMAL - && target_status != TRANSFER_OUT && target_status != TRANSFER_IN) { - b_ret = false; - } - break; - case DELETING: - if (target_status != NORMAL && target_status != DELETED - && target_status != DELETING) { - b_ret = false; - } - break; - case DELETED: - break; - case MAX: - if (target_status != CREATING && target_status != DELETED) { - b_ret = false; - } - break; - case TRANSFER_OUT: - if (target_status != NORMAL && target_status != TRANSFER_OUT_DELETED && target_status != TRANSFER_OUT) { - b_ret = false; - } - break; - case TRANSFER_IN: - if (target_status != NORMAL && target_status != DELETED && target_status != TRANSFER_IN) { - b_ret = false; - } - break; - case TRANSFER_OUT_DELETED: - if (target_status != DELETED && target_status != TRANSFER_OUT_DELETED && target_status != TRANSFER_OUT_DELETED) { - b_ret = false; - } - break; - default: - b_ret = false; - break; - } - - return b_ret; -} - } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_status.h b/src/storage/tablet/ob_tablet_status.h index a2aa2cbac3..c85afdfbf1 100644 --- a/src/storage/tablet/ob_tablet_status.h +++ b/src/storage/tablet/ob_tablet_status.h @@ -53,8 +53,6 @@ public: int deserialize(const char *buf, const int64_t len, int64_t &pos); int64_t get_serialize_size() const; - static bool is_valid_status(const Status current_status, const Status target_status); - TO_STRING_KV(K_(status)); private: Status status_;