diff --git a/src/storage/high_availability/ob_transfer_backfill_tx.cpp b/src/storage/high_availability/ob_transfer_backfill_tx.cpp index 3d2613afc..6da289ca6 100644 --- a/src/storage/high_availability/ob_transfer_backfill_tx.cpp +++ b/src/storage/high_availability/ob_transfer_backfill_tx.cpp @@ -1288,12 +1288,13 @@ int ObTransferReplaceTableTask::init() return ret; } int ObTransferReplaceTableTask::check_src_memtable_is_empty_( + const ObTabletBackfillInfo &tablet_info, ObTablet *tablet, const share::SCN &transfer_scn) { int ret = OB_SUCCESS; ObArray memtables; - if (OB_ISNULL(tablet) || !transfer_scn.is_valid()) { + if (!tablet_info.is_valid() || OB_ISNULL(tablet) || !transfer_scn.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("tablet should not be nullptr.", KR(ret), K(transfer_scn), KPC(this)); } else if (OB_FAIL(tablet->get_all_memtables(memtables))) { @@ -1311,24 +1312,36 @@ int ObTransferReplaceTableTask::check_src_memtable_is_empty_( } else if (FALSE_IT(memtable = static_cast(table))) { } else if (memtable->is_active_memtable()) { if (memtable->not_empty()) { - ret = OB_TRANSFER_SYS_ERROR; - LOG_ERROR("memtable should not be active", K(ret), KPC_(ctx), - KPC(memtable), "transfer meta", tablet->get_tablet_meta()); + if (tablet_info.is_committed_) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("memtable should not be active", K(ret), KPC_(ctx), + KPC(memtable), "transfer meta", tablet->get_tablet_meta()); + } else { + ret = OB_EAGAIN; + LOG_WARN("transfer src has active memtable and not empty, maybe transfer transaction rollback, need retry", + K(ret), KPC(memtable), "transfer meta", tablet->get_tablet_meta(), K(tablet_info)); + } } } else if (!memtable->get_key().scn_range_.is_empty()) { - ret = OB_TRANSFER_SYS_ERROR; - LOG_ERROR("The range of the memtable is not empty", K(ret), KPC(memtable)); + if (tablet_info.is_committed_) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("The range of the memtable is not empty", K(ret), KPC(memtable)); + } else { + ret = OB_EAGAIN; + LOG_WARN("transfer src forzen memtable scn range is not empty, maybe transfer transaction rollback, need retry", + K(ret), KPC(memtable), "transfer meta", tablet->get_tablet_meta(), K(tablet_info)); + } } else if (memtable->not_empty() && memtable->get_start_scn() >= transfer_scn) { LOG_ERROR("There have been transactions in memtable but no data", K(OB_TRANSFER_SYS_ERROR), KPC_(ctx), KPC(memtable)); } } } - return ret; } int ObTransferReplaceTableTask::check_source_minor_end_scn_( + const ObTabletBackfillInfo &tablet_info, const ObTabletMemberWrapper &wrapper, const ObTablet *dest_tablet, bool &need_fill_minor) @@ -1337,9 +1350,9 @@ int ObTransferReplaceTableTask::check_source_minor_end_scn_( need_fill_minor = false; - if (!wrapper.is_valid() || OB_ISNULL(dest_tablet)) { + if (!tablet_info.is_valid() || !wrapper.is_valid() || OB_ISNULL(dest_tablet)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("wrapper is invalid or tablet be nullptr.", KR(ret), K(wrapper), KPC(this)); + LOG_WARN("wrapper is invalid or tablet be nullptr.", KR(ret), K(tablet_info), K(wrapper), KPC(this)); } else { const ObTabletTableStore &table_store = *(wrapper.get_member()); ObITable *last_minor_mini_sstable = table_store.get_minor_sstables().get_boundary_table(true /*is_last*/); @@ -1356,16 +1369,28 @@ int ObTransferReplaceTableTask::check_source_minor_end_scn_( } else if (last_minor_mini_sstable->get_start_scn() >= dest_tablet->get_tablet_meta().transfer_info_.transfer_start_scn_) { ObSSTable *sstable = static_cast(last_minor_mini_sstable); if (!sstable->is_empty()) { - ret = OB_TRANSFER_SYS_ERROR; - LOG_ERROR("last sstable start scn is bigger than transfer start scn", K(ret), KPC(last_minor_mini_sstable), - "transfer info", dest_tablet->get_tablet_meta().transfer_info_); + if (tablet_info.is_committed_) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("last sstable start scn is bigger than transfer start scn", K(ret), KPC(last_minor_mini_sstable), + "transfer info", dest_tablet->get_tablet_meta().transfer_info_); + } else { + ret = OB_EAGAIN; + LOG_WARN("transfer src sstable start scn is bigger than transfer start scn, maybe transfer transaction rollback, need retry", + K(ret), KPC(sstable), K(tablet_info), "dest tablet meta", dest_tablet->get_tablet_meta()); + } } } else if (last_minor_mini_sstable->get_end_scn() > dest_tablet->get_tablet_meta().transfer_info_.transfer_start_scn_) { // After adding transfer_freeze_flag_, it can ensure that start is less than transfer_start_scn's sstable, // and end_scn will not be greater than transfer_start_scn - ret = OB_TRANSFER_SYS_ERROR; - LOG_ERROR("last sstable end scn is bigger than transfer start scn", K(ret), KPC(last_minor_mini_sstable), - "transfer info", dest_tablet->get_tablet_meta().transfer_info_); + if (tablet_info.is_committed_) { + ret = OB_TRANSFER_SYS_ERROR; + LOG_ERROR("last sstable end scn is bigger than transfer start scn", K(ret), KPC(last_minor_mini_sstable), + "transfer info", dest_tablet->get_tablet_meta().transfer_info_); + } else { + ret = OB_EAGAIN; + LOG_WARN("transfer src sstable end scn is bigger than transfer start scn, maybe transfer transaction rollback, need retry", + K(ret), KPC(last_minor_mini_sstable), K(tablet_info), "dest tablet meta", dest_tablet->get_tablet_meta()); + } } } return ret; @@ -1560,9 +1585,9 @@ int ObTransferReplaceTableTask::get_source_tablet_tables_( LOG_WARN("failed to get tablet restore status", K(ret)); } else if (OB_FAIL(tablet->fetch_table_store(wrapper))) { LOG_WARN("fetch table store fail", K(ret), KP(tablet)); - } else if (OB_FAIL(check_src_memtable_is_empty_(tablet, transfer_scn))) { + } else if (OB_FAIL(check_src_memtable_is_empty_(tablet_info, tablet, transfer_scn))) { LOG_WARN("failed to check src memtable", K(ret), KPC(tablet)); - } else if (OB_FAIL(check_source_minor_end_scn_(wrapper, dest_tablet, need_backill))) { + } else if (OB_FAIL(check_source_minor_end_scn_(tablet_info, wrapper, dest_tablet, need_backill))) { LOG_WARN("fail to check source max end scn from tablet", K(ret), KPC(tablet)); } else if (OB_FAIL(get_all_sstable_handles_(tablet, wrapper, sstable_iter, tables_handle))) { LOG_WARN("failed to get all sstable handles", K(ret), KPC(tablet)); diff --git a/src/storage/high_availability/ob_transfer_backfill_tx.h b/src/storage/high_availability/ob_transfer_backfill_tx.h index 010e87352..91f20e6e1 100644 --- a/src/storage/high_availability/ob_transfer_backfill_tx.h +++ b/src/storage/high_availability/ob_transfer_backfill_tx.h @@ -234,6 +234,7 @@ private: ObTablesHandleArray &sstable_handles); int check_src_tablet_sstables_(const ObTablet *tablet, ObTablesHandleArray &tables_handle); int check_source_minor_end_scn_( + const ObTabletBackfillInfo &tablet_info, const ObTabletMemberWrapper &wrapper, const ObTablet *dest_tablet, bool &need_fill_minor); @@ -244,7 +245,10 @@ private: const ObTabletMemberWrapper &wrapper, common::ObArenaAllocator &allocator, ObTablesHandleArray &tables_handle); - int check_src_memtable_is_empty_(ObTablet *tablet, const share::SCN &transfer_scn); + int check_src_memtable_is_empty_( + const ObTabletBackfillInfo &tablet_info, + ObTablet *tablet, + const share::SCN &transfer_scn); int build_migration_param_( const ObTablet *tablet, ObTabletHandle &src_tablet_handle,