From f8c34635e1039edbe04b98289da81be331317f9e Mon Sep 17 00:00:00 2001 From: obdev Date: Mon, 21 Oct 2024 07:43:22 +0000 Subject: [PATCH] update split dest restore status remote on demand. --- src/share/ob_ddl_common.cpp | 2 +- src/share/ob_ddl_common.h | 2 +- src/storage/ddl/ob_tablet_lob_split_task.cpp | 3 +- src/storage/ddl/ob_tablet_split_task.cpp | 81 +++++++++++++++++++- src/storage/ddl/ob_tablet_split_task.h | 8 +- src/storage/ob_storage_struct.h | 1 - src/storage/tablet/ob_tablet.cpp | 27 +++++++ src/storage/tablet/ob_tablet.h | 4 + 8 files changed, 121 insertions(+), 7 deletions(-) diff --git a/src/share/ob_ddl_common.cpp b/src/share/ob_ddl_common.cpp index 8d595703d..6a89010e6 100644 --- a/src/share/ob_ddl_common.cpp +++ b/src/share/ob_ddl_common.cpp @@ -1749,7 +1749,7 @@ int ObDDLUtil::check_and_cancel_single_replica_dag( } int ObDDLUtil::ddl_get_tablet( - ObLSHandle &ls_handle, + const ObLSHandle &ls_handle, const ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle, storage::ObMDSGetTabletMode mode) diff --git a/src/share/ob_ddl_common.h b/src/share/ob_ddl_common.h index c3a4dc266..aa8e554eb 100644 --- a/src/share/ob_ddl_common.h +++ b/src/share/ob_ddl_common.h @@ -639,7 +639,7 @@ public: ObSqlString &rowkey_column_sql_string); static int ddl_get_tablet( - storage::ObLSHandle &ls_handle, + const storage::ObLSHandle &ls_handle, const ObTabletID &tablet_id, storage::ObTabletHandle &tablet_handle, const storage::ObMDSGetTabletMode mode = storage::ObMDSGetTabletMode::READ_WITHOUT_CHECK); diff --git a/src/storage/ddl/ob_tablet_lob_split_task.cpp b/src/storage/ddl/ob_tablet_lob_split_task.cpp index 37f7b157c..e166bed7e 100644 --- a/src/storage/ddl/ob_tablet_lob_split_task.cpp +++ b/src/storage/ddl/ob_tablet_lob_split_task.cpp @@ -1549,7 +1549,8 @@ int ObTabletLobWriteDataTask::create_sstables( ctx_->lob_meta_tablet_handle_, ctx_->new_lob_tablet_ids_.at(i), batch_sstables_handle.at(i), - split_sstable_type))) { + split_sstable_type, + false/*can_reuse_macro_block*/))) { LOG_WARN("update table store with batch tables failed", K(ret), K(batch_sstables_handle.at(i)), K(split_sstable_type)); } } diff --git a/src/storage/ddl/ob_tablet_split_task.cpp b/src/storage/ddl/ob_tablet_split_task.cpp index 0bff83a38..e9145c7b4 100644 --- a/src/storage/ddl/ob_tablet_split_task.cpp +++ b/src/storage/ddl/ob_tablet_split_task.cpp @@ -1393,7 +1393,8 @@ int ObTabletSplitMergeTask::create_sstable( context_->tablet_handle_, dest_tablet_id, batch_sstables_handle, - split_sstable_type))) { + split_sstable_type, + param_->can_reuse_macro_block_))) { LOG_WARN("update table store with batch tables failed", K(ret), K(batch_sstables_handle), K(split_sstable_type)); } } @@ -1466,6 +1467,7 @@ int ObTabletSplitMergeTask::build_create_sstable_param( create_sstable_param.data_block_ids_ = res.data_block_ids_; create_sstable_param.other_block_ids_ = res.other_block_ids_; create_sstable_param.ddl_scn_.set_min(); + create_sstable_param.table_backup_flag_ = res.table_backup_flag_; // to tag whether there is any remote macro block. MEMCPY(create_sstable_param.encrypt_key_, res.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); if (src_table.is_major_sstable()) { if (OB_FAIL(create_sstable_param.column_checksums_.assign(res.data_column_checksums_))) { @@ -1571,7 +1573,8 @@ int ObTabletSplitMergeTask::update_table_store_with_batch_tables( const ObTabletHandle &src_tablet_handle, const ObTabletID &dst_tablet_id, const ObTablesHandleArray &tables_handle, - const share::ObSplitSSTableType &split_sstable_type) + const share::ObSplitSSTableType &split_sstable_type, + const bool can_reuse_macro_block) { int ret = OB_SUCCESS; ObBatchUpdateTableStoreParam param; @@ -1620,6 +1623,13 @@ int ObTabletSplitMergeTask::update_table_store_with_batch_tables( } } + if (OB_SUCC(ret) && can_reuse_macro_block && share::ObSplitSSTableType::SPLIT_MAJOR == split_sstable_type) { + // iterate all major and minors, to determine the dest restore status. + if (OB_FAIL(check_and_determine_restore_status(ls_handle, dst_tablet_id, param.tables_handle_, param.restore_status_))) { + LOG_WARN("check and determine restore status failed", K(ret), K(dst_tablet_id)); + } + } + if (OB_SUCC(ret)) { param.tablet_split_param_.snapshot_version_ = src_tablet_handle.get_obj()->get_tablet_meta().snapshot_version_; param.tablet_split_param_.multi_version_start_ = src_tablet_handle.get_obj()->get_multi_version_start(); @@ -1633,6 +1643,73 @@ int ObTabletSplitMergeTask::update_table_store_with_batch_tables( return ret; } +int ObTabletSplitMergeTask::check_and_determine_restore_status( + const ObLSHandle &ls_handle, + const ObTabletID &dst_tablet_id, + const ObTablesHandleArray &major_handles_array, + ObTabletRestoreStatus::STATUS &restore_status) +{ + int ret = OB_SUCCESS; + restore_status = ObTabletRestoreStatus::FULL; + ObSEArray major_tables_array; + if (OB_UNLIKELY(!ls_handle.is_valid() || !dst_tablet_id.is_valid() || major_handles_array.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_handle), K(dst_tablet_id), K(major_handles_array)); + } else if (OB_FAIL(major_handles_array.get_tables(major_tables_array))) { + LOG_WARN("get batch sstables failed", K(ret)); + } else { + // 1. to check if there is any remote macro block in major tables. + for (int64_t i = 0; OB_SUCC(ret) && ObTabletRestoreStatus::is_full(restore_status) && i < major_tables_array.count(); i++) { + ObITable *table = major_tables_array.at(i); + ObSSTableMetaHandle sstable_meta_handle; + if (OB_UNLIKELY(nullptr == table || !table->is_major_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null table", K(ret), K(dst_tablet_id), KPC(table), K(major_handles_array)); + } else if (OB_FAIL(static_cast(table)->get_meta(sstable_meta_handle))) { + LOG_WARN("get sstable meta failed", K(ret)); + } else { + restore_status = sstable_meta_handle.get_sstable_meta().get_basic_meta().table_backup_flag_.has_backup() ? + ObTabletRestoreStatus::REMOTE : restore_status; + LOG_TRACE("with backup macro block sstable is found", K(ret), K(dst_tablet_id), KPC(table)); + } + } + } + + if (OB_SUCC(ret) && ObTabletRestoreStatus::is_full(restore_status)) { + // 2. to check if there is any remote macro block in minor tables. + ObTabletHandle tablet_handle; + ObTableStoreIterator table_iter; + if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, dst_tablet_id, tablet_handle, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("get tablet failed", K(ret), K(dst_tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->get_all_sstables(table_iter, true/*need_unpack*/))) { + LOG_WARN("get all sstables failed", K(ret)); + } else { + while (OB_SUCC(ret) && ObTabletRestoreStatus::is_full(restore_status)) { + ObITable *table = nullptr; + ObSSTableMetaHandle sstable_meta_handle; + if (OB_FAIL(table_iter.get_next(table))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("iterate tables failed", K(ret), K(dst_tablet_id)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_UNLIKELY(nullptr == table || table->is_major_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sstable should not be NULL", K(ret), KPC(table), K(table_iter)); + } else if (OB_FAIL(static_cast(table)->get_meta(sstable_meta_handle))) { + LOG_WARN("get sstable meta failed", K(ret)); + } else { + restore_status = sstable_meta_handle.get_sstable_meta().get_basic_meta().table_backup_flag_.has_backup() ? + ObTabletRestoreStatus::REMOTE : restore_status; + LOG_TRACE("with backup macro block sstable is found", K(ret), K(dst_tablet_id), KPC(table)); + } + } + } + } + return ret; +} + ObRowScan::ObRowScan() : is_inited_(false), row_iter_(nullptr), ctx_(), access_ctx_(), rowkey_read_info_(nullptr), access_param_(), allocator_("SplitScanRow") {} diff --git a/src/storage/ddl/ob_tablet_split_task.h b/src/storage/ddl/ob_tablet_split_task.h index 850ccca7a..47d9e24a0 100644 --- a/src/storage/ddl/ob_tablet_split_task.h +++ b/src/storage/ddl/ob_tablet_split_task.h @@ -256,7 +256,8 @@ public: const ObTabletHandle &src_tablet_handle, const ObTabletID &dst_tablet_id, const ObTablesHandleArray &tables_handle, - const share::ObSplitSSTableType &split_sstable_type); + const share::ObSplitSSTableType &split_sstable_type, + const bool can_reuse_macro_block); private: int create_sstable( const share::ObSplitSSTableType &split_sstable_type); @@ -265,6 +266,11 @@ private: const ObTabletID &dst_tablet_id, ObSSTableIndexBuilder *index_builder, ObTabletCreateSSTableParam &create_sstable_param); + static int check_and_determine_restore_status( + const ObLSHandle &ls_handle, + const ObTabletID &dst_tablet_id, + const ObTablesHandleArray &major_handles_array, + ObTabletRestoreStatus::STATUS &restore_status); private: bool is_inited_; ObTabletSplitParam *param_; diff --git a/src/storage/ob_storage_struct.h b/src/storage/ob_storage_struct.h index 326d35ed2..0755799c5 100644 --- a/src/storage/ob_storage_struct.h +++ b/src/storage/ob_storage_struct.h @@ -487,7 +487,6 @@ public: int64_t snapshot_version_; int64_t multi_version_start_; bool update_with_major_tables_; - bool need_replace_remote_sstable_; // only true for restore replace sstable. }; struct ObBatchUpdateTableStoreParam final diff --git a/src/storage/tablet/ob_tablet.cpp b/src/storage/tablet/ob_tablet.cpp index 75b2a4a0b..a6d9a3165 100644 --- a/src/storage/tablet/ob_tablet.cpp +++ b/src/storage/tablet/ob_tablet.cpp @@ -895,6 +895,31 @@ int ObTablet::handle_transfer_replace_(const ObBatchUpdateTableStoreParam ¶m return ret; } +// Update restore status from Full to Remote for split. +// Reuse backup macro block should be pulled from the remote by the remote restore status tag. +int ObTablet::update_restore_status_for_split_(const ObBatchUpdateTableStoreParam ¶m) +{ + int ret = OB_SUCCESS; + ObTabletRestoreStatus::STATUS old_restore_status; + if (!param.tablet_split_param_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(param)); + } else if (!param.tablet_split_param_.update_with_major_tables_ || ObTabletRestoreStatus::is_full(param.restore_status_)) { + // update restore status only when updating major sstables and inputing remote restore status. + } else if (!ObTabletRestoreStatus::is_remote(param.restore_status_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid restore status, input restore status should be full or remote", K(ret), "restore_status", param.restore_status_, K(param)); + } else if (OB_FAIL(tablet_meta_.ha_status_.get_restore_status(old_restore_status))) { + LOG_WARN("get restore status failed", K(ret), K(tablet_meta_)); + } else if (!ObTabletRestoreStatus::is_full(old_restore_status)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected restore status in split dest", K(ret), K(old_restore_status), K(param)); + } else if (OB_FAIL(tablet_meta_.ha_status_.set_restore_status(param.restore_status_))) { + LOG_WARN("failed to set tablet restore status", K(ret), "restore_status", param.restore_status_); + } + return ret; +} + int ObTablet::init_for_sstable_replace( common::ObArenaAllocator &allocator, const ObBatchUpdateTableStoreParam ¶m, @@ -954,6 +979,8 @@ int ObTablet::init_for_sstable_replace( LOG_WARN("failed to choose and save storage schema", K(ret), K(old_tablet), K(param)); } else if (is_tablet_split && OB_FAIL(try_update_table_store_flag(param.tablet_split_param_.update_with_major_tables_))) { LOG_WARN("failed to update table store flag", K(ret), K(param), K(table_store_addr_)); + } else if (is_tablet_split && OB_FAIL(update_restore_status_for_split_(param))) { + LOG_WARN("update restore status for tablet split failed", K(ret), K(param), KPC(this)); } else if (OB_FAIL(try_update_start_scn())) { LOG_WARN("failed to update start scn", K(ret), K(param), K(table_store_addr_)); } else if (OB_FAIL(check_tablet_schema_mismatch(old_tablet, *storage_schema, false/*is_convert_co_major_merge*/))) { diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h index be5eb21c1..03e28e413 100644 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -875,6 +875,10 @@ private: int wait_release_memtables_(); int mark_mds_table_switched_to_empty_shell_(); int handle_transfer_replace_(const ObBatchUpdateTableStoreParam ¶m); + + // DDL. + int update_restore_status_for_split_(const ObBatchUpdateTableStoreParam ¶m); + // NOTICE: // - Because the `calc_tablet_attr()` may has I/O operations, you can bypass it if wantn't to update it. int get_updating_tablet_pointer_param(