[CP] [BUG.FIX] Add _temporary_file_meta_memory_limit for tmp file
This commit is contained in:
@ -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",
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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_)));
|
||||||
|
|||||||
@ -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> ¯o_id_list);
|
int get_disk_macro_block_list(common::ObIArray<MacroBlockId> ¯o_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);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user