diff --git a/mittest/mtlenv/mock_tenant_module_env.h b/mittest/mtlenv/mock_tenant_module_env.h index 5890bcfc3..15aa36ff0 100644 --- a/mittest/mtlenv/mock_tenant_module_env.h +++ b/mittest/mtlenv/mock_tenant_module_env.h @@ -664,7 +664,7 @@ int MockTenantModuleEnv::init() STORAGE_LOG(ERROR, "init_before_start_mtl failed", K(ret)); } else { oceanbase::ObClusterVersion::get_instance().update_data_version(DATA_CURRENT_VERSION); - MTL_BIND(ObTenantIOManager::mtl_init, ObTenantIOManager::mtl_destroy); + MTL_BIND2(nullptr, ObTenantIOManager::mtl_init, nullptr, ObTenantIOManager::mtl_stop, ObTenantIOManager::mtl_wait, ObTenantIOManager::mtl_destroy); MTL_BIND2(mtl_new_default, ObTenantSchemaService::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObStorageLogger::mtl_init, ObStorageLogger::mtl_start, ObStorageLogger::mtl_stop, ObStorageLogger::mtl_wait, mtl_destroy_default); MTL_BIND2(ObTenantMetaMemMgr::mtl_new, mtl_init_default, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); diff --git a/src/observer/omt/ob_multi_tenant.cpp b/src/observer/omt/ob_multi_tenant.cpp index 63e86f721..56405e1ae 100644 --- a/src/observer/omt/ob_multi_tenant.cpp +++ b/src/observer/omt/ob_multi_tenant.cpp @@ -401,7 +401,7 @@ int ObMultiTenant::init(ObAddr myaddr, } if (OB_SUCC(ret) && mtl_bind_flag) { - MTL_BIND(ObTenantIOManager::mtl_init, ObTenantIOManager::mtl_destroy); + MTL_BIND2(nullptr, ObTenantIOManager::mtl_init, nullptr, ObTenantIOManager::mtl_stop, ObTenantIOManager::mtl_wait, ObTenantIOManager::mtl_destroy); // base mtl MTL_BIND2(mtl_new_default, storage::mds::ObTenantMdsService::mtl_init, storage::mds::ObTenantMdsService::mtl_start, storage::mds::ObTenantMdsService::mtl_stop, storage::mds::ObTenantMdsService::mtl_wait, mtl_destroy_default); diff --git a/src/share/io/ob_io_manager.cpp b/src/share/io/ob_io_manager.cpp index 8abe2071a..b95323359 100644 --- a/src/share/io/ob_io_manager.cpp +++ b/src/share/io/ob_io_manager.cpp @@ -611,7 +611,7 @@ int ObTenantIOManager::mtl_init(ObTenantIOManager *&io_service) return ret; } -void ObTenantIOManager::mtl_destroy(ObTenantIOManager *&io_service) +void ObTenantIOManager::mtl_stop(ObTenantIOManager *&io_service) { const uint64_t tenant_id = MTL_ID(); int ret = OB_SUCCESS; @@ -624,6 +624,34 @@ void ObTenantIOManager::mtl_destroy(ObTenantIOManager *&io_service) } } +void ObTenantIOManager::mtl_wait(ObTenantIOManager *&io_service) +{ + int ret = OB_SUCCESS; + const int64_t start_ts = ObTimeUtility::current_time(); + while (OB_NOT_NULL(io_service) && OB_SUCC(ret)) { + if (io_service->get_ref_cnt() == 0) { + break; + } else { + if (REACH_TIME_INTERVAL(1000L * 1000L)) { //1s + LOG_INFO("wait tenant io manager quit", K(MTL_ID()), K(start_ts), K(io_service->get_ref_cnt())); + } + ob_usleep((useconds_t)10L * 1000L); //10ms + } + } +} + +void ObTenantIOManager::mtl_destroy(ObTenantIOManager *&io_service) +{ + int ret = OB_SUCCESS; + if (OB_NOT_NULL(io_service) && io_service->get_ref_cnt() == 0) { + io_service->~ObTenantIOManager(); + OB_IO_MANAGER.allocator_.free(io_service); + } else if (OB_NOT_NULL(io_service) && io_service->get_ref_cnt() != 0) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ERROR: tenant io manager ref_cnt is not zero", K(ret)); + } +} + ObTenantIOManager::ObTenantIOManager() : is_inited_(false), is_working_(false), @@ -1337,9 +1365,5 @@ void ObTenantIOManager::dec_ref() ret = OB_ERR_UNEXPECTED; LOG_ERROR("bug: ref_cnt < 0", K(ret), K(tmp_ref), KCSTRING(lbt())); abort(); - } else if (0 == tmp_ref) { - // destroy will be called when free - this->~ObTenantIOManager(); - OB_IO_MANAGER.allocator_.free(this); } } diff --git a/src/share/io/ob_io_manager.h b/src/share/io/ob_io_manager.h index 0e11bd1b5..efdf4abf6 100644 --- a/src/share/io/ob_io_manager.h +++ b/src/share/io/ob_io_manager.h @@ -101,6 +101,8 @@ class ObTenantIOManager final { public: static int mtl_init(ObTenantIOManager *&io_service); + static void mtl_stop(ObTenantIOManager *&io_service); + static void mtl_wait(ObTenantIOManager *&io_service); static void mtl_destroy(ObTenantIOManager *&io_service); public: ObTenantIOManager(); @@ -150,6 +152,7 @@ public: const ObTenantIOConfig &get_io_config(); int trace_request_if_need(const ObIORequest *req, const char* msg, ObIOTracer::TraceType trace_type); int64_t get_group_num(); + int64_t get_ref_cnt() { return ATOMIC_LOAD(&ref_cnt_); } uint64_t get_usage_index(const int64_t group_id); ObIOAllocator *get_tenant_io_allocator() { return &io_allocator_; } void print_io_status(); diff --git a/unittest/storage/test_major_rows_merger.cpp b/unittest/storage/test_major_rows_merger.cpp index 95168a67c..b4194c52e 100644 --- a/unittest/storage/test_major_rows_merger.cpp +++ b/unittest/storage/test_major_rows_merger.cpp @@ -163,7 +163,7 @@ void ObMajorRowsMergerTest::prepare_merge_context(const ObMergeType &merge_type, } -TEST_F(ObMajorRowsMergerTest, tset_compare_func) +TEST_F(ObMajorRowsMergerTest, test_compare_func) { int ret = OB_SUCCESS; ObTabletMergeDagParam param; @@ -283,6 +283,12 @@ TEST_F(ObMajorRowsMergerTest, tset_compare_func) OK(item_0.iter_->next()); OK(cmp.compare(item_0, item_1, cmp_ret)); ASSERT_EQ(1, cmp_ret); + if (OB_NOT_NULL(iter_0)) { + iter_0->~ObPartitionMergeIter(); + } + if (OB_NOT_NULL(iter_1)) { + iter_1->~ObPartitionMergeIter(); + } } TEST_F(ObMajorRowsMergerTest, single) @@ -388,6 +394,12 @@ TEST_F(ObMajorRowsMergerTest, single) ASSERT_EQ(OB_SUCCESS, merger.top(top)); ASSERT_EQ(item_1.iter_idx_, top->iter_idx_); ASSERT_EQ(OB_SUCCESS, merger.pop()); + if (OB_NOT_NULL(iter_0)) { + iter_0->~ObPartitionMergeIter(); + } + if (OB_NOT_NULL(iter_1)) { + iter_1->~ObPartitionMergeIter(); + } } TEST_F(ObMajorRowsMergerTest, two_iters) @@ -491,6 +503,12 @@ TEST_F(ObMajorRowsMergerTest, two_iters) ASSERT_EQ(0, top->iter_idx_); OK(merger.pop()); ASSERT_TRUE(merger.empty()); + if (OB_NOT_NULL(iter_0)) { + iter_0->~ObPartitionMergeIter(); + } + if (OB_NOT_NULL(iter_1)) { + iter_1->~ObPartitionMergeIter(); + } } }