diff --git a/src/objit/src/ob_llvm_di_helper.cpp b/src/objit/src/ob_llvm_di_helper.cpp index a98674b182..e4cbc66006 100644 --- a/src/objit/src/ob_llvm_di_helper.cpp +++ b/src/objit/src/ob_llvm_di_helper.cpp @@ -43,9 +43,9 @@ uint64_t ObLLVMDIType::get_align_bits() int ObLLVMDIHelper::init(core::JitContext *jc) { - int ret = OB_SUCCESS; - if (OB_ISNULL(jc)) { - ret = OB_ERR_UNEXPECTED; + int ret = OB_SUCCESS; + if (OB_ISNULL(jc)) { + ret = OB_ERR_UNEXPECTED; LOG_WARN("jc is NULL", K(ret)); } else if (OB_ISNULL(jc_ = OB_NEWx(core::JitDIContext, (&allocator_), (jc->get_module())))) { ret = OB_ALLOCATE_MEMORY_FAILED; @@ -152,9 +152,9 @@ int ObLLVMDIHelper::create_local_variable(const ObString &name, uint32_t arg_no, { int ret = OB_SUCCESS; ObDIFile *file = NULL; - ObDISubprogram *sp = NULL; - ObDILocalVariable *var_ptr; - if (name.empty() || OB_ISNULL(jc_) || OB_ISNULL(file = jc_->file_) + ObDISubprogram *sp = NULL; + ObDILocalVariable *var_ptr; + if (name.empty() || OB_ISNULL(jc_) || OB_ISNULL(file = jc_->file_) || OB_ISNULL(sp = jc_->sp_) || OB_ISNULL(type.get_v())) { ret = OB_NOT_INIT; LOG_WARN("jc or file or sp or type is NULL", K(name), K(ret)); @@ -230,9 +230,9 @@ int ObLLVMDIHelper::create_pointer_type(ObLLVMDIType &pointee_type, } else { pointer_type.set_v(ptr_type); } - return ret; -} - + return ret; +} + int ObLLVMDIHelper::create_basic_type(ObObjType obj_type, ObLLVMDIType &basic_type) { diff --git a/src/observer/ob_rpc_processor_simple.cpp b/src/observer/ob_rpc_processor_simple.cpp index dc7f08ff97..7125335522 100644 --- a/src/observer/ob_rpc_processor_simple.cpp +++ b/src/observer/ob_rpc_processor_simple.cpp @@ -78,6 +78,7 @@ #include "rootserver/ob_admin_drtask_util.h" // ObAdminDRTaskUtil #include "rootserver/ob_primary_ls_service.h" // for ObPrimaryLSService #include "rootserver/ob_root_utils.h" +#include "rootserver/ob_split_partition_helper.h" #include "sql/session/ob_sql_session_info.h" #include "sql/session/ob_sess_info_verify.h" #include "observer/table/ttl/ob_ttl_service.h" @@ -612,7 +613,7 @@ int ObRpcFreezeSplitSrcTabletP::process() LOG_ERROR("invalid arguments", K(ret), KP(gctx_.ob_service_)); } else { const int64_t abs_timeout_us = nullptr == rpc_pkt_ ? 0 : get_receive_timestamp() + rpc_pkt_->get_timeout(); - ret = gctx_.ob_service_->freeze_split_src_tablet(arg_, result_, abs_timeout_us); + ret = ObSplitPartitionHelper::freeze_split_src_tablet(arg_, result_, abs_timeout_us); } return ret; } diff --git a/src/observer/ob_service.cpp b/src/observer/ob_service.cpp index e461965c4f..cbd95ca8a1 100644 --- a/src/observer/ob_service.cpp +++ b/src/observer/ob_service.cpp @@ -2898,56 +2898,6 @@ int ObService::build_split_tablet_data_finish_request(const obrpc::ObTabletSplit return ret; } -int ObService::freeze_split_src_tablet(const ObFreezeSplitSrcTabletArg &arg, - ObFreezeSplitSrcTabletRes &res, - const int64_t abs_timeout_us) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("service not inited", K(ret)); - } else if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arg", K(ret), K(arg)); - } else { - MTL_SWITCH(arg.tenant_id_) { - ObLSService *ls_service = MTL(ObLSService *); - logservice::ObLogService *log_service = MTL(logservice::ObLogService*); - ObLSHandle ls_handle; - ObLS *ls = nullptr; - ObRole role = INVALID_ROLE; - int64_t proposal_id = -1; - bool has_active_memtable = false; - if (OB_ISNULL(ls_service) || OB_ISNULL(log_service)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected ls_service or log_service", K(ret)); - } else if (OB_FAIL(ls_service->get_ls(arg.ls_id_, ls_handle, ObLSGetMod::OBSERVER_MOD))) { - LOG_WARN("get ls failed", K(ret), K(arg)); - } else if (OB_ISNULL(ls = ls_handle.get_ls())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid ls", K(ret), K(arg.ls_id_)); - } else if (OB_FAIL(ls->get_ls_role(role))) { - LOG_WARN("get role failed", K(ret), K(MTL_ID()), K(arg.ls_id_)); - } else if (OB_UNLIKELY(ObRole::LEADER != role)) { - ret = OB_NOT_MASTER; - LOG_WARN("ls not leader", K(ret), K(MTL_ID()), K(arg.ls_id_)); - } else if (OB_FAIL(ls->tablet_freeze(checkpoint::INVALID_TRACE_ID, arg.tablet_ids_, true/*is_sync*/, abs_timeout_us, - false/*need_rewrite_meta*/, ObFreezeSourceFlag::TABLET_SPLIT))) { - LOG_WARN("batch tablet freeze failed", K(ret), K(arg)); - } else if (OB_FAIL(ls->check_tablet_no_active_memtable(arg.tablet_ids_, has_active_memtable))) { - // safer with this check, non-mandatory - LOG_WARN("check tablet has active memtable failed", K(ret), K(arg)); - } else if (has_active_memtable) { - ret = OB_EAGAIN; - LOG_WARN("tablet has active memtable need retry", K(ret), K(arg)); - } else if (OB_FAIL(ls->get_log_handler()->get_max_scn(res.data_end_scn_))) { - LOG_WARN("log_handler get_max_scn failed", K(ret), K(arg)); - } - } - } - return ret; -} - int ObService::fetch_split_tablet_info(const ObFetchSplitTabletInfoArg &arg, ObFetchSplitTabletInfoRes &res, const int64_t abs_timeout_us) diff --git a/src/rootserver/ob_split_partition_helper.cpp b/src/rootserver/ob_split_partition_helper.cpp index 62c69bde90..65a8f3e5d5 100644 --- a/src/rootserver/ob_split_partition_helper.cpp +++ b/src/rootserver/ob_split_partition_helper.cpp @@ -15,6 +15,7 @@ #include "rootserver/ob_split_partition_helper.h" #include "share/tablet/ob_tablet_to_table_history_operator.h" #include "src/share/scheduler/ob_partition_auto_split_helper.h" +#include "storage/compaction/ob_tenant_tablet_scheduler.h" namespace oceanbase { @@ -174,6 +175,68 @@ int ObSplitPartitionHelper::check_allow_split( return ret; } +int ObSplitPartitionHelper::freeze_split_src_tablet(const ObFreezeSplitSrcTabletArg &arg, + ObFreezeSplitSrcTabletRes &res, + const int64_t abs_timeout_us) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg)); + } else { + MTL_SWITCH(arg.tenant_id_) { + ObLSService *ls_service = MTL(ObLSService *); + logservice::ObLogService *log_service = MTL(logservice::ObLogService*); + compaction::ObTenantTabletScheduler *tenant_tablet_scheduler = MTL(compaction::ObTenantTabletScheduler*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObRole role = INVALID_ROLE; + int64_t proposal_id = -1; + bool has_active_memtable = false; + const ObIArray &tablet_ids = arg.tablet_ids_; + if (OB_ISNULL(ls_service) || OB_ISNULL(log_service) || OB_ISNULL(tenant_tablet_scheduler)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected ls_service or log_service", K(ret)); + } else if (OB_FAIL(ls_service->get_ls(arg.ls_id_, ls_handle, ObLSGetMod::OBSERVER_MOD))) { + LOG_WARN("get ls failed", K(ret), K(arg)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid ls", K(ret), K(arg.ls_id_)); + } else if (OB_FAIL(ls->get_ls_role(role))) { + LOG_WARN("get role failed", K(ret), K(MTL_ID()), K(arg.ls_id_)); + } else if (OB_UNLIKELY(ObRole::LEADER != role)) { + ret = OB_NOT_MASTER; + LOG_WARN("ls not leader", K(ret), K(MTL_ID()), K(arg.ls_id_)); + } else if (OB_FAIL(ls->tablet_freeze(checkpoint::INVALID_TRACE_ID, tablet_ids, true/*is_sync*/, abs_timeout_us, + false/*need_rewrite_meta*/, ObFreezeSourceFlag::TABLET_SPLIT))) { + LOG_WARN("batch tablet freeze failed", K(ret), K(arg)); + } else if (OB_FAIL(ls->check_tablet_no_active_memtable(tablet_ids, has_active_memtable))) { + // safer with this check, non-mandatory + LOG_WARN("check tablet has active memtable failed", K(ret), K(arg)); + } else if (has_active_memtable) { + ret = OB_EAGAIN; + LOG_WARN("tablet has active memtable need retry", K(ret), K(arg)); + } + + // the followings are workarounds, still INCORRECT in some leader switch corner cases + // 1. wait write end for medium + if (OB_FAIL(ret)) { + } else if (OB_FAIL(tenant_tablet_scheduler->stop_tablets_schedule_medium(tablet_ids, compaction::ObProhibitScheduleMediumMap::ProhibitFlag::SPLIT))) { + LOG_WARN("failed to stop tablets schedule medium", K(ret), K(arg)); + } else if (OB_FAIL(tenant_tablet_scheduler->clear_tablets_prohibit_medium_flag(tablet_ids, compaction::ObProhibitScheduleMediumMap::ProhibitFlag::SPLIT))) { + LOG_WARN("failed to clear prohibit schedule medium flag", K(ret), K(arg)); + } + // 2. wait write end for table autoinc seq will be done in batch_get_tablet_autoinc_seq + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ls->get_log_handler()->get_max_scn(res.data_end_scn_))) { + LOG_WARN("log_handler get_max_scn failed", K(ret), K(arg)); + } + } + } + return ret; +} + int ObSplitPartitionHelper::prepare_start_args_( const uint64_t tenant_id, const ObIArray &new_table_schemas, @@ -666,25 +729,6 @@ int ObSplitPartitionHelper::start_src_( start_time = finish_time; } - // get data end scn - if (OB_SUCC(ret)) { - const int64_t timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : GCONF.rpc_timeout; - obrpc::ObFreezeSplitSrcTabletArg arg; - obrpc::ObFreezeSplitSrcTabletRes res; - arg.tenant_id_ = tenant_id; - arg.ls_id_ = ls_id; - if (OB_FAIL(arg.tablet_ids_.assign(src_tablet_ids))) { - LOG_WARN("failed to assign", KR(ret)); - } else if (OB_FAIL(srv_rpc_proxy->to(leader_addr).timeout(timeout_us).freeze_split_src_tablet(arg, res))) { - LOG_WARN("failed to freeze src tablet", KR(ret), K(leader_addr)); - } else { - data_end_scn = res.data_end_scn_; - } - finish_time = ObTimeUtility::current_time(); - LOG_INFO("finish get data end scn", KR(ret), "cost_ts", finish_time - start_time, K(data_end_scn)); - start_time = finish_time; - } - // get src tablet's non-empty autoinc_seq that are needed to sync to dst tablet if (OB_SUCC(ret)) { const int64_t timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : GCONF.rpc_timeout; @@ -727,6 +771,25 @@ int ObSplitPartitionHelper::start_src_( LOG_INFO("finish batch_get_tablet_autoinc_seq", KR(ret), "cost_ts", finish_time - start_time); start_time = finish_time; } + + // get data end scn finally to guarantee both mds_checkpoint_scn and clog_checkpoint_scn are less than data_end_scn + if (OB_SUCC(ret)) { + const int64_t timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : GCONF.rpc_timeout; + obrpc::ObFreezeSplitSrcTabletArg arg; + obrpc::ObFreezeSplitSrcTabletRes res; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + if (OB_FAIL(arg.tablet_ids_.assign(src_tablet_ids))) { + LOG_WARN("failed to assign", KR(ret)); + } else if (OB_FAIL(srv_rpc_proxy->to(leader_addr).timeout(timeout_us).freeze_split_src_tablet(arg, res))) { + LOG_WARN("failed to freeze src tablet", KR(ret), K(leader_addr)); + } else { + data_end_scn = res.data_end_scn_; + } + finish_time = ObTimeUtility::current_time(); + LOG_INFO("finish get data end scn", KR(ret), "cost_ts", finish_time - start_time, K(data_end_scn)); + start_time = finish_time; + } return ret; } diff --git a/src/rootserver/ob_split_partition_helper.h b/src/rootserver/ob_split_partition_helper.h index de7f4220e2..1476c22db6 100644 --- a/src/rootserver/ob_split_partition_helper.h +++ b/src/rootserver/ob_split_partition_helper.h @@ -18,6 +18,12 @@ namespace oceanbase { +namespace obrpc +{ +struct ObFreezeSplitSrcTabletArg; +struct ObFreezeSplitSrcTabletRes; +} + namespace rootserver { @@ -50,6 +56,10 @@ public: static int check_allow_split( share::schema::ObSchemaGetterGuard &schema_guard, const share::schema::ObTableSchema &table_schema); + static int freeze_split_src_tablet( + const obrpc::ObFreezeSplitSrcTabletArg &arg, + obrpc::ObFreezeSplitSrcTabletRes &res, + const int64_t abs_timeout_us); private: static int prepare_start_args_( diff --git a/src/storage/compaction/ob_compaction_diagnose.cpp b/src/storage/compaction/ob_compaction_diagnose.cpp index 6d518a856b..acf37357f4 100644 --- a/src/storage/compaction/ob_compaction_diagnose.cpp +++ b/src/storage/compaction/ob_compaction_diagnose.cpp @@ -802,7 +802,8 @@ int ObCompactionDiagnoseMgr::diagnose_tenant( //TODO(mingqiao): check tenant res // step 2: check if major compaction is paused if (!MERGE_SCHEDULER_PTR->could_major_merge_start() || - MTL(ObTenantTabletScheduler *)->get_prohibit_medium_ls_map().get_transfer_flag_cnt() > 0) { + MTL(ObTenantTabletScheduler *)->get_prohibit_medium_ls_map().get_transfer_flag_cnt() > 0 || + MTL(ObTenantTabletScheduler *)->get_prohibit_medium_ls_map().get_split_flag_cnt() > 0) { ADD_COMMON_DIAGNOSE_INFO(!MERGE_SCHEDULER_PTR->could_major_merge_start() ? MAJOR_MERGE : MEDIUM_MERGE, ObCompactionDiagnoseInfo::DIA_STATUS_NOT_SCHEDULE, ObTimeUtility::fast_current_time(), diff --git a/src/storage/compaction/ob_schedule_status_cache.cpp b/src/storage/compaction/ob_schedule_status_cache.cpp index fbc5267ddc..16efe49f18 100644 --- a/src/storage/compaction/ob_schedule_status_cache.cpp +++ b/src/storage/compaction/ob_schedule_status_cache.cpp @@ -151,6 +151,7 @@ const static char * ObTabletScheduleNewRoundStateStr[] = { "EXIST_UNFINISH_MEDIUM", "SCHEDULE_CONFLICT", "NONE", + "LOCKED_BY_TRANSFER_OR_SPLIT", "STATE_MAX" }; @@ -270,6 +271,9 @@ int ObTabletStatusCache::inner_init_state( } else { execute_state_ = CAN_MERGE; } + if (FAILEDx(tablet.read_medium_info_list(allocator_, medium_list_))) { + LOG_WARN("failed to load medium info list", K(ret), K(tablet_id)); + } return ret; } @@ -294,7 +298,8 @@ void ObTabletStatusCache::inner_init_could_schedule_new_round( if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INVERVAL)) { LOG_INFO("tablet status is TRANSFER_OUT or TRANSFER_OUT_DELETED, merging is not allowed", K(user_data), K(tablet)); } - } else if (ObTabletStatus::SPLIT_SRC_DELETED == user_data.tablet_status_) { + } else if (ObTabletStatus::SPLIT_SRC == user_data.tablet_status_ + || ObTabletStatus::SPLIT_SRC_DELETED == user_data.tablet_status_) { new_round_state_ = DURING_SPLIT; if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INVERVAL)) { LOG_INFO("tablet status is split, merging is not allowed", K(user_data), K(tablet)); @@ -305,7 +310,7 @@ void ObTabletStatusCache::inner_init_could_schedule_new_round( } else if (!ls_could_schedule_new_round || NEW_ROUND_STATE_MAX != new_round_state_) { // do nothing } else if (need_register_map) { - if (OB_FAIL(register_map(tablet_id))) { + if (OB_FAIL(register_map(tablet))) { // register_map must be the last step LOG_WARN("failed to add tablet", K(ret), K(ls_id), K(tablet_id)); } @@ -345,8 +350,9 @@ int ObTabletStatusCache::check_medium_list( int ret = OB_SUCCESS; const ObTabletID &tablet_id = tablet.get_tablet_id(); - if (OB_FAIL(tablet.read_medium_info_list(allocator_, medium_list_))) { - LOG_WARN("failed to load medium info list", K(ret), K(tablet_id)); + if (OB_UNLIKELY(nullptr == medium_list_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("medium info list is unexpected null", K(ret), K(tablet_id)); } else if (medium_list_->need_check_finish()) { // need check finished new_round_state_ = NEED_CHECK_LAST_MEDIUM_CKM; int tmp_ret = OB_SUCCESS; @@ -363,11 +369,18 @@ int ObTabletStatusCache::check_medium_list( } int ObTabletStatusCache::register_map( - const ObTabletID &tablet_id) + const ObTablet &tablet) { int ret = OB_SUCCESS; + const ObTabletID &tablet_id = tablet.get_tablet_id(); + ObTenantTabletScheduler *tenant_tablet_scheduler = MTL(ObTenantTabletScheduler*); bool could_schedule_merge = false; - if (OB_FAIL(MTL(ObTenantTabletScheduler*)->tablet_start_schedule_medium( + bool need_clear_flag = false; + ObTabletCreateDeleteMdsUserData user_data; + mds::MdsWriter writer; + mds::TwoPhaseCommitState trans_stat; + share::SCN trans_version; + if (OB_FAIL(tenant_tablet_scheduler->tablet_start_schedule_medium( tablet_id, could_schedule_merge))) { if (OB_ENTRY_EXIST == ret) { new_round_state_ = SCHEDULE_CONFLICT; @@ -375,10 +388,22 @@ int ObTabletStatusCache::register_map( } else { LOG_WARN("failed to add tablet", K(ret), K(tablet_id)); } - } else if (could_schedule_merge) { - new_round_state_ = CAN_SCHEDULE_NEW_ROUND; + } else if (!could_schedule_merge) { + new_round_state_ = LOCKED_BY_TRANSFER_OR_SPLIT; + } else if (OB_FAIL(tablet.ObITabletMdsInterface::get_latest_tablet_status(user_data, writer, trans_stat, trans_version))) { + need_clear_flag = true; + LOG_WARN("failed to get tablet status", K(ret), K(tablet), K(user_data)); + } else if (ObTabletStatus::SPLIT_SRC == user_data.tablet_status_) { + need_clear_flag = true; + new_round_state_ = DURING_SPLIT; } else { - new_round_state_ = DURING_TRANSFER; + new_round_state_ = CAN_SCHEDULE_NEW_ROUND; + } + + if (need_clear_flag) { + if (OB_SUCCESS != tenant_tablet_scheduler->clear_prohibit_medium_flag(tablet_id, ObProhibitScheduleMediumMap::ProhibitFlag::MEDIUM)) { + ob_abort(); + } } return ret; } diff --git a/src/storage/compaction/ob_schedule_status_cache.h b/src/storage/compaction/ob_schedule_status_cache.h index 966621a232..669cd1e4a7 100644 --- a/src/storage/compaction/ob_schedule_status_cache.h +++ b/src/storage/compaction/ob_schedule_status_cache.h @@ -95,6 +95,7 @@ public: EXIST_UNFINISH_MEDIUM, SCHEDULE_CONFLICT, DIAGNOSE_NORMAL, // for diagnose + LOCKED_BY_TRANSFER_OR_SPLIT, NEW_ROUND_STATE_MAX, }; static const char *new_round_state_to_str(const TabletScheduleNewRoundState &state); @@ -152,7 +153,7 @@ protected: int check_medium_list( const share::ObLSID &ls_id, const storage::ObTablet &tablet); - int register_map(const ObTabletID &tablet_id); + int register_map(const ObTablet &tablet); void inner_init_could_schedule_new_round( const ObLSID &ls_id, const ObTablet &tablet, diff --git a/src/storage/compaction/ob_tenant_tablet_scheduler.cpp b/src/storage/compaction/ob_tenant_tablet_scheduler.cpp index d18e545ef2..89d0d3293a 100644 --- a/src/storage/compaction/ob_tenant_tablet_scheduler.cpp +++ b/src/storage/compaction/ob_tenant_tablet_scheduler.cpp @@ -709,9 +709,11 @@ int ObTenantTabletScheduler::schedule_merge(const int64_t broadcast_version) const char *ObProhibitScheduleMediumMap::ProhibitFlagStr[] = { "TRANSFER", "MEDIUM", + "SPLIT", }; ObProhibitScheduleMediumMap::ObProhibitScheduleMediumMap() : transfer_flag_cnt_(0), + split_flag_cnt_(0), lock_(), tablet_id_map_() { @@ -777,15 +779,17 @@ int ObProhibitScheduleMediumMap::batch_add_flags(const ObIArray &tab { int ret = OB_SUCCESS; obsys::ObWLockGuard lock_guard(lock_); - if (OB_UNLIKELY(ProhibitFlag::TRANSFER != input_flag)) { + if (OB_UNLIKELY(ProhibitFlag::TRANSFER != input_flag && ProhibitFlag::SPLIT != input_flag)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument, batch_add_flags only support TRANSFER now", K(ret), K(input_flag)); + LOG_WARN("invalid argument, batch_add_flags only support TRANSFER or SPLIT now", K(ret), K(input_flag)); } else if (OB_FAIL(inner_batch_check_tablets_not_prohibited_(tablet_ids))) { LOG_WARN("failed to check all tablets not prohibited", K(ret), K(tablet_ids)); } else if (OB_FAIL(inner_batch_add_tablets_prohibit_flags_(tablet_ids, input_flag))){ LOG_WARN("failed to add tablets prohibit_flags", K(ret), K(tablet_ids), K(input_flag)); } else if (ProhibitFlag::TRANSFER == input_flag){ ++transfer_flag_cnt_; + } else if (ProhibitFlag::SPLIT == input_flag) { + ++split_flag_cnt_; } return ret; } @@ -793,9 +797,9 @@ int ObProhibitScheduleMediumMap::batch_add_flags(const ObIArray &tab int ObProhibitScheduleMediumMap::batch_clear_flags(const ObIArray &tablet_ids, const ProhibitFlag &input_flag) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(ProhibitFlag::TRANSFER != input_flag)) { + if (OB_UNLIKELY(ProhibitFlag::TRANSFER != input_flag && ProhibitFlag::SPLIT != input_flag)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument, batch_clear_flags only support TRANSFER now", K(ret), K(input_flag)); + LOG_WARN("invalid argument, batch_clear_flags only support TRANSFER or SPLIT now", K(ret), K(input_flag)); } else { const int64_t tablets_cnt = tablet_ids.count(); obsys::ObWLockGuard lock_guard(lock_); @@ -808,6 +812,9 @@ int ObProhibitScheduleMediumMap::batch_clear_flags(const ObIArray &t if (OB_SUCC(ret) && ProhibitFlag::TRANSFER == input_flag) { --transfer_flag_cnt_; } + if (OB_SUCC(ret) && ProhibitFlag::SPLIT == input_flag) { + --split_flag_cnt_; + } } return ret; } @@ -816,6 +823,7 @@ void ObProhibitScheduleMediumMap::destroy() { obsys::ObWLockGuard lock_guard(lock_); transfer_flag_cnt_ = 0; + split_flag_cnt_ = 0; if (tablet_id_map_.created()) { tablet_id_map_.destroy(); } @@ -924,6 +932,12 @@ int64_t ObProhibitScheduleMediumMap::get_transfer_flag_cnt() const return transfer_flag_cnt_; } +int64_t ObProhibitScheduleMediumMap::get_split_flag_cnt() const +{ + obsys::ObRLockGuard lock_guard(lock_); + return split_flag_cnt_; +} + int ObTenantTabletScheduler::stop_tablets_schedule_medium(const ObIArray &tablet_ids, const ObProhibitScheduleMediumMap::ProhibitFlag &input_flag) { int ret = OB_SUCCESS; @@ -1585,7 +1599,8 @@ int ObTenantTabletScheduler::schedule_all_tablets_medium() LOG_WARN("failed to medium loop", K(ret)); } } - if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INTERVAL) && prohibit_medium_map_.get_transfer_flag_cnt() > 0) { + if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INTERVAL) && + (prohibit_medium_map_.get_transfer_flag_cnt() > 0 || prohibit_medium_map_.get_split_flag_cnt() > 0)) { LOG_INFO("tenant is blocking schedule medium", KR(ret), K_(prohibit_medium_map)); } } diff --git a/src/storage/compaction/ob_tenant_tablet_scheduler.h b/src/storage/compaction/ob_tenant_tablet_scheduler.h index c7fbd9e5f1..053d885c06 100644 --- a/src/storage/compaction/ob_tenant_tablet_scheduler.h +++ b/src/storage/compaction/ob_tenant_tablet_scheduler.h @@ -97,6 +97,7 @@ public: { TRANSFER = 0, MEDIUM = 1, + SPLIT = 2, FLAG_MAX }; @@ -115,6 +116,7 @@ public: int batch_add_flags(const ObIArray &tablet_ids, const ProhibitFlag &input_flag); int64_t to_string(char *buf, const int64_t buf_len) const; int64_t get_transfer_flag_cnt() const; + int64_t get_split_flag_cnt() const; private: static const int64_t PRINT_LOG_INTERVAL = 2 * 60 * 1000 * 1000L; // 2m static const int64_t TABLET_ID_MAP_BUCKET_NUM = OB_MAX_LS_NUM_PER_TENANT_PER_SERVER * 1024; @@ -123,6 +125,7 @@ private: int inner_batch_add_tablets_prohibit_flags_(const ObIArray &tablet_ids, const ProhibitFlag &input_flag); // hold lock outside !! int inner_clear_flag_(const ObTabletID &tablet_id, const ProhibitFlag &input_flag); // hold lock outside !! int64_t transfer_flag_cnt_; + int64_t split_flag_cnt_; mutable obsys::ObRWLock lock_; common::hash::ObHashMap tablet_id_map_; // tablet is used for transfer of medium compaction }; diff --git a/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp b/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp index 2068164140..7375f4ccdd 100644 --- a/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp +++ b/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp @@ -171,6 +171,11 @@ int ObTabletAutoincSeqRpcHandler::fetch_tablet_autoinc_seq_cache( ObTabletAutoincInterval autoinc_interval; const ObTabletID &tablet_id = arg.tablet_id_; int64_t proposal_id = -1; + ObTabletCreateDeleteMdsUserData user_data; + mds::MdsWriter writer; + mds::TwoPhaseCommitState trans_stat; + share::SCN trans_version; + bool is_committed = false; ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); if (OB_FAIL(MTL(logservice::ObLogService*)->get_palf_role(ls_id, role, proposal_id))) { LOG_WARN("get palf role failed", K(ret)); @@ -181,6 +186,11 @@ int ObTabletAutoincSeqRpcHandler::fetch_tablet_autoinc_seq_cache( LOG_WARN("get ls failed", K(ret), K(ls_id)); } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle, THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : obrpc::ObRpcProxy::MAX_RPC_TIMEOUT))) { LOG_WARN("failed to get tablet", KR(ret), K(arg)); + } else if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_latest_tablet_status(user_data, writer, trans_stat, trans_version))) { + LOG_WARN("fail to get latest tablet status", K(ret), K(arg)); + } else if (OB_UNLIKELY(trans_stat != mds::TwoPhaseCommitState::ON_COMMIT)) { + ret = OB_EAGAIN; + LOG_WARN("tablet status not committed, maybe transfer or split start trans", K(ret), K(user_data), K(trans_stat), K(writer)); // TODO(lihongqin.lhq): fetch from split dst to avoid retry } else if (OB_FAIL(tablet_handle.get_obj()->fetch_tablet_autoinc_seq_cache( arg.cache_size_, autoinc_interval))) {