bugfix for tmp file flush and swap mechanism

This commit is contained in:
obdev
2024-09-02 07:53:58 +00:00
committed by ob-robot
parent 4942521cce
commit 0da18c43f7
6 changed files with 73 additions and 7 deletions

View File

@ -1035,5 +1035,37 @@ int ObTmpFileFlushManager::reset_flush_ctx_for_file_(const ObSharedNothingTmpFil
return ret;
}
void ObTmpFileFlushManager::try_remove_unused_file_flush_ctx()
{
int ret = OB_SUCCESS;
ObArray<int64_t> deleted_fd_arr;
ObTmpFileBatchFlushContext::ObTmpFileFlushCtxHash& file_ctx_hash = flush_ctx_.get_file_ctx_hash();
for (ObTmpFileBatchFlushContext::ObTmpFileFlushCtxHash::iterator iter = file_ctx_hash.begin();
OB_SUCC(ret) && iter != file_ctx_hash.end();
++iter) {
int64_t fd = iter->first;
ObTmpFileSingleFlushContext &file_flush_ctx = iter->second;
ObSharedNothingTmpFile *file = file_flush_ctx.file_handle_.get();
if (OB_ISNULL(file)) {
ret = OB_ERR_UNEXPECTED;
STORAGE_LOG(WARN, "file is nullptr", KR(ret), K(fd), K(file_flush_ctx));
} else if (file->is_deleting()) {
STORAGE_LOG(INFO, "the file is deleting, delete unused file flush ctx",
KR(ret), K(fd), K(file_flush_ctx));
if (OB_FAIL(deleted_fd_arr.push_back(fd))) {
STORAGE_LOG(WARN, "fail to deleted_fd_arr.push_back", KR(ret), K(fd), K(file_flush_ctx));
}
}
}
int tmp_ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCCESS == tmp_ret && i < deleted_fd_arr.count(); ++i) {
if (OB_TMP_FAIL(flush_ctx_.get_file_ctx_hash().erase_refactored(deleted_fd_arr[i]))) {
STORAGE_LOG(ERROR, "fail to erase file ctx from hash", KR(tmp_ret), K(deleted_fd_arr[i]));
}
}
}
} // end namespace tmp_file
} // end namespace oceanbase

View File

@ -67,6 +67,8 @@ public:
~ObTmpFileFlushManager() {}
int init();
void destroy();
TO_STRING_KV(K(is_inited_), K(flush_ctx_));
public:
int free_tmp_file_block(ObTmpFileFlushTask &flush_task);
int alloc_flush_task(ObTmpFileFlushTask *&flush_task);
@ -79,6 +81,7 @@ public:
int retry(ObTmpFileFlushTask &flush_task);
int io_finished(ObTmpFileFlushTask &flush_task);
int update_file_meta_after_flush(ObTmpFileFlushTask &flush_task);
void try_remove_unused_file_flush_ctx();
private:
int fill_block_buf_(ObTmpFileFlushTask &flush_task);
int fast_fill_block_buf_with_meta_(ObTmpFileFlushTask &flush_task);

View File

@ -239,6 +239,8 @@ int ObTmpFileFlushTG::do_work_()
}
}
flush_mgr_.try_remove_unused_file_flush_ctx();
if (TC_REACH_TIME_INTERVAL(1 * 1000 * 1000)) {
tmp_file_block_mgr_.print_block_usage();
flush_monitor_.print_statistics();
@ -361,7 +363,7 @@ int ObTmpFileFlushTG::wash_(const int64_t expect_flush_size, const RUNNING_MODE
}
bool idle_loop = flushing_task_cnt == 0;
if (idle_loop && wbp_.get_dirty_page_percentage() < ObTmpFileFlushManager::FLUSH_WATERMARK_F5) {
if (idle_loop && wbp_.get_cannot_be_evicted_page_percentage() < ObTmpFileFlushManager::FLUSH_WATERMARK_F3) {
signal_io_finish(OB_SUCCESS);
}
@ -963,7 +965,7 @@ int ObTmpFileSwapTG::wakeup_satisfied_jobs_(int64_t& wakeup_job_cnt)
{
int ret = OB_SUCCESS;
wakeup_job_cnt = 0;
int64_t wbp_free_page_cnt = wbp_.get_max_data_page_num() - wbp_.get_data_page_num();
int64_t wbp_free_page_cnt = wbp_.get_free_data_page_num();
while (OB_SUCC(ret) && wbp_free_page_cnt > 0 && !working_list_.is_empty()) {
ObTmpFileSwapJob *swap_job = nullptr;
if (OB_FAIL(pop_working_job_(swap_job))) {

View File

@ -55,9 +55,11 @@ public:
int64_t get_flush_io_finished_round();
int64_t cal_idle_time();
void clean_up_lists();
TO_STRING_KV(K(is_inited_), K(flushing_block_num_), K(is_fast_flush_meta_), K(fast_flush_meta_task_cnt_), K(mode_),
TO_STRING_KV(K(is_inited_), K(mode_), K(last_flush_timestamp_), K(flush_io_finished_ret_), K(flush_io_finished_round_),
K(flushing_block_num_), K(is_fast_flush_meta_), K(fast_flush_meta_task_cnt_),
K(wait_list_size_), K(retry_list_size_), K(finished_list_size_),
K(normal_loop_cnt_), K(normal_idle_loop_cnt_), K(fast_loop_cnt_), K(fast_idle_loop_cnt_));
K(normal_loop_cnt_), K(normal_idle_loop_cnt_), K(fast_loop_cnt_), K(fast_idle_loop_cnt_),
K(flush_mgr_));
private:
int do_work_();
int handle_generated_flush_tasks_(ObSpLinkQueue &flushing_list, int64_t &task_num);

View File

@ -566,9 +566,9 @@ int64_t ObTmpWriteBufferPool::get_memory_limit()
} else if (0 == tenant_config->_temporary_file_io_area_size) {
memory_limit = 0;
} else {
memory_limit = common::upper_align(
lib::get_tenant_memory_limit(MTL_ID()) * tenant_config->_temporary_file_io_area_size / 100,
WBP_BLOCK_SIZE);
int64_t config_memory_limit =
lib::get_tenant_memory_limit(MTL_ID()) * tenant_config->_temporary_file_io_area_size / 100;
memory_limit = ((config_memory_limit + WBP_BLOCK_SIZE - 1) / WBP_BLOCK_SIZE) * WBP_BLOCK_SIZE;
}
ATOMIC_STORE(&wbp_memory_limit_, memory_limit);
ATOMIC_STORE(&last_access_tenant_config_ts_, common::ObClockGenerator::getClock());
@ -918,6 +918,19 @@ int64_t ObTmpWriteBufferPool::get_dirty_page_percentage()
return max_page_num == 0 ? 0 : dirty_page_num * 100 / max_page_num;
}
int64_t ObTmpWriteBufferPool::get_cannot_be_evicted_page_percentage()
{
int64_t max_page_num = get_max_page_num();
int64_t dirty_page_num = ATOMIC_LOAD(&dirty_page_num_);
int64_t write_back_data_num = ATOMIC_LOAD(&write_back_data_cnt_);
int64_t write_back_meta_num = ATOMIC_LOAD(&write_back_meta_cnt_);
int64_t total_write_back_num = write_back_data_num + write_back_meta_num;
return max_page_num == 0 ? 0 : (dirty_page_num + total_write_back_num) * 100 / max_page_num;
}
int64_t ObTmpWriteBufferPool::get_dirty_page_num()
{
return ATOMIC_LOAD(&dirty_page_num_);
@ -948,6 +961,17 @@ int64_t ObTmpWriteBufferPool::get_meta_page_num()
return ATOMIC_LOAD(&meta_page_cnt_);
}
int64_t ObTmpWriteBufferPool::get_free_data_page_num()
{
int64_t data_page_cnt = ATOMIC_LOAD(&data_page_cnt_);
int64_t meta_page_cnt = ATOMIC_LOAD(&meta_page_cnt_);
int64_t total_free_page_cnt = get_max_page_num() - data_page_cnt - meta_page_cnt;
int64_t data_free_page_cnt = get_max_data_page_num() - data_page_cnt;
return MIN(total_free_page_cnt, data_free_page_cnt);
}
bool ObTmpWriteBufferPool::has_free_page_(PageEntryType type)
{
int ret = OB_SUCCESS;

View File

@ -241,11 +241,14 @@ public:
int64_t get_max_page_num();
int64_t get_data_page_num();
int64_t get_dirty_page_num();
int64_t get_write_back_page_num();
int64_t get_dirty_meta_page_num();
int64_t get_dirty_data_page_num();
int64_t get_dirty_page_percentage();
int64_t get_cannot_be_evicted_page_percentage();
int64_t get_max_data_page_num();
int64_t get_meta_page_num();
int64_t get_free_data_page_num();
void print_statistics();
private:
static double MAX_DATA_PAGE_USAGE_RATIO; // control data pages ratio, can be preempted by meta pages