/** * Copyright (c) 2021 OceanBase * OceanBase CE is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan PubL v2. * You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ #include "io/easy_connection.h" #include "lib/list/ob_dlist.h" #include "lib/ob_errno.h" #include "lib/string/ob_string_holder.h" #include "logservice/leader_coordinator/failure_event.h" #include "logservice/leader_coordinator/ob_failure_detector.h" #include "share/inner_table/ob_inner_table_schema_constants.h" #include "share/ob_table_access_helper.h" #include "share/rc/ob_tenant_base.h" #define USING_LOG_PREFIX RS #include "ob_system_admin_util.h" #include "lib/time/ob_time_utility.h" #include "lib/container/ob_array_iterator.h" #include "share/ob_srv_rpc_proxy.h" #include "share/ob_rpc_struct.h" #include "share/schema/ob_schema_getter_guard.h" #include "share/schema/ob_multi_version_schema_service.h" #include "share/config/ob_server_config.h" #include "share/config/ob_config_manager.h" #include "share/ob_dml_sql_splicer.h" #include "share/ob_cluster_version.h" #include "share/ob_upgrade_utils.h" #include "share/ob_share_util.h" // ObShareUtil #include "storage/ob_file_system_router.h" #include "observer/ob_server_struct.h" #include "observer/omt/ob_tenant_config_mgr.h" #include "observer/omt/ob_multi_tenant.h" #include "observer/ob_srv_network_frame.h" #include "ob_server_manager.h" #include "ob_ddl_operator.h" #include "ob_zone_manager.h" #include "ob_ddl_service.h" #include "ob_unit_manager.h" #include "ob_root_inspection.h" #include "ob_root_service.h" #include "storage/ob_file_system_router.h" #include "logservice/leader_coordinator/table_accessor.h" #include "rootserver/freeze/ob_major_freeze_helper.h" namespace oceanbase { using namespace common; using namespace common::hash; using namespace share; using namespace share::schema; using namespace obrpc; namespace rootserver { int ObSystemAdminUtil::check_service() const { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else { ret = ctx_.rs_status_->in_service()? OB_SUCCESS : OB_CANCELED; } return ret; } int ObAdminSwitchReplicaRole::execute(const ObAdminSwitchReplicaRoleArg &arg) { LOG_INFO("execute switch replica role request", K(arg)); ObArenaAllocator allocator(ObModIds::OB_RS_PARTITION_TABLE_TEMP); int ret = OB_SUCCESS; const ObLSID ls_id(arg.ls_id_); uint64_t tenant_id = OB_INVALID_TENANT_ID; ObLSInfo ls_info; auto get_tenant_id_by_name = [this](const ObAdminSwitchReplicaRoleArg &arg, uint64_t &tenant_id) -> int { int ret = OB_SUCCESS; ObSchemaGetterGuard schema_guard; ObString tenant_name; tenant_name.assign_ptr(arg.tenant_name_.ptr(), static_cast(strlen(arg.tenant_name_.ptr()))); if (tenant_name.empty()) { tenant_id = OB_INVALID_TENANT_ID; } else if (OB_FAIL(ctx_.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { LOG_WARN("get schema manager failed", KR(ret)); } else if (OB_FAIL(schema_guard.get_tenant_id(tenant_name, tenant_id)) || OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { ret = OB_TENANT_NOT_EXIST; LOG_WARN("tenant not exist", K(tenant_name), KR(ret)); } return ret; }; auto check_server_valid = [](const ObAddr &server) -> int { int ret = OB_SUCCESS; const char *columns[1] = {"status"}; constexpr int64_t buffer_size = 128; char where_condition[buffer_size] = {0}; char ip_str_buffer[buffer_size] = {0}; if (!server.ip_to_string(ip_str_buffer, buffer_size)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ip to string failed", K(ip_str_buffer), K(server)); } else { if (OB_FAIL(databuff_printf(where_condition, buffer_size, "where svr_ip='%s' and svr_port=%d", ip_str_buffer, server.get_port()))) { LOG_WARN("fail to create where confition", K(ip_str_buffer), K(server)); } else { ObStringHolder server_status; if (OB_FAIL(ObTableAccessHelper::read_single_row(OB_SYS_TENANT_ID, columns, OB_ALL_SERVER_TNAME, where_condition, server_status))) { if (OB_ITER_END == ret) { ret = OB_ENTRY_NOT_EXIST; LOG_USER_ERROR(OB_ENTRY_NOT_EXIST, "server not in cluster"); LOG_WARN("server not in __all_server table", K(server), KR(ret)); } else { LOG_WARN("fail to read all_server table", K(server), KR(ret)); } } else if (server_status.get_ob_string().compare("ACTIVE") != 0) { ret = OB_OP_NOT_ALLOW; LOG_USER_ERROR(OB_OP_NOT_ALLOW, "server not active"); LOG_WARN("server status not valid", K(server), K(server_status)); } } } return ret; }; auto update_ls_election_reference_info_table = [](const ObAdminSwitchReplicaRoleArg &arg, const int64_t tenant_id, const ObLSInfo &info) -> int { int ret = OB_SUCCESS; ObSwitchLeaderArg switch_leader_arg(arg.ls_id_, arg.role_, tenant_id, arg.server_); const ObLSReplica *ls_replica = nullptr; if (switch_leader_arg.ls_id_ < 0 || OB_INVALID_TENANT_ID == switch_leader_arg.tenant_id_ || !switch_leader_arg.dest_server_.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(switch_leader_arg)); } else if (switch_leader_arg.role_ == ObRole::LEADER) { logservice::coordinator::LsElectionReferenceInfoRow row(tenant_id, share::ObLSID(arg.ls_id_)); if (OB_FAIL(row.change_manual_leader(arg.server_))) { LOG_WARN("fail to change manual leader in __all_ls_election_reference_info", K(ret), K(arg)); } else { LOG_INFO("successfully to change manual leader in __all_ls_election_reference_info", K(ret), K(arg)); } } else if (switch_leader_arg.role_ == ObRole::FOLLOWER) { logservice::coordinator::LsElectionReferenceInfoRow row(tenant_id, share::ObLSID(arg.ls_id_)); if (OB_FAIL(row.add_server_to_blacklist(arg.server_, logservice::coordinator::InsertElectionBlacklistReason::SWITCH_REPLICA))) { LOG_WARN("fail to add remove member info in __all_ls_election_reference_info", K(ret), K(arg)); } else { LOG_INFO("successfully to add remove member info in __all_ls_election_reference_info", K(ret), K(arg)); } } else if (switch_leader_arg.role_ == ObRole::INVALID_ROLE) { logservice::coordinator::LsElectionReferenceInfoRow row(tenant_id, share::ObLSID(arg.ls_id_)); if (OB_FAIL(row.change_manual_leader(ObAddr()))) { LOG_WARN("fail to change manual leader in __all_ls_election_reference_info", K(ret), K(arg)); } else if (OB_FAIL(row.delete_server_from_blacklist(arg.server_))) { if (OB_ENTRY_NOT_EXIST != ret) { LOG_WARN("fail to del remove member info in __all_ls_election_reference_info", K(ret), K(arg)); } else { ret = OB_SUCCESS; } } if (OB_SUCC(ret)) { LOG_INFO("successfully to reset server status in __all_ls_election_reference_info", K(ret), K(arg)); } } return ret; }; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else if (!ls_id.is_valid()) {// 表示需要改变server上或者zone中所有日志流的状态 ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "switch server's role or zone's role"); } else if (!arg.server_.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("server must set", K(arg), KR(ret)); } else if (OB_FAIL(check_server_valid(arg.server_))) { LOG_WARN("check server valid state failed", K(arg), KR(ret)); } else if (OB_FAIL(get_tenant_id_by_name(arg, tenant_id))) { if (OB_ENTRY_NOT_EXIST == ret) { LOG_USER_ERROR(OB_ENTRY_NOT_EXIST, "invalid tenant"); } LOG_WARN("fail to convert tenant name to id", K(arg), KR(ret)); } else if (OB_ISNULL(GCTX.lst_operator_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("GCTX.lst_operator_ is NULL", K(arg), KR(ret), K(tenant_id)); } else if (OB_FAIL(GCTX.lst_operator_->get(GCONF.cluster_id, tenant_id, ls_id, ls_info))) { LOG_WARN("get ls info from GCTX.lst_operator_ failed", K(arg), KR(ret), K(tenant_id)); } else if (OB_FAIL(update_ls_election_reference_info_table(arg, tenant_id, ls_info))) { LOG_WARN("fail to update ls election reference info", K(arg), KR(ret), K(tenant_id)); } LOG_INFO("switch leader done", KR(ret), K(arg), K(tenant_id), K(ls_info)); return ret; } int ObAdminSwitchReplicaRole::alloc_tenant_id_set(common::hash::ObHashSet &tenant_id_set) { int ret = OB_SUCCESS; if (tenant_id_set.created()) { if(OB_FAIL(tenant_id_set.clear())) { LOG_WARN("clear tenant id set failed", KR(ret)); } } else if (OB_FAIL(tenant_id_set.create(TENANT_BUCKET_NUM))) { LOG_WARN("create tenant id set failed", LITERAL_K(TENANT_BUCKET_NUM), KR(ret)); } return ret; } template int ObAdminSwitchReplicaRole::convert_set_to_array(const common::hash::ObHashSet &set, ObArray &array) { int ret = common::OB_SUCCESS; array.reuse(); if (!set.created()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("set not created", "set created", set.created(), KR(ret)); } else if (OB_FAIL(array.reserve(set.size()))) { LOG_WARN("array reserver failed", "capacity", set.size(), KR(ret)); } else { for (typename common::hash::ObHashSet::const_iterator iter = set.begin(); OB_SUCCESS == ret && iter != set.end(); ++iter) { if (OB_FAIL(array.push_back(iter->first))) { LOG_WARN("push_back failed", KR(ret)); } } } return ret; } int ObAdminSwitchReplicaRole::get_tenants_of_zone(const ObZone &zone, common::hash::ObHashSet &tenant_id_set) { int ret = OB_SUCCESS; ObArray server_array; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (zone.is_empty() || !tenant_id_set.created()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(zone), "tenant_id_set created", tenant_id_set.created(), KR(ret)); } else if (OB_FAIL(ctx_.server_mgr_->get_alive_servers(zone, server_array))) { LOG_WARN("get alive servers failed", K(zone), KR(ret)); } else { FOREACH_CNT_X(server, server_array, OB_SUCCESS == ret) { if (OB_FAIL(ctx_.unit_mgr_->get_tenants_of_server(*server, tenant_id_set))) { LOG_WARN("get tenants of server failed", "server", *server, KR(ret)); } } } return ret; } int ObAdminSwitchReplicaRole::get_switch_replica_tenants(const ObZone &zone, const ObAddr &server, const uint64_t &tenant_id, ObArray &tenant_ids) { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (zone.is_empty() && !server.is_valid() && OB_INVALID_ID == tenant_id) { ret = OB_INVALID_ARGUMENT; LOG_WARN("zone, server and tenant_id are all invalid", K(zone), K(server), K(tenant_id), KR(ret)); } else if (OB_INVALID_ID != tenant_id) { if (OB_FAIL(tenant_ids.push_back(tenant_id))) { LOG_WARN("push back tenant id failed", KR(ret)); } } else if (server.is_valid() || !zone.is_empty()) { ObHashSet tenant_id_set; if (OB_FAIL(alloc_tenant_id_set(tenant_id_set))) { LOG_WARN("alloc tenant id set failed", KR(ret)); } else { if (server.is_valid()) { if (OB_FAIL(ctx_.unit_mgr_->get_tenants_of_server(server, tenant_id_set))) { LOG_WARN("get tenants of server failed", K(server), KR(ret)); } } else { if (OB_FAIL(get_tenants_of_zone(zone, tenant_id_set))) { LOG_WARN("get tenants of zone failed", K(zone), KR(ret)); } } } if (OB_SUCC(ret)) { if (OB_FAIL(convert_set_to_array(tenant_id_set, tenant_ids))) { LOG_WARN("convert set to array failed", KR(ret)); } } } return ret; } int ObAdminCallServer::get_server_list(const ObServerZoneArg &arg, ObIArray &server_list) { int ret = OB_SUCCESS; server_list.reset(); if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else if (arg.server_.is_valid()) { bool is_alive = false; if (OB_FAIL(ctx_.server_mgr_->check_server_alive(arg.server_, is_alive))) { LOG_WARN("fail to check server alive", KR(ret), "server", arg.server_); } else if (!is_alive) { ret = OB_INVALID_ARGUMENT; LOG_WARN("server is not alive", KR(ret), "server", arg.server_); } else if (OB_FAIL(server_list.push_back(arg.server_))) { LOG_WARN("push back server failed", KR(ret)); } } else { bool zone_exist = true; if (!arg.zone_.is_empty() && OB_FAIL(ctx_.zone_mgr_->check_zone_exist(arg.zone_, zone_exist))) { LOG_WARN("fail to check zone exist", KR(ret)); } else if (!zone_exist) { ret = OB_ZONE_INFO_NOT_EXIST; LOG_WARN("zone info not exist", KR(ret), K(arg.zone_)); } else if (OB_FAIL(ctx_.server_mgr_->get_alive_servers(arg.zone_, server_list))) { LOG_WARN("get alive servers failed", KR(ret), K(arg)); } } return ret; } int ObAdminCallServer::call_all(const ObServerZoneArg &arg) { int ret = OB_SUCCESS; ObArray server_list; if (OB_FAIL(get_server_list(arg, server_list))) { LOG_WARN("get server list failed", K(ret), K(arg)); } else { FOREACH_CNT(server, server_list) { int tmp_ret = call_server(*server); if (OB_SUCCESS != tmp_ret) { LOG_WARN("call server failed", KR(ret), "server", *server); ret = OB_SUCCESS == ret ? tmp_ret : ret; } } } return ret; } int ObAdminReportReplica::execute(const obrpc::ObAdminReportReplicaArg &arg) { LOG_INFO("execute report request", K(arg)); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else if (OB_FAIL(call_all(arg))) { LOG_WARN("execute report replica failed", KR(ret), K(arg)); } return ret; } int ObAdminReportReplica::call_server(const ObAddr &server) { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!server.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid server", K(server), KR(ret)); } else if (OB_FAIL(ctx_.rpc_proxy_->to(server).report_replica())) { LOG_WARN("request server report replica failed", KR(ret), K(server)); } return ret; } int ObAdminRecycleReplica::execute(const obrpc::ObAdminRecycleReplicaArg &arg) { LOG_INFO("execute recycle request", K(arg)); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else if (OB_FAIL(call_all(arg))) { LOG_WARN("execute recycle replica failed", KR(ret), K(arg)); } return ret; } int ObAdminRecycleReplica::call_server(const ObAddr &server) { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!server.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid server", K(server), KR(ret)); } else if (OB_FAIL(ctx_.rpc_proxy_->to(server).recycle_replica())) { LOG_WARN("request server recycle replica failed", KR(ret), K(server)); } return ret; } int ObAdminClearLocationCache::execute(const obrpc::ObAdminClearLocationCacheArg &arg) { LOG_INFO("execute clear location cache request", K(arg)); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else if (OB_FAIL(call_all(arg))) { LOG_WARN("execute clear location cache failed", KR(ret), K(arg)); } return ret; } int ObAdminClearLocationCache::call_server(const ObAddr &server) { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!server.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid server", K(server), KR(ret)); } else if (OB_FAIL(ctx_.rpc_proxy_->to(server).clear_location_cache())) { LOG_WARN("request clear location cache failed", KR(ret), K(server)); } return ret; } int ObAdminReloadUnit::execute() { LOG_INFO("execute reload unit request"); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (OB_FAIL(ctx_.unit_mgr_->load())) { LOG_WARN("unit manager load failed", KR(ret)); } LOG_INFO("finish execute reload unit request", KR(ret)); return ret; } int ObAdminReloadServer::execute() { LOG_INFO("execute reload server request"); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (OB_FAIL(ctx_.server_mgr_->load_server_manager())) { LOG_WARN("build server status failed", KR(ret)); } return ret; } int ObAdminReloadZone::execute() { LOG_INFO("execute reload zone request"); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (OB_FAIL(ctx_.zone_mgr_->reload())) { LOG_ERROR("zone manager reload failed", KR(ret)); } return ret; } int ObAdminClearMergeError::execute(const obrpc::ObAdminMergeArg &arg) { LOG_INFO("execute clear merge error request", K(arg)); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else { ObTenantAdminMergeParam param; param.transport_ = GCTX.net_frame_->get_req_transport(); if (arg.affect_all_) { param.need_all_ = true; } else if (OB_FAIL(param.tenant_array_.assign(arg.tenant_ids_))) { LOG_WARN("fail to assign tenant_ids", KR(ret), K(arg)); } if (FAILEDx(ObMajorFreezeHelper::clear_merge_error(param))) { LOG_WARN("fail to clear merge error", KR(ret), K(param)); } } return ret; } int ObAdminZoneFastRecovery::execute(const obrpc::ObAdminRecoveryArg &arg) { LOG_INFO("execute zone fast recovery admin request", K(arg)); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else { switch (arg.type_) { case ObAdminRecoveryArg::SUSPEND_RECOVERY: if (OB_FAIL(ctx_.zone_mgr_->update_recovery_status( arg.zone_, share::ObZoneInfo::RECOVERY_STATUS_SUSPEND))) { LOG_WARN("fail to update zone fast recovery status", KR(ret)); } break; case ObAdminRecoveryArg::RESUME_RECOVERY: if (OB_FAIL(ctx_.zone_mgr_->update_recovery_status( arg.zone_, share::ObZoneInfo::RECOVERY_STATUS_NORMAL))) { LOG_WARN("fail to update zone fast recovery status", KR(ret)); } break; default: ret = OB_ERR_UNEXPECTED; LOG_WARN("arg type unexpected", KR(ret), "type", arg.type_); break; } } return ret; } int ObAdminMerge::execute(const obrpc::ObAdminMergeArg &arg) { LOG_INFO("execute merge admin request", K(arg)); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else { switch(arg.type_) { case ObAdminMergeArg::START_MERGE: { /* if (OB_FAIL(ctx_.daily_merge_scheduler_->manual_start_merge(arg.zone_))) { LOG_WARN("start merge zone failed", K(ret), K(arg)); }*/ break; } case ObAdminMergeArg::SUSPEND_MERGE: { ObTenantAdminMergeParam param; param.transport_ = GCTX.net_frame_->get_req_transport(); if (arg.affect_all_) { param.need_all_ = true; } else if (OB_FAIL(param.tenant_array_.assign(arg.tenant_ids_))) { LOG_WARN("fail to assign tenant_ids", KR(ret), K(arg)); } if (FAILEDx(ObMajorFreezeHelper::suspend_merge(param))) { LOG_WARN("fail to suspend merge", KR(ret), K(param)); } break; } case ObAdminMergeArg::RESUME_MERGE: { ObTenantAdminMergeParam param; param.transport_ = GCTX.net_frame_->get_req_transport(); if (arg.affect_all_) { param.need_all_ = true; } else if (OB_FAIL(param.tenant_array_.assign(arg.tenant_ids_))) { LOG_WARN("fail to assign tenant_ids", KR(ret), K(arg)); } if (FAILEDx(ObMajorFreezeHelper::resume_merge(param))) { LOG_WARN("fail to resume merge", KR(ret), K(param)); } break; } default: { ret = OB_NOT_SUPPORTED; LOG_WARN("unsupported merge admin type", "type", arg.type_, KR(ret)); } } } return ret; } int ObAdminClearRoottable::execute(const obrpc::ObAdminClearRoottableArg &arg) { int ret = OB_NOT_SUPPORTED; UNUSED(arg); return ret; } //FIXME: flush schemas of all tenants int ObAdminRefreshSchema::execute(const obrpc::ObAdminRefreshSchemaArg &arg) { LOG_INFO("execute refresh schema", K(arg)); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else if (OB_FAIL(ctx_.ddl_service_->refresh_schema(OB_SYS_TENANT_ID))) { LOG_WARN("refresh schema failed", KR(ret)); } else { if (OB_FAIL(ctx_.schema_service_->get_tenant_schema_version(OB_SYS_TENANT_ID, schema_version_))) { LOG_WARN("fail to get schema version", KR(ret)); } else if (OB_FAIL(ctx_.schema_service_->get_refresh_schema_info(schema_info_))) { LOG_WARN("fail to get refresh schema info", KR(ret), K(schema_info_)); } else if (!schema_info_.is_valid()) { schema_info_.set_schema_version(schema_version_); } if (OB_FAIL(ret)) { } else if (OB_FAIL(call_all(arg))) { LOG_WARN("execute notify refresh schema failed", KR(ret), K(arg)); } } return ret; } int ObAdminRefreshSchema::call_server(const ObAddr &server) { int ret = OB_SUCCESS; ObTimeoutCtx ctx; if (OB_UNLIKELY(!ctx_.is_inited())) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (OB_UNLIKELY(!server.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid server", KR(ret), K(server)); } else if (OB_ISNULL(GCTX.srv_rpc_proxy_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("GCTX.srv_rpc_proxy_ is null", KR(ret)); } else if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, GCONF.rpc_timeout))) { LOG_WARN("fail to set timeout ctx", KR(ret)); } else { ObSwitchSchemaArg arg; arg.schema_info_ = schema_info_; ObArray return_code_array; ObSwitchSchemaProxy proxy(*GCTX.srv_rpc_proxy_, &ObSrvRpcProxy::switch_schema); const int64_t timeout_ts = ctx.get_timeout(0); if (OB_FAIL(proxy.call(server, timeout_ts, arg))) { LOG_WARN("notify switch schema failed", KR(ret), K(server), K_(schema_version), K_(schema_info)); } else if (OB_FAIL(proxy.wait_all(return_code_array))) { LOG_WARN("fail to wait all", KR(ret), K(server)); } else if (OB_UNLIKELY(return_code_array.empty())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("return_code_array is empty", KR(ret), K(server)); } else { ret = return_code_array.at(0); } } return ret; } int ObAdminRefreshMemStat::execute(const ObAdminRefreshMemStatArg &arg) { LOG_INFO("execute refresh memory stat"); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (OB_FAIL(call_all(arg))) { LOG_WARN("execute notify refresh memory stat failed", KR(ret)); } return ret; } int ObAdminRefreshMemStat::call_server(const ObAddr &server) { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!server.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid server", K(server), KR(ret)); } else if (OB_FAIL(ctx_.rpc_proxy_->to(server).refresh_memory_stat())) { LOG_WARN("notify refresh memory stat failed", KR(ret), K(server)); } return ret; } int ObAdminWashMemFragmentation::execute(const ObAdminWashMemFragmentationArg &arg) { LOG_INFO("execute sync wash fragment"); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); } else if (OB_FAIL(call_all(arg))) { LOG_WARN("execute notify sync wash fragment failed", K(ret)); } return ret; } int ObAdminWashMemFragmentation::call_server(const ObAddr &server) { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); } else if (!server.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid server", K(server), K(ret)); } else if (OB_FAIL(ctx_.rpc_proxy_->to(server).wash_memory_fragmentation())) { LOG_WARN("notify sync wash fragment failed", K(ret), K(server)); } return ret; } int ObAdminSetConfig::verify_config(obrpc::ObAdminSetConfigArg &arg) { int ret = OB_SUCCESS; void *ptr = nullptr, *cfg_ptr = nullptr; ObServerConfigChecker *cfg = nullptr; ObTenantConfigChecker *tenant_cfg = nullptr; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } FOREACH_X(item, arg.items_, OB_SUCCESS == ret) { if (item->name_.is_empty()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("empty config name", "item", *item, KR(ret)); } else { ObConfigItem *ci = nullptr; if (OB_SYS_TENANT_ID != item->exec_tenant_id_ || item->tenant_name_.size() > 0) { // tenants(user or sys tenants) modify tenant level configuration if (nullptr == tenant_cfg) { if (OB_ISNULL(cfg_ptr = ob_malloc(sizeof(ObTenantConfigChecker), ObModIds::OB_RS_PARTITION_TABLE_TEMP))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory", KR(ret)); } else if (OB_ISNULL(tenant_cfg = new (cfg_ptr) ObTenantConfigChecker())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("new tenant_cfg failed", KR(ret)); } } // if if (OB_SUCC(ret)) { ObConfigItem * const *ci_ptr = tenant_cfg->get_container().get( ObConfigStringKey(item->name_.ptr())); if (OB_ISNULL(ci_ptr)) { ret = OB_ERR_SYS_CONFIG_UNKNOWN; LOG_WARN("can't found config item", KR(ret), "item", *item); } else { ci = *ci_ptr; share::schema::ObSchemaGetterGuard schema_guard; if (OB_FAIL(ctx_.ddl_service_->get_tenant_schema_guard_with_version_in_inner_table(OB_SYS_TENANT_ID, schema_guard))) { LOG_WARN("get_schema_guard failed", KR(ret)); } else if (OB_SYS_TENANT_ID == item->exec_tenant_id_ && item->tenant_name_ == ObFixedLengthString("all")) { common::ObArray tenant_ids; if (OB_FAIL(schema_guard.get_tenant_ids(tenant_ids))) { LOG_WARN("get_tenant_ids failed", KR(ret)); } else { for (const uint64_t tenant_id: tenant_ids) { if (!is_virtual_tenant_id(tenant_id) && OB_FAIL(item->tenant_ids_.push_back(tenant_id))) { LOG_WARN("add tenant_id failed", K(tenant_id), KR(ret)); break; } } // for } } else if (OB_SYS_TENANT_ID == item->exec_tenant_id_ && item->tenant_name_ == ObFixedLengthString("seed")) { uint64_t tenant_id = OB_PARAMETER_SEED_ID; if (OB_FAIL(item->tenant_ids_.push_back(tenant_id))) { LOG_WARN("add seed tenant_id failed", KR(ret)); break; } } else { uint64_t tenant_id = OB_INVALID_TENANT_ID; if (OB_SYS_TENANT_ID != item->exec_tenant_id_) { tenant_id = item->exec_tenant_id_; } else { if (OB_FAIL(schema_guard.get_tenant_id( ObString(item->tenant_name_.ptr()), tenant_id)) || OB_INVALID_ID == tenant_id) { ret = OB_ERR_INVALID_TENANT_NAME; LOG_WARN("get_tenant_id failed", KR(ret), "tenant", item->tenant_name_); } } if (OB_SUCC(ret) && OB_FAIL(item->tenant_ids_.push_back(tenant_id))) { LOG_WARN("add tenant_id failed", K(tenant_id), KR(ret)); } } // else } // else } // if } else { // sys tenant try to modify configration(cluster level or sys tenant level) if (nullptr == cfg) { if (OB_ISNULL(ptr = ob_malloc(sizeof(ObServerConfigChecker), ObModIds::OB_RS_PARTITION_TABLE_TEMP))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory", KR(ret)); } else if (OB_ISNULL(cfg = new (ptr) ObServerConfigChecker)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("new cfg failed", KR(ret)); } } // if if (OB_SUCC(ret) && nullptr == tenant_cfg) { if (OB_ISNULL(cfg_ptr = ob_malloc(sizeof(ObTenantConfigChecker), ObModIds::OB_RS_PARTITION_TABLE_TEMP))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory", KR(ret)); } else if (OB_ISNULL(tenant_cfg = new (cfg_ptr) ObTenantConfigChecker())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("new tenant_cfg failed", KR(ret)); } } // if if (OB_SUCC(ret)) { ObConfigItem * const *sys_ci_ptr = cfg->get_container().get( ObConfigStringKey(item->name_.ptr())); ObConfigItem * const *tenant_ci_ptr = tenant_cfg->get_container().get( ObConfigStringKey(item->name_.ptr())); if (OB_NOT_NULL(sys_ci_ptr)) { ci = *sys_ci_ptr; } else if (OB_NOT_NULL(tenant_ci_ptr)) { ci = *tenant_ci_ptr; if (OB_FAIL(item->tenant_ids_.push_back(OB_SYS_TENANT_ID))) { LOG_WARN("add tenant_id failed", KR(ret)); } } else { ret = OB_ERR_SYS_CONFIG_UNKNOWN; LOG_WARN("can't found config item", KR(ret), "item", *item); } } // if } // else if (OB_SUCC(ret)) { const char *err = NULL; if (ci->is_not_editable() && !arg.is_inner_) { ret = OB_INVALID_CONFIG; //TODO: specific report not editable LOG_WARN("config is not editable", "item", *item, KR(ret)); } else if (!ci->set_value(item->value_.ptr())) { ret = OB_INVALID_CONFIG; LOG_WARN("invalid config", "item", *item, KR(ret)); } else if (!ci->check()) { ret = OB_INVALID_CONFIG; LOG_WARN("invalid value range", "item", *item, KR(ret)); } else if (!ctx_.root_service_->check_config(*ci, err)) { ret = OB_INVALID_CONFIG; LOG_WARN("invalid value range", "item", *item, KR(ret)); } if (OB_FAIL(ret)) { if (nullptr != err) { LOG_USER_ERROR(OB_INVALID_CONFIG, err); } } } // if } // else } // FOREACH_X if (nullptr != cfg) { cfg->~ObServerConfigChecker(); ob_free(cfg); cfg = nullptr; ptr = nullptr; } else if (nullptr != ptr) { ob_free(ptr); ptr = nullptr; } if (nullptr != tenant_cfg) { tenant_cfg->~ObTenantConfigChecker(); ob_free(tenant_cfg); tenant_cfg = nullptr; cfg_ptr = nullptr; } else if (nullptr != cfg_ptr) { ob_free(cfg_ptr); cfg_ptr = nullptr; } return ret; } int ObAdminSetConfig::update_config(obrpc::ObAdminSetConfigArg &arg, int64_t new_version) { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else { FOREACH_X(item, arg.items_, OB_SUCCESS == ret) { char svr_ip[OB_MAX_SERVER_ADDR_SIZE] = "ANY"; int64_t svr_port = 0; if (item->server_.is_valid()) { if (false == item->server_.ip_to_string(svr_ip, sizeof(svr_ip))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("convert server addr to ip failed", KR(ret), "server", item->server_); } else { svr_port = item->server_.get_port(); ObAddr addr; bool is_server_exist = false; if (false == addr.set_ip_addr(svr_ip, static_cast(svr_port))){ ret = OB_ERR_UNEXPECTED; LOG_WARN("set addr fail", KR(ret), "svr_ip", svr_ip, K(svr_port)); } else if (OB_FAIL(ctx_.server_mgr_->is_server_exist(addr, is_server_exist))) { LOG_WARN("check server exist fail", K(addr)); } else if (!is_server_exist) { ret = OB_INVALID_ARGUMENT; LOG_WARN("server is not exist", KR(ret), K(addr)); LOG_USER_ERROR(OB_INVALID_ARGUMENT, "server"); } } // else } // if if (OB_FAIL(ret)) { } else if (!item->zone_.is_empty()) { bool is_zone_exist = false; if (OB_FAIL(ctx_.zone_mgr_->check_zone_exist(item->zone_, is_zone_exist))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("check zone exist fail", KR(ret), "zone", item->zone_); } else if(!is_zone_exist) { ret = OB_INVALID_ARGUMENT; LOG_WARN("zone is not exist", KR(ret), "zone", item->zone_); LOG_USER_ERROR(OB_INVALID_ARGUMENT, "zone"); } } if (OB_FAIL(ret)) { } else if (item->tenant_ids_.size() > 0) { // tenant config ObDMLSqlSplicer dml; for (uint64_t tenant_id : item->tenant_ids_) { const char *table_name = (ObAdminSetConfig::OB_PARAMETER_SEED_ID == tenant_id ? OB_ALL_SEED_PARAMETER_TNAME : OB_TENANT_PARAMETER_TNAME); tenant_id = (ObAdminSetConfig::OB_PARAMETER_SEED_ID == tenant_id ? OB_SYS_TENANT_ID : tenant_id); uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id); dml.reset(); if (OB_FAIL(dml.add_pk_column("tenant_id", tenant_id)) || OB_FAIL(dml.add_pk_column("zone", item->zone_.ptr())) || OB_FAIL(dml.add_pk_column("svr_type", print_server_role(OB_SERVER))) || OB_FAIL(dml.add_pk_column(K(svr_ip))) || OB_FAIL(dml.add_pk_column(K(svr_port))) || OB_FAIL(dml.add_pk_column("name", item->name_.ptr())) || OB_FAIL(dml.add_column("data_type", "varchar")) || OB_FAIL(dml.add_column("value", item->value_.ptr())) || OB_FAIL(dml.add_column("info", item->comment_.ptr())) || OB_FAIL(dml.add_column("config_version", new_version))) { LOG_WARN("add column failed", KR(ret)); } else if (OB_FAIL(dml.get_values().append_fmt("usec_to_time(%ld)", new_version))) { LOG_WARN("append valued failed", KR(ret)); } else if (OB_FAIL(dml.add_column(false, "gmt_modified"))) { LOG_WARN("add column failed", KR(ret)); } else { int64_t affected_rows = 0; ObDMLExecHelper exec(*ctx_.sql_proxy_, exec_tenant_id); ObConfigItem *ci = nullptr; // tenant not exist in RS, use SYS instead omt::ObTenantConfigGuard tenant_config(TENANT_CONF(OB_SYS_TENANT_ID)); if (!tenant_config.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("failed to get tenant config",K(tenant_id), KR(ret)); } else if (OB_ISNULL(tenant_config->get_container().get( ObConfigStringKey(item->name_.ptr())))) { ret = OB_ERR_SYS_CONFIG_UNKNOWN; LOG_WARN("can't found config item", KR(ret), K(tenant_id), "item", *item); } else { ci = *(tenant_config->get_container().get( ObConfigStringKey(item->name_.ptr()))); if (OB_FAIL(dml.add_column("section", ci->section())) || OB_FAIL(dml.add_column("scope", ci->scope())) || OB_FAIL(dml.add_column("source", ci->source())) || OB_FAIL(dml.add_column("edit_level", ci->edit_level()))) { LOG_WARN("add column failed", KR(ret)); } else if (OB_FAIL(exec.exec_insert_update(table_name, dml, affected_rows))) { LOG_WARN("execute insert update failed", K(tenant_id), KR(ret), "item", *item); } else if (is_zero_row(affected_rows) || affected_rows > 2) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected affected rows", K(tenant_id), K(affected_rows), KR(ret)); } } } if (OB_FAIL(ret)) { break; } } // for } else { // sys config ObDMLSqlSplicer dml; dml.reset(); if (OB_SYS_TENANT_ID != item->exec_tenant_id_) { uint64_t tenant_id = item->exec_tenant_id_; ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected tenant_id", K(tenant_id), KR(ret)); } else if (OB_FAIL(dml.add_pk_column("zone", item->zone_.ptr())) || OB_FAIL(dml.add_pk_column("svr_type", print_server_role(OB_SERVER))) || OB_FAIL(dml.add_pk_column(K(svr_ip))) || OB_FAIL(dml.add_pk_column(K(svr_port))) || OB_FAIL(dml.add_pk_column("name", item->name_.ptr())) || OB_FAIL(dml.add_column("data_type", "varchar")) || OB_FAIL(dml.add_column("value", item->value_.ptr())) || OB_FAIL(dml.add_column("info", item->comment_.ptr())) || OB_FAIL(dml.add_column("config_version", new_version))) { LOG_WARN("add column failed", KR(ret)); } else if (OB_FAIL(dml.get_values().append_fmt("usec_to_time(%ld)", new_version))) { LOG_WARN("append valued failed", KR(ret)); } else if (OB_FAIL(dml.add_column(false, "gmt_modified"))) { LOG_WARN("add column failed", KR(ret)); } else { int64_t affected_rows = 0; ObDMLExecHelper exec(*ctx_.sql_proxy_, OB_SYS_TENANT_ID); ObConfigItem *ci = nullptr; ObConfigItem *const *ci_ptr = GCONF.get_container().get( ObConfigStringKey(item->name_.ptr())); if (OB_ISNULL(ci_ptr)) { ret = OB_ERR_SYS_CONFIG_UNKNOWN; LOG_WARN("can't found config item", KR(ret), "item", *item); } else { ci = *ci_ptr; if (OB_FAIL(dml.add_column("section", ci->section())) || OB_FAIL(dml.add_column("scope", ci->scope())) || OB_FAIL(dml.add_column("source", ci->source())) || OB_FAIL(dml.add_column("edit_level", ci->edit_level()))) { LOG_WARN("add column failed", KR(ret)); } else if (OB_FAIL(exec.exec_insert_update(OB_ALL_SYS_PARAMETER_TNAME, dml, affected_rows))) { LOG_WARN("execute insert update failed", KR(ret), "item", *item); } else if (is_zero_row(affected_rows) || affected_rows > 2) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected affected rows", K(affected_rows), KR(ret)); } } // else } // else } // else sys config } // FOREACH_X } if (OB_SUCC(ret)) { FOREACH_X(item, arg.items_, OB_SUCCESS == ret) { if (item->tenant_ids_.size() > 0) { for (uint64_t tenant_id : item->tenant_ids_) { if (ObAdminSetConfig::OB_PARAMETER_SEED_ID == tenant_id) { } else if (OB_FAIL(OTC_MGR.set_tenant_config_version(tenant_id, new_version))) { LOG_WARN("failed to set tenant config version", K(tenant_id), KR(ret)); } else if(GCTX.omt_->has_tenant(tenant_id) && OB_FAIL(OTC_MGR.got_version(tenant_id, new_version))) { LOG_WARN("failed to got version", K(tenant_id), KR(ret)); } if (OB_FAIL(ret)) { break; } } // for } else { if (OB_FAIL(ctx_.zone_mgr_->update_config_version(new_version))) { LOG_WARN("set new config version failed", KR(ret), K(new_version)); } else if (OB_FAIL(ctx_.config_mgr_->got_version(new_version))) { LOG_WARN("config mgr got version failed", KR(ret), K(new_version)); } } } // FOREACH_X } // if return ret; } int ObAdminSetConfig::execute(obrpc::ObAdminSetConfigArg &arg) { LOG_INFO("execute set config request", K(arg)); int ret = OB_SUCCESS; int64_t config_version = 0; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else if (OB_FAIL(verify_config(arg))) { LOG_WARN("verify config failed", KR(ret), K(arg)); } else if (OB_FAIL(ctx_.zone_mgr_->get_config_version(config_version))) { LOG_WARN("get_config_version failed", KR(ret)); } else { const int64_t now = ObTimeUtility::current_time(); const int64_t new_version = std::max(config_version + 1, now); if (OB_FAIL(ctx_.root_service_->set_config_pre_hook(arg))) { LOG_WARN("fail to process pre hook", K(arg), KR(ret)); } else if (OB_FAIL(update_config(arg, new_version))) { LOG_WARN("update config failed", KR(ret), K(arg)); } else if (OB_ISNULL(ctx_.root_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("error inner stat", KR(ret), K(ctx_.root_service_)); } else if (OB_FAIL(ctx_.root_service_->set_config_post_hook(arg))) { LOG_WARN("fail to set config callback", KR(ret)); } else { LOG_INFO("get new config version", K(new_version), K(arg)); } } return ret; } int ObAdminMigrateUnit::execute(const ObAdminMigrateUnitArg &arg) { int ret = OB_SUCCESS; LOG_INFO("execute migrate unit request", K(arg)); if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else { const uint64_t unit_id = arg.unit_id_; const ObAddr &dst = arg.destination_; if (OB_FAIL(ctx_.unit_mgr_->admin_migrate_unit(unit_id, dst, arg.is_cancel_))) { LOG_WARN("migrate unit failed", K(unit_id), K(dst), KR(ret)); } else { ctx_.root_balancer_->wakeup(); } } return ret; } int ObAdminUpgradeVirtualSchema::execute() { int ret = OB_SUCCESS; LOG_INFO("execute upgrade virtual schema request"); int64_t upgrade_cnt = 0; ObSchemaGetterGuard schema_guard; ObArray tenant_ids; if (OB_UNLIKELY(!ctx_.is_inited())) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (GCTX.is_standby_cluster()) { // standby cluster cannot upgrade virtual schema independently, // need to get these information from the primary cluster ret = OB_OP_NOT_ALLOW; LOG_WARN("upgrade virtual schema in standby cluster not allow", KR(ret)); LOG_USER_ERROR(OB_OP_NOT_ALLOW, "upgrade virtual schema in standby cluster"); } else if (OB_ISNULL(ctx_.root_inspection_) || OB_ISNULL(ctx_.ddl_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ptr is null", KR(ret), KP(ctx_.root_inspection_), KP(ctx_.ddl_service_)); } else if (OB_FAIL(ctx_.ddl_service_->get_tenant_schema_guard_with_version_in_inner_table( OB_SYS_TENANT_ID, schema_guard))) { LOG_WARN("get_schema_guard failed", KR(ret)); } else if (OB_FAIL(schema_guard.get_tenant_ids(tenant_ids))) { LOG_WARN("fail to get tenant ids", KR(ret)); } else { FOREACH(tenant_id, tenant_ids) { // ignore ret int tmp_ret = OB_SUCCESS; if (OB_SUCCESS != (tmp_ret = execute_(*tenant_id, upgrade_cnt))) { LOG_WARN("fail to execute upgrade virtual table by tenant", KR(tmp_ret), K(*tenant_id)); } ret = OB_SUCC(ret) ? tmp_ret : ret; } } if (OB_SUCC(ret) && upgrade_cnt > 0) { // if schema upgraded, inspect schema again int tmp_ret = ctx_.root_inspection_->check_all(); if (OB_SUCCESS != tmp_ret) { LOG_WARN("root inspection failed", KR(tmp_ret)); } } return ret; } int ObAdminUpgradeVirtualSchema::execute_( const uint64_t tenant_id, int64_t &upgrade_cnt) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!ctx_.is_inited())) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (OB_UNLIKELY( is_virtual_tenant_id(tenant_id) || OB_INVALID_TENANT_ID == tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id)); } else if (OB_ISNULL(ctx_.root_inspection_) || OB_ISNULL(ctx_.ddl_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ptr is null", KR(ret), KP(ctx_.root_inspection_), KP(ctx_.ddl_service_)); } const schema_create_func *creator_ptr_array[] = { share::virtual_table_schema_creators, share::sys_view_schema_creators, NULL }; ObArray hard_code_tables; ObTableSchema table_schema; for (const schema_create_func **creator_ptr_ptr = creator_ptr_array; OB_SUCC(ret) && OB_NOT_NULL(*creator_ptr_ptr); ++creator_ptr_ptr) { for (const schema_create_func *creator_ptr = *creator_ptr_ptr; OB_SUCC(ret) && OB_NOT_NULL(*creator_ptr); ++creator_ptr) { table_schema.reset(); bool exist = false; if (OB_FAIL((*creator_ptr)(table_schema))) { LOG_WARN("create table schema failed", KR(ret)); } else if (!is_sys_tenant(tenant_id) && OB_FAIL(ObSchemaUtils::construct_tenant_space_full_table( tenant_id, table_schema))) { LOG_WARN("fail to construct tenant space table", KR(ret), K(tenant_id)); } else if (OB_FAIL(ObSysTableChecker::is_inner_table_exist( tenant_id, table_schema, exist))) { LOG_WARN("fail to check inner table exist", KR(ret), K(tenant_id), K(table_schema)); } else if (!exist) { // skip } else if (is_sys_table(table_schema.get_table_id())) { // only check and upgrade virtual table && sys views } else if (OB_FAIL(hard_code_tables.push_back(table_schema))) { LOG_WARN("push_back failed", KR(ret), K(tenant_id)); } } } // remove tables not exist on hard code tables ObSchemaGetterGuard schema_guard; ObArray in_mem_tables; if (FAILEDx(ctx_.ddl_service_->get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { LOG_WARN("get_schema_guard failed", KR(ret), K(tenant_id)); } else if (OB_FAIL(schema_guard.get_table_schemas_in_tenant(tenant_id, in_mem_tables))) { LOG_WARN("get_table_schemas_in_tenant failed", KR(ret), K(tenant_id)); } else { FOREACH_CNT_X(in_mem_table, in_mem_tables, OB_SUCC(ret)) { if (OB_ISNULL(in_mem_table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("in mem table is null", KR(ret), K(tenant_id)); } else if (!is_inner_table((*in_mem_table)->get_table_id()) || is_sys_table((*in_mem_table)->get_table_id())) { continue; } bool exist = false; FOREACH_CNT_X(hard_code_table, hard_code_tables, OB_SUCC(ret) && !exist) { if (OB_ISNULL(hard_code_table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("hard code table is null", KR(ret), K(tenant_id)); } else if ((*in_mem_table)->get_table_id() == hard_code_table->get_table_id()) { exist = true; } } if (!exist) { if (FAILEDx(ctx_.ddl_service_->drop_inner_table(**in_mem_table))) { LOG_WARN("drop table schema failed", KR(ret), K(tenant_id), KPC(*in_mem_table)); } else if (OB_FAIL(ctx_.ddl_service_->refresh_schema(tenant_id))) { LOG_WARN("refresh_schema failed", KR(ret), K(tenant_id)); } } } } // upgrade tables FOREACH_CNT_X(hard_code_table, hard_code_tables, OB_SUCC(ret)) { if (OB_ISNULL(hard_code_table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("hard code table is null", KR(ret), K(tenant_id)); } else if (OB_FAIL(ctx_.root_inspection_->check_table_schema(tenant_id, *hard_code_table))) { if (OB_SCHEMA_ERROR != ret) { LOG_WARN("check table schema failed", KR(ret), K(tenant_id), K(*hard_code_table)); } else { LOG_INFO("table schema need upgrade", K(tenant_id), K(*hard_code_table)); if (OB_FAIL(upgrade_(tenant_id, *hard_code_table))) { LOG_WARN("upgrade failed", KR(ret), K(tenant_id), K(*hard_code_table)); } else { LOG_INFO("update table schema success", K(tenant_id), K(*hard_code_table)); upgrade_cnt++; } } } } return ret; } int ObAdminUpgradeVirtualSchema::upgrade_( const uint64_t tenant_id, share::schema::ObTableSchema &table) { int ret = OB_SUCCESS; const ObTableSchema *exist_schema = NULL; ObSchemaGetterGuard schema_guard; if (OB_UNLIKELY(!ctx_.is_inited())) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (OB_UNLIKELY( is_virtual_tenant_id(tenant_id) || OB_INVALID_TENANT_ID == tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id)); } else if (OB_UNLIKELY( !table.is_valid() || is_sys_table(table.get_table_id()) || table.get_tenant_id() != tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid table", KR(ret), K(tenant_id), K(table)); } else if (OB_ISNULL(ctx_.ddl_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ddl service is null", KR(ret)); } // 1. check table name duplicated if (FAILEDx(ctx_.ddl_service_->get_tenant_schema_guard_with_version_in_inner_table( tenant_id, schema_guard))) { LOG_WARN("get schema guard in inner table failed", KR(ret), K(tenant_id)); } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table.get_database_id(), table.get_table_name(), table.is_index_table(), exist_schema))) { LOG_WARN("get table schema failed", KR(ret), K(tenant_id), "table", table.get_table_name()); if (OB_TABLE_NOT_EXIST == ret) { ret = OB_SUCCESS; } } else if (OB_ISNULL(exist_schema)) { // no duplicate table name } else if (OB_FAIL(ctx_.ddl_service_->drop_inner_table(*exist_schema))) { LOG_WARN("get table schema failed", KR(ret), K(tenant_id), "table", table.get_table_name(), "table_id", table.get_table_id()); } else if (OB_FAIL(ctx_.ddl_service_->get_tenant_schema_guard_with_version_in_inner_table( tenant_id, schema_guard))) { LOG_WARN("get schema guard in inner table failed", KR(ret), K(tenant_id)); } // 2. try drop table first exist_schema = NULL; if (FAILEDx(schema_guard.get_table_schema(tenant_id, table.get_table_id(), exist_schema))) { LOG_WARN("get table schema failed", KR(ret), "table", table.get_table_name(), "table_id", table.get_table_id()); if (OB_TABLE_NOT_EXIST == ret) { ret = OB_SUCCESS; } } else if (OB_ISNULL(exist_schema)) { // missed table } else if (OB_FAIL(ctx_.ddl_service_->drop_inner_table(*exist_schema))) { LOG_WARN("drop table schema failed", KR(ret), "table_schema", *exist_schema); } else if (OB_FAIL(ctx_.ddl_service_->get_tenant_schema_guard_with_version_in_inner_table( tenant_id, schema_guard))) { LOG_WARN("get schema guard in inner table failed", KR(ret), K(tenant_id)); } // 3. create table if (FAILEDx(ctx_.ddl_service_->add_table_schema(table, schema_guard))) { LOG_WARN("add table schema failed", KR(ret), K(tenant_id), K(table)); } else if (OB_FAIL(ctx_.ddl_service_->refresh_schema(tenant_id))) { LOG_WARN("refresh schema failed", KR(ret), K(tenant_id)); } return ret; } int ObAdminUpgradeCmd::execute(const Bool &upgrade) { int ret = OB_SUCCESS; char min_server_version[OB_SERVER_VERSION_LENGTH]; uint64_t current_version = 0; if (OB_FAIL(ctx_.server_mgr_->get_min_server_version(min_server_version))) { LOG_WARN("failed to get the min server version", KR(ret)); } else if (OB_FAIL(ObClusterVersion::get_version(min_server_version, current_version))) { LOG_WARN("fail to parse current version", KR(ret), K(min_server_version)); } else { // set min_observer_version and enable_upgrade_mode HEAP_VAR(ObAdminSetConfigItem, item) { obrpc::ObAdminSetConfigArg set_config_arg; set_config_arg.is_inner_ = true; const char *min_obs_version_name = "min_observer_version"; const char *enable_upgrade_name = "enable_upgrade_mode"; ObAdminSetConfig admin_set_config(ctx_); if (OB_FAIL(item.name_.assign(min_obs_version_name))) { LOG_WARN("assign min_observer_version config name failed", KR(ret)); } else if (OB_FAIL(item.value_.assign(min_server_version))) { LOG_WARN("assign min_observer_version config value failed", KR(ret)); } else if (OB_FAIL(set_config_arg.items_.push_back(item))) { LOG_WARN("add min_observer_version config item failed", KR(ret)); } else if (OB_FAIL(item.name_.assign(enable_upgrade_name))) { LOG_WARN("assign enable_upgrade_mode config name failed", KR(ret)); } else if (OB_FAIL(item.value_.assign((upgrade ? "true" : "false")))) { LOG_WARN("assign enable_upgrade_mode config value failed", KR(ret)); } else if (OB_FAIL(set_config_arg.items_.push_back(item))) { LOG_WARN("add enable_upgrade_mode config item failed", KR(ret)); } else if (current_version >= CLUSTER_VERSION_2250) { const char *upgrade_stage_name = "_upgrade_stage"; obrpc::ObUpgradeStage stage = upgrade ? obrpc::OB_UPGRADE_STAGE_PREUPGRADE : obrpc::OB_UPGRADE_STAGE_NONE; if (OB_FAIL(item.name_.assign(upgrade_stage_name))) { LOG_WARN("assign _upgrade_stage config name failed", KR(ret), K(upgrade)); } else if (OB_FAIL(item.value_.assign(obrpc::get_upgrade_stage_str(stage)))) { LOG_WARN("assign _upgrade_stage config value failed", KR(ret), K(stage), K(upgrade)); } else if (OB_FAIL(set_config_arg.items_.push_back(item))) { LOG_WARN("add _upgrade_stage config item failed", KR(ret), K(stage), K(upgrade)); } } if (OB_FAIL(ret)) { } else if (admin_set_config.execute(set_config_arg)) { LOG_WARN("execute set config failed", KR(ret)); } else { LOG_INFO("change upgrade parameters", "min_observer_version", min_server_version, "enable_upgrade_mode", upgrade, "in_major_version_upgrade_mode", GCONF.in_major_version_upgrade_mode()); } } } return ret; } int ObAdminRollingUpgradeCmd::execute(const obrpc::ObAdminRollingUpgradeArg &arg) { int ret = OB_SUCCESS; HEAP_VAR(ObAdminSetConfigItem, upgrade_stage_item) { obrpc::ObAdminSetConfigArg set_config_arg; set_config_arg.is_inner_ = true; const char *upgrade_stage_name = "_upgrade_stage"; ObAdminSetConfig admin_set_config(ctx_); if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", KR(ret), K(arg)); } else if (OB_FAIL(upgrade_stage_item.name_.assign(upgrade_stage_name))) { LOG_WARN("assign _upgrade_stage config name failed", KR(ret), K(arg)); } else if (OB_FAIL(upgrade_stage_item.value_.assign(obrpc::get_upgrade_stage_str(arg.stage_)))) { LOG_WARN("assign _upgrade_stage config value failed", KR(ret), K(arg)); } else if (OB_FAIL(set_config_arg.items_.push_back(upgrade_stage_item))) { LOG_WARN("add _upgrade_stage config item failed", KR(ret), K(arg)); } else if (admin_set_config.execute(set_config_arg)) { LOG_WARN("execute set config failed", KR(ret)); } else { LOG_INFO("change upgrade parameters", KR(ret), "_upgrade_stage", arg.stage_); } } return ret; } DEFINE_ENUM_FUNC(ObInnerJob, inner_job, OB_INNER_JOB_DEF); int ObAdminRunJob::execute(const ObRunJobArg &arg) { int ret = OB_SUCCESS; ObInnerJob job = INVALID_INNER_JOB; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else if (INVALID_INNER_JOB == (job = get_inner_job_value(arg.job_))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid inner job", K(arg), KR(ret)); } else { switch(job) { case CHECK_PARTITION_TABLE: { ObAdminCheckPartitionTable job_executor(ctx_); if (OB_FAIL(job_executor.execute(arg))) { LOG_WARN("execute job failed", K(arg), KR(ret)); } break; } case ROOT_INSPECTION: { ObAdminRootInspection job_executor(ctx_); if (OB_FAIL(job_executor.execute(arg))) { LOG_WARN("execute job failed", K(arg), KR(ret)); } break; } case UPGRADE_STORAGE_FORMAT_VERSION: case STOP_UPGRADE_STORAGE_FORMAT_VERSION: { ObAdminUpgradeStorageFormatVersionExecutor job_executor(ctx_); if (OB_FAIL(job_executor.execute(arg))) { LOG_WARN("fail to execute upgrade storage format version job", KR(ret)); } break; } case CREATE_INNER_SCHEMA: { ObAdminCreateInnerSchema job_executor(ctx_); if (OB_FAIL(job_executor.execute(arg))) { LOG_WARN("execute job failed", KR(ret)); } break; } case IO_CALIBRATION: { ObAdminIOCalibration job_executor(ctx_); if (OB_FAIL(job_executor.execute(arg))) { LOG_WARN("execute job failed", KR(ret)); } break; } default: { ret = OB_ERR_UNEXPECTED; LOG_WARN("not known job", K(job), KR(ret)); break; } } } return ret; } int ObAdminCheckPartitionTable::execute(const obrpc::ObRunJobArg &arg) { UNUSEDx(arg); return OB_NOT_SUPPORTED; } int ObAdminCheckPartitionTable::call_server(const ObAddr &server) { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!server.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid server", K(server), KR(ret)); } else if (OB_FAIL(ctx_.rpc_proxy_->to(server).check_partition_table())) { LOG_WARN("request check partition table failed", KR(ret), K(server)); } return ret; } int ObAdminCreateInnerSchema::execute(const obrpc::ObRunJobArg &arg) { int ret = OB_SUCCESS; LOG_INFO("execute create inner role request", KR(ret)); if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(arg)); } else if (CREATE_INNER_SCHEMA != get_inner_job_value(arg.job_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("job to run not create inner role", KR(ret), K(arg)); } else if (OB_UNLIKELY(nullptr == ctx_.root_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("root service ptr is null", KR(ret)); } else if (OB_FAIL(ctx_.root_service_->submit_create_inner_schema_task())) { LOG_WARN("fail to submit create inner role task", KR(ret)); } return ret; } int ObAdminIOCalibration::execute(const obrpc::ObRunJobArg &arg) { int ret = OB_SUCCESS; LOG_INFO("execute io calibration quest", KR(ret)); if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(arg)); } else if (IO_CALIBRATION != get_inner_job_value(arg.job_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected job type", KR(ret), K(arg)); } else if (OB_FAIL(call_all(arg))) { LOG_WARN("call all server failed", K(ret), K(arg)); } return ret; } int ObAdminIOCalibration::call_server(const common::ObAddr &server) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!ctx_.is_inited())) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); } else if (OB_UNLIKELY(!server.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid server", K(server), K(ret)); } else if (OB_FAIL(ctx_.rpc_proxy_->to(server).execute_io_benchmark())) { LOG_WARN("request io calibration failed", KR(ret), K(server)); } return ret; } int ObAdminRefreshIOCalibration::execute(const obrpc::ObAdminRefreshIOCalibrationArg &arg) { int ret = OB_SUCCESS; ObArray server_list; if (OB_UNLIKELY(!ctx_.is_inited())) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); } else if (OB_UNLIKELY(!arg.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(arg)); } else if (OB_FAIL(get_server_list(arg, server_list))) { LOG_WARN("get server list failed", K(ret), K(arg)); } else if (arg.only_refresh_) { // do nothing } else { ObIOAbility io_ability; for (int64_t i = 0; OB_SUCC(ret) && i < arg.calibration_list_.count(); ++i) { const ObIOBenchResult &item = arg.calibration_list_.at(i); if (OB_FAIL(io_ability.add_measure_item(item))) { LOG_WARN("add item failed", K(ret), K(item)); } } if (OB_SUCC(ret)) { if (arg.calibration_list_.count() > 0 && !io_ability.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid calibration list", K(ret), K(arg), K(io_ability)); } } if (OB_SUCC(ret)) { ObMySQLTransaction trans; if (OB_FAIL(trans.start(ctx_.sql_proxy_, OB_SYS_TENANT_ID))) { LOG_WARN("start transaction failed", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < server_list.count(); ++i) { if (OB_FAIL(ObIOCalibration::get_instance().write_into_table(trans, server_list.at(i), io_ability))) { LOG_WARN("write io ability failed", K(ret), K(io_ability), K(server_list.at(i))); } } bool is_commit = OB_SUCCESS == ret; int tmp_ret = trans.end(is_commit); if (OB_UNLIKELY(OB_SUCCESS != tmp_ret)) { LOG_WARN("end transaction failed", K(tmp_ret), K(is_commit)); ret = OB_SUCC(ret) ? tmp_ret : ret; } } } } if (OB_SUCC(ret)) { ObRefreshIOCalibrationArg refresh_arg; refresh_arg.storage_name_ = arg.storage_name_; refresh_arg.only_refresh_ = arg.only_refresh_; if (OB_FAIL(refresh_arg.calibration_list_.assign(arg.calibration_list_))) { LOG_WARN("assign calibration list failed", K(ret), K(arg.calibration_list_)); } else { int64_t succ_count = 0; FOREACH_CNT(server, server_list) { int tmp_ret = ctx_.rpc_proxy_->to(*server).refresh_io_calibration(refresh_arg); if (OB_UNLIKELY(OB_SUCCESS != tmp_ret)) { LOG_WARN("request io calibration failed", KR(tmp_ret), K(*server), K(refresh_arg)); } else { ++succ_count; } } if (server_list.count() != succ_count) { ret = OB_PARTIAL_FAILED; LOG_USER_ERROR(OB_PARTIAL_FAILED); } } } LOG_INFO("admin refresh io calibration", K(ret), K(arg), K(server_list)); return ret; } int ObAdminRefreshIOCalibration::call_server(const common::ObAddr &server) { // should never go here UNUSED(server); return OB_NOT_SUPPORTED; } int ObAdminRootInspection::execute(const obrpc::ObRunJobArg &arg) { int ret = OB_SUCCESS; LOG_INFO("execute root inspection request", K(arg)); if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else if (ROOT_INSPECTION != get_inner_job_value(arg.job_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("job to run not root inspection", K(arg), KR(ret)); } else if (!ctx_.server_mgr_->is_inited()) { ret = OB_INNER_STAT_ERROR; LOG_WARN("server_mgr_ not inited", KR(ret)); } else if (!ctx_.root_inspection_->is_inited()) { ret = OB_INNER_STAT_ERROR; LOG_WARN("root_inspection not inited", KR(ret)); } else if (!arg.zone_.is_empty()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("root inspection can't execute by zone", K(arg), KR(ret)); } else if (arg.server_.is_valid() && arg.server_ != ctx_.server_mgr_->get_rs_addr()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("only rs can execute root inspection", K(arg), "rs", ctx_.server_mgr_->get_rs_addr(), KR(ret)); } else if (OB_FAIL(ctx_.root_inspection_->check_all())) { LOG_WARN("root_inspection check_all failed", KR(ret)); } return ret; } int ObAdminUpgradeStorageFormatVersionExecutor::execute(const obrpc::ObRunJobArg &arg) { int ret = OB_SUCCESS; ObInnerJob job = INVALID_INNER_JOB; LOG_INFO("execute upgrade storage format version request", K(arg)); if (OB_UNLIKELY(!ctx_.is_inited())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("ObAdminUpgradeStorageFormatVersionExecutor has not been inited", KR(ret)); } else if (OB_UNLIKELY(!arg.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", KR(ret), K(arg)); } else { job = get_inner_job_value(arg.job_); if (UPGRADE_STORAGE_FORMAT_VERSION == job) { if (OB_ISNULL(ctx_.root_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("error unexpected, root service must not be NULL", KR(ret)); } else if (OB_FAIL(ctx_.root_service_->submit_upgrade_storage_format_version_task())) { LOG_WARN("fail to submit upgrade storage format version task", KR(ret)); } } else if (STOP_UPGRADE_STORAGE_FORMAT_VERSION == job) { if (OB_ISNULL(ctx_.upgrade_storage_format_executor_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("executor is null", KR(ret)); } else if (OB_FAIL(ctx_.upgrade_storage_format_executor_->stop())) { LOG_WARN("fail to stop upgrade_storage_format task", KR(ret)); } else { ctx_.upgrade_storage_format_executor_->start(); } } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid job type", KR(ret), K(job)); } } return ret; } int ObAdminFlushCache::execute(const obrpc::ObAdminFlushCacheArg &arg) { int ret = OB_SUCCESS; int64_t tenant_num = arg.tenant_ids_.count(); ObSEArray server_list; ObFlushCacheArg fc_arg; // fine-grained plan evict only will pass this way. // This because fine-grained plan evict must specify tenant // if tenant num is 0, flush all tenant, else, flush appointed tenant if (tenant_num != 0) { //flush appointed tenant for (int64_t i = 0; OB_SUCC(ret) && i < tenant_num; ++i) { //get tenant server list; if (OB_FAIL(get_tenant_servers(arg.tenant_ids_.at(i), server_list))) { LOG_WARN("fail to get tenant servers", "tenant_id", arg.tenant_ids_.at(i)); } else { //call tenant servers; fc_arg.is_all_tenant_ = false; fc_arg.cache_type_ = arg.cache_type_; fc_arg.ns_type_ = arg.ns_type_; // fine-grained plan evict args if (arg.is_fine_grained_) { fc_arg.sql_id_ = arg.sql_id_; fc_arg.is_fine_grained_ = arg.is_fine_grained_; for(int64_t j=0; OB_SUCC(ret) && j &servers) { int ret = OB_SUCCESS; // sys tenant, get all servers directly if (OB_SYS_TENANT_ID == tenant_id) { if (OB_FAIL(get_all_servers(servers))) { LOG_WARN("fail to get all servers", KR(ret)); } } else { ObArray pool_ids; if (OB_ISNULL(ctx_.server_mgr_) || OB_ISNULL(ctx_.unit_mgr_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ctx_.server_mgr_), K(ctx_.unit_mgr_), KR(ret)); } else if (!ctx_.server_mgr_->has_build() || !ctx_.unit_mgr_->check_inner_stat()) { ret = OB_SERVER_IS_INIT; LOG_WARN("server manager or unit manager hasn't built", "server_mgr built", ctx_.server_mgr_->has_build(), "unit_mgr built", ctx_.unit_mgr_->check_inner_stat(), KR(ret)); } else if (OB_FAIL(ctx_.unit_mgr_->get_pool_ids_of_tenant(tenant_id, pool_ids))) { LOG_WARN("get_pool_ids_of_tenant failed", K(tenant_id), KR(ret)); } else { ObArray unit_infos; for (int64_t i = 0; OB_SUCC(ret) && i < pool_ids.count(); ++i) { unit_infos.reuse(); if (OB_FAIL(ctx_.unit_mgr_->get_unit_infos_of_pool(pool_ids.at(i), unit_infos))) { LOG_WARN("get_unit_infos_of_pool failed", "pool_id", pool_ids.at(i), KR(ret)); } else { for (int64_t j = 0; OB_SUCC(ret) && j < unit_infos.count(); ++j) { bool is_alive = false; const ObUnit &unit = unit_infos.at(j).unit_; if (OB_FAIL(ctx_.server_mgr_->check_server_alive(unit.server_, is_alive))) { LOG_WARN("check_server_alive failed", "server", unit.server_, KR(ret)); } else if (is_alive) { if (OB_FAIL(servers.push_back(unit.server_))) { LOG_WARN("push_back failed", KR(ret)); } } if (OB_SUCC(ret)) { if (unit.migrate_from_server_.is_valid()) { if (OB_FAIL(ctx_.server_mgr_->check_server_alive( unit.migrate_from_server_, is_alive))) { LOG_WARN("check_server_alive failed", "server", unit.migrate_from_server_, KR(ret)); } else if (is_alive) { if (OB_FAIL(servers.push_back(unit.migrate_from_server_))) { LOG_WARN("push_back failed", KR(ret)); } } } } } // for unit infos end } } // for pool ids end } } return ret; } int ObTenantServerAdminUtil::get_all_servers(common::ObIArray &servers) { int ret = OB_SUCCESS; ObZone empty_zone; if (OB_ISNULL(ctx_.server_mgr_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ctx_.server_mgr_), KR(ret)); } else if (OB_FAIL(ctx_.server_mgr_->get_alive_servers(empty_zone, servers))){ //if zone is empty, get all servers LOG_WARN("fail to get all servers", KR(ret)); } return ret; } int ObAdminFlushCache::call_server(const common::ObAddr &server, const obrpc::ObFlushCacheArg &arg) { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!server.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid server", K(server), KR(ret)); } else if (OB_FAIL(ctx_.rpc_proxy_->to(server).flush_cache(arg))) { LOG_WARN("request server flush cache failed", KR(ret), K(server)); } return ret; } int ObAdminSetTP::execute(const obrpc::ObAdminSetTPArg &arg) { LOG_INFO("start execute set_tp request", K(arg)); int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!arg.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(arg), KR(ret)); } else if (OB_FAIL(call_all(arg))) { LOG_WARN("execute report replica failed", KR(ret), K(arg)); } LOG_INFO("end execute set_tp request", K(arg)); return ret; } int ObAdminSetTP::call_server(const ObAddr &server) { int ret = OB_SUCCESS; if (!ctx_.is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", KR(ret)); } else if (!server.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid server", K(server), KR(ret)); } else if (OB_FAIL(ctx_.rpc_proxy_->to(server).set_tracepoint(arg_))) { LOG_WARN("request server report replica failed", KR(ret), K(server)); } return ret; } } // end namespace rootserver } // end namespace oceanbase