diff --git a/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp b/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp index 319ddcb54..1a3402c38 100644 --- a/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp +++ b/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp @@ -367,6 +367,8 @@ void TestConcurrentT3M::run1() addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; handle.get_obj()->set_tablet_addr(addr); + handle.get_obj()->is_inited_ = true; // to pass test + handle.get_obj()->table_store_addr_.addr_.set_none_addr(); ret = t3m_.compare_and_swap_tablet(key, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); @@ -591,6 +593,8 @@ TEST_F(TestTenantMetaMemMgr, test_tablet) addr.size_ = 4096; addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; handle.get_obj()->set_tablet_addr(addr); + handle.get_obj()->is_inited_ = true; // to pass test + handle.get_obj()->table_store_addr_.addr_.set_none_addr(); ret = t3m_.compare_and_swap_tablet(key, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); @@ -1199,6 +1203,9 @@ TEST_F(TestTenantMetaMemMgr, test_replace_tablet) ASSERT_EQ(common::OB_ITEM_NOT_SETTED, ret); ASSERT_TRUE(!tmp_handle.is_valid()); + handle.get_obj()->is_inited_ = true; // to pass test + handle.get_obj()->table_store_addr_.addr_.set_none_addr(); + ret = t3m_.compare_and_swap_tablet(key, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); @@ -1270,6 +1277,9 @@ TEST_F(TestTenantMetaMemMgr, test_replace_tablet) addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; tablet->set_tablet_addr(addr); + tablet->is_inited_ = true; // to pass test + tablet->table_store_addr_.addr_.set_none_addr(); + ret = t3m_.compare_and_swap_tablet(key, old_handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, t3m_.tablet_map_.map_.size()); diff --git a/src/observer/virtual_table/ob_all_virtual_table_mgr.cpp b/src/observer/virtual_table/ob_all_virtual_table_mgr.cpp index 8076417fb..e7d23197d 100644 --- a/src/observer/virtual_table/ob_all_virtual_table_mgr.cpp +++ b/src/observer/virtual_table/ob_all_virtual_table_mgr.cpp @@ -115,7 +115,7 @@ int ObAllVirtualTableMgr::get_next_tablet() if (nullptr == tablet_iter_) { tablet_allocator_.set_tenant_id(MTL_ID()); ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_))) { + if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_, nullptr/*no op*/))) { ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "fail to new tablet_iter_", K(ret)); } diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_compaction_info.cpp b/src/observer/virtual_table/ob_all_virtual_tablet_compaction_info.cpp index 2a436248e..181618e65 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_compaction_info.cpp +++ b/src/observer/virtual_table/ob_all_virtual_tablet_compaction_info.cpp @@ -116,7 +116,7 @@ int ObAllVirtualTabletCompactionInfo::get_next_tablet() if (nullptr == tablet_iter_) { tablet_allocator_.set_tenant_id(MTL_ID()); ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_))) { + if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_, nullptr/*no op*/))) { ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "fail to new tablet_iter_", K(ret)); } diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.cpp b/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.cpp index 5035b55c2..78e2e0f47 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.cpp +++ b/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.cpp @@ -561,7 +561,7 @@ int ObAllVirtualTabletSSTableMacroInfo::get_next_tablet() iter_allocator_.set_tenant_id(MTL_ID()); rowkey_allocator_.set_tenant_id(MTL_ID()); ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_))) { + if (OB_ISNULL(tablet_iter_ = new (iter_buf_) ObTenantTabletIterator(*t3m, tablet_allocator_, nullptr/*no op*/))) { ret = OB_ERR_UNEXPECTED; SERVER_LOG(WARN, "fail to new tablet_iter_", K(ret)); } diff --git a/src/storage/blocksstable/ob_block_manager.cpp b/src/storage/blocksstable/ob_block_manager.cpp index 98face2e9..0790624d1 100644 --- a/src/storage/blocksstable/ob_block_manager.cpp +++ b/src/storage/blocksstable/ob_block_manager.cpp @@ -1068,7 +1068,7 @@ int ObBlockManager::mark_tenant_blocks( LOG_WARN("fail to mark tenant meta blocks", K(ret)); } else { ObArenaAllocator iter_allocator("MarkIter", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); - ObTenantTabletIterator tablet_iter(*t3m, iter_allocator); + ObTenantTabletIterator tablet_iter(*t3m, iter_allocator, nullptr/*no op*/); ObTabletHandle handle; while (OB_SUCC(ret)) { handle.reset(); diff --git a/src/storage/blocksstable/ob_shared_macro_block_manager.cpp b/src/storage/blocksstable/ob_shared_macro_block_manager.cpp index 8953a7ad8..5ede0f0e6 100644 --- a/src/storage/blocksstable/ob_shared_macro_block_manager.cpp +++ b/src/storage/blocksstable/ob_shared_macro_block_manager.cpp @@ -435,7 +435,8 @@ int ObSharedMacroBlockMgr::defragment() ObArenaAllocator task_allocator("SSTDefragTask", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); ObArenaAllocator iter_allocator("SSTDefragIter", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); ObFixedArray macro_ids(task_allocator); - ObTenantTabletIterator tablet_iter(*(MTL(ObTenantMetaMemMgr*)), iter_allocator); + ObHasNestedTableFilterOp op; + ObTenantTabletIterator tablet_iter(*(MTL(ObTenantMetaMemMgr*)), iter_allocator, &op); ObSSTableIndexBuilder *sstable_index_builder = nullptr; ObIndexBlockRebuilder *index_block_rebuilder = nullptr; int64_t rewrite_cnt = 0; diff --git a/src/storage/blocksstable/ob_shared_macro_block_manager.h b/src/storage/blocksstable/ob_shared_macro_block_manager.h index 00c521533..2d19918ec 100644 --- a/src/storage/blocksstable/ob_shared_macro_block_manager.h +++ b/src/storage/blocksstable/ob_shared_macro_block_manager.h @@ -18,6 +18,7 @@ #include "storage/blocksstable/ob_block_manager.h" #include "lib/task/ob_timer.h" #include "storage/compaction/ob_compaction_util.h" +#include "storage/meta_mem/ob_tablet_pointer.h" namespace oceanbase { @@ -196,6 +197,15 @@ private: bool is_inited_; }; +class ObHasNestedTableFilterOp final : public ObITabletFilterOp +{ +public: + int do_filter(const ObTabletResidentInfo &info, bool &is_skipped) override { + is_skipped = !info.has_nested_table(); + return OB_SUCCESS; + } +}; + } // namespace blocksstable } // namespace oceanbase diff --git a/src/storage/high_availability/ob_tablet_ha_status.h b/src/storage/high_availability/ob_tablet_ha_status.h index d5f3d1791..26f3d4ac0 100644 --- a/src/storage/high_availability/ob_tablet_ha_status.h +++ b/src/storage/high_availability/ob_tablet_ha_status.h @@ -104,6 +104,8 @@ public: int deserialize(const char *buf, const int64_t len, int64_t &pos); int64_t get_serialize_size() const; void reset(); + int64_t get_ha_status() const { return ha_status_; } + void set_ha_status(int64_t ha_status) { ha_status_ = ha_status;} bool is_none() const { return is_data_status_complete() && is_restore_status_full(); } bool is_data_status_complete() const { return ObTabletDataStatus::is_complete(data_status_); } bool is_restore_status_full() const { return ObTabletRestoreStatus::is_full(restore_status_); } diff --git a/src/storage/ls/ob_ls_tablet_service.cpp b/src/storage/ls/ob_ls_tablet_service.cpp index d68379785..9fb3aadec 100644 --- a/src/storage/ls/ob_ls_tablet_service.cpp +++ b/src/storage/ls/ob_ls_tablet_service.cpp @@ -6007,6 +6007,28 @@ int ObLSTabletService::build_tablet_iter(ObHALSTabletIterator &iter) return ret; } +int ObLSTabletService::build_tablet_iter(ObLSTabletFastIter &iter, const bool except_ls_inner_tablet) +{ + int ret = common::OB_SUCCESS; + GetAllTabletIDOperator op(iter.tablet_ids_, except_ls_inner_tablet); + iter.ls_tablet_service_ = this; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(tablet_id_set_.foreach(op))) { + STORAGE_LOG(WARN, "fail to get all tablet ids from set", K(ret)); + } else if (OB_UNLIKELY(!iter.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("iter is invalid", K(ret), K(iter)); + } + + if (OB_FAIL(ret)) { + iter.reset(); + } + return ret; +} + + int ObLSTabletService::set_allow_to_read_(ObLS *ls) { int ret = OB_SUCCESS; diff --git a/src/storage/ls/ob_ls_tablet_service.h b/src/storage/ls/ob_ls_tablet_service.h index 6009fe002..93972f840 100644 --- a/src/storage/ls/ob_ls_tablet_service.h +++ b/src/storage/ls/ob_ls_tablet_service.h @@ -78,6 +78,7 @@ class ObSingleRowGetter; class ObLSTabletIterator; class ObHALSTabletIDIterator; class ObHALSTabletIterator; +class ObLSTabletFastIter; class ObTabletMapKey; struct ObStorageLogParam; struct ObTabletCreateSSTableParam; @@ -411,6 +412,7 @@ public: int build_tablet_iter(ObLSTabletIterator &iter, const bool except_ls_inner_tablet = false); int build_tablet_iter(ObHALSTabletIDIterator &iter); int build_tablet_iter(ObHALSTabletIterator &iter); + int build_tablet_iter(ObLSTabletFastIter &iter, const bool except_ls_inner_tablet = false); // migration section typedef common::ObFunction HandleTabletMetaFunc; @@ -783,6 +785,7 @@ private: private: friend class ObLSTabletIterator; friend class ObTabletCreateMdsHelper; + friend class ObLSTabletFastIter; ObLS *ls_; ObTxDataMemtableMgr tx_data_memtable_mgr_; diff --git a/src/storage/meta_mem/ob_tablet_pointer.cpp b/src/storage/meta_mem/ob_tablet_pointer.cpp index d2c43aa54..4b1f4fa2d 100644 --- a/src/storage/meta_mem/ob_tablet_pointer.cpp +++ b/src/storage/meta_mem/ob_tablet_pointer.cpp @@ -47,10 +47,11 @@ ObTabletPointer::ObTabletPointer() initial_state_(true), ddl_kv_mgr_lock_(), mds_table_handler_(), - old_version_chain_(nullptr) + old_version_chain_(nullptr), + attr_() { #if defined(__x86_64__) && !defined(ENABLE_OBJ_LEAK_CHECK) - static_assert(sizeof(ObTabletPointer) == 280, "The size of ObTabletPointer will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); + static_assert(sizeof(ObTabletPointer) == 296, "The size of ObTabletPointer will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); #endif } @@ -175,6 +176,9 @@ int ObTabletPointer::hook_obj(ObTablet *&t, ObMetaObjGuard &guard) obj_.ptr_ = t; guard.set_obj(obj_); ObMetaObjBufferHelper::set_in_map(reinterpret_cast(t), true/*in_map*/); + if (!is_attr_valid() && OB_FAIL(set_tablet_attr(*t))) { // only set tablet attr when first hook obj + STORAGE_LOG(WARN, "failed to update tablet attr", K(ret), K(guard)); + } } if (OB_FAIL(ret) && OB_NOT_NULL(t)) { @@ -649,5 +653,58 @@ int ObTabletPointer::release_obj(ObTablet *&t) return ret; } +int ObTabletPointer::set_tablet_attr(ObTablet &tablet) +{ + int ret = OB_SUCCESS; + attr_.reset(); + if (OB_FAIL(tablet.calc_tablet_attr(attr_))) { + if (OB_ALLOCATE_MEMORY_FAILED == ret) { + ret = OB_SUCCESS; // the invalid attr is allowed + } else { + STORAGE_LOG(WARN, "failed to update tablet attr", K(ret), K(tablet)); + } + } + return ret; +} + +ObTabletResidentInfo::ObTabletResidentInfo(const ObTabletMapKey &key, ObTabletPointer &tablet_ptr) + : attr_(tablet_ptr.attr_), tablet_addr_(tablet_ptr.phy_addr_) +{ + tablet_id_ = key.tablet_id_; + ls_id_ = key.ls_id_; +} + +int64_t ObITabletFilterOp::total_skip_cnt_ = 0; +int64_t ObITabletFilterOp::total_tablet_cnt_ = 0; +int64_t ObITabletFilterOp::not_in_mem_tablet_cnt_ = 0; +int64_t ObITabletFilterOp::invalid_attr_tablet_cnt_ = 0; +ObITabletFilterOp::~ObITabletFilterOp() +{ + total_skip_cnt_ += skip_cnt_; + total_tablet_cnt_ += total_cnt_; + not_in_mem_tablet_cnt_ += not_in_mem_cnt_; + invalid_attr_tablet_cnt_ += invalid_attr_cnt_; + LOG_INFO("zhuixin debug filter destructed", + K_(total_cnt), K_(skip_cnt), K_(not_in_mem_cnt), K_(invalid_attr_cnt), + K_(total_tablet_cnt), K_(total_skip_cnt), K_(not_in_mem_tablet_cnt), K_(invalid_attr_tablet_cnt)); +} + +int ObITabletFilterOp::operator()(const ObTabletResidentInfo &info, bool &is_skipped) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("try to skip tablet with invalid resident info", K(ret), K(info)); + } else if (OB_FAIL((do_filter(info, is_skipped)))) { + LOG_WARN("fail to do filter", K(ret), K(info), K_(skip_cnt), K_(total_cnt)); + } else if (is_skipped) { + ++skip_cnt_; + } + ++total_cnt_; + return ret; +} + + + } // namespace storage } // namespace oceanbase diff --git a/src/storage/meta_mem/ob_tablet_pointer.h b/src/storage/meta_mem/ob_tablet_pointer.h index 2c93e3cb0..da13ad716 100644 --- a/src/storage/meta_mem/ob_tablet_pointer.h +++ b/src/storage/meta_mem/ob_tablet_pointer.h @@ -29,11 +29,39 @@ class ObTablet; class ObTabletDDLKvMgr; typedef ObMetaObjGuard ObDDLKvMgrHandle; +struct ObTabletAttr final +{ +public: + ObTabletAttr() + :v_(0), + ha_status_(0) + {} + ~ObTabletAttr() { reset(); } + void reset() { v_ = 0; ha_status_ = 0; } + bool is_valid() const { return valid_; } + TO_STRING_KV(K_(valid), K_(is_empty_shell), K_(has_transfer_table), + K_(has_next_tablet), K_(has_nested_table), K_(ha_status)); +public: + union { + int64_t v_; + struct { + bool valid_ : 1; // valid_ = true means attr is filled + bool is_empty_shell_ : 1; + bool has_transfer_table_ : 1; + bool has_next_tablet_ : 1; + bool has_nested_table_: 1; + }; + }; + + int64_t ha_status_; +}; + class ObTabletPointer final { friend class ObTablet; friend class ObLSTabletService; friend class ObTenantMetaMemMgr; + friend class ObTabletResidentInfo; public: ObTabletPointer(); ObTabletPointer(const ObLSHandle &ls_handle, @@ -75,7 +103,7 @@ public: int dump_meta_obj(ObMetaObjGuard &guard, void *&free_obj); // do not KPC memtable_mgr, may dead lock - TO_STRING_KV(K_(phy_addr), K_(obj), K_(ls_handle), K_(ddl_kv_mgr_handle), + TO_STRING_KV(K_(phy_addr), K_(obj), K_(ls_handle), K_(ddl_kv_mgr_handle), K_(attr), K_(protected_memtable_mgr_handle), K_(ddl_info), K_(initial_state), KP_(old_version_chain)); public: bool get_initial_state() const; @@ -94,6 +122,9 @@ public: int release_memtable_and_mds_table_for_ls_offline(const ObTabletID &tablet_id); int get_min_mds_ckpt_scn(share::SCN &scn); ObLS *get_ls() const; + // the RW operations of tablet_attr are protected by lock guard of tablet_map_ + int set_tablet_attr(ObTablet &tablet); + bool is_attr_valid() const { return attr_.is_valid(); } private: int wash_obj(); int add_tablet_to_old_version_chain(ObTablet *tablet); @@ -109,7 +140,51 @@ private: ObByteLock ddl_kv_mgr_lock_; // 1B mds::ObMdsTableHandler mds_table_handler_;// 48B ObTablet *old_version_chain_; // 8B - DISALLOW_COPY_AND_ASSIGN(ObTabletPointer); // 272B + ObTabletAttr attr_; // 16B // protected by rw lock of tablet_map_ + DISALLOW_COPY_AND_ASSIGN(ObTabletPointer); // 288B +}; + +struct ObTabletResidentInfo final { + ObTabletResidentInfo(ObTabletAttr &attr, ObTabletID &tablet_id, share::ObLSID &ls_id) + : attr_(attr), tablet_addr_(), tablet_id_(tablet_id), ls_id_(ls_id) + {} + + ObTabletResidentInfo(const ObTabletMapKey &key, ObTabletPointer &tablet_ptr); + ~ObTabletResidentInfo() = default; + bool is_valid() const { return attr_.valid_ && tablet_id_.is_valid() && tablet_addr_.is_valid(); } + bool has_transfer_table() const { return attr_.has_transfer_table_; } + bool is_empty_shell() const { return attr_.is_empty_shell_; } + bool has_next_tablet() const { return attr_.has_next_tablet_; } + bool has_nested_table() const { return attr_.has_nested_table_; } + TO_STRING_KV(K_(ls_id), K_(tablet_id), K_(tablet_addr), K_(attr)); +public: + ObTabletAttr &attr_; + ObMetaDiskAddr tablet_addr_; // used to identify one tablet + ObTabletID tablet_id_; + share::ObLSID ls_id_; +}; + +class ObITabletFilterOp +{ +public: + ObITabletFilterOp() + :skip_cnt_(0), total_cnt_(0), not_in_mem_cnt_(0), invalid_attr_cnt_(0) + {} + virtual ~ObITabletFilterOp(); + int operator()(const ObTabletResidentInfo &info, bool &is_skipped); + virtual int do_filter(const ObTabletResidentInfo &info, bool &is_skipped) = 0; + void inc_not_in_memory_cnt() { ++total_cnt_; ++not_in_mem_cnt_; } + void inc_invalid_attr_cnt() { ++total_cnt_; ++invalid_attr_cnt_; } +private: + int64_t skip_cnt_; + int64_t total_cnt_; + int64_t not_in_mem_cnt_; + int64_t invalid_attr_cnt_; + static int64_t total_skip_cnt_; + static int64_t total_tablet_cnt_; + static int64_t not_in_mem_tablet_cnt_; + static int64_t invalid_attr_tablet_cnt_; + DISALLOW_COPY_AND_ASSIGN(ObITabletFilterOp); }; } // namespace storage diff --git a/src/storage/meta_mem/ob_tablet_pointer_map.cpp b/src/storage/meta_mem/ob_tablet_pointer_map.cpp index 8da34c584..aaab4276a 100644 --- a/src/storage/meta_mem/ob_tablet_pointer_map.cpp +++ b/src/storage/meta_mem/ob_tablet_pointer_map.cpp @@ -206,6 +206,54 @@ int ObTabletPointerMap::try_get_in_memory_meta_obj( return ret; } +int ObTabletPointerMap::try_get_in_memory_meta_obj_with_filter( + const ObTabletMapKey &key, + ObITabletFilterOp &op, + ObTabletPointerHandle &ptr_hdl, + ObMetaObjGuard &guard, + bool &is_in_memory) +{ + int ret = OB_SUCCESS; + uint64_t hash_val = 0; + ObTabletPointer *t_ptr = nullptr; + is_in_memory = false; + if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) { + STORAGE_LOG(WARN, "fail to calc hash", K(ret), K(key)); + } else { + common::ObBucketHashRLockGuard lock_guard(ResourceMap::bucket_lock_, hash_val); + if (OB_FAIL(ResourceMap::get_without_lock(key, ptr_hdl))) { + if (common::OB_ENTRY_NOT_EXIST != ret) { + STORAGE_LOG(WARN, "fail to get pointer handle", K(ret)); + } + } else if (OB_ISNULL(t_ptr = ptr_hdl.get_resource_ptr())) { + ret = common::OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "fail to get meta pointer", K(ret), KP(t_ptr), K(key)); + } else if (OB_UNLIKELY(t_ptr->get_addr().is_none())) { + ret = OB_ITEM_NOT_SETTED; + STORAGE_LOG(DEBUG, "pointer addr is none, no object to be got", K(ret), K(key), KPC(t_ptr)); + } else if (t_ptr->is_in_memory()) { + if (t_ptr->is_attr_valid()) { // try skip tablet with attr + ObTabletResidentInfo info(key, *t_ptr); + bool is_skipped = false; + if (OB_FAIL(op(info, is_skipped))) { + STORAGE_LOG(WARN, "fail to skip tablet", K(ret), KP(t_ptr), K(key), K(info)); + } else if (is_skipped) { + ret = OB_NOT_THE_OBJECT; + } + } else { + op.inc_invalid_attr_cnt(); + } + if (OB_SUCC(ret)) { + t_ptr->get_obj(guard); + is_in_memory = true; + } + } else { + op.inc_not_in_memory_cnt(); + } + } + return ret; +} + int ObTabletPointerMap::get_meta_obj( const ObTabletMapKey &key, ObMetaObjGuard &guard) @@ -235,6 +283,39 @@ int ObTabletPointerMap::get_meta_obj( return ret; } +int ObTabletPointerMap::get_meta_obj_with_filter( + const ObTabletMapKey &key, + ObITabletFilterOp &op, + ObMetaObjGuard &guard) +{ + int ret = common::OB_SUCCESS; + ObTabletPointerHandle ptr_hdl(*this); + bool is_in_memory = false; + guard.reset(); + if (OB_UNLIKELY(!key.is_valid())) { + ret = common::OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid argument", K(ret), K(key)); + } else if (OB_FAIL(try_get_in_memory_meta_obj_with_filter(key, op, ptr_hdl, guard, is_in_memory))) { + if (OB_ENTRY_NOT_EXIST == ret || OB_ITEM_NOT_SETTED == ret) { + STORAGE_LOG(DEBUG, "meta obj does not exist", K(ret), K(key)); + } else if (OB_NOT_THE_OBJECT == ret) { + STORAGE_LOG(DEBUG, "this tablet has been skipped", K(ret), K(key)); + } else { + STORAGE_LOG(WARN, "fail to try get in memory meta obj", K(ret), K(key)); + } + } else if (OB_UNLIKELY(!is_in_memory)) { + if (OB_FAIL(load_and_hook_meta_obj(key, ptr_hdl, guard))) { + STORAGE_LOG(WARN, "fail to load and hook meta obj", K(ret), K(key)); + } else { + EVENT_INC(ObStatEventIds::TABLET_CACHE_MISS); + } + } else { + EVENT_INC(ObStatEventIds::TABLET_CACHE_HIT); + } + return ret; +} + + int ObTabletPointerMap::load_and_hook_meta_obj( const ObTabletMapKey &key, ObTabletPointerHandle &ptr_hdl, @@ -395,7 +476,8 @@ int ObTabletPointerMap::get_meta_obj_with_external_memory( const ObTabletMapKey &key, common::ObArenaAllocator &allocator, ObMetaObjGuard &guard, - const bool force_alloc_new) + const bool force_alloc_new, + ObITabletFilterOp *op) { int ret = common::OB_SUCCESS; uint64_t hash_val = 0; @@ -403,7 +485,7 @@ int ObTabletPointerMap::get_meta_obj_with_external_memory( ObTabletPointer *t_ptr = nullptr; bool is_in_memory = false; guard.reset(); - if (OB_UNLIKELY(!key.is_valid())) { + if (OB_UNLIKELY(!key.is_valid() || (force_alloc_new && nullptr != op))) { /*only support filter when not force new*/ ret = common::OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "invalid argument", K(ret), K(key)); } else if (OB_FAIL(ResourceMap::hash_func_(key, hash_val))) { @@ -415,7 +497,8 @@ int ObTabletPointerMap::get_meta_obj_with_external_memory( STORAGE_LOG(WARN, "fail to get pointer handle", K(ret)); } } - } else if (OB_FAIL(try_get_in_memory_meta_obj(key, ptr_hdl, guard, is_in_memory))) { + } else if ((nullptr == op && OB_FAIL(try_get_in_memory_meta_obj(key, ptr_hdl, guard, is_in_memory))) + || (nullptr != op && OB_FAIL(try_get_in_memory_meta_obj_with_filter(key, *op, ptr_hdl, guard, is_in_memory)))) { if (OB_ENTRY_NOT_EXIST == ret) { STORAGE_LOG(DEBUG, "meta obj does not exist", K(ret), K(key)); } else { @@ -612,6 +695,9 @@ int ObTabletPointerMap::compare_and_swap_addr_and_object( if (OB_SUCC(ret)) { t_ptr->set_addr_with_reset_obj(new_addr); t_ptr->set_obj(new_guard); + if (OB_FAIL(t_ptr->set_tablet_attr(*new_guard.get_obj()))) { + STORAGE_LOG(WARN, "failed to update tablet attr", K(ret), K(key), K(new_addr), K(new_guard)); + } } } diff --git a/src/storage/meta_mem/ob_tablet_pointer_map.h b/src/storage/meta_mem/ob_tablet_pointer_map.h index f974ae57e..e559aac22 100644 --- a/src/storage/meta_mem/ob_tablet_pointer_map.h +++ b/src/storage/meta_mem/ob_tablet_pointer_map.h @@ -33,11 +33,13 @@ public: int erase(const ObTabletMapKey &key, ObMetaObjGuard &guard); int exist(const ObTabletMapKey &key, bool &is_exist); int get_meta_obj(const ObTabletMapKey &key, ObMetaObjGuard &guard); + int get_meta_obj_with_filter(const ObTabletMapKey &key, ObITabletFilterOp &op, ObMetaObjGuard &guard); int get_meta_obj_with_external_memory( const ObTabletMapKey &key, common::ObArenaAllocator &allocator, ObMetaObjGuard &guard, - const bool force_alloc_new = false); + const bool force_alloc_new, + ObITabletFilterOp *op); int try_get_in_memory_meta_obj(const ObTabletMapKey &key, bool &success, ObMetaObjGuard &guard); int try_get_in_memory_meta_obj_and_addr( const ObTabletMapKey &key, @@ -84,6 +86,12 @@ private: ObTabletPointerHandle &ptr_hdl, ObMetaObjGuard &guard, bool &is_in_memory); + int try_get_in_memory_meta_obj_with_filter( + const ObTabletMapKey &key, + ObITabletFilterOp &op, + ObTabletPointerHandle &ptr_hdl, + ObMetaObjGuard &guard, + bool &is_in_memory); int inner_erase(const ObTabletMapKey &key); public: diff --git a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp index 2e038712e..aae8030d0 100644 --- a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp +++ b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp @@ -1586,6 +1586,33 @@ int ObTenantMetaMemMgr::get_tablet( return ret; } +int ObTenantMetaMemMgr::get_tablet_with_filter( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + ObITabletFilterOp &op, + ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + handle.reset(); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantMetaMemMgr hasn't been initialized", K(ret)); + } else if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(key)); + } else if (OB_FAIL(tablet_map_.get_meta_obj_with_filter(key, op, handle))) { + if (OB_ENTRY_NOT_EXIST != ret && OB_ITEM_NOT_SETTED != ret && OB_NOT_THE_OBJECT != ret) { + LOG_WARN("fail to get tablet", K(ret), K(key)); + } + } else if (OB_ISNULL(handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(key), K(handle)); + } else { + handle.set_wash_priority(priority); + } + return ret; +} + int ObTenantMetaMemMgr::get_tablet_with_allocator( const WashTabletPriority &priority, const ObTabletMapKey &key, @@ -1601,7 +1628,7 @@ int ObTenantMetaMemMgr::get_tablet_with_allocator( } else if (OB_UNLIKELY(!key.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(key), KP(&allocator)); - } else if (OB_FAIL(tablet_map_.get_meta_obj_with_external_memory(key, allocator, handle, force_alloc_new))) { + } else if (OB_FAIL(tablet_map_.get_meta_obj_with_external_memory(key, allocator, handle, force_alloc_new, nullptr/*no_op*/))) { if (OB_ENTRY_NOT_EXIST != ret) { LOG_WARN("fail to get tablet", K(ret), K(key)); } @@ -1882,8 +1909,7 @@ int ObTenantMetaMemMgr::compare_and_swap_tablet( if (OB_ISNULL(t_ptr = reinterpret_cast(ptr_hdl.get_resource_ptr()))) { ret = common::OB_ERR_UNEXPECTED; LOG_WARN("fail to get tablet pointer", K(ret), K(key), K(ptr_hdl)); - } else if (CLICK_FAIL(t_ptr->add_tablet_to_old_version_chain( - reinterpret_cast(old_handle.get_obj())))) { + } else if (CLICK_FAIL(t_ptr->add_tablet_to_old_version_chain(old_handle.get_obj()))) { LOG_WARN("fail to add tablet to old version chain", K(ret), K(key), KPC(old_tablet)); } } @@ -1902,7 +1928,6 @@ int ObTenantMetaMemMgr::compare_and_swap_tablet( LOG_WARN("failed to check and set initial state", K(ret), K(key)); } } - LOG_DEBUG("compare and swap object", K(ret), KPC(new_handle.get_obj()), K(lbt())); return ret; } @@ -2354,9 +2379,11 @@ int ObT3mTabletMapIterator::FetchTabletItemOp::operator()(TabletPair &pair) ObTenantTabletIterator::ObTenantTabletIterator( ObTenantMetaMemMgr &t3m, - common::ObArenaAllocator &allocator) + common::ObArenaAllocator &allocator, + ObITabletFilterOp *op) : ObT3mTabletMapIterator(t3m), - allocator_(&allocator) + allocator_(&allocator), + op_(op) { } @@ -2377,7 +2404,7 @@ int ObTenantTabletIterator::get_next_tablet(ObTabletHandle &handle) ret = OB_ERR_UNEXPECTED; LOG_WARN("allocator_ is nullptr, which is not allowed", K(ret)); } else if (OB_FAIL(tablet_map_.get_meta_obj_with_external_memory( - key, *allocator_, handle)) && OB_ENTRY_NOT_EXIST != ret) { + key, *allocator_, handle, false/*force*/, op_)) && !ignore_err_code(ret)) { LOG_WARN("fail to get tablet handle", K(ret), K(key)); } if (OB_SUCC(ret) || ignore_err_code(ret)) { @@ -2389,7 +2416,7 @@ int ObTenantTabletIterator::get_next_tablet(ObTabletHandle &handle) ++idx_; } } - } while (ignore_err_code(ret)); // ignore deleted tablet + } while (ignore_err_code(ret)); // ignore deleted tablet or skipped tablet } return ret; } diff --git a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h index 4c3c50003..6a36c0d9f 100644 --- a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h +++ b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h @@ -243,6 +243,12 @@ public: const WashTabletPriority &priority, const ObTabletMapKey &key, ObTabletHandle &handle); + int get_tablet_with_filter( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + ObITabletFilterOp &op, + ObTabletHandle &handle); + // NOTE: This interface return tablet handle, which couldn't be used by compare_and_swap_tablet. int get_tablet_with_allocator( const WashTabletPriority &priority, @@ -540,7 +546,7 @@ protected: typedef common::hash::HashMapPair TabletPair; int fetch_tablet_item(); - static bool ignore_err_code(const int ret) { return OB_ENTRY_NOT_EXIST == ret || OB_ITEM_NOT_SETTED == ret; } + static bool ignore_err_code(const int ret) { return OB_ENTRY_NOT_EXIST == ret || OB_ITEM_NOT_SETTED == ret || OB_NOT_THE_OBJECT == ret; } private: class FetchTabletItemOp final { @@ -569,12 +575,14 @@ class ObTenantTabletIterator : public ObT3mTabletMapIterator, public: ObTenantTabletIterator( ObTenantMetaMemMgr &t3m, - common::ObArenaAllocator &allocator); + common::ObArenaAllocator &allocator, + ObITabletFilterOp *op); virtual ~ObTenantTabletIterator() = default; virtual int get_next_tablet(ObTabletHandle &handle) override; private: common::ObArenaAllocator *allocator_; + storage::ObITabletFilterOp *op_; }; class ObTenantInMemoryTabletIterator : public ObT3mTabletMapIterator, diff --git a/src/storage/ob_disk_usage_reporter.cpp b/src/storage/ob_disk_usage_reporter.cpp index 137d999cb..af9d6f434 100644 --- a/src/storage/ob_disk_usage_reporter.cpp +++ b/src/storage/ob_disk_usage_reporter.cpp @@ -190,7 +190,7 @@ int ObDiskUsageReportTask::count_tenant_data(const uint64_t tenant_id) } else { ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); ObArenaAllocator iter_allocator("DiskReport", OB_MALLOC_NORMAL_BLOCK_SIZE, tenant_id); - ObTenantTabletIterator tablet_iter(*t3m, iter_allocator); + ObTenantTabletIterator tablet_iter(*t3m, iter_allocator, nullptr/*no op*/); ObTabletHandle tablet_handle; while (OB_SUCC(ret) && OB_SUCC(tablet_iter.get_next_tablet(tablet_handle))) { if (OB_UNLIKELY(!tablet_handle.is_valid())) { diff --git a/src/storage/ob_storage_rpc.cpp b/src/storage/ob_storage_rpc.cpp index 0764d9a8b..595061063 100644 --- a/src/storage/ob_storage_rpc.cpp +++ b/src/storage/ob_storage_rpc.cpp @@ -1783,9 +1783,8 @@ int ObFetchLSMetaInfoP::process() LOG_WARN("failed to get ls meta package", K(ret), K(arg_)); } else if (OB_FAIL(ObStorageHAUtils::get_server_version(result_.version_))) { LOG_WARN("failed to get server version", K(ret), K_(arg)); - } else { - // TODO(yangyi.yyy): do not check transfer table for now, fix in 4.3 - result_.has_transfer_table_ = false; + } else if (OB_FAIL(check_has_transfer_logical_table_(ls))) { + LOG_WARN("failed to check has tranfer logical table", K(ret)); } } return ret; @@ -1794,11 +1793,12 @@ int ObFetchLSMetaInfoP::process() int ObFetchLSMetaInfoP::check_has_transfer_logical_table_(storage::ObLS *ls) { int ret = OB_SUCCESS; - storage::ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_WITHOUT_CHECK); + ObHasTransferTableFilterOp op; + ObLSTabletFastIter tablet_iter(op, ObMDSGetTabletMode::READ_WITHOUT_CHECK); if (OB_ISNULL(ls)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls not should be null", K(ret), KP(ls)); - } else if (OB_FAIL(ls->build_tablet_iter(tablet_iter))) { + } else if (OB_FAIL(ls->build_tablet_iter(tablet_iter, true/*except_inner*/))) { LOG_WARN("failed to build ls tablet iter", K(ret)); } else { bool has_logical_table = true; @@ -1817,10 +1817,7 @@ int ObFetchLSMetaInfoP::check_has_transfer_logical_table_(storage::ObLS *ls) } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); - } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { - //do nothing - } else if (tablet->get_tablet_meta().has_transfer_table()) { - bool has_dependent_ls = false; + } else { result_.has_transfer_table_ = true; LOG_INFO("tablet still has logical table", K(tablet_handle)); break; diff --git a/src/storage/ob_storage_rpc.h b/src/storage/ob_storage_rpc.h index b0244f775..3a280fe2c 100644 --- a/src/storage/ob_storage_rpc.h +++ b/src/storage/ob_storage_rpc.h @@ -33,6 +33,7 @@ #include "storage/lob/ob_lob_rpc_struct.h" #include "storage/blocksstable/ob_logic_macro_id.h" #include "share/rpc/ob_async_rpc_proxy.h" +#include "storage/meta_mem/ob_tablet_pointer.h" namespace oceanbase { @@ -1333,6 +1334,16 @@ private: int64_t data_size_; }; +class ObHasTransferTableFilterOp final : public ObITabletFilterOp +{ +public: + int do_filter(const ObTabletResidentInfo &info, bool &is_skipped) override + { + is_skipped = !info.has_transfer_table(); + return OB_SUCCESS; + } +}; + } // storage } // oceanbase diff --git a/src/storage/tablet/ob_tablet.cpp b/src/storage/tablet/ob_tablet.cpp index 8a8cfad2f..bb2c13757 100644 --- a/src/storage/tablet/ob_tablet.cpp +++ b/src/storage/tablet/ob_tablet.cpp @@ -5566,6 +5566,51 @@ int ObTablet::get_storage_schema_for_transfer_in( return ret; } +int ObTablet::calc_tablet_attr(ObTabletAttr &attr) +{ + int ret = OB_SUCCESS; + attr.reset(); + attr.has_transfer_table_ = tablet_meta_.has_transfer_table(); + attr.is_empty_shell_ = table_store_addr_.addr_.is_none(); + attr.has_next_tablet_ = tablet_meta_.has_next_tablet_; + attr.ha_status_ = tablet_meta_.ha_status_.get_ha_status(); + + attr.has_nested_table_ = false; + ObTabletMemberWrapper wrapper; + const ObTabletTableStore *table_store = nullptr; + ObTableStoreIterator table_iter; + if (attr.is_empty_shell_) { // skip empty shell + } else if (OB_FAIL(fetch_table_store(wrapper))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(wrapper.get_member(table_store))) { + LOG_WARN("fail to get table store from wrapper", K(ret), K(wrapper)); + } else if (OB_FAIL(table_store->get_all_sstable(table_iter))) { + LOG_WARN("fail to get all sstable iterator", K(ret), KPC(table_store)); + } else { + ObITable *table = nullptr; + while (OB_SUCC(ret) && OB_SUCC(table_iter.get_next(table))) { + if (OB_ISNULL(table) || OB_UNLIKELY(!table->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + } else if (static_cast(table)->is_small_sstable()) { + attr.has_nested_table_ = true; + break; + } + } + + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + } + + if (OB_SUCC(ret)) { + attr.valid_ = true; + } else { + attr.reset(); + } + + return ret; +} + int ObTablet::check_and_set_initial_state() { int ret = OB_SUCCESS; diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h index a49c9d27b..1a778d6b1 100644 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -816,6 +816,7 @@ private: int mark_mds_table_switched_to_empty_shell_(); int fetch_autoinc_seq(ObTabletMemberWrapper &wrapper) const; int handle_transfer_replace_(const ObBatchUpdateTableStoreParam ¶m); + int calc_tablet_attr(ObTabletAttr &attr); private: // ObTabletDDLKvMgr::MAX_DDL_KV_CNT_IN_STORAGE // Array size is too large, need to shrink it if possible diff --git a/src/storage/tablet/ob_tablet_iterator.cpp b/src/storage/tablet/ob_tablet_iterator.cpp index 8ccb0b8f5..e0e5681c9 100644 --- a/src/storage/tablet/ob_tablet_iterator.cpp +++ b/src/storage/tablet/ob_tablet_iterator.cpp @@ -139,6 +139,16 @@ int ObLSTabletIterator::get_next_ddl_kv_mgr(ObDDLKvMgrHandle &ddl_kv_mgr_handle) } +int ObLSTabletIterator::get_tablet_ids(ObIArray &ids) +{ + int ret = OB_SUCCESS; + ids.reset(); + if (OB_FAIL(ids.assign(tablet_ids_))) { + LOG_WARN("fail to get tablet ids", K(ret)); + } + return ret; +} + ObHALSTabletIDIterator::ObHALSTabletIDIterator( const share::ObLSID &ls_id, const bool need_initial_state) @@ -242,5 +252,63 @@ int ObHALSTabletIterator::get_next_tablet(ObTabletHandle &handle) return ret; } + + +ObLSTabletFastIter::ObLSTabletFastIter(ObITabletFilterOp &op, const ObMDSGetTabletMode mode) + : ls_tablet_service_(nullptr), + tablet_ids_(), + idx_(0), + mode_(mode), + op_(op) +{ +} + +bool ObLSTabletFastIter::is_valid() const +{ + return nullptr != ls_tablet_service_ + && mode_ <= ObMDSGetTabletMode::READ_WITHOUT_CHECK; // READ_READABLE_COMMITED is not supported +} + +void ObLSTabletFastIter::reset() +{ + ls_tablet_service_ = nullptr; + tablet_ids_.reset(); + idx_ = 0; +} + +int ObLSTabletFastIter::get_next_tablet(ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + + handle.reset(); + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + if (OB_ISNULL(t3m)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant meta mem mgr is nullptr", K(ret), KP(t3m)); + } else { + do { + if (OB_UNLIKELY(tablet_ids_.count() == idx_)) { + ret = OB_ITER_END; + } else { + const common::ObTabletID &tablet_id = tablet_ids_.at(idx_); + const ObTabletMapKey key(ls_tablet_service_->ls_->get_ls_id(), tablet_id); + if (OB_FAIL(t3m->get_tablet_with_filter(WashTabletPriority::WTP_LOW, key, op_, handle))) { + if (OB_ENTRY_NOT_EXIST != ret && OB_ITEM_NOT_SETTED != ret && OB_NOT_THE_OBJECT != ret) { + LOG_WARN("fail to get tablet", K(ret), K_(idx), K(key)); + } else { + ++idx_; + } + } else { + handle.set_wash_priority(WashTabletPriority::WTP_LOW); + ++idx_; + } + } + } while (OB_ENTRY_NOT_EXIST == ret || OB_ITEM_NOT_SETTED == ret || OB_NOT_THE_OBJECT == ret); + } + + return ret; +} + + } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_iterator.h b/src/storage/tablet/ob_tablet_iterator.h index 76fa2386e..ced444b1f 100644 --- a/src/storage/tablet/ob_tablet_iterator.h +++ b/src/storage/tablet/ob_tablet_iterator.h @@ -42,6 +42,7 @@ public: int get_next_tablet(ObTabletHandle &handle); int get_next_tablet_addr(ObTabletMapKey &key, ObMetaDiskAddr &addr); int get_next_ddl_kv_mgr(ObDDLKvMgrHandle &handle); + int get_tablet_ids(ObIArray &ids); void reset(); bool is_valid() const; @@ -99,6 +100,29 @@ private: ObHALSTabletIDIterator tablet_id_iter_; }; +class ObLSTabletFastIter final +{ + friend class ObLSTabletService; +public: + ObLSTabletFastIter(ObITabletFilterOp &op, + const ObMDSGetTabletMode mode); + ~ObLSTabletFastIter() = default; + int get_next_tablet(ObTabletHandle &handle); + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(idx), K_(mode)); +private: + ObLSTabletService *ls_tablet_service_; + common::ObSEArray tablet_ids_; + int64_t idx_; + ObMDSGetTabletMode mode_; + ObITabletFilterOp &op_; + DISALLOW_COPY_AND_ASSIGN(ObLSTabletFastIter); +}; + + + + } // namespace storage } // namespace oceanbase diff --git a/unittest/storage/test_tablet_pointer_map.cpp b/unittest/storage/test_tablet_pointer_map.cpp index b23d2f139..f567c35b2 100644 --- a/unittest/storage/test_tablet_pointer_map.cpp +++ b/unittest/storage/test_tablet_pointer_map.cpp @@ -261,6 +261,9 @@ TEST_F(TestMetaPointerMap, test_meta_pointer_map) phy_addr.offset_ = 0; phy_addr.size_ = 4096; phy_addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; + + old_tablet->is_inited_ = true; + old_tablet->table_store_addr_.addr_.set_none_addr(); // mock empty_shell to pass test ret = tablet_map_.compare_and_swap_addr_and_object(key, phy_addr, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret); @@ -271,6 +274,9 @@ TEST_F(TestMetaPointerMap, test_meta_pointer_map) tablet_obj.pool_ = &MTL(ObTenantMetaMemMgr*)->tablet_buffer_pool_; ObTabletHandle tablet_handle; tablet_handle.set_obj(tablet_obj); + + tablet->is_inited_ = true; + tablet->table_store_addr_.addr_.set_none_addr(); // mock empty_shell to pass test ret = tablet_map_.compare_and_swap_addr_and_object(key, phy_addr, handle, tablet_handle); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet_map_.map_.size()); @@ -344,6 +350,10 @@ TEST_F(TestMetaPointerMap, test_erase_and_load_concurrency) phy_addr.offset_ = 0; phy_addr.size_ = 4096; phy_addr.type_ = ObMetaDiskAddr::DiskType::BLOCK; + + old_tablet->is_inited_ = true; + old_tablet->table_store_addr_.addr_.set_none_addr(); // mock empty_shell to pass test + ret = tablet_map_.compare_and_swap_addr_and_object(key, phy_addr, handle, handle); ASSERT_EQ(common::OB_SUCCESS, ret);