From cc86072c8a7d7d0edd2075e655f40ff0dadacf42 Mon Sep 17 00:00:00 2001 From: Handora Date: Thu, 14 Sep 2023 12:44:10 +0000 Subject: [PATCH] [BUG] batch destroy keybtree --- src/storage/ddl/ob_tablet_ddl_kv.cpp | 2 +- src/storage/memtable/mvcc/ob_keybtree.cpp | 37 +++++++++++++++++-- src/storage/memtable/mvcc/ob_keybtree.h | 12 +++--- src/storage/memtable/mvcc/ob_query_engine.cpp | 7 +++- src/storage/memtable/mvcc/ob_query_engine.h | 3 ++ src/storage/memtable/ob_memtable.cpp | 5 +++ src/storage/memtable/ob_memtable.h | 1 + .../meta_mem/ob_tenant_meta_mem_mgr.cpp | 25 +++++++++++-- src/storage/meta_mem/ob_tenant_meta_mem_mgr.h | 1 + 9 files changed, 79 insertions(+), 14 deletions(-) diff --git a/src/storage/ddl/ob_tablet_ddl_kv.cpp b/src/storage/ddl/ob_tablet_ddl_kv.cpp index 0539d5736d..172b9cadd7 100755 --- a/src/storage/ddl/ob_tablet_ddl_kv.cpp +++ b/src/storage/ddl/ob_tablet_ddl_kv.cpp @@ -152,7 +152,7 @@ void ObBlockMetaTree::destroy() { is_inited_ = false; macro_blocks_.reset(); - block_tree_.destroy(); + block_tree_.destroy(false /*is_batch_destroy*/); data_desc_.reset(); for (int64_t i = 0; i < sorted_rowkeys_.count(); ++i) { const ObDataMacroBlockMeta *cur_meta = sorted_rowkeys_.at(i).block_meta_; diff --git a/src/storage/memtable/mvcc/ob_keybtree.cpp b/src/storage/memtable/mvcc/ob_keybtree.cpp index 78933f7237..18abe69dae 100644 --- a/src/storage/memtable/mvcc/ob_keybtree.cpp +++ b/src/storage/memtable/mvcc/ob_keybtree.cpp @@ -1613,11 +1613,17 @@ void ObKeyBtree::print(FILE *file) const } template -int ObKeyBtree::destroy() +int ObKeyBtree::pre_batch_destroy() { - ObTimeGuard tg("keybtree destroy", 50L * 1000L); // 50ms + ObTimeGuard tg("keybtree pre_batch_destroy", 50L * 1000L); // 50ms destroy(ATOMIC_SET(&root_, nullptr)); - tg.click(); + return OB_SUCCESS; +} + +template +int ObKeyBtree::batch_destroy() +{ + ObTimeGuard tg("keybtree batch_destroy", 50L * 1000L); // 50ms { HazardList reclaim_list; BtreeNode *p = nullptr; @@ -1635,6 +1641,31 @@ int ObKeyBtree::destroy() return OB_SUCCESS; } +template +int ObKeyBtree::destroy(const bool is_batch_destroy) +{ + if (!is_batch_destroy) { + ObTimeGuard tg("keybtree destroy", 50L * 1000L); // 50ms + destroy(ATOMIC_SET(&root_, nullptr)); + tg.click(); + { + HazardList reclaim_list; + BtreeNode *p = nullptr; + CriticalGuard(get_qsync()); + get_retire_station().purge(reclaim_list); + tg.click(); + while (OB_NOT_NULL(p = reinterpret_cast(reclaim_list.pop()))) { + free_node(p); + p = nullptr; + } + tg.click(); + } + WaitQuiescent(get_qsync()); + tg.click(); + } + return OB_SUCCESS; +} + template int ObKeyBtree::del(const BtreeKey key, BtreeVal &value, int64_t version) { diff --git a/src/storage/memtable/mvcc/ob_keybtree.h b/src/storage/memtable/mvcc/ob_keybtree.h index e492728d5f..294432e611 100644 --- a/src/storage/memtable/mvcc/ob_keybtree.h +++ b/src/storage/memtable/mvcc/ob_keybtree.h @@ -220,7 +220,9 @@ public: int64_t size() const { return size_.value(); } void dump(FILE *file) { print(file); } void print(FILE *file) const; - int destroy(); + int destroy(const bool is_batch_destroy); + int pre_batch_destroy(); + static int batch_destroy(); int del(const BtreeKey key, BtreeVal &value, int64_t version); int re_insert(const BtreeKey key, BtreeVal value); int insert(const BtreeKey key, BtreeVal &value); @@ -230,12 +232,12 @@ public: int set_key_range(BtreeRawIterator &handle, const BtreeKey min_key, const bool start_exclude, const BtreeKey max_key, bool end_exclude, int64_t version); BtreeNode *alloc_node(const bool is_emergency); - void free_node(BtreeNode *p); + static void free_node(BtreeNode *p); void retire(common::HazardList &retire_list); int32_t update_split_info(int32_t split_pos); - common::RetireStation &get_retire_station(); - common::QClock& get_qclock(); - common::ObQSync& get_qsync(); + static common::RetireStation &get_retire_station(); + static common::QClock& get_qclock(); + static common::ObQSync& get_qsync(); private: void destroy(BtreeNode *root); private: diff --git a/src/storage/memtable/mvcc/ob_query_engine.cpp b/src/storage/memtable/mvcc/ob_query_engine.cpp index 323f97e67d..bd52bf1081 100644 --- a/src/storage/memtable/mvcc/ob_query_engine.cpp +++ b/src/storage/memtable/mvcc/ob_query_engine.cpp @@ -175,13 +175,18 @@ void ObQueryEngine::destroy() if (IS_NOT_INIT) { // do nothing } else { - keybtree_.destroy(); + keybtree_.destroy(true /*is_batch_destroy*/); btree_allocator_.reset(); keyhash_.destroy(); } is_inited_ = false; } +void ObQueryEngine::pre_batch_destroy_keybtree() +{ + (void)keybtree_.pre_batch_destroy(); +} + int ObQueryEngine::set(const ObMemtableKey *key, ObMvccRow *value) { int ret = OB_SUCCESS; diff --git a/src/storage/memtable/mvcc/ob_query_engine.h b/src/storage/memtable/mvcc/ob_query_engine.h index 6d892af1fa..c6f841dd55 100644 --- a/src/storage/memtable/mvcc/ob_query_engine.h +++ b/src/storage/memtable/mvcc/ob_query_engine.h @@ -31,6 +31,8 @@ namespace memtable { class ObMvccRow; +typedef keybtree::ObKeyBtree ObMemtableKeyBtree; + class ObIQueryEngineIterator { public: @@ -152,6 +154,7 @@ public: ~ObQueryEngine() { destroy(); } int init(const uint64_t tenant_id); void destroy(); + void pre_batch_destroy_keybtree(); int set(const ObMemtableKey *key, ObMvccRow *value); int get(const ObMemtableKey *parameter_key, ObMvccRow *&row, ObMemtableKey *returned_key); int ensure(const ObMemtableKey *key, ObMvccRow *value); diff --git a/src/storage/memtable/ob_memtable.cpp b/src/storage/memtable/ob_memtable.cpp index 1ac856c798..1c6b13009b 100755 --- a/src/storage/memtable/ob_memtable.cpp +++ b/src/storage/memtable/ob_memtable.cpp @@ -208,6 +208,11 @@ int ObMemtable::init(const ObITable::TableKey &table_key, return ret; } +void ObMemtable::pre_batch_destroy_keybtree() +{ + (void)query_engine_.pre_batch_destroy_keybtree(); +} + int ObMemtable::batch_remove_unused_callback_for_uncommited_txn( const ObLSID ls_id, const memtable::ObMemtableSet *memtable_set) { diff --git a/src/storage/memtable/ob_memtable.h b/src/storage/memtable/ob_memtable.h index 99a46c2bd6..dffd78ec59 100644 --- a/src/storage/memtable/ob_memtable.h +++ b/src/storage/memtable/ob_memtable.h @@ -384,6 +384,7 @@ public: int64_t get_memtable_mgr_op_cnt() { return ATOMIC_LOAD(&memtable_mgr_op_cnt_); } int64_t inc_memtable_mgr_op_cnt() { return ATOMIC_AAF(&memtable_mgr_op_cnt_, 1); } int64_t dec_memtable_mgr_op_cnt() { return ATOMIC_SAF(&memtable_mgr_op_cnt_, 1); } + void pre_batch_destroy_keybtree(); static int batch_remove_unused_callback_for_uncommited_txn( const share::ObLSID ls_id, const memtable::ObMemtableSet *memtable_set); 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 60052de873..3701282461 100755 --- a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp +++ b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp @@ -31,6 +31,7 @@ #include "storage/tx_storage/ob_ls_handle.h" #include "storage/tx_storage/ob_ls_map.h" #include "storage/tx_storage/ob_ls_service.h" +#include "storage/memtable/mvcc/ob_query_engine.h" #include "storage/ddl/ob_tablet_ddl_kv.h" #include "share/ob_thread_define.h" #include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" @@ -527,12 +528,22 @@ int ObTenantMetaMemMgr::gc_tables_in_queue(bool &all_table_cleaned) return ret; } +void ObTenantMetaMemMgr::batch_destroy_memtable_(memtable::ObMemtableSet *memtable_set) +{ + for (common::hash::ObHashSet::iterator set_iter = memtable_set->begin(); + set_iter != memtable_set->end(); + ++set_iter) { + (void)(((memtable::ObMemtable *)set_iter->first)->pre_batch_destroy_keybtree()); + } + memtable::ObMemtableKeyBtree::batch_destroy(); +} + void ObTenantMetaMemMgr::batch_gc_memtable_() { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; - for (auto iter = gc_memtable_map_.begin(); + for (common::hash::ObHashMap::iterator iter = gc_memtable_map_.begin(); iter != gc_memtable_map_.end(); ++iter) { const ObLSID &ls_id = iter->first; memtable::ObMemtableSet *memtable_set = iter->second; @@ -545,7 +556,9 @@ void ObTenantMetaMemMgr::batch_gc_memtable_() } else { LOG_WARN("batch remove memtable set failed", K(tmp_ret), KPC(memtable_set)); } - for (auto set_iter = memtable_set->begin(); set_iter != memtable_set->end(); ++set_iter) { + for (common::hash::ObHashSet::iterator set_iter = memtable_set->begin(); + set_iter != memtable_set->end(); + ++set_iter) { if (OB_TMP_FAIL(push_table_into_gc_queue((ObITable *)(set_iter->first), ObITable::TableType::DATA_MEMTABLE))) { LOG_ERROR("push table into gc queue failed, maybe there will be leak", @@ -558,7 +571,11 @@ void ObTenantMetaMemMgr::batch_gc_memtable_() LOG_ERROR("clear memtable set failed", K(tmp_ret), KPC(memtable_set)); } } else { - for (auto set_iter = memtable_set->begin(); set_iter != memtable_set->end(); ++set_iter) { + (void)batch_destroy_memtable_(memtable_set); + + for (common::hash::ObHashSet::iterator set_iter = memtable_set->begin(); + set_iter != memtable_set->end(); + ++set_iter) { pool_arr_[static_cast(ObITable::TableType::DATA_MEMTABLE)]->free_obj((void *)(set_iter->first)); } @@ -571,7 +588,7 @@ void ObTenantMetaMemMgr::batch_gc_memtable_() } if (REACH_TENANT_TIME_INTERVAL(1_hour)) { - for (auto iter = gc_memtable_map_.begin(); + for (common::hash::ObHashMap::iterator iter = gc_memtable_map_.begin(); iter != gc_memtable_map_.end(); ++iter) { memtable::ObMemtableSet *memtable_set = iter->second; if (OB_NOT_NULL(memtable_set)) { 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 1345e5a091..f57adda3ca 100644 --- a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h +++ b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.h @@ -476,6 +476,7 @@ private: void destroy_gc_tablets_queue(); int push_memtable_into_gc_map_(memtable::ObMemtable *memtable); void batch_gc_memtable_(); + void batch_destroy_memtable_(memtable::ObMemtableSet *memtable_set); private: common::SpinRWLock wash_lock_;