[CP] [BUG.FIX] Add _temporary_file_meta_memory_limit for tmp file

This commit is contained in:
Tyshawn
2023-11-20 08:46:45 +00:00
committed by ob-robot
parent d9ca3d13de
commit af9c216530
5 changed files with 57 additions and 33 deletions

View File

@ -431,6 +431,11 @@ DEF_INT(_temporary_file_io_area_size, OB_TENANT_PARAMETER, "1", "[0, 50)",
"memory buffer size of temporary file, as a percentage of total tenant memory. " "memory buffer size of temporary file, as a percentage of total tenant memory. "
"Range: [0, 50), percentage", "Range: [0, 50), percentage",
ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
DEF_INT(_temporary_file_meta_memory_limit_percentage, OB_TENANT_PARAMETER, "0", "[0,100]",
"The memory limit of temporary file meta, and the value is a percentage of the tenant's memory. "
"The default value is 70. For compatibility, 0 is 70% of tenant memory."
"Range: [0, 100], percentage",
ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
DEF_INT(_storage_meta_memory_limit_percentage, OB_TENANT_PARAMETER, "20", "[0, 50)", DEF_INT(_storage_meta_memory_limit_percentage, OB_TENANT_PARAMETER, "20", "[0, 50)",
"maximum memory for storage meta, as a percentage of total tenant memory. " "maximum memory for storage meta, as a percentage of total tenant memory. "
"Range: [0, 50), percentage, 0 means no limit to storage meta memory", "Range: [0, 50), percentage, 0 means no limit to storage meta memory",

View File

@ -1525,25 +1525,12 @@ int ObTmpTenantMemBlockManager::exec_wait()
int ObTmpTenantMemBlockManager::change_mem() int ObTmpTenantMemBlockManager::change_mem()
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
uint64_t mem_limit = 0; // Here, this memory is used to store temporary file block metadata, which is related to the
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id_)); // datafile size. So, we set the upper limit of memory to be percentage (default, 70%) of tenant memory to
if (!tenant_config.is_valid()) { // avoid excessive tenant memory, and affecting system stability. In theory, the limit
COMMON_LOG(INFO, "failed to get tenant config", K_(tenant_id)); // will be reached only when the tenant's memory is extremely small and the disk is extremely
} else { // large.
// Here, this memory is used to store temporary file block metadata, which is related to the tenant_store_.refresh_memory_limit(tenant_id_);
// datafile size. So, we set the upper limit of memory to be 70% of tenant memory to
// avoid excessive tenant memory, and affecting system stability. In theory, the limit
// will be reached only when the tenant's memory is extremely small and the disk is extremely
// large.
if (0 == tenant_config->_temporary_file_io_area_size) {
mem_limit = 2 * (2 << 20);
} else {
mem_limit = common::upper_align(
lib::get_tenant_memory_limit(tenant_id_) * 0.7, ObTmpFileStore::get_block_size());
}
allocator_->set_total_limit(mem_limit);
}
return ret; return ret;
} }

View File

@ -13,6 +13,7 @@
#include "ob_tmp_file_store.h" #include "ob_tmp_file_store.h"
#include "ob_tmp_file.h" #include "ob_tmp_file.h"
#include "share/ob_task_define.h" #include "share/ob_task_define.h"
#include "observer/omt/ob_tenant_config_mgr.h"
using namespace oceanbase::share; using namespace oceanbase::share;
@ -902,7 +903,9 @@ ObTmpTenantFileStore::ObTmpTenantFileStore()
allocator_(), allocator_(),
io_allocator_(), io_allocator_(),
tmp_block_manager_(), tmp_block_manager_(),
tmp_mem_block_manager_(*this) tmp_mem_block_manager_(*this),
last_access_tenant_config_ts_(0),
last_meta_mem_limit_(TOTAL_LIMIT)
{ {
} }
@ -956,20 +959,41 @@ int ObTmpTenantFileStore::init(const uint64_t tenant_id)
return ret; return ret;
} }
int64_t ObTmpTenantFileStore::get_memory_limit(const uint64_t tenant_id) const { void ObTmpTenantFileStore::refresh_memory_limit(const uint64_t tenant_id)
int64_t memory_limit = 0; {
const int64_t lower_limit = 1 << 30; // 1G memory for 500G disk const int64_t old_limit = ATOMIC_LOAD(&last_meta_mem_limit_);
const int64_t upper_limit = int64_t(200) * (1 << 30); // 200G memory for 100T disk const int64_t new_limit = get_memory_limit(tenant_id);
const int64_t tenant_memory_limit = lib::get_tenant_memory_limit(tenant_id) * 0.7; if (old_limit != new_limit) {
if (tenant_memory_limit < lower_limit) { allocator_.set_total_limit(new_limit);
memory_limit = lower_limit; ObTaskController::get().allow_next_syslog();
} else if (tenant_memory_limit > upper_limit) { STORAGE_LOG(INFO, "succeed to refresh temporary file meta memory limit", K(tenant_id), K(old_limit), K(new_limit));
memory_limit = upper_limit;
} else {
memory_limit = tenant_memory_limit;
} }
memory_limit = common::upper_align(memory_limit, ObTmpFileStore::get_block_size()); }
int64_t ObTmpTenantFileStore::get_memory_limit(const uint64_t tenant_id)
{
const int64_t last_access_ts = ATOMIC_LOAD(&last_access_tenant_config_ts_);
int64_t memory_limit = TOTAL_LIMIT;
if (last_access_ts > 0 && common::ObClockGenerator::getClock() - last_access_ts < REFRESH_CONFIG_INTERVAL) {
memory_limit = ATOMIC_LOAD(&last_meta_mem_limit_);
} else {
omt::ObTenantConfigGuard config(TENANT_CONF(tenant_id));
const int64_t tenant_mem_limit = lib::get_tenant_memory_limit(tenant_id);
if (!config.is_valid() || 0 == tenant_mem_limit || INT64_MAX == tenant_mem_limit) {
COMMON_LOG(INFO, "failed to get tenant config", K(tenant_id), K(tenant_mem_limit));
} else {
const int64_t limit_percentage_config = config->_temporary_file_meta_memory_limit_percentage;
const int64_t limit_percentage = 0 == limit_percentage_config ? 70 : limit_percentage_config;
memory_limit = tenant_mem_limit * limit_percentage / 100;
if (OB_UNLIKELY(memory_limit <= 0)) {
STORAGE_LOG(INFO, "memory limit isn't more than 0", K(memory_limit));
memory_limit = ATOMIC_LOAD(&last_meta_mem_limit_);
} else {
ATOMIC_STORE(&last_meta_mem_limit_, memory_limit);
ATOMIC_STORE(&last_access_tenant_config_ts_, common::ObClockGenerator::getClock());
}
}
}
return memory_limit; return memory_limit;
} }
@ -982,6 +1006,8 @@ void ObTmpTenantFileStore::destroy()
} }
allocator_.destroy(); allocator_.destroy();
io_allocator_.reset(); io_allocator_.reset();
last_access_tenant_config_ts_ = 0;
last_meta_mem_limit_ = TOTAL_LIMIT;
is_inited_ = false; is_inited_ = false;
STORAGE_LOG(INFO, "cache num when destroy", STORAGE_LOG(INFO, "cache num when destroy",
K(ATOMIC_LOAD(&page_cache_num_)), K(ATOMIC_LOAD(&block_cache_num_))); K(ATOMIC_LOAD(&page_cache_num_)), K(ATOMIC_LOAD(&block_cache_num_)));

View File

@ -250,6 +250,7 @@ public:
int read(ObTmpBlockIOInfo &io_info, ObTmpFileIOHandle &handle); int read(ObTmpBlockIOInfo &io_info, ObTmpFileIOHandle &handle);
int write(const ObTmpBlockIOInfo &io_info); int write(const ObTmpBlockIOInfo &io_info);
int wash_block(const int64_t block_id, ObTmpTenantMemBlockManager::ObIOWaitInfoHandle &handle); int wash_block(const int64_t block_id, ObTmpTenantMemBlockManager::ObIOWaitInfoHandle &handle);
void refresh_memory_limit(const uint64_t tenant_id);
int sync_block(const int64_t block_id, ObTmpTenantMemBlockManager::ObIOWaitInfoHandle &handle); int sync_block(const int64_t block_id, ObTmpTenantMemBlockManager::ObIOWaitInfoHandle &handle);
int wait_write_finish(const int64_t block_id, const int64_t timeout_ms); int wait_write_finish(const int64_t block_id, const int64_t timeout_ms);
int get_disk_macro_block_list(common::ObIArray<MacroBlockId> &macro_id_list); int get_disk_macro_block_list(common::ObIArray<MacroBlockId> &macro_id_list);
@ -278,12 +279,14 @@ private:
int free_extent(const int64_t block_id, const int32_t start_page_id, const int32_t page_nums); int free_extent(const int64_t block_id, const int32_t start_page_id, const int32_t page_nums);
int free_macro_block(ObTmpMacroBlock *&t_mblk); int free_macro_block(ObTmpMacroBlock *&t_mblk);
int alloc_macro_block(const int64_t dir_id, const uint64_t tenant_id, ObTmpMacroBlock *&t_mblk); int alloc_macro_block(const int64_t dir_id, const uint64_t tenant_id, ObTmpMacroBlock *&t_mblk);
int64_t get_memory_limit(const uint64_t tenant_id) const; int64_t get_memory_limit(const uint64_t tenant_id);
int wait_write_io_finish_if_need();
private: private:
static const uint64_t IO_LIMIT = 4 * 1024L * 1024L * 1024L; static const uint64_t IO_LIMIT = 4 * 1024L * 1024L * 1024L;
static const uint64_t TOTAL_LIMIT = 15 * 1024L * 1024L * 1024L; static const uint64_t TOTAL_LIMIT = 15 * 1024L * 1024L * 1024L;
static const uint64_t HOLD_LIMIT = 8 * 1024L * 1024L; static const uint64_t HOLD_LIMIT = 8 * 1024L * 1024L;
static const uint64_t REFRESH_CONFIG_INTERVAL = 5 * 60 * 1000 * 1000L; // 5min
static const uint64_t BLOCK_SIZE = common::OB_MALLOC_MIDDLE_BLOCK_SIZE; static const uint64_t BLOCK_SIZE = common::OB_MALLOC_MIDDLE_BLOCK_SIZE;
static constexpr double DEFAULT_PAGE_IO_MERGE_RATIO = 0.5; static constexpr double DEFAULT_PAGE_IO_MERGE_RATIO = 0.5;
@ -297,6 +300,8 @@ private:
common::ObFIFOAllocator io_allocator_; common::ObFIFOAllocator io_allocator_;
ObTmpTenantMacroBlockManager tmp_block_manager_; ObTmpTenantMacroBlockManager tmp_block_manager_;
ObTmpTenantMemBlockManager tmp_mem_block_manager_; ObTmpTenantMemBlockManager tmp_mem_block_manager_;
int64_t last_access_tenant_config_ts_;
int64_t last_meta_mem_limit_;
DISALLOW_COPY_AND_ASSIGN(ObTmpTenantFileStore); DISALLOW_COPY_AND_ASSIGN(ObTmpTenantFileStore);
}; };

View File

@ -395,6 +395,7 @@ _storage_leak_check_mod
_storage_meta_memory_limit_percentage _storage_meta_memory_limit_percentage
_system_tenant_limit_mode _system_tenant_limit_mode
_temporary_file_io_area_size _temporary_file_io_area_size
_temporary_file_meta_memory_limit_percentage
_trace_control_info _trace_control_info
_transfer_finish_trans_timeout _transfer_finish_trans_timeout
_transfer_process_lock_tx_timeout _transfer_process_lock_tx_timeout