diff --git a/CMakeLists.txt b/CMakeLists.txt index 94c3c133c..661f2739b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,8 @@ endif() if (ENABLE_FATAL_ERROR_HANG) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFATAL_ERROR_HANG") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFATAL_ERROR_HANG") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_500_MEMORY_LIMIT") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_500_MEMORY_LIMIT") endif() if(OB_USE_ASAN) diff --git a/deps/oblib/src/lib/alloc/alloc_struct.h b/deps/oblib/src/lib/alloc/alloc_struct.h index 38f5d07e5..059f47106 100644 --- a/deps/oblib/src/lib/alloc/alloc_struct.h +++ b/deps/oblib/src/lib/alloc/alloc_struct.h @@ -119,7 +119,7 @@ struct ObLabel struct ObMemAttr { - friend ObMemAttr DoNotUseMe(ObMemAttr &attr); + friend ObMemAttr DoNotUseMe(ObMemAttr &attr, bool expect_500); uint64_t tenant_id_; ObLabel label_; uint64_t ctx_id_; @@ -136,35 +136,39 @@ struct ObMemAttr prio_(prio) {} int64_t to_string(char* buf, const int64_t buf_len) const; bool use_500() const { return use_500_; } + bool expect_500() const { return expect_500_; } private: bool use_500_ = false; + bool expect_500_ = true; }; -inline ObMemAttr DoNotUseMe(ObMemAttr &attr) +inline ObMemAttr DoNotUseMe(ObMemAttr &attr, bool expect_500) { attr.use_500_ = true; + attr.expect_500_ = expect_500; return attr; } -inline ObMemAttr DoNotUseMe(const ObMemAttr &&attr) +inline ObMemAttr DoNotUseMe(const ObMemAttr &&attr, const bool expect_500) { ObMemAttr attr_cpy = attr; - return DoNotUseMe(attr_cpy); + return DoNotUseMe(attr_cpy, expect_500); } -inline ObMemAttr DoNotUseMe(const ObLabel &label) +inline ObMemAttr DoNotUseMe(const ObLabel &label, const bool expect_500) { ObMemAttr attr(OB_SERVER_TENANT_ID, label); - return DoNotUseMe(attr); + return DoNotUseMe(attr, expect_500); } -inline ObMemAttr DoNotUseMe(const ObLabel &label, const uint64_t ctx_id) +inline ObMemAttr DoNotUseMe(const ObLabel &label, const uint64_t ctx_id, const bool expect_500) { ObMemAttr attr(OB_SERVER_TENANT_ID, label, ctx_id); - return DoNotUseMe(attr); + return DoNotUseMe(attr, expect_500); } -#define SET_USE_500(args...) ::oceanbase::lib::DoNotUseMe(args) +#define SET_USE_500(args...) ::oceanbase::lib::DoNotUseMe(args, true) +#define SET_USE_UNEXPECTED_500(args...) ::oceanbase::lib::DoNotUseMe(args, false) struct AllocHelper { diff --git a/deps/oblib/src/lib/alloc/ob_malloc_allocator.cpp b/deps/oblib/src/lib/alloc/ob_malloc_allocator.cpp index 5b663f09f..6a6b0add5 100644 --- a/deps/oblib/src/lib/alloc/ob_malloc_allocator.cpp +++ b/deps/oblib/src/lib/alloc/ob_malloc_allocator.cpp @@ -107,6 +107,10 @@ void *ObMallocAllocator::alloc(const int64_t size, const oceanbase::lib::ObMemAt LOG_ERROR("invalid tenant id", K(attr.tenant_id_)); attr.tenant_id_ = OB_SERVER_TENANT_ID; } + if (OB_SERVER_TENANT_ID == attr.tenant_id_ && + attr.use_500() && !attr.expect_500()) { + attr.ctx_id_ = ObCtxIds::UNEXPECTED_IN_500; + } lib::ObMemAttr inner_attr = attr; bool do_not_use_me = false; if (FORCE_EXPLICT_500_MALLOC()) { @@ -398,6 +402,40 @@ int ObMallocAllocator::with_resource_handle_invoke(uint64_t tenant_id, InvokeFun } return ret; } +#ifdef ENABLE_500_MEMORY_LIMIT +int ObMallocAllocator::set_500_tenant_limit() +{ + int ret = OB_SUCCESS; + for (int ctx_id = 0; OB_SUCC(ret) && ctx_id < ObCtxIds::MAX_CTX_ID; ++ctx_id) { + if (ObCtxIds::SCHEMA_SERVICE == ctx_id || + ObCtxIds::PKT_NIO == ctx_id || + ObCtxIds::CO_STACK == ctx_id || + ObCtxIds::LIBEASY == ctx_id || + ObCtxIds::GLIBC == ctx_id || + ObCtxIds::LOGGER_CTX_ID== ctx_id || + ObCtxIds::RPC_CTX_ID == ctx_id || + ObCtxIds::UNEXPECTED_IN_500 == ctx_id) { + continue; + } + auto ta = get_tenant_ctx_allocator(OB_SERVER_TENANT_ID, ctx_id); + if (OB_NOT_NULL(ta)) { + int64_t ctx_limit = ObCtxIds::DEFAULT_CTX_ID == ctx_id ? (3LL<<30) : (50LL<<20); + if (OB_FAIL(ta->set_limit(ctx_limit))) { + LIB_LOG(WARN, "set limit of 500 tenant failed", K(ret), K(ctx_limit), + "ctx_name", get_global_ctx_info().get_ctx_name(ctx_id)); + } else { + LIB_LOG(INFO, "set limit of 500 tenant succeed", K(ret), K(ctx_limit), + "ctx_name", get_global_ctx_info().get_ctx_name(ctx_id)); + } + } else { + ret = OB_INVALID_ARGUMENT; + LIB_LOG(WARN, "tenant ctx allocator is not exist", K(ret), + "ctx_name", get_global_ctx_info().get_ctx_name(ctx_id)); + } + } + return ret; +} +#endif int ObMallocAllocator::set_tenant_limit(uint64_t tenant_id, int64_t bytes) { diff --git a/deps/oblib/src/lib/alloc/ob_malloc_allocator.h b/deps/oblib/src/lib/alloc/ob_malloc_allocator.h index 5137bac83..c689bcfbe 100644 --- a/deps/oblib/src/lib/alloc/ob_malloc_allocator.h +++ b/deps/oblib/src/lib/alloc/ob_malloc_allocator.h @@ -122,6 +122,9 @@ public: int64_t get_urgent() const; void set_reserved(int64_t bytes); int64_t get_reserved() const; +#ifdef ENABLE_500_MEMORY_LIMIT + int set_500_tenant_limit(); +#endif int set_tenant_limit(uint64_t tenant_id, int64_t bytes); int64_t get_tenant_limit(uint64_t tenant_id); int64_t get_tenant_hold(uint64_t tenant_id); diff --git a/deps/oblib/src/lib/allocator/ob_fixed_size_block_allocator.h b/deps/oblib/src/lib/allocator/ob_fixed_size_block_allocator.h index 15eb9a3f3..599e6af5e 100644 --- a/deps/oblib/src/lib/allocator/ob_fixed_size_block_allocator.h +++ b/deps/oblib/src/lib/allocator/ob_fixed_size_block_allocator.h @@ -127,7 +127,7 @@ ObFixedSizeBlockAllocator::ObFixedSizeBlockAllocator() : lock_(common::ObLatchIds::FIXED_SIZE_ALLOCATOR_LOCK), total_block_num_(0), max_block_num_(0), - allocator_(SET_USE_500(ObMemAttr(OB_SERVER_TENANT_ID, ObModIds::OB_FIXED_SIZE_BLOCK_ALLOCATOR))), + allocator_(SET_USE_UNEXPECTED_500(ObMemAttr(OB_SERVER_TENANT_ID, ObModIds::OB_FIXED_SIZE_BLOCK_ALLOCATOR))), free_blocks_(), block_buf_list_(allocator_) { @@ -147,7 +147,7 @@ int ObFixedSizeBlockAllocator::init(const int64_t block_num, const lib::Ob COMMON_LOG(WARN, "init max block number fail", K(ret)); } else { ObMemAttr attr(OB_SERVER_TENANT_ID, label); - SET_USE_500(attr); + SET_USE_UNEXPECTED_500(attr); ObSpinLockGuard guard(lock_); if (IS_NOT_INIT) { if (OB_FAIL(free_blocks_.init(max_block_num_, global_default_allocator, attr))) { diff --git a/deps/oblib/src/lib/allocator/ob_mod_define.h b/deps/oblib/src/lib/allocator/ob_mod_define.h index 29b137b9b..f87f824f7 100644 --- a/deps/oblib/src/lib/allocator/ob_mod_define.h +++ b/deps/oblib/src/lib/allocator/ob_mod_define.h @@ -32,6 +32,7 @@ CTX_ITEM_DEF(PKT_NIO) CTX_ITEM_DEF(TX_DATA_TABLE) CTX_ITEM_DEF(STORAGE_LONG_TERM_META_CTX_ID) CTX_ITEM_DEF(SCHEMA_SERVICE) +CTX_ITEM_DEF(UNEXPECTED_IN_500) CTX_ITEM_DEF(MAX_CTX_ID) #endif diff --git a/deps/oblib/src/lib/hash/ob_linear_hash_map.h b/deps/oblib/src/lib/hash/ob_linear_hash_map.h index e2c7d6503..69b7fb5e2 100644 --- a/deps/oblib/src/lib/hash/ob_linear_hash_map.h +++ b/deps/oblib/src/lib/hash/ob_linear_hash_map.h @@ -229,7 +229,6 @@ private: void rm_map(void *ptr); private: ObExternalRef hash_ref_; - ObMemAttr attr_; ObSmallAllocator node_alloc_; ObConcurrentFIFOAllocator dir_alloc_; ObConcurrentFIFOAllocator cnter_alloc_; @@ -625,31 +624,26 @@ template ObLinearHashMap::HashMapMemMgrCore::HashMapMemMgrCore() : map_array_lock_(common::ObLatchIds::HASH_MAP_LOCK) { - attr_.label_ = ObModIds::OB_LINEAR_HASH_MAP; - SET_USE_500(attr_); // Init node alloc. - int ret = node_alloc_.init(static_cast(sizeof(Node)), attr_); + int ret = node_alloc_.init(static_cast(sizeof(Node)), SET_USE_500("LinearHashMapNo")); if (OB_FAIL(ret)) { LIB_LOG(WARN, "failed to init node alloc", K(ret)); } int64_t total_limit = 128 * (1L << 30); // 128GB int64_t page_size = 0; - if (!lib::is_mini_mode()) { - // - page_size = OB_MALLOC_BIG_BLOCK_SIZE; - } else { + if (lib::is_mini_mode()) { total_limit *= lib::mini_mode_resource_ratio(); - page_size = OB_MALLOC_MIDDLE_BLOCK_SIZE; } + page_size = OB_MALLOC_MIDDLE_BLOCK_SIZE; // Init dir alloc. ret = dir_alloc_.init(total_limit, 2 * page_size, page_size); - dir_alloc_.set_attr(attr_); + dir_alloc_.set_attr(SET_USE_500("LinearHashMapDi")); if (OB_FAIL(ret)) { LIB_LOG(WARN, "failed to init dir alloc", K(ret)); } // Init counter alloc. ret = cnter_alloc_.init(total_limit, 2 * page_size, page_size); - cnter_alloc_.set_attr(attr_); + cnter_alloc_.set_attr(SET_USE_500("LinearHashMapCn")); if (OB_FAIL(ret)) { LIB_LOG(WARN, "failed to init cnter alloc", K(ret)); } diff --git a/deps/oblib/src/lib/stat/ob_di_cache.cpp b/deps/oblib/src/lib/stat/ob_di_cache.cpp index 806e191c8..2bf8a782b 100644 --- a/deps/oblib/src/lib/stat/ob_di_cache.cpp +++ b/deps/oblib/src/lib/stat/ob_di_cache.cpp @@ -234,7 +234,7 @@ int ObDIThreadTenantCache::get_node(uint64_t tenant_id, ObDITenantCollect *&tena if (OB_ISNULL(tenant_collect = tenant_cache_.get_node(tenant_id))) { if (nullptr == extend_tenant_cache_) { extend_tenant_cache_ = OB_NEW(ObDIBaseTenantCache, - SET_USE_500("di_tenant_cache")); + SET_USE_UNEXPECTED_500("di_tenant_cache")); } if (nullptr != extend_tenant_cache_) { tenant_collect = extend_tenant_cache_->get_node(tenant_id, true /*replace*/); diff --git a/src/observer/ob_server.cpp b/src/observer/ob_server.cpp index 17e0d1a5c..627cf26e1 100644 --- a/src/observer/ob_server.cpp +++ b/src/observer/ob_server.cpp @@ -1755,6 +1755,11 @@ int ObServer::init_config() LOG_ERROR("some config setting is not valid", KR(ret)); } else if (OB_FAIL(GMEMCONF.reload_config(config_))) { LOG_ERROR("reload memory config failed", KR(ret)); +#ifdef ENABLE_500_MEMORY_LIMIT + } else if (config_._enable_system_tenant_memory_limit && + OB_FAIL(ObMallocAllocator::get_instance()->set_500_tenant_limit())) { + LOG_ERROR("set the limit of tenant 500 failed", KR(ret)); +#endif } else if (!is_arbitration_mode() && OB_FAIL(set_running_mode())) { LOG_ERROR("set running mode failed", KR(ret)); } else { diff --git a/src/observer/omt/ob_tenant_config_mgr.cpp b/src/observer/omt/ob_tenant_config_mgr.cpp index 6f7b3a0de..fcee744cf 100644 --- a/src/observer/omt/ob_tenant_config_mgr.cpp +++ b/src/observer/omt/ob_tenant_config_mgr.cpp @@ -283,7 +283,7 @@ int ObTenantConfigMgr::add_tenant_config(uint64_t tenant_id) } } else { ObTenantConfig *new_config = nullptr; - new_config = OB_NEW(ObTenantConfig, SET_USE_500("TenantConfig"), tenant_id); + new_config = OB_NEW(ObTenantConfig, SET_USE_UNEXPECTED_500("TenantConfig"), tenant_id); if (OB_NOT_NULL(new_config)) { if(OB_FAIL(new_config->init(this))) { LOG_WARN("new tenant config init failed", K(ret)); diff --git a/src/share/config/ob_config.cpp b/src/share/config/ob_config.cpp index 1c8af87f0..cbf4221e8 100644 --- a/src/share/config/ob_config.cpp +++ b/src/share/config/ob_config.cpp @@ -23,7 +23,7 @@ namespace oceanbase { namespace common { -ObMemAttr g_config_mem_attr = SET_USE_500("ConfigChecker"); +ObMemAttr g_config_mem_attr = SET_USE_UNEXPECTED_500("ConfigChecker"); const char *log_archive_config_keywords[] = { diff --git a/src/share/ob_occam_thread_pool.h b/src/share/ob_occam_thread_pool.h index 0b9730c7e..4e88de8ba 100644 --- a/src/share/ob_occam_thread_pool.h +++ b/src/share/ob_occam_thread_pool.h @@ -49,7 +49,7 @@ struct DefaultAllocator : public ObIAllocator { #ifdef UNIITTEST_DEBUG total_alive_num++; #endif - return ob_malloc(size, SET_USE_500("OccamThreadPool")); + return ob_malloc(size, SET_USE_UNEXPECTED_500("OccamThreadPool")); } void* alloc(const int64_t size, const ObMemAttr &attr) override { UNUSED(attr); diff --git a/src/share/parameter/ob_parameter_seed.ipp b/src/share/parameter/ob_parameter_seed.ipp index aed103824..c327e2962 100644 --- a/src/share/parameter/ob_parameter_seed.ipp +++ b/src/share/parameter/ob_parameter_seed.ipp @@ -1506,3 +1506,8 @@ DEF_BOOL(_force_explict_500_malloc, OB_CLUSTER_PARAMETER, "False", DEF_CAP(range_optimizer_max_mem_size, OB_TENANT_PARAMETER, "128M", "[16M,1G]", "to limit the memory consumption for the query range optimizer. Range: [16M,1G]", ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +#ifdef ENABLE_500_MEMORY_LIMIT +DEF_BOOL(_enable_system_tenant_memory_limit, OB_CLUSTER_PARAMETER, "True", + "specifies whether allowed to limit the memory of tenant 500", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::STATIC_EFFECTIVE)); +#endif diff --git a/src/storage/compaction/ob_sstable_merge_info_mgr.cpp b/src/storage/compaction/ob_sstable_merge_info_mgr.cpp index b194a68ec..30c987af5 100644 --- a/src/storage/compaction/ob_sstable_merge_info_mgr.cpp +++ b/src/storage/compaction/ob_sstable_merge_info_mgr.cpp @@ -149,7 +149,7 @@ void ObSSTableMergeInfoIterator::reset() */ ObTenantSSTableMergeInfoMgr::ObTenantSSTableMergeInfoMgr() : is_inited_(false), - allocator_(SET_USE_500(ObModIds::OB_SSTABLE_MERGE_INFO), OB_MALLOC_BIG_BLOCK_SIZE), + allocator_(SET_USE_UNEXPECTED_500(ObModIds::OB_SSTABLE_MERGE_INFO), OB_MALLOC_BIG_BLOCK_SIZE), major_merge_infos_(allocator_), minor_merge_infos_(allocator_) { diff --git a/src/storage/slog/ob_storage_logger_manager.cpp b/src/storage/slog/ob_storage_logger_manager.cpp index b4cbc4131..3b07cd7c1 100644 --- a/src/storage/slog/ob_storage_logger_manager.cpp +++ b/src/storage/slog/ob_storage_logger_manager.cpp @@ -24,7 +24,8 @@ using namespace common; namespace storage { ObStorageLoggerManager::ObStorageLoggerManager() - : log_dir_(nullptr), + : allocator_(SET_USE_UNEXPECTED_500("StorageLoggerM")), + log_dir_(nullptr), max_log_file_size_(0), is_inited_(false), log_file_spec_(), diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result index c4a62a636..1f15093bc 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result @@ -281,6 +281,7 @@ _enable_px_fast_reclaim _enable_px_ordered_coord _enable_reserved_user_dcl_restriction _enable_resource_limit_spec +_enable_system_tenant_memory_limit _enable_tenant_sql_net_thread _enable_trace_session_leak _enable_transaction_internal_routing