From 9dcf44983346a739dc86ada432aed23b64c78359 Mon Sep 17 00:00:00 2001 From: HaHaJeff Date: Mon, 8 May 2023 06:08:31 +0000 Subject: [PATCH] fixed restart failed due to incomplete log disk expansionoperation. --- src/logservice/ob_server_log_block_mgr.cpp | 11 ++++++- src/logservice/ob_server_log_block_mgr.h | 6 ++-- .../logservice/test_server_log_block_mgr.cpp | 32 +++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/logservice/ob_server_log_block_mgr.cpp b/src/logservice/ob_server_log_block_mgr.cpp index 14c4ab9b6b..c20e3e088c 100644 --- a/src/logservice/ob_server_log_block_mgr.cpp +++ b/src/logservice/ob_server_log_block_mgr.cpp @@ -40,6 +40,9 @@ using namespace share; namespace logservice { const char *ObServerLogBlockMgr::LOG_POOL_PATH = "log_pool"; +const int64_t ObServerLogBlockMgr::NORMAL_STATUS = 0; +const int64_t ObServerLogBlockMgr::EXPANDING_STATUS = 1; +const int64_t ObServerLogBlockMgr::SHRINKING_STATUS = 2; int ObServerLogBlockMgr::check_clog_directory_is_empty(const char *clog_dir, bool &result) { @@ -501,7 +504,13 @@ int ObServerLogBlockMgr::scan_log_pool_dir_and_do_trim_() int ret = OB_SUCCESS; GetBlockIdListFunctor functor; BlockIdArray &block_id_array = functor.block_id_array_; - if (OB_FAIL(palf::scan_dir(log_pool_path_, functor))) { + // NB: try to clear tmp file or directory in log loop. consider like this: + // there may be a expand operation in progress before restarting, if we + // not delete tmp directory which used to expand, the new expand operation + // will be failed. + if (OB_FAIL(FileDirectoryUtils::delete_tmp_file_or_directory_at(log_pool_path_))) { + CLOG_LOG(WARN, "delete_tmp_file_or_directory_at log pool failed", KPC(this)); + } else if (OB_FAIL(palf::scan_dir(log_pool_path_, functor))) { CLOG_LOG(ERROR, "scan_dir failed", K(ret), KPC(this)); } else if (true == block_id_array.empty()) { CLOG_LOG(INFO, "the log pool is empty, no need trime", K(ret), KPC(this)); diff --git a/src/logservice/ob_server_log_block_mgr.h b/src/logservice/ob_server_log_block_mgr.h index ee6ff1eda2..f4a6f36b52 100644 --- a/src/logservice/ob_server_log_block_mgr.h +++ b/src/logservice/ob_server_log_block_mgr.h @@ -58,9 +58,9 @@ private: typedef ObSEArray BlockIdArray; private: - static const int64_t NORMAL_STATUS = 0; - static const int64_t EXPANDING_STATUS = 1; - static const int64_t SHRINKING_STATUS = 2; + static const int64_t NORMAL_STATUS; + static const int64_t EXPANDING_STATUS; + static const int64_t SHRINKING_STATUS; struct LogPoolMeta { LogPoolMeta(const int64_t curr_total_size, const int64_t next_total_size, diff --git a/unittest/logservice/test_server_log_block_mgr.cpp b/unittest/logservice/test_server_log_block_mgr.cpp index 3d8509a022..d876efa8e1 100644 --- a/unittest/logservice/test_server_log_block_mgr.cpp +++ b/unittest/logservice/test_server_log_block_mgr.cpp @@ -515,6 +515,38 @@ TEST_F(TestServerLogBlockMgr, create_tenant_resize) EXPECT_EQ(3*GB, log_block_mgr_.min_log_disk_size_for_all_tenants_); } +TEST_F(TestServerLogBlockMgr, resize_log_loop_and_restart) +{ + ObServerLogBlockMgr::LogPoolMeta meta; + meta.curr_total_size_ = log_block_mgr_.log_pool_meta_.curr_total_size_; + int64_t next_total_size = meta.next_total_size_ = meta.curr_total_size_ + 1*1024*1024*1024; + meta.status_ = ObServerLogBlockMgr::EXPANDING_STATUS; + log_block_mgr_.update_log_pool_meta_guarded_by_lock_(meta); + char tmp_dir_path[OB_MAX_FILE_NAME_LENGTH] = {'\0'}; + snprintf(tmp_dir_path, OB_MAX_FILE_NAME_LENGTH, "%s/expanding.tmp", log_block_mgr_.log_pool_path_); + int tmp_dir_fd = -1; + EXPECT_EQ(OB_SUCCESS, log_block_mgr_.make_resizing_tmp_dir_(tmp_dir_path, tmp_dir_fd)); + EXPECT_EQ(OB_SUCCESS, log_block_mgr_.remove_resizing_tmp_dir_(tmp_dir_path, tmp_dir_fd)); + char file_path[OB_MAX_FILE_NAME_LENGTH] = {'\0'}; + auto touch_file_in_log_pool = [](const char *file_path) { + char cmd_touch[OB_MAX_FILE_NAME_LENGTH] = {'\0'}; + char cmd_fallocate[OB_MAX_FILE_NAME_LENGTH] = {'\0'}; + snprintf(cmd_touch, OB_MAX_FILE_NAME_LENGTH, "touch %s", file_path); + snprintf(cmd_fallocate, OB_MAX_FILE_NAME_LENGTH, "fallocate -l %lu %s", PALF_PHY_BLOCK_SIZE, file_path); + system(cmd_touch); + system(cmd_fallocate); + }; + for (int i = 0; i < 10; i++) { + int64_t file_id = i + 10000; + snprintf(file_path, OB_MAX_FILE_NAME_LENGTH, "%s/%ld", log_block_mgr_.log_pool_path_, file_id); + touch_file_in_log_pool(file_path); + } + log_block_mgr_.destroy(); + EXPECT_EQ(OB_SUCCESS, log_block_mgr_.init(log_pool_base_path_)); + EXPECT_EQ(ObServerLogBlockMgr::NORMAL_STATUS, log_block_mgr_.log_pool_meta_.status_); + EXPECT_EQ(next_total_size, log_block_mgr_.log_pool_meta_.curr_total_size_); +} + class DummyBlockPool : public palf::ILogBlockPool { public: virtual int create_block_at(const palf::FileDesc &dir_fd,