diff --git a/mittest/simple_server/env/ob_simple_server.h b/mittest/simple_server/env/ob_simple_server.h index 750c85f182..8139de7c38 100644 --- a/mittest/simple_server/env/ob_simple_server.h +++ b/mittest/simple_server/env/ob_simple_server.h @@ -41,6 +41,7 @@ public: int simple_start(); int simple_close(); std::string get_local_ip(); + int get_mysql_port() { return mysql_port_; } int bootstrap(); void reset(); common::ObMySQLProxy &get_sql_proxy() { return sql_proxy_; } diff --git a/mittest/simple_server/test_location_service.cpp b/mittest/simple_server/test_location_service.cpp index bfeefa4499..a01a491719 100644 --- a/mittest/simple_server/test_location_service.cpp +++ b/mittest/simple_server/test_location_service.cpp @@ -35,12 +35,13 @@ class TestLocationService : public unittest::ObSimpleClusterTestBase { public: TestLocationService() : unittest::ObSimpleClusterTestBase("test_location_service") {} - int batch_create_table(ObMySQLProxy &sql_proxy, const int64_t TOTAL_NUM, ObIArray &tablet_ls_pairs); + int batch_create_table(ObMySQLProxy &sql_proxy, const int64_t TOTAL_NUM, const bool oracle_mode, ObIArray &tablet_ls_pairs); }; int TestLocationService::batch_create_table( ObMySQLProxy &sql_proxy, const int64_t TOTAL_NUM, + const bool oracle_mode, ObIArray &tablet_ls_pairs) { int ret = OB_SUCCESS; @@ -50,26 +51,25 @@ int TestLocationService::batch_create_table( int64_t affected_rows = 0; for (int64_t i = 0; OB_SUCC(ret) && i < TOTAL_NUM; ++i) { sql.reset(); - if (OB_FAIL(sql.assign_fmt("create table t%ld(c1 int)", i))) { + if (OB_FAIL(sql.assign_fmt("create table T%ld(c1 int)", i))) { } else if (OB_FAIL(sql_proxy.write(sql.ptr(), affected_rows))) { } } // batch get table_id sql.reset(); - if (OB_FAIL(sql.assign_fmt("select TABLET_ID, LS_ID from oceanbase.DBA_OB_TABLE_LOCATIONS where table_name in ("))) { + if (OB_FAIL(sql.assign_fmt("select TABLET_ID, LS_ID from %sDBA_OB_TABLE_LOCATIONS where table_name in (", oracle_mode ? "" : "oceanbase."))) { } else { for (int64_t i = 0; OB_SUCC(ret) && i < TOTAL_NUM; ++i) { - if (OB_FAIL(sql.append_fmt("%s't%ld'", 0 == i ? "" : ",", i))) {} + if (OB_FAIL(sql.append_fmt("%s'T%ld'", 0 == i ? "" : ",", i))) {} } if (FAILEDx(sql.append_fmt(") order by TABLET_ID"))) {}; } SMART_VAR(ObMySQLProxy::MySQLResult, result) { if (OB_FAIL(tablet_ls_pairs.reserve(TOTAL_NUM))) { - } else if (OB_UNLIKELY(!is_valid_tenant_id(g_tenant_id))) { - ret = OB_ERR_UNEXPECTED; } else if (OB_FAIL(sql_proxy.read(result, sql.ptr()))) { } else if (OB_ISNULL(result.get_result())) { ret = OB_ERR_UNEXPECTED; + LOG_WARN("null result", KR(ret), K(sql)); } else { sqlclient::ObMySQLResult &res = *result.get_result(); uint64_t tablet_id = ObTabletID::INVALID_TABLET_ID; @@ -96,7 +96,7 @@ TEST_F(TestLocationService, prepare_data) ASSERT_EQ(OB_SUCCESS, get_tenant_id(g_tenant_id)); ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); - ASSERT_EQ(OB_SUCCESS, batch_create_table(sql_proxy, TOTAL_NUM, g_tablet_ls_pairs)); + ASSERT_EQ(OB_SUCCESS, batch_create_table(sql_proxy, TOTAL_NUM, false, g_tablet_ls_pairs)); } TEST_F(TestLocationService, test_ls_location_service) @@ -185,7 +185,7 @@ TEST_F(TestLocationService, test_tablet_ls_service) ASSERT_TRUE(tablet_ls_caches.at(0).get_tablet_id() == g_tablet_ls_pairs.at(0).get_tablet_id()); ASSERT_TRUE(tablet_ls_caches.at(0).get_ls_id() == g_tablet_ls_pairs.at(0).get_ls_id()); - // duplicated tablet_id return error + // duplicated tablet_id return OB_SUCCESS tablet_list.reset(); tablet_ls_caches.reset(); ASSERT_EQ(OB_SUCCESS, tablet_list.push_back(g_tablet_ls_pairs.at(0).get_tablet_id())); @@ -301,6 +301,81 @@ TEST_F(TestLocationService, test_check_ls_exist) ASSERT_TRUE(state.is_uncreated()); } +TEST_F(TestLocationService, test_clear_tablet_ls_cache) +{ + int ret = OB_SUCCESS; + ASSERT_TRUE(g_tablet_ls_pairs.count() == TOTAL_NUM); + ASSERT_TRUE(is_valid_tenant_id(g_tenant_id)); + ObLocationService *location_service = GCTX.location_service_; + ASSERT_TRUE(OB_NOT_NULL(location_service)); + ObTabletLSService *tablet_ls_service = &(location_service->tablet_ls_service_); + ASSERT_TRUE(OB_NOT_NULL(tablet_ls_service)); + + // create tenant + uint64_t tenant_id = OB_INVALID_TENANT_ID; + ASSERT_EQ(OB_SUCCESS, create_tenant("oracle", "2G", "2G", true)); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(tenant_id, "oracle")); + ASSERT_TRUE(is_valid_tenant_id(tenant_id)); + + // create sql_proxy + common::sqlclient::ObSingleMySQLConnectionPool sql_conn_pool; + common::ObMySQLProxy oracle_sql_proxy; + sql_conn_pool.set_db_param("sys@oracle", "", "SYS"); + ObConnPoolConfigParam param; + param.sqlclient_wait_timeout_ = 1000; + param.long_query_timeout_ = 300*1000*1000; + param.connection_refresh_interval_ = 200*1000; + param.connection_pool_warn_time_ = 10*1000*1000; + param.sqlclient_per_observer_conn_limit_ = 1000; + common::ObAddr db_addr; + db_addr.set_ip_addr(get_curr_simple_server().get_local_ip().c_str(), get_curr_simple_server().get_mysql_port()); + ret = sql_conn_pool.init(db_addr, param); + if (OB_SUCC(ret)) { + sql_conn_pool.set_mode(common::sqlclient::ObMySQLConnection::DEBUG_MODE); + ret = oracle_sql_proxy.init(&sql_conn_pool); + } + ASSERT_EQ(OB_SUCCESS, ret); + + // create table + const int64_t TABLET_COUNT = 10; + ObSEArray tablet_ls_pairs; + ASSERT_EQ(OB_SUCCESS, batch_create_table(oracle_sql_proxy, TABLET_COUNT, true, tablet_ls_pairs)); + ASSERT_TRUE(TABLET_COUNT == tablet_ls_pairs.count()); + const int64_t cache_size_before_renew = tablet_ls_service->inner_cache_.size(); + ObArenaAllocator allocator; + ObList tablet_list(allocator); + ObSEArray tablet_ls_caches; + ARRAY_FOREACH(tablet_ls_pairs, idx) { + const ObTabletLSPair &pair = tablet_ls_pairs.at(idx); + ASSERT_EQ(OB_SUCCESS, tablet_list.push_back(pair.get_tablet_id())); + } + + // renew cache + ASSERT_EQ(OB_SUCCESS, tablet_ls_service->batch_renew_tablet_ls_cache(tenant_id, tablet_list, tablet_ls_caches)); + int64_t cache_size = tablet_ls_service->inner_cache_.size(); + ASSERT_TRUE(TABLET_COUNT == cache_size - cache_size_before_renew); + + // test clear dropped tenant cache + ASSERT_EQ(OB_SUCCESS, delete_tenant("oracle")); + ASSERT_EQ(OB_SUCCESS, tablet_ls_service->clear_expired_cache()); + cache_size = tablet_ls_service->inner_cache_.size(); + ASSERT_TRUE(cache_size == cache_size_before_renew); + + // test 1 million cache clear + for (int64_t i = 0; i < 1000000; ++i) { + ObTabletLSCache cache; + ASSERT_EQ(OB_SUCCESS, cache.init(tenant_id, ObTabletID(i+300000), ObLSID(1002), ObClockGenerator::getClock(), 1)); + ASSERT_EQ(OB_SUCCESS, tablet_ls_service->inner_cache_.update(cache)); + } + cache_size = tablet_ls_service->inner_cache_.size(); + ASSERT_TRUE(1000000 == cache_size - cache_size_before_renew); + const int64_t start_time = ObTimeUtility::current_time(); + ASSERT_EQ(OB_SUCCESS, tablet_ls_service->clear_expired_cache()); + cache_size = tablet_ls_service->inner_cache_.size(); + ASSERT_TRUE(cache_size = cache_size_before_renew); + LOG_INFO("TEST: clear 1 million cache", "cost_time", ObTimeUtility::current_time() - start_time); // cost_time = 1.67s +} + } // namespace rootserver } // namespace oceanbase int main(int argc, char **argv) diff --git a/src/share/location_cache/ob_location_update_task.cpp b/src/share/location_cache/ob_location_update_task.cpp index f8d4852d8e..5a910c9a5a 100644 --- a/src/share/location_cache/ob_location_update_task.cpp +++ b/src/share/location_cache/ob_location_update_task.cpp @@ -14,6 +14,7 @@ #include "share/location_cache/ob_location_update_task.h" #include "share/location_cache/ob_ls_location_service.h" +#include "share/location_cache/ob_tablet_ls_service.h" namespace oceanbase { @@ -324,5 +325,19 @@ int ObVTableLocUpdateTask::assign_when_equal( return OB_NOT_SUPPORTED; } +ObClearTabletLSCacheTimerTask::ObClearTabletLSCacheTimerTask( + ObTabletLSService &tablet_ls_service) + : tablet_ls_service_(tablet_ls_service) +{ +} + +void ObClearTabletLSCacheTimerTask::runTimerTask() +{ + int ret = OB_SUCCESS; + if (OB_FAIL(tablet_ls_service_.clear_expired_cache())) { + LOG_WARN("fail to clear expired cache", KR(ret)); + } +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/location_cache/ob_location_update_task.h b/src/share/location_cache/ob_location_update_task.h index 2df686d4fe..f5f6115289 100644 --- a/src/share/location_cache/ob_location_update_task.h +++ b/src/share/location_cache/ob_location_update_task.h @@ -21,6 +21,7 @@ namespace oceanbase namespace share { class ObLSLocationService; +class ObTabletLSService; class ObLSLocationUpdateTask : public observer::ObIUniqTaskQueueTask @@ -199,6 +200,16 @@ private: int64_t add_timestamp_; }; +class ObClearTabletLSCacheTimerTask : public common::ObTimerTask +{ +public: + explicit ObClearTabletLSCacheTimerTask(ObTabletLSService &tablet_ls_service); + virtual ~ObClearTabletLSCacheTimerTask() {} + virtual void runTimerTask() override; +private: + ObTabletLSService &tablet_ls_service_; +}; + } // end namespace share } // end namespace oceanbase #endif diff --git a/src/share/location_cache/ob_tablet_ls_map.h b/src/share/location_cache/ob_tablet_ls_map.h index 8c22a6908c..ed6c1a4b27 100644 --- a/src/share/location_cache/ob_tablet_ls_map.h +++ b/src/share/location_cache/ob_tablet_ls_map.h @@ -49,6 +49,9 @@ public: int del(const ObTabletLSKey &key); int64_t size() const { return size_; } + template + int for_each_and_delete_if(Function &func); + private: // void try_update_access_ts_(ObTabletLSCache *cache_ptr); @@ -64,6 +67,40 @@ private: common::ObQSyncLock *buckets_lock_; }; +template +int ObTabletLSMap::for_each_and_delete_if(Function &func) +{ + int ret = OB_SUCCESS; + ObTabletLSCache *prev = NULL; + ObTabletLSCache *curr = NULL; + ObTabletLSCache *next = NULL; + for (int64_t i = 0; i < BUCKETS_CNT; ++i) { + ObQSyncLockWriteGuard guard(buckets_lock_[i % LOCK_SLOT_CNT]); + prev = NULL; + curr = ls_buckets_[i]; + next = NULL; + // foreach bucket + while (OB_NOT_NULL(curr) && OB_SUCC(ret)) { + next = static_cast(curr->next_); + if (func(*curr)) { // need to delete + if (OB_ISNULL(prev)) { + // the first node + ls_buckets_[i] = next; + } else { + prev->next_ = curr->next_; + } + curr->next_ = NULL; + op_free(curr); + ATOMIC_DEC(&size_); + } else { // no need to delete + prev = curr; + } + curr = next; + } + } + return ret; +} + } // end namespace share } // end namespace oceanbase #endif diff --git a/src/share/location_cache/ob_tablet_ls_service.cpp b/src/share/location_cache/ob_tablet_ls_service.cpp index b38fedef5d..55b12cf457 100644 --- a/src/share/location_cache/ob_tablet_ls_service.cpp +++ b/src/share/location_cache/ob_tablet_ls_service.cpp @@ -27,6 +27,7 @@ namespace oceanbase { using namespace common; +using namespace common::hash; namespace share { @@ -49,6 +50,12 @@ int ObTabletLSService::init(common::ObMySQLProxy &sql_proxy) } else if (OB_FAIL(async_queue_.init(this, user_thread_cnt, user_queue_size, "TabletLSAUp"))) { LOG_WARN("async_queue init failed", KR(ret), K(user_thread_cnt), K(user_queue_size)); + } else if (OB_FAIL(TG_SCHEDULE( + lib::TGDefIDs::ServerGTimer, + clear_expired_cache_task_, + CLEAR_EXPIRED_CACHE_INTERVAL_US, + true/*repeat*/))) { + LOG_WARN("schedule clear expired cache timer task failed", KR(ret)); } else { sql_proxy_ = &sql_proxy; inited_ = true; @@ -522,5 +529,75 @@ bool ObTabletLSService::belong_to_sys_ls_( return is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id) || tablet_id.is_sys_tablet(); } +class ObTabletLSService::IsDroppedTenantCacheFunctor +{ +public: + explicit IsDroppedTenantCacheFunctor( + ObHashSet &dropped_tenant_set_) + : dropped_tenant_set_(dropped_tenant_set_) {} + ~IsDroppedTenantCacheFunctor() {} + bool operator()(const ObTabletLSCache &cache) + { + int ret = OB_SUCCESS; + bool is_expired_cache = false; + const uint64_t tenant_id = cache.get_tenant_id(); + ret = dropped_tenant_set_.exist_refactored(tenant_id); + if (OB_HASH_EXIST == ret) { + is_expired_cache = true; + } else if (OB_HASH_NOT_EXIST == ret) { + is_expired_cache = false; + } else { + LOG_WARN("error unexpected", KR(ret), K(tenant_id)); + } + return is_expired_cache; + } +private: + DISALLOW_COPY_AND_ASSIGN(IsDroppedTenantCacheFunctor); + ObHashSet &dropped_tenant_set_; +}; + +// Only clear cache for dropped tenant now +// TODO: need a better clear strategy for each tenant expired caches +int ObTabletLSService::clear_expired_cache() +{ + int ret = OB_SUCCESS; + bool sys_tenant_schema_ready = false; + ObArray dropped_tenant_ids; + ObHashSet dropped_tenant_set; + const int64_t cache_size = inner_cache_.size(); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("service not init", KR(ret)); + } else if (OB_ISNULL(GCTX.schema_service_)) { + LOG_WARN("GCTX.schema_service_ is null", KR(ret)); + } else if (!GCTX.schema_service_->is_tenant_refreshed(OB_SYS_TENANT_ID)) { + ret = OB_NEED_RETRY; + LOG_WARN("can not clear expiered cache because sys tenant schema is not ready", KR(ret), K(cache_size)); + } else if (OB_FAIL(GCTX.schema_service_->get_dropped_tenant_ids(dropped_tenant_ids))) { + LOG_WARN("get tenant ids failed", KR(ret)); + } else if (OB_FAIL(dropped_tenant_set.create(dropped_tenant_ids.count()))) { + LOG_WARN("create failed", KR(ret), "count", dropped_tenant_ids.count()); + } else { + // use hashset to improve performance + ARRAY_FOREACH(dropped_tenant_ids, idx) { + const uint64_t tenant_id = dropped_tenant_ids.at(idx); + if (!is_user_tenant(tenant_id)) { + // skip + } else if (OB_FAIL(dropped_tenant_set.set_refactored(tenant_id))) { + // OB_HASH_EXIST is also unexpected + LOG_WARN("set_refactored failed", KR(ret), K(idx), K(tenant_id)); + } + } + IsDroppedTenantCacheFunctor functor(dropped_tenant_set); + if (FAILEDx(inner_cache_.for_each_and_delete_if(functor))) { + LOG_WARN("for each and delete if is dropped tenant cache failed", KR(ret)); + } else { + LOG_INFO("[TABLET_LOCATION] clear dropped tenant tablet ls cache successfully", + "cache_size_before_clear", cache_size, "cache_size_after_clear", inner_cache_.size()); + } + } + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/location_cache/ob_tablet_ls_service.h b/src/share/location_cache/ob_tablet_ls_service.h index 80748798ce..50afa853e9 100644 --- a/src/share/location_cache/ob_tablet_ls_service.h +++ b/src/share/location_cache/ob_tablet_ls_service.h @@ -35,7 +35,11 @@ class ObTabletLSService { public: ObTabletLSService() - : inited_(false), sql_proxy_(NULL), inner_cache_(), async_queue_() {} + : inited_(false), + sql_proxy_(NULL), + inner_cache_(), + async_queue_(), + clear_expired_cache_task_(*this) {} virtual ~ObTabletLSService() {} int init(common::ObMySQLProxy &sql_proxy); // Gets the mapping between the tablet and log stream synchronously. @@ -87,6 +91,8 @@ public: int destroy(); int reload_config(); + int clear_expired_cache(); + private: int get_from_cache_( const uint64_t tenant_id, @@ -102,15 +108,20 @@ private: int erase_cache_(const uint64_t tenant_id, const ObTabletID &tablet_id); bool belong_to_sys_ls_(const uint64_t tenant_id, const ObTabletID &tablet_id) const; +private: + class IsDroppedTenantCacheFunctor; // use to clear expired cache of dropped tenant + const int64_t MINI_MODE_UPDATE_THREAD_CNT = 1; const int64_t USER_TASK_QUEUE_SIZE = 100 * 1000; // 10W partitions const int64_t MINI_MODE_USER_TASK_QUEUE_SIZE = 10 * 1000; // 1W partitions + const int64_t CLEAR_EXPIRED_CACHE_INTERVAL_US = 6 * 3600 * 1000 * 1000L; // 6h bool inited_; bool stopped_; common::ObMySQLProxy *sql_proxy_; ObTabletLSMap inner_cache_; // Store the mapping between tablet and log stream in user tenant. ObTabletLSUpdateQueue async_queue_; + ObClearTabletLSCacheTimerTask clear_expired_cache_task_; // timer task used to clear the expired cache //TODO: need more queue later }; diff --git a/src/share/schema/ob_multi_version_schema_service.cpp b/src/share/schema/ob_multi_version_schema_service.cpp index 54e5a5410c..b85adbebb0 100644 --- a/src/share/schema/ob_multi_version_schema_service.cpp +++ b/src/share/schema/ob_multi_version_schema_service.cpp @@ -5146,6 +5146,28 @@ int ObMultiVersionSchemaService::batch_fetch_tablet_to_table_history_( return ret; } +int ObMultiVersionSchemaService::get_dropped_tenant_ids( + common::ObIArray &dropped_tenant_ids) +{ + int ret = OB_SUCCESS; + dropped_tenant_ids.reset(); + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("inner stat error", KR(ret)); + } else { + SpinRLockGuard guard(schema_manager_rwlock_); + ObSchemaGetterGuard schema_guard; + if (OB_UNLIKELY(!is_tenant_full_schema(OB_SYS_TENANT_ID))) { + ret = OB_NOT_INIT; + LOG_WARN("sys schema is not full", KR(ret)); + } else if (OB_FAIL(get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("get sys tenant schema guard failed", KR(ret)); + } else if (OB_FAIL(schema_guard.get_dropped_tenant_ids(dropped_tenant_ids))) { + LOG_WARN("get dropped tenant ids failed", KR(ret)); + } + } + return ret; +} }//end of namespace schema }//end of namespace share diff --git a/src/share/schema/ob_multi_version_schema_service.h b/src/share/schema/ob_multi_version_schema_service.h index 1b02355f5b..998b98c9c5 100644 --- a/src/share/schema/ob_multi_version_schema_service.h +++ b/src/share/schema/ob_multi_version_schema_service.h @@ -254,7 +254,7 @@ public: const uint64_t tenant_id, const int64_t version_cnt, int64_t &schema_version); - + int get_dropped_tenant_ids(common::ObIArray &dropped_tenant_ids); /*----------- check schema interface -----------------*/ bool is_sys_full_schema() const; diff --git a/src/share/schema/ob_schema_getter_guard.cpp b/src/share/schema/ob_schema_getter_guard.cpp index 04d574cd10..af5ea4abed 100644 --- a/src/share/schema/ob_schema_getter_guard.cpp +++ b/src/share/schema/ob_schema_getter_guard.cpp @@ -8812,6 +8812,22 @@ int ObSchemaGetterGuard::check_if_tenant_has_been_dropped(const uint64_t tenant_ return ret; } +int ObSchemaGetterGuard::get_dropped_tenant_ids(common::ObIArray &dropped_tenant_ids) const +{ + int ret = OB_SUCCESS; + dropped_tenant_ids.reset(); + const ObSchemaMgr *schema_mgr = NULL; + if (OB_FAIL(get_schema_mgr(OB_SYS_TENANT_ID, schema_mgr))) { + LOG_WARN("fail to get schema mgr", KR(ret)); + } else if (OB_ISNULL(schema_mgr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema_mgr is null", KR(ret)); + } else if (OB_FAIL(schema_mgr->get_drop_tenant_ids(dropped_tenant_ids))) { + LOG_WARN("fail to get drop tenant ids", KR(ret)); + } + return ret; +} + int ObSchemaGetterGuard::check_is_creating_standby_tenant(const uint64_t tenant_id, bool &is_creating_standby) { int ret = OB_SUCCESS; diff --git a/src/share/schema/ob_schema_getter_guard.h b/src/share/schema/ob_schema_getter_guard.h index 0c9ecaf88c..a51b141b5a 100644 --- a/src/share/schema/ob_schema_getter_guard.h +++ b/src/share/schema/ob_schema_getter_guard.h @@ -1021,6 +1021,7 @@ public: int check_tenant_is_restore(const uint64_t tenant_id, bool &is_restore); int get_tenant_status(const uint64_t tenant_id, ObTenantStatus &status); int check_if_tenant_has_been_dropped(const uint64_t tenant_id, bool &is_dropped); + int get_dropped_tenant_ids(common::ObIArray &dropped_tenant_ids) const; int check_is_creating_standby_tenant(const uint64_t tenant_id, bool &is_creating_standby); int check_keystore_exist(const uint64_t tenant_id, bool &exist); diff --git a/src/share/schema/ob_schema_mgr.cpp b/src/share/schema/ob_schema_mgr.cpp index f78bbd9e45..d7c8c0cbab 100644 --- a/src/share/schema/ob_schema_mgr.cpp +++ b/src/share/schema/ob_schema_mgr.cpp @@ -1307,6 +1307,28 @@ int ObSchemaMgr::get_drop_tenant_info(const uint64_t tenant_id, ObDropTenantInfo return ret; } +int ObSchemaMgr::get_drop_tenant_ids(common::ObIArray &drop_tenant_ids) const +{ + int ret = OB_SUCCESS; + drop_tenant_ids.reset(); + if (!check_inner_stat()) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_FAIL(drop_tenant_ids.reserve(drop_tenant_infos_.count()))) { + LOG_WARN("reserve failed", KR(ret), "count", drop_tenant_infos_.count()); + } else { + for (ConstDropTenantInfoIterator iter = drop_tenant_infos_.begin(); + OB_SUCC(ret) && iter != drop_tenant_infos_.end(); + iter++) { + const ObDropTenantInfo &drop_tenant_info = *(*iter); + if (OB_FAIL(drop_tenant_ids.push_back(drop_tenant_info.get_tenant_id()))) { + LOG_WARN("push back failed", KR(ret), K(drop_tenant_info)); + } + } + } + return ret; +} + int ObSchemaMgr::get_synonym_schema( const uint64_t tenant_id, const uint64_t synonym_id, diff --git a/src/share/schema/ob_schema_mgr.h b/src/share/schema/ob_schema_mgr.h index d73845e7e5..9f1bd881d6 100644 --- a/src/share/schema/ob_schema_mgr.h +++ b/src/share/schema/ob_schema_mgr.h @@ -795,6 +795,7 @@ public: int del_drop_tenant_info(const uint64_t tenant_id); // drop_tenant_info is invalid, indicating that the DDL of the drop tenant has not been read int get_drop_tenant_info(const uint64_t tenant_id, ObDropTenantInfo &drop_tenant_info) const; + int get_drop_tenant_ids(common::ObIArray &drop_tenant_ids) const; /*schema statistics*/ int get_schema_size(int64_t &total_size) const;