diff --git a/src/storage/backup/ob_backup_ctx.cpp b/src/storage/backup/ob_backup_ctx.cpp index 8fc8de0f1..12b9ccd8b 100644 --- a/src/storage/backup/ob_backup_ctx.cpp +++ b/src/storage/backup/ob_backup_ctx.cpp @@ -964,32 +964,32 @@ void ObLSBackupCtx::reuse() check_tablet_info_cost_time_ = 0; } -int ObLSBackupCtx::hold_tablet(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle) +int ObLSBackupCtx::set_tablet(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *tablet_handle) { int ret = OB_SUCCESS; ObMutexGuard guard(mutex_); - if (!tablet_id.is_valid() || !tablet_handle.is_valid()) { + if (!tablet_id.is_valid() || OB_ISNULL(tablet_handle)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), K(tablet_id), K(tablet_handle)); - } else if (OB_FAIL(tablet_holder_.hold_tablet(tablet_id, tablet_handle))) { - LOG_WARN("failed to hold tablet", K(ret), K(tablet_id)); + LOG_WARN("get invalid args", K(ret), K(tablet_id), KP(tablet_handle)); + } else if (OB_FAIL(tablet_holder_.set_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to hold tablet", K(ret), K(tablet_id), KPC(tablet_handle)); } else { - LOG_DEBUG("hold tablet", K(tablet_id)); + LOG_DEBUG("backup set tablet", K(tablet_id), KP(tablet_handle)); } return ret; } -int ObLSBackupCtx::get_tablet(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle) +int ObLSBackupCtx::get_tablet(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *&tablet_handle) { int ret = OB_SUCCESS; ObMutexGuard guard(mutex_); if (!tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), K(tablet_id), K(tablet_handle)); + LOG_WARN("get invalid args", K(ret), K(tablet_id)); } else if (OB_FAIL(tablet_holder_.get_tablet(tablet_id, tablet_handle))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); } else { - LOG_DEBUG("acquire tablet", K(tablet_id)); + LOG_DEBUG("backup get tablet", K(tablet_id), KP(tablet_handle)); } return ret; } diff --git a/src/storage/backup/ob_backup_ctx.h b/src/storage/backup/ob_backup_ctx.h index 403a99bfd..4e644df70 100644 --- a/src/storage/backup/ob_backup_ctx.h +++ b/src/storage/backup/ob_backup_ctx.h @@ -233,8 +233,8 @@ public: const ObLSBackupParam ¶m, const share::ObBackupDataType &backup_data_type, common::ObMySQLProxy &sql_proxy); int next(common::ObTabletID &tablet_id); void set_backup_data_type(const share::ObBackupDataType &backup_data_type); - int hold_tablet(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle); - int get_tablet(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle); + int set_tablet(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *tablet_handle); + int get_tablet(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *&tablet_handle); int release_tablet(const common::ObTabletID &tablet_id); void set_result_code(const int64_t result, bool &is_set); int64_t get_result_code() const; diff --git a/src/storage/backup/ob_backup_task.cpp b/src/storage/backup/ob_backup_task.cpp index 2cd7d7288..4e25c91c8 100644 --- a/src/storage/backup/ob_backup_task.cpp +++ b/src/storage/backup/ob_backup_task.cpp @@ -2805,16 +2805,16 @@ int ObLSBackupDataTask::do_backup_meta_data_() const common::ObTabletID &tablet_id = item.get_tablet_id(); ObITabletMetaBackupReader *reader = NULL; ObBufferReader buffer_reader; - ObTabletHandle tablet_handle; + ObBackupTabletHandleRef *tablet_ref = NULL; ObTabletMetaReaderType reader_type; ObBackupMetaType meta_type; ObBackupMetaIndex meta_index; const ObBackupPhysicalID physical_id = ObBackupPhysicalID::get_default(); if (OB_FAIL(get_tablet_meta_info_(item, reader_type, meta_type))) { LOG_WARN("failed to get tablet meta info", K(ret), K(item)); - } else if (OB_FAIL(get_tablet_handle_(tablet_id, tablet_handle))) { + } else if (OB_FAIL(get_tablet_handle_(tablet_id, tablet_ref))) { LOG_WARN("failed to get tablet handle", K(ret), K_(task_id), K(tablet_id), K(item), K(i), K(item_list)); - } else if (OB_FAIL(prepare_tablet_meta_reader_(tablet_id, reader_type, tablet_handle, reader))) { + } else if (OB_FAIL(prepare_tablet_meta_reader_(tablet_id, reader_type, tablet_ref->tablet_handle_, reader))) { LOG_WARN("failed to prepare tablet meta reader", K(tablet_id), K(reader_type)); } else if (OB_FAIL(reader->get_meta_data(buffer_reader))) { LOG_WARN("failed to get meta data", K(ret), K(tablet_id)); @@ -3208,9 +3208,10 @@ int ObLSBackupDataTask::write_backup_meta_(const ObBufferReader &data, const com return ret; } -int ObLSBackupDataTask::get_tablet_handle_(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle) +int ObLSBackupDataTask::get_tablet_handle_(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *&tablet_handle) { int ret = OB_SUCCESS; + tablet_handle = NULL; if (!tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(tablet_id)); @@ -3219,6 +3220,9 @@ int ObLSBackupDataTask::get_tablet_handle_(const common::ObTabletID &tablet_id, LOG_WARN("ls backup ctx should not be null", K(ret)); } else if (OB_FAIL(ls_backup_ctx_->get_tablet(tablet_id, tablet_handle))) { LOG_WARN("failed to acquire tablet", K(ret), K(tablet_id)); + } else if (OB_ISNULL(tablet_handle)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet handle should not be null", K(ret), K(tablet_id)); } else { LOG_DEBUG("get tablet handle", K(tablet_id)); } @@ -3456,7 +3460,7 @@ int ObLSBackupDataTask::may_fill_reused_backup_items_( const common::ObTabletID &tablet_id, ObBackupTabletStat *tablet_stat) { int ret = OB_SUCCESS; - ObTabletHandle tablet_handle; + ObBackupTabletHandleRef *tablet_ref = NULL; ObTabletMemberWrapper table_store_wrapper; ObBackupDataType backup_data_type; backup_data_type.set_major_data_backup(); @@ -3469,25 +3473,25 @@ int ObLSBackupDataTask::may_fill_reused_backup_items_( // do nothing } else if (tablet_id.id() != ls_backup_ctx_->backup_retry_ctx_.need_skip_logic_id_.tablet_id_) { // do nothing - } else if (OB_FAIL(get_tablet_handle_(tablet_id, tablet_handle))) { + } else if (OB_FAIL(get_tablet_handle_(tablet_id, tablet_ref))) { LOG_WARN("failed to get tablet handle", K(ret), K(tablet_id)); - } else if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + } else if (OB_FAIL(tablet_ref->tablet_handle_.get_obj()->fetch_table_store(table_store_wrapper))) { LOG_WARN("fail to fetch table store", K(ret)); - } else if (OB_FAIL(ObBackupUtils::get_sstables_by_data_type(tablet_handle, + } else if (OB_FAIL(ObBackupUtils::get_sstables_by_data_type(tablet_ref->tablet_handle_, backup_data_type, *table_store_wrapper.get_member(), sstable_array))) { - LOG_WARN("failed to get sstable by data type", K(ret), K(tablet_handle)); + LOG_WARN("failed to get sstable by data type", K(ret), K(tablet_ref)); } else if (sstable_array.empty()) { // do nothing - } else if (1 != sstable_array.count() && tablet_handle.get_obj()->is_row_store()) { + } else if (1 != sstable_array.count() && tablet_ref->tablet_handle_.get_obj()->is_row_store()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sstable array count not 1", K(ret), K(sstable_array)); } else if (1 == sstable_array.count()) { - if (OB_FAIL(check_and_mark_item_reused_(sstable_array.at(0).get_sstable(), tablet_handle, tablet_stat))) { + if (OB_FAIL(check_and_mark_item_reused_(sstable_array.at(0).get_sstable(), tablet_ref->tablet_handle_, tablet_stat))) { LOG_WARN("failed to check and mark item reused", K(ret)); } } else { for (int64_t i = 0; OB_SUCC(ret) && i < sstable_array.count(); ++i) { - if (OB_FAIL(check_and_mark_item_reused_(sstable_array.at(i).get_sstable(), tablet_handle, tablet_stat))) { + if (OB_FAIL(check_and_mark_item_reused_(sstable_array.at(i).get_sstable(), tablet_ref->tablet_handle_, tablet_stat))) { LOG_WARN("failed to check and mark item reused", K(ret)); } } diff --git a/src/storage/backup/ob_backup_task.h b/src/storage/backup/ob_backup_task.h index d7c42f01c..221451b5f 100644 --- a/src/storage/backup/ob_backup_task.h +++ b/src/storage/backup/ob_backup_task.h @@ -558,7 +558,7 @@ private: ObBackupMacroBlockIndex ¯o_index); int write_backup_meta_(const blocksstable::ObBufferReader &data, const common::ObTabletID &tablet_id, const ObBackupMetaType &meta_type, ObBackupMetaIndex &meta_index); - int get_tablet_handle_(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle); + int get_tablet_handle_(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *&tablet_handle); int release_tablet_handle_(const common::ObTabletID &tablet_id); int check_backup_finish_(bool &finish); int do_generate_next_backup_dag_(); diff --git a/src/storage/backup/ob_backup_utils.cpp b/src/storage/backup/ob_backup_utils.cpp index a27efd655..512b412de 100644 --- a/src/storage/backup/ob_backup_utils.cpp +++ b/src/storage/backup/ob_backup_utils.cpp @@ -1051,17 +1051,24 @@ int ObBackupTabletStat::PrintTabletStatOp::operator()( /* ObBackupTabletHolder */ -ObBackupTabletHolder::ObBackupTabletHolder() : is_inited_(false), ls_id_(), holder_map_() +ObBackupTabletHolder::ObBackupTabletHolder() + : is_inited_(false), + ls_id_(), + holder_map_(), + fifo_allocator_() {} ObBackupTabletHolder::~ObBackupTabletHolder() -{} +{ + reset(); +} int ObBackupTabletHolder::init(const uint64_t tenant_id, const share::ObLSID &ls_id) { int ret = OB_SUCCESS; const int64_t MAX_BUCKET_NUM = 1024; lib::ObMemAttr mem_attr(tenant_id, ObModIds::BACKUP); + const int64_t block_size = common::OB_MALLOC_NORMAL_BLOCK_SIZE; if (IS_INIT) { ret = OB_INIT_TWICE; LOG_WARN("backup tablet holder init twice", K(ret)); @@ -1070,6 +1077,8 @@ int ObBackupTabletHolder::init(const uint64_t tenant_id, const share::ObLSID &ls LOG_WARN("get invalid args", K(ret), K(ls_id)); } else if (OB_FAIL(holder_map_.create(MAX_BUCKET_NUM, mem_attr))) { LOG_WARN("failed to create tablet handle map", K(ret)); + } else if (OB_FAIL(fifo_allocator_.init(NULL, block_size, mem_attr))) { + LOG_WARN("failed to init fifo allocator", K(ret)); } else { is_inited_ = true; ls_id_ = ls_id; @@ -1077,29 +1086,56 @@ int ObBackupTabletHolder::init(const uint64_t tenant_id, const share::ObLSID &ls return ret; } -int ObBackupTabletHolder::hold_tablet(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle) +int ObBackupTabletHolder::alloc_tablet_ref(ObBackupTabletHandleRef *&tablet_handle) +{ + int ret = OB_SUCCESS; + tablet_handle = NULL; + void *buf = NULL; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tablet holder not init", K(ret)); + } else if (OB_ISNULL(buf = fifo_allocator_.alloc(sizeof(ObBackupTabletHandleRef)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret)); + } else { + tablet_handle = new (buf) ObBackupTabletHandleRef; + } + return ret; +} + +void ObBackupTabletHolder::free_tablet_ref(ObBackupTabletHandleRef *&tablet_handle) +{ + if (OB_NOT_NULL(tablet_handle)) { + tablet_handle->~ObBackupTabletHandleRef(); + fifo_allocator_.free(tablet_handle); + tablet_handle = NULL; + } +} + +int ObBackupTabletHolder::set_tablet(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *tablet_handle) { int ret = OB_SUCCESS; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("tablet holder not init", K(ret)); - } else if (!tablet_id.is_valid() || !tablet_handle.is_valid()) { + } else if (!tablet_id.is_valid() || OB_ISNULL(tablet_handle)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("get invalid args", K(ret), K(tablet_id), K(tablet_handle)); + LOG_WARN("get invalid args", K(ret), K(tablet_id), KP(tablet_handle)); } else if (OB_FAIL(holder_map_.set_refactored(tablet_id, tablet_handle))) { if (OB_HASH_EXIST == ret) { ret = OB_SUCCESS; LOG_WARN("tablet handle hold before", K(tablet_id)); } else { - LOG_WARN("failed to set refactored", K(ret), K(tablet_id), K(tablet_handle)); + LOG_WARN("failed to set refactored", K(ret), K(tablet_id), KPC(tablet_handle)); } } return ret; } -int ObBackupTabletHolder::get_tablet(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle) +int ObBackupTabletHolder::get_tablet(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *&tablet_handle) { int ret = OB_SUCCESS; + tablet_handle = NULL; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("tablet holder not init", K(ret)); @@ -1115,19 +1151,22 @@ int ObBackupTabletHolder::get_tablet(const common::ObTabletID &tablet_id, storag int ObBackupTabletHolder::release_tablet(const common::ObTabletID &tablet_id) { int ret = OB_SUCCESS; + ObBackupTabletHandleRef *tablet_ref = NULL; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("tablet holder not init", K(ret)); } else if (!tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(tablet_id)); - } else if (OB_FAIL(holder_map_.erase_refactored(tablet_id))) { + } else if (OB_FAIL(holder_map_.erase_refactored(tablet_id, &tablet_ref))) { if (OB_HASH_NOT_EXIST == ret) { ret = OB_SUCCESS; LOG_WARN("tablet handle do not exit", K(ret), K(tablet_id)); } else { LOG_WARN("failed to erase refactored", K(ret), K(tablet_id)); } + } else { + free_tablet_ref(tablet_ref); } return ret; } @@ -1144,6 +1183,10 @@ void ObBackupTabletHolder::reuse() void ObBackupTabletHolder::reset() { + FOREACH(it, holder_map_) { + ObBackupTabletHandleRef *&ref = it->second; + free_tablet_ref(ref); + } holder_map_.reuse(); is_inited_ = false; } @@ -1708,7 +1751,7 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar int ret = OB_SUCCESS; total_count = 0; ObArray sstable_array; - ObTabletHandle tablet_handle; + ObBackupTabletHandleRef *tablet_ref = NULL; bool is_normal = false; bool can_explain = false; ObTabletMemberWrapper table_store_wrapper; @@ -1718,7 +1761,7 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar } else if (!tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(tablet_id)); - } else if (OB_FAIL(get_tablet_handle_(tenant_id, ls_id, tablet_id, tablet_handle))) { + } else if (OB_FAIL(get_tablet_handle_without_memtables_(tenant_id, ls_id, tablet_id, tablet_ref))) { if (OB_TABLET_NOT_EXIST == ret) { LOG_WARN("failed to get tablet handle", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); ret = OB_SUCCESS; @@ -1733,22 +1776,23 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar } else { LOG_WARN("failed to get tablet handle", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); } - } else if (OB_FAIL(check_tablet_continuity_(ls_id, tablet_id, tablet_handle))) { - LOG_WARN("failed to check tablet continuity", K(ret), K(ls_id), K(tablet_id), K(tablet_handle)); - } else if (OB_FAIL(check_tx_data_can_explain_user_data_(tablet_handle, can_explain))) { + } else if (OB_FAIL(check_tablet_continuity_(ls_id, tablet_id, tablet_ref->tablet_handle_))) { + LOG_WARN("failed to check tablet continuity", K(ret), K(ls_id), K(tablet_id), KPC(tablet_ref)); + } else if (OB_FAIL(check_tx_data_can_explain_user_data_(tablet_ref->tablet_handle_, can_explain))) { LOG_WARN("failed to check tx data can explain user data", K(ret), K(ls_id), K(tablet_id)); } else if (!can_explain) { ret = OB_REPLICA_CANNOT_BACKUP; LOG_WARN("can not backup replica", K(ret), K(tablet_id), K(ls_id)); } else if (OB_FAIL(check_tablet_replica_validity_(tenant_id, ls_id, tablet_id, backup_data_type))) { LOG_WARN("failed to check tablet replica validity", K(ret), K(tenant_id), K(ls_id), K(tablet_id), K(backup_data_type)); - } else if (OB_FAIL(hold_tablet_handle_(tablet_id, tablet_handle))) { - LOG_WARN("failed to hold tablet handle", K(ret), K(tablet_id), K(tablet_handle)); - } else if (OB_FAIL(tablet_handle.get_obj()->fetch_table_store(table_store_wrapper))) { + } else if (OB_FAIL(hold_tablet_handle_(tablet_id, tablet_ref))) { + ls_backup_ctx_->tablet_holder_.free_tablet_ref(tablet_ref); + LOG_WARN("failed to hold tablet handle", K(ret), K(tablet_id), KPC(tablet_ref)); + } else if (OB_FAIL(tablet_ref->tablet_handle_.get_obj()->fetch_table_store(table_store_wrapper))) { LOG_WARN("fail to fetch table store", K(ret)); } else if (OB_FAIL(fetch_tablet_sstable_array_( - tablet_id, tablet_handle, *table_store_wrapper.get_member(), backup_data_type, sstable_array))) { - LOG_WARN("failed to fetch tablet sstable array", K(ret), K(tablet_id), K(tablet_handle), K(backup_data_type)); + tablet_id, tablet_ref->tablet_handle_, *table_store_wrapper.get_member(), backup_data_type, sstable_array))) { + LOG_WARN("failed to fetch tablet sstable array", K(ret), K(tablet_id), KPC(tablet_ref), K(backup_data_type)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < sstable_array.count(); ++i) { int64_t count = 0; @@ -1759,8 +1803,8 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar } else { // TODO(COLUMN_STORE) Attention !!! MajorSSTable in column store canbe COSSTable, maybe should adapt here. const ObITable::TableKey &table_key = sstable->get_key(); - if (OB_FAIL(fetch_all_logic_macro_block_id_(tablet_id, tablet_handle, table_key, *sstable, count))) { - LOG_WARN("failed to fetch all logic macro block id", K(ret), K(tablet_id), K(tablet_handle), K(table_key)); + if (OB_FAIL(fetch_all_logic_macro_block_id_(tablet_id, tablet_ref->tablet_handle_, table_key, *sstable, count))) { + LOG_WARN("failed to fetch all logic macro block id", K(ret), K(tablet_id), KPC(tablet_ref), K(table_key)); } else { total_count += count; } @@ -1775,7 +1819,7 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar } if (OB_SUCC(ret)) { if (OB_FAIL(ls_backup_ctx_->tablet_stat_.prepare_tablet_sstables( - tenant_id, backup_data_type, tablet_id, tablet_handle, sstable_array))) { + tenant_id, backup_data_type, tablet_id, tablet_ref->tablet_handle_, sstable_array))) { LOG_WARN("failed to prepare tablet sstable", K(ret), K(backup_data_type), K(tablet_id), K(sstable_array)); } else if (OB_FAIL(add_tablet_item_(tablet_id))) { LOG_WARN("failed to add tablet item", K(ret), K(tablet_id)); @@ -1935,6 +1979,44 @@ int ObBackupTabletProvider::get_tablet_handle_(const uint64_t tenant_id, const s return ret; } +int ObBackupTabletProvider::get_tablet_handle_without_memtables_(const uint64_t tenant_id, const share::ObLSID &ls_id, + const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *&tablet_ref) +{ + int ret = OB_SUCCESS; + tablet_ref = NULL; + storage::ObLS *ls = NULL; + ObLSService *ls_service = NULL; + ObLSHandle handle; + const WashTabletPriority priority = WashTabletPriority::WTP_LOW; + const ObTabletMapKey key(ls_id, tablet_id); + if (OB_ISNULL(ls_backup_ctx_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls backup ctx should not be null", K(ret)); + } else if (OB_FAIL(ls_backup_ctx_->tablet_holder_.alloc_tablet_ref(tablet_ref))) { + LOG_WARN("failed to alloc tablet ref", K(ret)); + } else if (OB_ISNULL(ls_service = MTL_WITH_CHECK_TENANT(ObLSService *, tenant_id))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream service is NULL", K(ret), K(tenant_id)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get log stream", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log stream not exist", K(ret), K(ls_id)); + } else if (ls->is_stopped()) { + ret = OB_REPLICA_CANNOT_BACKUP; + LOG_WARN("ls has stopped, can not backup", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(ls->get_tablet_without_memtables( + priority, key, tablet_ref->allocator_, tablet_ref->tablet_handle_))) { + LOG_WARN("failed to alloc tablet handle", K(ret), K(key)); + } else { + LOG_INFO("get tablet handle without memtables", K(ret), K(ls_id), K(tablet_id)); + } + if (OB_FAIL(ret) && OB_NOT_NULL(ls_backup_ctx_) && OB_NOT_NULL(tablet_ref)) { + ls_backup_ctx_->tablet_holder_.free_tablet_ref(tablet_ref); + } + return ret; +} + int ObBackupTabletProvider::get_tablet_skipped_type_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, ObBackupSkippedType &skipped_type) { @@ -2027,7 +2109,7 @@ int ObBackupTabletProvider::report_tablet_skipped_(const common::ObTabletID &tab } int ObBackupTabletProvider::hold_tablet_handle_( - const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle) + const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *tablet_handle) { int ret = OB_SUCCESS; if (!tablet_id.is_valid()) { @@ -2036,7 +2118,7 @@ int ObBackupTabletProvider::hold_tablet_handle_( } else if (OB_ISNULL(ls_backup_ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls backup ctx should not be null", K(ret)); - } else if (OB_FAIL(ls_backup_ctx_->hold_tablet(tablet_id, tablet_handle))) { + } else if (OB_FAIL(ls_backup_ctx_->set_tablet(tablet_id, tablet_handle))) { LOG_WARN("failed to hold tablet", K(ret), K(tablet_id), K(tablet_handle)); } else { LOG_DEBUG("hold tablet handle", K(tablet_id), K(tablet_handle)); diff --git a/src/storage/backup/ob_backup_utils.h b/src/storage/backup/ob_backup_utils.h index ec9dac798..7a2a102ce 100644 --- a/src/storage/backup/ob_backup_utils.h +++ b/src/storage/backup/ob_backup_utils.h @@ -145,25 +145,40 @@ private: DISALLOW_COPY_AND_ASSIGN(ObBackupTabletStat); }; +struct ObBackupTabletHandleRef +{ +public: + ObBackupTabletHandleRef() : allocator_(), tablet_handle_() {} + ~ObBackupTabletHandleRef() {} + bool is_valid() const { return tablet_handle_.is_valid(); } + TO_STRING_KV(K_(tablet_handle)); + common::ObArenaAllocator allocator_; + storage::ObTabletHandle tablet_handle_; +}; + class ObBackupTabletHolder final { public: ObBackupTabletHolder(); ~ObBackupTabletHolder(); int init(const uint64_t tenant_id, const share::ObLSID &ls_id); - int hold_tablet(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle); - int get_tablet(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle); + int alloc_tablet_ref(ObBackupTabletHandleRef *&tablet_handle); + void free_tablet_ref(ObBackupTabletHandleRef *&tablet_handle); + int set_tablet(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *tablet_handle); + int get_tablet(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *&tablet_handle); int release_tablet(const common::ObTabletID &tablet_id); bool is_empty() const; void reuse(); void reset(); private: - typedef common::hash::ObHashMap TabletHandleMap; + typedef common::hash::ObHashMap TabletHandleMap; + typedef common::DefaultPageAllocator BaseAllocator; private: bool is_inited_; share::ObLSID ls_id_; TabletHandleMap holder_map_; + ObFIFOAllocator fifo_allocator_; DISALLOW_COPY_AND_ASSIGN(ObBackupTabletHolder); }; @@ -285,12 +300,14 @@ private: // make sure clog checkpoint scn of the returned tablet is >= consistent_scn. int get_tablet_handle_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle); + int get_tablet_handle_without_memtables_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, + ObBackupTabletHandleRef *&tablet_ref); int get_consistent_scn_(share::SCN &consistent_scn) const; int report_tablet_skipped_(const common::ObTabletID &tablet_id, const share::ObBackupSkippedType &skipped_type, const share::ObBackupDataType &backup_data_type); int get_tablet_skipped_type_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, share::ObBackupSkippedType &skipped_type); - int hold_tablet_handle_(const common::ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle); + int hold_tablet_handle_(const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *tablet_handle); int fetch_tablet_sstable_array_(const common::ObTabletID &tablet_id, const storage::ObTabletHandle &tablet_handle, const ObTabletTableStore &table_store, const share::ObBackupDataType &backup_data_type, common::ObIArray &sstable_array); diff --git a/src/storage/compaction/ob_basic_tablet_merge_ctx.cpp b/src/storage/compaction/ob_basic_tablet_merge_ctx.cpp index 71efee7c2..43900235b 100644 --- a/src/storage/compaction/ob_basic_tablet_merge_ctx.cpp +++ b/src/storage/compaction/ob_basic_tablet_merge_ctx.cpp @@ -547,16 +547,9 @@ int ObBasicTabletMergeCtx::swap_tablet() { int ret = OB_SUCCESS; const ObTabletMapKey key(get_ls_id(), get_tablet_id()); - if (OB_FAIL(MTL(ObTenantMetaMemMgr *)->get_tablet_with_allocator( - WashTabletPriority::WTP_LOW, key, mem_ctx_.get_allocator(), - tablet_handle_, true /*force_alloc_new*/))) { - if (OB_ENTRY_NOT_EXIST == ret) { - ret = OB_TABLET_NOT_EXIST; - } else { - LOG_WARN("failed to get alloc tablet handle", K(ret), K(key)); - } - } else if (OB_FAIL(get_tablet()->clear_memtables_on_table_store())) { - LOG_WARN("failed to clear memtables on table_store", K(ret), K(tablet_handle_)); + if (OB_FAIL(get_ls()->get_tablet_svr()->get_tablet_without_memtables( + WashTabletPriority::WTP_LOW, key, mem_ctx_.get_allocator(), tablet_handle_))) { + LOG_WARN("failed to get alloc tablet handle", K(ret), K(key)); } else { static_param_.rowkey_read_info_ = static_cast(&(get_tablet()->get_rowkey_read_info())); LOG_INFO("success to swap tablet handle", K(ret), K(tablet_handle_), diff --git a/src/storage/high_availability/ob_storage_ha_reader.cpp b/src/storage/high_availability/ob_storage_ha_reader.cpp index 51e9070cc..6817115e2 100644 --- a/src/storage/high_availability/ob_storage_ha_reader.cpp +++ b/src/storage/high_availability/ob_storage_ha_reader.cpp @@ -571,6 +571,7 @@ ObCopyMacroBlockObProducer::ObCopyMacroBlockObProducer() macro_idx_(0), handle_idx_(0), prefetch_meta_time_(0), + tablet_allocator_("HaTabletHdl"), tablet_handle_(), sstable_handle_(), sstable_(nullptr), @@ -606,6 +607,9 @@ int ObCopyMacroBlockObProducer::init( MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); ObSSTableMetaHandle meta_handle; common::ObSafeArenaAllocator allocator(allocator_); + ObTabletMapKey map_key; + map_key.ls_id_ = ls_id; + map_key.tablet_id_ = table_key.get_tablet_id(); if (is_inited_) { ret = OB_INIT_TWICE; @@ -625,8 +629,9 @@ int ObCopyMacroBlockObProducer::init( } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream should not be NULL", KR(ret), K(tenant_id), K(ls_id), KPC(ls)); - } else if (OB_FAIL(ls->ha_get_tablet(table_key.get_tablet_id(), tablet_handle_))) { - LOG_WARN("failed to get tablet handle", K(ret), K(table_key), K(ls_id)); + } else if (OB_FAIL(ls->ha_get_tablet_without_memtables( + WashTabletPriority::WTP_LOW, map_key, tablet_allocator_, tablet_handle_))) { + LOG_WARN("failed to ha get tablet with allocator without memtables", K(ret), K(map_key)); } else if (OB_UNLIKELY(nullptr == (tablet = tablet_handle_.get_obj()))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet not be NULL", KR(ret), K(tenant_id), K(ls_id), KPC(tablet)); diff --git a/src/storage/high_availability/ob_storage_ha_reader.h b/src/storage/high_availability/ob_storage_ha_reader.h index 5c5fed76a..42457cb50 100644 --- a/src/storage/high_availability/ob_storage_ha_reader.h +++ b/src/storage/high_availability/ob_storage_ha_reader.h @@ -193,6 +193,7 @@ private: ObCopyMacroBlockHandle copy_macro_block_handle_[MAX_PREFETCH_MACRO_BLOCK_NUM]; int64_t handle_idx_; int64_t prefetch_meta_time_; + common::ObArenaAllocator tablet_allocator_; ObTabletHandle tablet_handle_; ObTableHandleV2 sstable_handle_; const ObSSTable *sstable_; diff --git a/src/storage/ls/ob_ls.h b/src/storage/ls/ob_ls.h index 6d3b96838..3720da82a 100644 --- a/src/storage/ls/ob_ls.h +++ b/src/storage/ls/ob_ls.h @@ -571,6 +571,8 @@ public: DELEGATE_WITH_RET(ls_tablet_svr_, rebuild_create_tablet, int); DELEGATE_WITH_RET(ls_tablet_svr_, update_tablet_ha_data_status, int); DELEGATE_WITH_RET(ls_tablet_svr_, ha_get_tablet, int); + DELEGATE_WITH_RET(ls_tablet_svr_, get_tablet_without_memtables, int); + DELEGATE_WITH_RET(ls_tablet_svr_, ha_get_tablet_without_memtables, int); DELEGATE_WITH_RET(ls_tablet_svr_, update_tablet_restore_status, int); DELEGATE_WITH_RET(ls_tablet_svr_, create_or_update_migration_tablet, int); DELEGATE_WITH_RET(ls_tablet_svr_, flush_mds_table, int); diff --git a/src/storage/ls/ob_ls_tablet_service.cpp b/src/storage/ls/ob_ls_tablet_service.cpp index 18c090c82..b3f4d97dd 100644 --- a/src/storage/ls/ob_ls_tablet_service.cpp +++ b/src/storage/ls/ob_ls_tablet_service.cpp @@ -6561,6 +6561,58 @@ int ObLSTabletService::ha_get_tablet( return ret; } +int ObLSTabletService::get_tablet_without_memtables( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + common::ObArenaAllocator &allocator, + ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + const bool force_alloc_new = true; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_ISNULL(t3m)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant meta mem mgr should not be null", K(ret), KP(t3m)); + } else if (OB_FAIL(t3m->get_tablet_with_allocator( + priority, key, allocator, handle, force_alloc_new))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_TABLET_NOT_EXIST; + } else { + LOG_WARN("failed to get tablet with allocator", K(ret), K(priority), K(key)); + } + } else if (OB_FAIL(handle.get_obj()->clear_memtables_on_table_store())) { + LOG_WARN("failed to clear memtables on table store", K(ret), K(key)); + } + return ret; +} + +int ObLSTabletService::ha_get_tablet_without_memtables( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + common::ObArenaAllocator &allocator, + ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(get_tablet_without_memtables(priority, key, allocator, handle))) { + LOG_WARN("failed to get tablet without memtables", K(ret), K(priority), K(key)); + } else if (OB_ISNULL(tablet = handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), K(key)); + } else if (tablet->is_empty_shell()) { + // treat empty shell as tablet not exist. + ret = OB_TABLET_NOT_EXIST; + } + return ret; +} + int ObLSTabletService::check_real_leader_for_4377_(const ObLSID ls_id) { int ret = OB_SUCCESS; diff --git a/src/storage/ls/ob_ls_tablet_service.h b/src/storage/ls/ob_ls_tablet_service.h index b8d66b50a..d633803dd 100644 --- a/src/storage/ls/ob_ls_tablet_service.h +++ b/src/storage/ls/ob_ls_tablet_service.h @@ -269,6 +269,16 @@ public: int ha_get_tablet( const common::ObTabletID &tablet_id, ObTabletHandle &handle); + int get_tablet_without_memtables( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + common::ObArenaAllocator &allocator, + ObTabletHandle &handle); + int ha_get_tablet_without_memtables( + const WashTabletPriority &priority, + const ObTabletMapKey &key, + common::ObArenaAllocator &allocator, + ObTabletHandle &handle); int update_tablet_mstx( const ObTabletMapKey &key, const ObMetaDiskAddr &old_addr, diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h index 048e1ac47..06da73a14 100644 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -496,7 +496,6 @@ public: int notify_mds_table_flush_ret( const share::SCN &flush_scn, const int flush_ret); - int clear_memtables_on_table_store(); // be careful to call this func, will destroy memtables array on table_store int64_t get_memtable_count() const { return memtable_count_; } // tablet mds data read interface @@ -800,6 +799,7 @@ private: const bool need_tablet_attr = true) const; int calc_tablet_attr(ObTabletAttr &attr) const; int check_ready_for_read_if_need(const ObTablet &old_tablet); + int clear_memtables_on_table_store(); // be careful to call this func, will destroy memtables array on table_store private: // ObTabletDDLKvMgr::MAX_DDL_KV_CNT_IN_STORAGE // Array size is too large, need to shrink it if possible