diff --git a/src/storage/tablet/ob_i_tablet_mds_interface.h b/src/storage/tablet/ob_i_tablet_mds_interface.h index f0d420b474..916b441e3b 100644 --- a/src/storage/tablet/ob_i_tablet_mds_interface.h +++ b/src/storage/tablet/ob_i_tablet_mds_interface.h @@ -51,6 +51,7 @@ public: int get_tablet_status(const share::SCN &snapshot, ObTabletCreateDeleteMdsUserData &data, const int64_t timeout = 0) const; + int get_latest_ddl_data(ObTabletBindingMdsUserData &data, bool &is_committed) const; int get_ddl_data(const share::SCN &snapshot, ObTabletBindingMdsUserData &data, const int64_t timeout = 0) const; diff --git a/src/storage/tablet/ob_i_tablet_mds_interface.ipp b/src/storage/tablet/ob_i_tablet_mds_interface.ipp index 5065bde3da..5d43505de9 100644 --- a/src/storage/tablet/ob_i_tablet_mds_interface.ipp +++ b/src/storage/tablet/ob_i_tablet_mds_interface.ipp @@ -53,7 +53,32 @@ inline int ObITabletMdsInterface::get_latest_tablet_status(ObTabletCreateDeleteM [&data](const ObTabletCreateDeleteMdsUserData &user_data) -> int { return data.assign(user_data); }, is_committed, 0))) { - MDS_LOG_GET(WARN, "fail to get_latest_tablet_status"); + MDS_LOG_GET(WARN, "fail to get_latest_tablet_status", K(ret)); + } else if (!data.is_valid()) { + ret = OB_ERR_UNEXPECTED; + MDS_LOG_GET(WARN, "invalid user data", K(lbt())); + } + return ret; + #undef PRINT_WRAPPER +} + +inline int ObITabletMdsInterface::get_latest_ddl_data(ObTabletBindingMdsUserData &data, bool &is_committed) const +{ + #define PRINT_WRAPPER KR(ret), K(data) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!check_is_inited_())) { + ret = OB_NOT_INIT; + MDS_LOG_GET(WARN, "not inited"); + } else if (CLICK_FAIL(get_latest( + [&data](const ObTabletBindingMdsUserData &user_data) -> int { + return data.assign(user_data); + }, is_committed, 0))) { + if (OB_EMPTY_RESULT == ret) { + // ignore frequent log + } else { + MDS_LOG_GET(WARN, "fail to get_latest_ddl_data", K(ret)); + } } else if (!data.is_valid()) { ret = OB_ERR_UNEXPECTED; MDS_LOG_GET(WARN, "invalid user data", K(lbt())); diff --git a/src/storage/tablet/ob_tablet.cpp b/src/storage/tablet/ob_tablet.cpp index f56fd1181a..c8373984e7 100644 --- a/src/storage/tablet/ob_tablet.cpp +++ b/src/storage/tablet/ob_tablet.cpp @@ -7050,7 +7050,7 @@ int ObTablet::check_schema_version_with_cache( { SpinRLockGuard guard(mds_cache_lock_); if (ddl_data_cache_.is_valid()) { - if (OB_FAIL(check_schema_version(schema_version))) { + if (OB_FAIL(check_schema_version(ddl_data_cache_, schema_version))) { LOG_WARN("fail to check schema version", K(ret)); } r_valid = true; @@ -7060,19 +7060,49 @@ int ObTablet::check_schema_version_with_cache( if (OB_SUCC(ret) && !r_valid) { SpinWLockGuard guard(mds_cache_lock_); if (ddl_data_cache_.is_valid()) { - if (OB_FAIL(check_schema_version(schema_version))) { + if (OB_FAIL(check_schema_version(ddl_data_cache_, schema_version))) { LOG_WARN("fail to check schema version", K(ret)); } } else { ObTabletBindingMdsUserData tmp_ddl_data; - if (OB_FAIL(ObITabletMdsInterface::get_ddl_data(share::SCN::max_scn(), tmp_ddl_data, timeout))) { + ObDDLInfoCache tmp_ddl_data_cache; + ObDDLInfoCache *candidate_cache = nullptr; + bool is_committed = false; + if (OB_FAIL(ObITabletMdsInterface::get_latest_ddl_data(tmp_ddl_data, is_committed))) { + if (OB_EMPTY_RESULT == ret) { + is_committed = true; + tmp_ddl_data.set_default_value(); // use default value + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get latest ddl data", KR(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (is_committed) { + // already get valid tmp_ddl_data + } else if (OB_FAIL(ObITabletMdsInterface::get_ddl_data(share::SCN::max_scn(), tmp_ddl_data, timeout))) { LOG_WARN("failed to get snapshot", KR(ret), K(timeout)); - } else if (FALSE_IT(ddl_data_cache_.set_value(tmp_ddl_data))) { - } else if (OB_FAIL(check_schema_version(schema_version))) { - LOG_WARN("fail to check schema version", K(ret), K(ddl_data_cache_)); - } else { - LOG_INFO("refresh ddl data cache", K(ret), K(tablet_meta_.ls_id_), K(tablet_id), K(ddl_data_cache_), - K(schema_version), K(timeout), KP(this)); + } + + if (OB_SUCC(ret)) { + // only enable cache without any on going transaction during the write lock + if (is_committed) { + ddl_data_cache_.set_value(tmp_ddl_data); + candidate_cache = &ddl_data_cache_; + LOG_INFO("refresh ddl data cache", K(ret), K(tablet_meta_.ls_id_), K(tablet_id), K(ddl_data_cache_)); + } else { + tmp_ddl_data_cache.set_value(tmp_ddl_data); + candidate_cache = &tmp_ddl_data_cache; + } + + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(candidate_cache)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ddl data cache is null", K(ret), KP(candidate_cache), K(tablet_meta_.ls_id_), K(tablet_id)); + } else if (OB_FAIL(check_schema_version(*candidate_cache, schema_version))) { + LOG_WARN("fail to check schema version", K(ret), K(tablet_meta_.ls_id_), K(tablet_id)); + } } } } @@ -7081,13 +7111,12 @@ int ObTablet::check_schema_version_with_cache( return ret; } -int ObTablet::check_schema_version(int64_t schema_version) +/*static*/ int ObTablet::check_schema_version(const ObDDLInfoCache& ddl_info_cache, const int64_t schema_version) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(schema_version < ddl_data_cache_.get_schema_version())) { + if (OB_UNLIKELY(schema_version < ddl_info_cache.get_schema_version())) { ret = OB_SCHEMA_EAGAIN; - LOG_WARN("use stale schema before ddl", K(ret), K(get_tablet_meta().tablet_id_), - K(ddl_data_cache_.get_schema_version()), K(schema_version)); + LOG_WARN("use stale schema before ddl", K(ret), K(ddl_info_cache), K(schema_version)); } return ret; } @@ -7109,7 +7138,7 @@ int ObTablet::check_snapshot_readable_with_cache( { SpinRLockGuard guard(mds_cache_lock_); if (ddl_data_cache_.is_valid()) { - if (OB_FAIL(check_snapshot_readable(snapshot_version))) { + if (OB_FAIL(check_snapshot_readable(ddl_data_cache_, snapshot_version))) { LOG_WARN("fail to check schema version", K(ret)); } r_valid = true; @@ -7119,19 +7148,49 @@ int ObTablet::check_snapshot_readable_with_cache( if (OB_SUCC(ret) && !r_valid) { SpinWLockGuard guard(mds_cache_lock_); if (ddl_data_cache_.is_valid()) { - if (OB_FAIL(check_snapshot_readable(snapshot_version))) { + if (OB_FAIL(check_snapshot_readable(ddl_data_cache_, snapshot_version))) { LOG_WARN("fail to check snapshot version", K(ret)); } } else { ObTabletBindingMdsUserData tmp_ddl_data; - if (OB_FAIL(ObITabletMdsInterface::get_ddl_data(share::SCN::max_scn(), tmp_ddl_data, timeout))) { + ObDDLInfoCache tmp_ddl_data_cache; + ObDDLInfoCache *candidate_cache = nullptr; + bool is_committed = false; + if (OB_FAIL(ObITabletMdsInterface::get_latest_ddl_data(tmp_ddl_data, is_committed))) { + if (OB_EMPTY_RESULT == ret) { + is_committed = false; + tmp_ddl_data.set_default_value(); // use default value + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get latest ddl data", KR(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (is_committed) { + // already get valid tmp_ddl_data + } else if (OB_FAIL(ObITabletMdsInterface::get_ddl_data(share::SCN::max_scn(), tmp_ddl_data, timeout))) { LOG_WARN("failed to get snapshot", KR(ret), K(timeout)); - } else if (FALSE_IT(ddl_data_cache_.set_value(tmp_ddl_data))) { - } else if (OB_FAIL(check_snapshot_readable(snapshot_version))) { - LOG_WARN("fail to check snapshot version", K(ret), K(ddl_data_cache_)); - } else { - LOG_INFO("refresh ddl data cache", K(ret), K(tablet_meta_.ls_id_), K(tablet_id), K(ddl_data_cache_), - K(snapshot_version), K(timeout), KP(this)); + } + + if (OB_SUCC(ret)) { + // only enable cache without any on going transaction during the write lock + if (is_committed) { + ddl_data_cache_.set_value(tmp_ddl_data); + candidate_cache = &ddl_data_cache_; + LOG_INFO("refresh ddl data cache", K(ret), K(tablet_meta_.ls_id_), K(tablet_id), K(ddl_data_cache_)); + } else { + tmp_ddl_data_cache.set_value(tmp_ddl_data); + candidate_cache = &tmp_ddl_data_cache; + } + + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(candidate_cache)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ddl data cache is null", K(ret), KP(candidate_cache), K(tablet_meta_.ls_id_), K(tablet_id)); + } else if (OB_FAIL(check_snapshot_readable(*candidate_cache, snapshot_version))) { + LOG_WARN("fail to check snapshot version", K(ret), K(tablet_meta_.ls_id_), K(tablet_id)); + } } } } @@ -7140,17 +7199,15 @@ int ObTablet::check_snapshot_readable_with_cache( return ret; } -int ObTablet::check_snapshot_readable(int64_t snapshot_version) +int ObTablet::check_snapshot_readable(const ObDDLInfoCache& ddl_info_cache, const int64_t snapshot_version) { int ret = OB_SUCCESS; - const share::ObLSID &ls_id = tablet_meta_.ls_id_; - const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; - if (OB_UNLIKELY(ddl_data_cache_.is_redefined() && snapshot_version >= ddl_data_cache_.get_snapshot_version())) { + if (OB_UNLIKELY(ddl_info_cache.is_redefined() && snapshot_version >= ddl_info_cache.get_snapshot_version())) { ret = OB_SCHEMA_EAGAIN; - LOG_WARN("read data after ddl, need to retry on new tablet", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K_(ddl_data_cache)); - } else if (OB_UNLIKELY(!ddl_data_cache_.is_redefined() && snapshot_version < ddl_data_cache_.get_snapshot_version())) { + LOG_WARN("read data after ddl, need to retry on new tablet", K(ret), K(snapshot_version), K(ddl_info_cache)); + } else if (OB_UNLIKELY(!ddl_info_cache.is_redefined() && snapshot_version < ddl_info_cache.get_snapshot_version())) { ret = OB_SNAPSHOT_DISCARDED; - LOG_WARN("read data before ddl", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K_(ddl_data_cache)); + LOG_WARN("read data before ddl", K(ret), K(snapshot_version), K(ddl_info_cache)); } return ret; } diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h index 7d400a94f7..5b6723f9fd 100644 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -629,15 +629,10 @@ private: private: static bool ignore_ret(const int ret); int inner_check_valid(const bool ignore_ha_status = false) const; - int get_min_medium_snapshot(int64_t &min_medium_snapshot) const; int self_serialize(char *buf, const int64_t len, int64_t &pos) const; int64_t get_self_serialize_size() const; - int get_memtable_mgr(ObIMemtableMgr *&memtable_mgr) const; - int get_tablet_memtable_mgr(ObTabletMemtableMgr *&memtable_mgr) const; - - int64_t get_self_size() const; - int check_schema_version(const int64_t schema_version); - int check_snapshot_readable(const int64_t snapshot_version); + static int check_schema_version(const ObDDLInfoCache& ddl_info_cache, const int64_t schema_version); + static int check_snapshot_readable(const ObDDLInfoCache& ddl_info_cache, const int64_t snapshot_version); int get_column_store_sstable_checksum(common::ObIArray &column_checksums, ObCOSSTableV2 &co_sstable); logservice::ObLogHandler *get_log_handler() const { return log_handler_; } // TODO(bowen.gbw): get log handler from tablet pointer handle