diff --git a/src/share/parameter/ob_parameter_seed.ipp b/src/share/parameter/ob_parameter_seed.ipp index 0900494e259bcea758c2c490aa538661d793a65f..ae229e83b6af5f6ee687d41c049b83b8ae59c85a 100644 --- a/src/share/parameter/ob_parameter_seed.ipp +++ b/src/share/parameter/ob_parameter_seed.ipp @@ -1452,3 +1452,7 @@ DEF_BOOL(_auto_drop_tenant_if_restore_failed, OB_CLUSTER_PARAMETER, "True", DEF_BOOL(ob_proxy_readonly_transaction_routing_policy, OB_TENANT_PARAMETER, "true", "Proxy route policy for readonly sql", ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); + +DEF_BOOL(_enable_block_file_punch_hole, OB_CLUSTER_PARAMETER, "False", + "specifies whether to punch whole when free blocks in block_file", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); diff --git a/src/storage/blocksstable/ob_local_file_system.h b/src/storage/blocksstable/ob_local_file_system.h index 79fc1447a68782ed3af8570032298da24adc5869..b51373e5d8d5ff035fdfee2f3ecfff03588c2e40 100644 --- a/src/storage/blocksstable/ob_local_file_system.h +++ b/src/storage/blocksstable/ob_local_file_system.h @@ -113,6 +113,8 @@ public: virtual int get_super_block_version(int64_t& super_block_version) override; virtual int resize_file(const int64_t new_data_file_size, const int64_t new_data_file_disk_percentage) override; + OB_INLINE int get_block_file_fd() const { return fd_.fd_; } + TO_STRING_KV("type", "LOCAL"); private: diff --git a/src/storage/blocksstable/ob_store_file.cpp b/src/storage/blocksstable/ob_store_file.cpp index 31fbd6ec9e31b0b4bf5b52e3df95b34f8bd28138..55340b0d1f8f249ba42011fa299f30a26c62a016 100644 --- a/src/storage/blocksstable/ob_store_file.cpp +++ b/src/storage/blocksstable/ob_store_file.cpp @@ -11,6 +11,7 @@ */ #define USING_LOG_PREFIX STORAGE +#include #include "ob_store_file.h" #include "lib/file/file_directory_utils.h" #include "share/config/ob_server_config.h" @@ -410,7 +411,9 @@ ObStoreFile::ObStoreFile() store_file_system_(NULL), is_mark_sweep_enabled_(false), is_doing_mark_sweep_(false), - cond_() + cond_(), + is_fs_support_punch_hole_(true), + block_file_fd_(OB_INVALID_FD) { MEMSET(used_macro_cnt_, 0, sizeof(used_macro_cnt_)); } @@ -430,6 +433,7 @@ int ObStoreFile::init(const ObStorageEnv& storage_env, ObStoreFileSystem* store_ { int ret = OB_SUCCESS; ObLogCursor replay_start_cursor; + ObLocalFileSystem *local_fs = nullptr; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; @@ -446,9 +450,17 @@ int ObStoreFile::init(const ObStorageEnv& storage_env, ObStoreFileSystem* store_ STORAGE_LOG(WARN, "Fail to allocate memory, ", K(ret), K_(print_buffer_size)); } else if (OB_FAIL(cond_.init(common::ObWaitEventIds::DEFAULT_COND_WAIT))) { STORAGE_LOG(WARN, "fail to init thread cond", K(ret)); + } else if (FALSE_IT(local_fs = dynamic_cast(store_file_system))) { } else { store_file_system_ = store_file_system; + if (nullptr != local_fs) { + block_file_fd_ = local_fs->get_block_file_fd(); + is_fs_support_punch_hole_ = true; + } else { + is_fs_support_punch_hole_ = false; + } + if (OB_SUCC(ret)) { if (OB_FAIL(alloc_memory(store_file_system_->get_total_macro_block_count(), free_block_array_, @@ -580,6 +592,8 @@ void ObStoreFile::destroy() is_mark_sweep_enabled_ = false; is_doing_mark_sweep_ = false; cond_.destroy(); + is_fs_support_punch_hole_ = true; + block_file_fd_ = OB_INVALID_FD; } void ObStoreFile::stop() @@ -1021,6 +1035,27 @@ void ObStoreFile::free_block(const uint32_t block_idx, bool& is_freed) free_block_array_[free_block_push_pos_] = block_idx; free_block_push_pos_ = (free_block_push_pos_ + 1) % store_file_system_->get_total_macro_block_count(); ++free_block_cnt_; + + // punch hole + if (is_fs_support_punch_hole_ && GCONF._enable_block_file_punch_hole) { + const int64_t len = store_file_system_->get_macro_block_size(); + const int64_t offset = store_file_system_->get_macro_block_size() * block_idx; + const int sys_ret = ::fallocate(block_file_fd_, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len); + if (sys_ret < 0) { + const int sys_err = errno; + if (EOPNOTSUPP == sys_err) { + // The file system containing the file referred to by fd does + // not support this operation; or the mode is not supported + // by the file system containing the file referred to by fd. + is_fs_support_punch_hole_ = false; + SHARE_LOG(WARN, "Punch hole not support", K(block_idx), K(offset), K(len), K(sys_ret), K(sys_err), KERRMSG); + } else { + SHARE_LOG(ERROR, "Punch hole fail", K(block_idx), K(offset), K(len), K(sys_ret), K(sys_err), KERRMSG); + } + } else { + SHARE_LOG(INFO, "Punch hole success", K(block_idx), K(offset), K(len)); + } + } } } diff --git a/src/storage/blocksstable/ob_store_file.h b/src/storage/blocksstable/ob_store_file.h index a23128b1f6f4b43599f7f79ae9e70a620c460afb..e9b67b1867277723d481e3209350390d7bdcdf1d 100644 --- a/src/storage/blocksstable/ob_store_file.h +++ b/src/storage/blocksstable/ob_store_file.h @@ -432,6 +432,8 @@ private: bool is_mark_sweep_enabled_; bool is_doing_mark_sweep_; ObThreadCond cond_; // for mark sweep + bool is_fs_support_punch_hole_; + int block_file_fd_; }; OB_INLINE bool ObStoreFile::is_valid(const MacroBlockId macro_id)