diff --git a/src/observer/ob_rpc_processor_simple.cpp b/src/observer/ob_rpc_processor_simple.cpp index 68f70b137a..d477548712 100644 --- a/src/observer/ob_rpc_processor_simple.cpp +++ b/src/observer/ob_rpc_processor_simple.cpp @@ -465,7 +465,7 @@ int ObRpcBuildDDLSingleReplicaRequestP::process() ret = OB_INVALID_ARGUMENT; LOG_ERROR("invalid arguments", K(ret), KP(gctx_.ob_service_)); } else { - ret = gctx_.ob_service_->build_ddl_single_replica_request(arg_); + ret = gctx_.ob_service_->build_ddl_single_replica_request(arg_, result_); } return ret; } diff --git a/src/observer/ob_server.cpp b/src/observer/ob_server.cpp index 1d8fcf2566..398d5dc69a 100644 --- a/src/observer/ob_server.cpp +++ b/src/observer/ob_server.cpp @@ -71,7 +71,6 @@ #include "sql/ob_sql_init.h" #include "sql/ob_sql_task.h" #include "storage/ob_i_store.h" -#include "storage/ob_long_ops_monitor.h" #include "storage/compaction/ob_sstable_merge_info_mgr.h" #include "storage/tablelock/ob_table_lock_service.h" #include "storage/tx/ob_ts_mgr.h" @@ -97,6 +96,7 @@ #include "share/ash/ob_active_sess_hist_list.h" #include "share/ob_server_blacklist.h" #include "share/ob_primary_standby_service.h" // ObPrimaryStandbyService +#include "share/longops_mgr/ob_longops_mgr.h" #include "logservice/palf/election/interface/election.h" #include "storage/ddl/ob_ddl_redo_log_writer.h" @@ -149,7 +149,6 @@ ObServer::ObServer() scramble_rand_(), duty_task_(), sql_mem_task_(), - long_ops_task_(), ctas_clean_up_task_(), refresh_active_time_task_(), refresh_network_speed_task_(), @@ -329,8 +328,8 @@ int ObServer::init(const ObServerOptions &opts, const ObPLogWriterCfg &log_cfg) LOG_ERROR("set_use_rpc_table failed", KR(ret)); } else if (OB_FAIL(ObSysTaskStatMgr::get_instance().set_self_addr(self_addr_))) { LOG_ERROR("set sys task status self addr failed", KR(ret)); - } else if (OB_FAIL(LONG_OPS_MONITOR_INSTANCE.init())) { - LOG_ERROR("init long ops monitor instance failed", KR(ret)); + } else if (OB_FAIL(ObTableStoreStatMgr::get_instance().init())) { + LOG_ERROR("init table store stat mgr failed", KR(ret)); } else if (OB_FAIL(ObCompatModeGetter::instance().init(&sql_proxy_))) { LOG_ERROR("init get compat mode server failed",KR(ret)); } else if (OB_FAIL(table_service_.init(gctx_))) { @@ -369,6 +368,8 @@ int ObServer::init(const ObServerOptions &opts, const ObPLogWriterCfg &log_cfg) LOG_ERROR("init ASH failed", KR(ret)); } else if (OB_FAIL(ObServerBlacklist::get_instance().init(self_addr_, net_frame_.get_req_transport()))) { LOG_ERROR("init server blacklist failed", KR(ret)); + } else if (OB_FAIL(ObLongopsMgr::get_instance().init())) { + LOG_WARN("init longops mgr fail", KR(ret)); } else if (OB_FAIL(ObDDLRedoLogWriter::get_instance().init())) { LOG_WARN("init DDL redo log writer failed", KR(ret)); } else { @@ -1753,8 +1754,6 @@ int ObServer::init_multi_tenant() if (OB_SUCC(ret)) { if (OB_FAIL(duty_task_.schedule(lib::TGDefIDs::ServerGTimer))) { LOG_ERROR("schedule tenant duty task fail", KR(ret)); - } else if (OB_FAIL(long_ops_task_.init(&schema_service_, lib::TGDefIDs::ServerGTimer))) { - LOG_ERROR("fail to init create index task", KR(ret)); } else if (OB_FAIL(sql_mem_task_.schedule(lib::TGDefIDs::SqlMemTimer))) { LOG_ERROR("schedule tenant sql memory manager task fail", KR(ret)); } diff --git a/src/observer/ob_server.h b/src/observer/ob_server.h index cbf9449290..d72aa930c2 100644 --- a/src/observer/ob_server.h +++ b/src/observer/ob_server.h @@ -35,8 +35,7 @@ #include "pl/ob_pl.h" #include "storage/tx/wrs/ob_weak_read_service.h" // ObWeakReadService -#include "storage/tx/wrs/ob_black_list.h" // ObBLService -#include "storage/ob_long_ops_monitor.h" +#include "storage/tx/wrs/ob_black_list.h" #include "storage/ob_partition_component_factory.h" #include "rootserver/ob_root_service.h" @@ -393,7 +392,6 @@ private: common::ObMysqlRandom scramble_rand_; ObTenantDutyTask duty_task_; ObTenantSqlMemoryTimerTask sql_mem_task_; - storage::ObPurgeCompletedMonitorInfoTask long_ops_task_; ObCTASCleanUpTask ctas_clean_up_task_; // repeat & no retry ObRefreshTimeTask refresh_active_time_task_; // repeat & no retry ObRefreshNetworkSpeedTask refresh_network_speed_task_; // repeat & no retry diff --git a/src/observer/ob_service.cpp b/src/observer/ob_service.cpp index 408bae7c7c..3103e0a311 100644 --- a/src/observer/ob_service.cpp +++ b/src/observer/ob_service.cpp @@ -1989,7 +1989,8 @@ int ObService::broadcast_rs_list(const ObRsListArg &arg) return ret; } -int ObService::build_ddl_single_replica_request(const ObDDLBuildSingleReplicaRequestArg &arg) +int ObService::build_ddl_single_replica_request(const ObDDLBuildSingleReplicaRequestArg &arg, + ObDDLBuildSingleReplicaRequestResult &res) { int ret = OB_SUCCESS; LOG_INFO("receive build single replica request", K(arg)); @@ -2019,8 +2020,13 @@ int ObService::build_ddl_single_replica_request(const ObDDLBuildSingleReplicaReq } else if (OB_FAIL(dag_scheduler->add_dag(dag))) { saved_ret = ret; LOG_WARN("add dag failed", K(ret), K(arg)); + if (OB_EAGAIN == saved_ret) { + dag_scheduler->get_complement_data_dag_progress(dag, res.row_scanned_, res.row_inserted_); + } + } else { + dag = nullptr; } - if (OB_FAIL(ret) && OB_NOT_NULL(dag)) { + if (OB_NOT_NULL(dag)) { (void) dag->handle_init_failed_ret_code(ret); dag_scheduler->free_dag(*dag); dag = nullptr; diff --git a/src/observer/ob_service.h b/src/observer/ob_service.h index a174bcec2b..738c018c53 100644 --- a/src/observer/ob_service.h +++ b/src/observer/ob_service.h @@ -127,7 +127,7 @@ public: // ObRpcSwitchSchemaP @RS DDL int switch_schema(const obrpc::ObSwitchSchemaArg &arg, obrpc::ObSwitchSchemaResult &result); int calc_column_checksum_request(const obrpc::ObCalcColumnChecksumRequestArg &arg, obrpc::ObCalcColumnChecksumRequestRes &res); - int build_ddl_single_replica_request(const obrpc::ObDDLBuildSingleReplicaRequestArg &arg); + int build_ddl_single_replica_request(const obrpc::ObDDLBuildSingleReplicaRequestArg &arg, obrpc::ObDDLBuildSingleReplicaRequestResult &res); int write_ddl_sstable_commit_log(const obrpc::ObDDLWriteSSTableCommitLogArg &arg); int stop_partition_write(const obrpc::Int64 &switchover_timestamp, obrpc::Int64 &result); int check_partition_log(const obrpc::Int64 &switchover_timestamp, obrpc::Int64 &result); diff --git a/src/observer/virtual_table/ob_all_virtual_long_ops_status.cpp b/src/observer/virtual_table/ob_all_virtual_long_ops_status.cpp index acdf56a859..b14683774a 100644 --- a/src/observer/virtual_table/ob_all_virtual_long_ops_status.cpp +++ b/src/observer/virtual_table/ob_all_virtual_long_ops_status.cpp @@ -16,143 +16,118 @@ using namespace oceanbase::common; using namespace oceanbase::observer; -using namespace oceanbase::storage; +using namespace oceanbase::share; ObAllVirtualLongOpsStatus::ObAllVirtualLongOpsStatus() - : is_inited_(false), iter_(), ip_() + : ObVirtualTableScannerIterator(), + addr_(), longops_value_(), longops_iter_() { } -int ObAllVirtualLongOpsStatus::init() +ObAllVirtualLongOpsStatus::~ObAllVirtualLongOpsStatus() { - int ret = OB_SUCCESS; - if (OB_UNLIKELY(is_inited_)) { - ret = OB_INIT_TWICE; - LOG_WARN("ObAllVirtualLongOpsStatus has been inited twice", K(ret)); - } else if (OB_FAIL(iter_.init())) { - LOG_WARN("fail to init iterator", K(ret)); - } else if (!GCTX.self_addr().ip_to_string(ip_, sizeof(ip_))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fail to convert ip to string", K(ret), "addr", GCTX.self_addr()); - } else { - is_inited_ = true; - } - return ret; + reset(); } -int ObAllVirtualLongOpsStatus::convert_stat_to_row( - const ObILongOpsStat &stat, ObNewRow *&row) +void ObAllVirtualLongOpsStatus::reset() { - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("ObAllVirtualLongOpsStatus has not been inited", K(ret)); - } else if (OB_UNLIKELY(!stat.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(stat)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < output_column_ids_.count(); ++i) { - const uint64_t col_id = output_column_ids_.at(i); - switch (col_id) { - case OB_APP_MIN_COLUMN_ID: - // tenant id - cur_row_.cells_[i].set_int(stat.get_key().tenant_id_); - break; - case OB_APP_MIN_COLUMN_ID + 1: - // sid - cur_row_.cells_[i].set_int(stat.get_key().sid_); - break; - case OB_APP_MIN_COLUMN_ID + 2: - // op_name - cur_row_.cells_[i].set_varchar(stat.get_key().name_); - cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); - break; - case OB_APP_MIN_COLUMN_ID + 3: - // target - cur_row_.cells_[i].set_varchar(stat.get_key().target_); - cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); - break; - case OB_APP_MIN_COLUMN_ID + 4: - //svr_ip - cur_row_.cells_[i].set_varchar(ip_); - cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); - break; - case OB_APP_MIN_COLUMN_ID + 5: - // svr_port - cur_row_.cells_[i].set_int(GCTX.self_addr().get_port()); - break; - case OB_APP_MIN_COLUMN_ID + 6: - // start_time - cur_row_.cells_[i].set_int(stat.common_value_.start_time_); - break; - case OB_APP_MIN_COLUMN_ID + 7: - // finish_time - cur_row_.cells_[i].set_int(stat.common_value_.finish_time_); - break; - case OB_APP_MIN_COLUMN_ID + 8: - // elapsed_time - cur_row_.cells_[i].set_int(stat.common_value_.elapsed_time_); - break; - case OB_APP_MIN_COLUMN_ID + 9: - // remaining_time - cur_row_.cells_[i].set_int(stat.common_value_.remaining_time_); - break; - case OB_APP_MIN_COLUMN_ID + 10: - // last_update_time - cur_row_.cells_[i].set_int(stat.common_value_.last_update_time_); - break; - case OB_APP_MIN_COLUMN_ID + 11: - // percentage - cur_row_.cells_[i].set_int(stat.common_value_.percentage_); - break; - case OB_APP_MIN_COLUMN_ID + 12: - // message - cur_row_.cells_[i].set_varchar(stat.common_value_.message_); - cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); - break; - case OB_APP_MIN_COLUMN_ID + 13: - // trace id - cur_row_.cells_[i].set_varchar(""); - cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); - break; - } - } - - if (OB_SUCC(ret)) { - row = &cur_row_; - } - } - return ret; + addr_.reset(); + ObVirtualTableScannerIterator::reset(); } int ObAllVirtualLongOpsStatus::inner_get_next_row(ObNewRow *&row) { int ret = OB_SUCCESS; - ObILongOpsStatHandle handle; - ObILongOpsStat *stat = NULL; - row = NULL; - if (OB_UNLIKELY(!is_inited_)) { + const int64_t col_count = output_column_ids_.count(); + if (NULL == allocator_) { ret = OB_NOT_INIT; - LOG_WARN("ObAllVirtualLongOpsStatus has not been inited", KR(ret)); + LOG_WARN("allocator_ shouldn't be NULL", K(allocator_), K(ret)); + } else if (FALSE_IT(start_to_read_ = true)) { + } else if (!longops_iter_.is_inited() && OB_FAIL(ObLongopsMgr::get_instance().begin_iter(longops_iter_))) { + LOG_WARN("fail to begin longops iter", K(ret)); + } else if (OB_FAIL(longops_iter_.get_next(longops_value_))) { + LOG_WARN("fail to get next longops value", K(ret)); } else { - while (OB_SUCC(ret) && OB_SUCC(iter_.get_next_stat(handle))) { - if (OB_ISNULL(stat = handle.get_resource_ptr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("error unexpected, part stat must not be NULL", KR(ret)); - } else if (OB_FAIL(stat->estimate_cost())) { - LOG_WARN("fail to estimate partition cost", KR(ret)); - } else if (!is_sys_tenant(effective_tenant_id_) - && stat->get_key().tenant_id_ != effective_tenant_id_) { - continue; - } else if (OB_FAIL(convert_stat_to_row(*stat, row))) { - LOG_WARN("fail to convert stat to row", KR(ret)); - } else { - break; + for (int64_t i = 0; OB_SUCC(ret) && i < col_count; ++i) { + uint64_t col_id = output_column_ids_.at(i); + switch (col_id) { + case OB_APP_MIN_COLUMN_ID: + // tenant id + cur_row_.cells_[i].set_int(longops_value_.tenant_id_); + break; + case OB_APP_MIN_COLUMN_ID + 1: + // sid + cur_row_.cells_[i].set_int(longops_value_.sid_); + break; + case OB_APP_MIN_COLUMN_ID + 2: + // op_name + cur_row_.cells_[i].set_varchar(longops_value_.op_name_); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + break; + case OB_APP_MIN_COLUMN_ID + 3: + // target + cur_row_.cells_[i].set_varchar(longops_value_.target_); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + break; + case OB_APP_MIN_COLUMN_ID + 4: + // svr_ip + if (addr_.ip_to_string(ip_buf_, sizeof(ip_buf_))) { + cur_row_.cells_[i].set_varchar(ip_buf_); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to execute ip_to_string", K(ret)); + } + break; + case OB_APP_MIN_COLUMN_ID + 5: + // svr_port + cur_row_.cells_[i].set_int(addr_.get_port()); + break; + case OB_APP_MIN_COLUMN_ID + 6: + // start_time + cur_row_.cells_[i].set_int(longops_value_.start_time_); + break; + case OB_APP_MIN_COLUMN_ID + 7: + // finish_time + cur_row_.cells_[i].set_int(longops_value_.finish_time_); + break; + case OB_APP_MIN_COLUMN_ID + 8: + // elapsed_seconds + cur_row_.cells_[i].set_int(longops_value_.elapsed_seconds_); + break; + case OB_APP_MIN_COLUMN_ID + 9: + // time_remaining + cur_row_.cells_[i].set_int(longops_value_.time_remaining_); + break; + case OB_APP_MIN_COLUMN_ID + 10: + // last_update_time + cur_row_.cells_[i].set_int(longops_value_.last_update_time_); + break; + case OB_APP_MIN_COLUMN_ID + 11: + // percentage + cur_row_.cells_[i].set_int(longops_value_.percentage_); + break; + case OB_APP_MIN_COLUMN_ID + 12: + // message + cur_row_.cells_[i].set_varchar(longops_value_.message_); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + break; + case OB_APP_MIN_COLUMN_ID + 13: { + // trace id + int len = longops_value_.trace_id_.to_string(trace_id_, OB_MAX_TRACE_ID_BUFFER_SIZE); + cur_row_.cells_[i].set_varchar(trace_id_, len); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + break; + } + default: + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid col_id", K(ret), K(col_id)); + break; } - } // end while - if (OB_SUCCESS != ret && OB_ITER_END != ret) { - LOG_WARN("fail to iter next stat", KR(ret)); } } + if (OB_SUCC(ret)) { + row = &cur_row_; + } return ret; } diff --git a/src/observer/virtual_table/ob_all_virtual_long_ops_status.h b/src/observer/virtual_table/ob_all_virtual_long_ops_status.h index 3e5ca1ec4e..483744e2c5 100644 --- a/src/observer/virtual_table/ob_all_virtual_long_ops_status.h +++ b/src/observer/virtual_table/ob_all_virtual_long_ops_status.h @@ -13,9 +13,9 @@ #ifndef OB_ALL_VIRTUAL_LONG_OPS_STATUS_H_ #define OB_ALL_VIRTUAL_LONG_OPS_STATUS_H_ +#include "observer/omt/ob_multi_tenant_operator.h" #include "share/ob_virtual_table_scanner_iterator.h" -#include "observer/ob_server_struct.h" -#include "storage/ob_long_ops_monitor.h" +#include "share/longops_mgr/ob_longops_mgr.h" namespace oceanbase { @@ -26,16 +26,22 @@ class ObAllVirtualLongOpsStatus : public common::ObVirtualTableScannerIterator { public: ObAllVirtualLongOpsStatus(); - virtual ~ObAllVirtualLongOpsStatus() = default; - int init(); + virtual ~ObAllVirtualLongOpsStatus(); virtual int inner_get_next_row(common::ObNewRow *&row) override; + virtual void reset() override; + inline void set_addr(common::ObAddr &addr) + { + addr_ = addr; + } private: - int convert_stat_to_row(const storage::ObILongOpsStat &stat, common::ObNewRow *&row); + private: DISALLOW_COPY_AND_ASSIGN(ObAllVirtualLongOpsStatus); - bool is_inited_; - storage::ObLongOpsMonitorIterator iter_; - char ip_[common::OB_MAX_SERVER_ADDR_SIZE]; + common::ObAddr addr_; + share::ObLongopsValue longops_value_; + share::ObLongopsIterator longops_iter_; + char ip_buf_[common::OB_IP_STR_BUFF]; + char trace_id_[common::OB_MAX_TRACE_ID_BUFFER_SIZE]; }; } // end namespace observer diff --git a/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp b/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp index e7a591c4e6..a7552d3ab9 100644 --- a/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp +++ b/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp @@ -1760,9 +1760,8 @@ int ObVTIterCreator::create_vt_iter(ObVTableScanParam ¶ms, ObAllVirtualLongOpsStatus *long_ops_status = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAllVirtualLongOpsStatus, long_ops_status))) { SERVER_LOG(ERROR, "fail to placement new ObAllVirtualLongOpsStatus", K(ret)); - } else if (OB_FAIL(long_ops_status->init())) { - SERVER_LOG(WARN, "fail to init ObAllVirtualLongOpsStatus", K(ret)); } else { + long_ops_status->set_addr(addr_); vt_iter = static_cast(long_ops_status); } break; diff --git a/src/rootserver/ddl_task/ob_column_redefinition_task.cpp b/src/rootserver/ddl_task/ob_column_redefinition_task.cpp index 7be4080921..dbb5509e06 100644 --- a/src/rootserver/ddl_task/ob_column_redefinition_task.cpp +++ b/src/rootserver/ddl_task/ob_column_redefinition_task.cpp @@ -67,8 +67,12 @@ int ObColumnRedefinitionTask::init(const uint64_t tenant_id, const int64_t task_ task_id_ = task_id; parallelism_ = parallelism; execution_id_ = 1L; - cluster_version_ = GET_MIN_CLUSTER_VERSION(); - is_inited_ = true; + if (OB_FAIL(init_ddl_task_monitor_info(&alter_table_arg_.alter_table_schema_))) { + LOG_WARN("init ddl task monitor info failed", K(ret)); + } else { + cluster_version_ = GET_MIN_CLUSTER_VERSION(); + is_inited_ = true; + } } return ret; } @@ -80,6 +84,8 @@ int ObColumnRedefinitionTask::init(const ObDDLTaskRecord &task_record) const uint64_t dest_table_id = task_record.target_object_id_; const int64_t schema_version = task_record.schema_version_; int64_t pos = 0; + const ObTableSchema *data_schema = nullptr; + ObSchemaGetterGuard schema_guard; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("ObColumnRedefinitionTask has already been inited", K(ret)); @@ -90,6 +96,16 @@ int ObColumnRedefinitionTask::init(const ObDDLTaskRecord &task_record) LOG_WARN("deserialize params from message failed", K(ret)); } else if (OB_FAIL(set_ddl_stmt_str(task_record.ddl_stmt_str_))) { LOG_WARN("set ddl stmt str failed", K(ret)); + } else if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard( + task_record.tenant_id_, schema_guard, schema_version))) { + LOG_WARN("fail to get schema guard", K(ret), K(schema_version)); + } else if (OB_FAIL(schema_guard.check_formal_guard())) { + LOG_WARN("schema_guard is not formal", K(ret)); + } else if (OB_FAIL(schema_guard.get_table_schema(task_record.tenant_id_, data_table_id, data_schema))) { + LOG_WARN("fail to get table schema", K(ret), K(data_table_id)); + } else if (OB_ISNULL(data_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("fail to get table schema", K(ret), K(data_schema)); } else { task_id_ = task_record.task_id_; task_type_ = task_record.ddl_type_; @@ -101,7 +117,12 @@ int ObColumnRedefinitionTask::init(const ObDDLTaskRecord &task_record) execution_id_ = task_record.execution_id_; tenant_id_ = task_record.tenant_id_; ret_code_ = task_record.ret_code_; - is_inited_ = true; + + if (OB_FAIL(init_ddl_task_monitor_info(&alter_table_arg_.alter_table_schema_))) { + LOG_WARN("init ddl task monitor info failed", K(ret)); + } else { + is_inited_ = true; + } } return ret; } @@ -192,7 +213,8 @@ int ObColumnRedefinitionTask::check_build_single_replica(bool &is_end) int ObColumnRedefinitionTask::update_complete_sstable_job_status(const common::ObTabletID &tablet_id, const int64_t snapshot_version, const int64_t execution_id, - const int ret_code) + const int ret_code, + const ObDDLTaskInfo &addition_info) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { @@ -205,7 +227,10 @@ int ObColumnRedefinitionTask::update_complete_sstable_job_status(const common::O LOG_WARN("snapshot version not match", K(ret), K(snapshot_version), K(snapshot_version_)); } else if (execution_id < execution_id_) { LOG_INFO("receive a mismatch execution result, ignore", K(ret_code), K(execution_id), K(execution_id_)); - } else if (OB_FAIL(replica_builder_.set_partition_task_status(tablet_id, ret_code))) { + } else if (OB_FAIL(replica_builder_.set_partition_task_status(tablet_id, + ret_code, + addition_info.row_scanned_, + addition_info.row_inserted_))) { LOG_WARN("fail to set partition task status", K(ret)); } return ret; @@ -309,6 +334,7 @@ int ObColumnRedefinitionTask::copy_table_indexes() const uint64_t task_key = index_ids.at(i); DependTaskStatus status; status.task_id_ = task_record.task_id_; // child task id is used to judge whether child task finish. + TCWLockGuard guard(lock_); if (OB_FAIL(dependent_task_result_map_.set_refactored(task_key, status))) { if (OB_HASH_EXIST == ret) { ret = OB_SUCCESS; @@ -454,6 +480,7 @@ int ObColumnRedefinitionTask::copy_table_dependent_objects(const ObDDLTaskStatus } else { // wait copy dependent objects to be finished ObAddr unused_addr; + TCRLockGuard guard(lock_); for (common::hash::ObHashMap::const_iterator iter = dependent_task_result_map_.begin(); iter != dependent_task_result_map_.end(); ++iter) { const uint64_t task_key = iter->first; @@ -616,3 +643,124 @@ int ObColumnRedefinitionTask::process() } return ret; } + +int ObColumnRedefinitionTask::collect_longops_stat(ObLongopsValue &value) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + const ObDDLTaskStatus status = static_cast(task_status_); + databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "TENANT_ID: %ld, TASK_ID: %ld, ", tenant_id_, task_id_); + switch(status) { + case ObDDLTaskStatus::PREPARE: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: PREPARE"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_TRANS_END: { + if (snapshot_version_ > 0) { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: ACQUIRE SNAPSHOT, SNAPSHOT_VERSION: %ld", + snapshot_version_))) { + LOG_WARN("failed to print", K(ret)); + } + } else { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: WAIT TRANS END, PENDING_TX_ID: %ld", + wait_trans_ctx_.get_pending_tx_id().get_id()))) { + LOG_WARN("failed to print", K(ret)); + } + } + break; + } + case ObDDLTaskStatus::LOCK_TABLE: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: ACQUIRE TABLE LOCK"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::REDEFINITION: { + int64_t row_scanned = 0; + int64_t row_inserted = 0; + if (OB_FAIL(replica_builder_.get_progress(row_scanned, row_inserted))) { + LOG_WARN("failed to gather redefinition stats", K(ret)); + } else if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: REPLICA BUILD, ROW_SCANNED: %ld, ROW_INSERTED: %ld", + row_scanned, + row_inserted))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::COPY_TABLE_DEPENDENT_OBJECTS: { + char child_task_ids[MAX_LONG_OPS_MESSAGE_LENGTH]; + if (OB_FAIL(get_child_task_ids(child_task_ids, MAX_LONG_OPS_MESSAGE_LENGTH))) { + if (ret == OB_SIZE_OVERFLOW) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get all child task ids", K(ret)); + } + } else if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: COPY DEPENDENT OBJECTS, CHILD TASK IDS: %s", + child_task_ids))) { + if (ret == OB_SIZE_OVERFLOW) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to print", K(ret)); + } + } + break; + } + case ObDDLTaskStatus::TAKE_EFFECT: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: ENABLE INDEX"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::FAIL: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: CLEAN ON FAIL"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::SUCCESS: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: CLEAN ON SUCCESS"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + default: + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not expected status", K(ret), K(status), K(*this)); + break; + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(copy_longops_stat(value))) { + LOG_WARN("failed to collect common longops stat", K(ret)); + } + + return ret; +} diff --git a/src/rootserver/ddl_task/ob_column_redefinition_task.h b/src/rootserver/ddl_task/ob_column_redefinition_task.h index 3a329142f3..5681f4fb4a 100644 --- a/src/rootserver/ddl_task/ob_column_redefinition_task.h +++ b/src/rootserver/ddl_task/ob_column_redefinition_task.h @@ -45,7 +45,10 @@ public: const common::ObTabletID &tablet_id, const int64_t snapshot_version, const int64_t execution_id, - const int ret_code) override; + const int ret_code, + const ObDDLTaskInfo &addition_info) override; + virtual int collect_longops_stat(share::ObLongopsValue &value) override; + virtual bool support_longops_monitoring() const { return true; } private: int wait_data_complement(const share::ObDDLTaskStatus next_task_status); int send_build_single_replica_request(); diff --git a/src/rootserver/ddl_task/ob_constraint_task.cpp b/src/rootserver/ddl_task/ob_constraint_task.cpp index 18f660afe4..630beb5b18 100644 --- a/src/rootserver/ddl_task/ob_constraint_task.cpp +++ b/src/rootserver/ddl_task/ob_constraint_task.cpp @@ -147,7 +147,8 @@ int ObCheckConstraintValidationTask::process() } } } - if (OB_SUCCESS != (tmp_ret = root_service->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, task_key, 1L/*unused snapshot version*/, 1L/*unused execution id*/, ret))) { + ObDDLTaskInfo info; + if (OB_SUCCESS != (tmp_ret = root_service->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, task_key, 1L/*unused snapshot version*/, 1L/*unused execution id*/, ret, info))) { LOG_WARN("fail to finish check constraint task", K(ret), K(tmp_ret)); } return ret; @@ -189,11 +190,12 @@ int ObForeignKeyConstraintValidationTask::process() } else { ObTabletID unused_tablet_id; ObDDLTaskKey task_key(foregin_key_id_, schema_version_); + ObDDLTaskInfo info; int tmp_ret = OB_SUCCESS; if (OB_FAIL(check_fk_by_send_sql())) { LOG_WARN("failed to check fk", K(ret)); } - if (OB_SUCCESS != (tmp_ret = root_service->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, task_key, 1L/*unused snapshot version*/, 1L/*unused execution id*/, ret))) { + if (OB_SUCCESS != (tmp_ret = root_service->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, task_key, 1L/*unused snapshot version*/, 1L/*unused execution id*/, ret, info))) { LOG_WARN("fail to finish check constraint task", K(ret)); } LOG_INFO("execute check foreign key task finish", K(ret), K(task_key), K(data_table_id_), K(foregin_key_id_)); diff --git a/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp b/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp index 1f1860e07e..5d84297c35 100644 --- a/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp +++ b/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp @@ -84,6 +84,7 @@ int ObDDLRedefinitionSSTableBuildTask::process() ObSchemaGetterGuard schema_guard; const ObSysVariableSchema *sys_variable_schema = nullptr; ObDDLTaskKey task_key(dest_table_id_, schema_version_); + ObDDLTaskInfo info; bool oracle_mode = false; bool need_exec_new_inner_sql = true; @@ -170,7 +171,7 @@ int ObDDLRedefinitionSSTableBuildTask::process() } } } - if (OB_SUCCESS != (tmp_ret = root_service_->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, task_key, snapshot_version_, execution_id_, ret))) { + if (OB_SUCCESS != (tmp_ret = root_service_->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, task_key, snapshot_version_, execution_id_, ret, info))) { LOG_WARN("fail to finish sstable complement", K(ret)); } return ret; @@ -1205,6 +1206,8 @@ int ObDDLRedefinitionTask::cleanup() LOG_WARN("report error code failed", K(ret)); } else if (OB_FAIL(remove_task_record())) { LOG_WARN("remove task record failed", K(ret)); + } else { + need_retry_ = false; // clean succ, stop the task } return ret; } @@ -1918,6 +1921,35 @@ int ObDDLRedefinitionTask::check_need_check_table_empty(bool &need_check_table_e return ret; } +int ObDDLRedefinitionTask::get_child_task_ids(char *buf, int64_t len) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + MEMSET(buf, 0, len); + TCRLockGuard guard(lock_); + common::hash::ObHashMap ::const_iterator iter = + dependent_task_result_map_.begin(); + if (OB_FAIL(databuff_printf(buf, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "[ "))) { + LOG_WARN("failed to print", K(ret)); + } else { + while (OB_SUCC(ret) && iter != dependent_task_result_map_.end()) { + const int64_t child_task_id = iter->second.task_id_; + if (OB_FAIL(databuff_printf(buf, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "%ld ", + child_task_id))) { + LOG_WARN("failed to print", K(ret)); + } + ++iter; + } + if (OB_SUCC(ret)) { + databuff_printf(buf, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "]"); + } + } + return ret; +} + ObSyncTabletAutoincSeqCtx::ObSyncTabletAutoincSeqCtx() : is_inited_(false), is_synced_(false), tenant_id_(OB_INVALID_ID), orig_src_tablet_ids_(), src_tablet_ids_(), dest_tablet_ids_(), autoinc_params_() diff --git a/src/rootserver/ddl_task/ob_ddl_redefinition_task.h b/src/rootserver/ddl_task/ob_ddl_redefinition_task.h index 7aff865206..88f5a95564 100644 --- a/src/rootserver/ddl_task/ob_ddl_redefinition_task.h +++ b/src/rootserver/ddl_task/ob_ddl_redefinition_task.h @@ -117,7 +117,8 @@ public: const common::ObTabletID &tablet_id, const int64_t snapshot_version, const int64_t execution_id, - const int ret_code) = 0; + const int ret_code, + const ObDDLTaskInfo &addition_info) = 0; int on_child_task_finish( const uint64_t child_task_key, const int ret_code); @@ -190,6 +191,7 @@ protected: ObIArray &constraint_ids, bool &need_rebuild_constraint); int check_need_check_table_empty(bool &need_check_table_empty); + int get_child_task_ids(char *buf, int64_t len); int get_estimated_timeout(const share::schema::ObTableSchema *dst_table_schema, int64_t &estimated_timeout); protected: struct DependTaskStatus final diff --git a/src/rootserver/ddl_task/ob_ddl_scheduler.cpp b/src/rootserver/ddl_task/ob_ddl_scheduler.cpp index d4a9b32caf..841c4665a4 100644 --- a/src/rootserver/ddl_task/ob_ddl_scheduler.cpp +++ b/src/rootserver/ddl_task/ob_ddl_scheduler.cpp @@ -28,6 +28,7 @@ #include "rootserver/ddl_task/ob_table_redefinition_task.h" #include "share/ob_ddl_common.h" #include "share/ob_rpc_struct.h" +#include "share/longops_mgr/ob_longops_mgr.h" #include "share/scheduler/ob_sys_task_stat.h" namespace oceanbase @@ -101,7 +102,8 @@ int ObDDLTaskQueue::push_task(ObDDLTask *task) } } else { task_add_to_map = true; - if (OB_FAIL(task_id_map_.set_refactored(task->get_task_id(), task, is_overwrite))) { + if (OB_FAIL(ret)) { + } else if (OB_FAIL(task_id_map_.set_refactored(task->get_task_id(), task, is_overwrite))) { if (common::OB_HASH_EXIST == ret) { ret = common::OB_ENTRY_EXIST; } else { @@ -343,13 +345,8 @@ void ObDDLScheduler::run1() STORAGE_LOG(ERROR, "fail to add task to last, which should not happen", K(ret), K(*task)); } first_retry_task = nullptr == first_retry_task ? task : first_retry_task; - } else { - if (OB_FAIL(task_queue_.remove_task(task))) { - LOG_WARN("fail to remove task, which should not happen", K(ret), K(*task), KP(task)); - } else { - remove_sys_task(task); - free_ddl_task(task); - } + } else if (OB_FAIL(remove_ddl_task(task))) { + LOG_WARN("remove ddl task failed", K(ret)); } } } @@ -566,32 +563,33 @@ int ObDDLScheduler::create_build_index_task( ObDDLTaskRecord &task_record) { int ret = OB_SUCCESS; - ObIndexBuildTask index_task; int64_t task_id = 0; - if (OB_UNLIKELY(!is_inited_)) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (OB_ISNULL(create_index_arg) || OB_ISNULL(data_table_schema) || OB_ISNULL(index_schema)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(create_index_arg), K(data_table_schema), K(index_schema)); - } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), task_id))) { - LOG_WARN("fetch new task id failed", K(ret)); - } else if (OB_FAIL(index_task.init(data_table_schema->get_tenant_id(), - task_id, - data_table_schema, - index_schema, - index_schema->get_schema_version(), - parallelism, - *create_index_arg, - parent_task_id))) { - LOG_WARN("init global index task failed", K(ret), K(data_table_schema), K(index_schema)); - } else if (OB_FAIL(index_task.set_trace_id(*ObCurTraceId::get_trace_id()))) { - LOG_WARN("set trace id failed", K(ret)); - } else if (OB_FAIL(insert_task_record(proxy, index_task, allocator, task_record))) { - LOG_WARN("fail to insert task record", K(ret)); - } + SMART_VAR(ObIndexBuildTask, index_task) { + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(create_index_arg) || OB_ISNULL(data_table_schema) || OB_ISNULL(index_schema)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(create_index_arg), K(data_table_schema), K(index_schema)); + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), task_id))) { + LOG_WARN("fetch new task id failed", K(ret)); + } else if (OB_FAIL(index_task.init(data_table_schema->get_tenant_id(), + task_id, + data_table_schema, + index_schema, + index_schema->get_schema_version(), + parallelism, + *create_index_arg, + parent_task_id))) { + LOG_WARN("init global index task failed", K(ret), K(data_table_schema), K(index_schema)); + } else if (OB_FAIL(index_task.set_trace_id(*ObCurTraceId::get_trace_id()))) { + LOG_WARN("set trace id failed", K(ret)); + } else if (OB_FAIL(insert_task_record(proxy, index_task, allocator, task_record))) { + LOG_WARN("fail to insert task record", K(ret)); + } - LOG_INFO("ddl_scheduler create build index task finished", K(ret), K(index_task)); + LOG_INFO("ddl_scheduler create build index task finished", K(ret), K(index_task)); + } return ret; } @@ -649,7 +647,7 @@ int ObDDLScheduler::create_constraint_task( ObDDLTaskRecord &task_record) { int ret = OB_SUCCESS; - ObConstraintTask constraint_task; + SMART_VAR(ObConstraintTask, constraint_task) { int64_t task_id = 0; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; @@ -668,6 +666,7 @@ int ObDDLScheduler::create_constraint_task( LOG_WARN("fail to insert task record", K(ret)); } LOG_INFO("ddl_scheduler create constraint task finished", K(ret), K(constraint_task)); + } return ret; } @@ -1241,6 +1240,56 @@ int ObDDLScheduler::schedule_drop_index_task(const ObDDLTaskRecord &task_record) return ret; } +int ObDDLScheduler::add_task_to_longops_mgr(ObDDLTask *ddl_task) +{ + int ret = OB_SUCCESS; + ObLongopsMgr &longops_mgr = ObLongopsMgr::get_instance(); + ObDDLLongopsStat *longops_stat = nullptr; + bool registered = false; + if (OB_ISNULL(ddl_task)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(ddl_task)); + } else if (ddl_task->support_longops_monitoring()) { + if (OB_FAIL(longops_mgr.alloc_longops(longops_stat))) { + LOG_WARN("failed to allocate longops stat", K(ret)); + } else if (OB_FAIL(longops_stat->init(ddl_task))) { + LOG_WARN("failed to init longops stat", K(ret), KPC(ddl_task)); + } else if (OB_FAIL(longops_mgr.register_longops(longops_stat))) { + LOG_WARN("failed to register longops", K(ret)); + if (OB_ENTRY_EXIST == ret) { + ret = OB_SUCCESS; + } + } else { + ddl_task->set_longops_stat(longops_stat); + longops_stat = nullptr; + } + if (nullptr != longops_stat) { + longops_mgr.free_longops(longops_stat); + } + } + return ret; +} + +int ObDDLScheduler::remove_ddl_task(ObDDLTask *ddl_task) +{ + int ret = OB_SUCCESS; + ObLongopsMgr &longops_mgr = ObLongopsMgr::get_instance(); + if (OB_ISNULL(ddl_task)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(ddl_task)); + } else if (OB_FAIL(task_queue_.remove_task(ddl_task))) { + LOG_WARN("fail to remove task, which should not happen", K(ret), KPC(ddl_task)); + } else { + int tmp_ret = OB_SUCCESS; + if (ddl_task->support_longops_monitoring() && OB_TMP_FAIL(longops_mgr.unregister_longops(ddl_task->get_longops_stat()))) { + LOG_WARN("failed to unregister longops", K(tmp_ret)); + } + remove_sys_task(ddl_task); + free_ddl_task(ddl_task); + } + return ret; +} + int ObDDLScheduler::inner_schedule_ddl_task(ObDDLTask *ddl_task) { int ret = OB_SUCCESS; @@ -1255,6 +1304,8 @@ int ObDDLScheduler::inner_schedule_ddl_task(ObDDLTask *ddl_task) int tmp_ret = OB_SUCCESS; if (OB_TMP_FAIL(add_sys_task(ddl_task))) { LOG_WARN("add sys task failed", K(tmp_ret)); + } else if (OB_TMP_FAIL(add_task_to_longops_mgr(ddl_task))) { + LOG_WARN("add task to longops mgr failed", K(tmp_ret)); } idler_.wakeup(); } @@ -1330,7 +1381,8 @@ int ObDDLScheduler::on_sstable_complement_job_reply( const ObDDLTaskKey &task_key, const int64_t snapshot_version, const int64_t execution_id, - const int ret_code) + const int ret_code, + const ObDDLTaskInfo &addition_info) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { @@ -1352,12 +1404,12 @@ int ObDDLScheduler::on_sstable_complement_job_reply( const int64_t task_type = ddl_task->get_task_type(); switch (task_type) { case ObDDLType::DDL_CREATE_INDEX: - if (OB_FAIL(static_cast(ddl_task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code))) { + if (OB_FAIL(static_cast(ddl_task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) { LOG_WARN("update complete sstable job status failed", K(ret)); } break; case ObDDLType::DDL_DROP_PRIMARY_KEY: - if (OB_FAIL(static_cast(ddl_task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code))) { + if (OB_FAIL(static_cast(ddl_task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) { LOG_WARN("update complete sstable job status", K(ret)); } break; @@ -1367,7 +1419,7 @@ int ObDDLScheduler::on_sstable_complement_job_reply( case ObDDLType::DDL_MODIFY_COLUMN: case ObDDLType::DDL_CONVERT_TO_CHARACTER: case ObDDLType::DDL_TABLE_REDEFINITION: - if (OB_FAIL(static_cast(ddl_task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code))) { + if (OB_FAIL(static_cast(ddl_task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) { LOG_WARN("update complete sstable job status", K(ret)); } break; @@ -1381,7 +1433,7 @@ int ObDDLScheduler::on_sstable_complement_job_reply( case ObDDLType::DDL_DROP_COLUMN: case ObDDLType::DDL_ADD_COLUMN_OFFLINE: case ObDDLType::DDL_COLUMN_REDEFINITION: - if (OB_FAIL(static_cast(ddl_task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code))) { + if (OB_FAIL(static_cast(ddl_task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) { LOG_WARN("update complete sstable job status", K(ret), K(tablet_id), K(snapshot_version), K(ret_code)); } break; @@ -1495,15 +1547,14 @@ void ObDDLScheduler::destroy_all_tasks() { int ret = OB_SUCCESS; ObDDLTask *ddl_task = nullptr; + ObLongopsMgr &longops_mgr = ObLongopsMgr::get_instance(); while (OB_SUCC(ret)) { if (OB_FAIL(task_queue_.get_next_task(ddl_task))) { if (common::OB_ENTRY_NOT_EXIST == ret) { break; } - } else { - remove_sys_task(ddl_task); - task_queue_.remove_task(ddl_task); - free_ddl_task(ddl_task); + } else if (OB_FAIL(remove_ddl_task(ddl_task))) { + LOG_WARN("remove ddl task failed", K(ret)); } } } diff --git a/src/rootserver/ddl_task/ob_ddl_scheduler.h b/src/rootserver/ddl_task/ob_ddl_scheduler.h index 595665bfd9..2b7ef6ce18 100644 --- a/src/rootserver/ddl_task/ob_ddl_scheduler.h +++ b/src/rootserver/ddl_task/ob_ddl_scheduler.h @@ -115,7 +115,8 @@ public: const ObDDLTaskKey &task_key, const int64_t snapshot_version, const int64_t execution_id, - const int ret_code); + const int ret_code, + const ObDDLTaskInfo &addition_info); int on_ddl_task_finish( const int64_t parent_task_id, @@ -251,6 +252,8 @@ private: int schedule_ddl_retry_task(const ObDDLTaskRecord &task_record); int add_sys_task(ObDDLTask *task); int remove_sys_task(ObDDLTask *task); + int add_task_to_longops_mgr(ObDDLTask *ddl_task); + int remove_ddl_task(ObDDLTask *ddl_task); private: static const int64_t TOTAL_LIMIT = 1024L * 1024L * 1024L; diff --git a/src/rootserver/ddl_task/ob_ddl_single_replica_executor.cpp b/src/rootserver/ddl_task/ob_ddl_single_replica_executor.cpp index d9bcdf8221..a0589ddb2a 100644 --- a/src/rootserver/ddl_task/ob_ddl_single_replica_executor.cpp +++ b/src/rootserver/ddl_task/ob_ddl_single_replica_executor.cpp @@ -141,7 +141,8 @@ int ObDDLSingleReplicaExecutor::schedule_task() LOG_WARN("rpc_proxy wait failed", K(ret), K(tmp_ret)); ret = (OB_SUCCESS == ret) ? tmp_ret : ret; } else if (OB_SUCC(ret)) { - if (ret_array.count() != idxs.count()) { + const ObIArray &result_array = proxy.get_results(); + if (ret_array.count() != idxs.count() || result_array.count() != idxs.count()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("error unexpected, ret array count is not equal to request count", K(ret)); } @@ -153,14 +154,20 @@ int ObDDLSingleReplicaExecutor::schedule_task() } else if (OB_SUCCESS == ret_array.at(i)) { build_infos.at(idx).stat_ = ObPartitionBuildStat::BUILD_REQUESTED; build_infos.at(idx).heart_beat_time_ = ObTimeUtility::current_time(); + build_infos.at(idx).row_inserted_ = MAX(build_infos.at(idx).row_inserted_, result_array.at(i)->row_inserted_); + build_infos.at(idx).row_scanned_ = MAX(build_infos.at(idx).row_scanned_, result_array.at(i)->row_scanned_); LOG_INFO("rpc send successfully", K(source_tablet_ids_.at(idx)), K(dest_tablet_ids_.at(idx))); } else if (ObIDDLTask::in_ddl_retry_white_list(ret_array.at(i))) { build_infos.at(idx).stat_ = ObPartitionBuildStat::BUILD_RETRY; + build_infos.at(idx).row_inserted_ = 0; + build_infos.at(idx).row_scanned_ = 0; LOG_INFO("task need retry", K(ret_array.at(i)), K(source_tablet_ids_.at(idx)), K(dest_tablet_ids_.at(idx))); } else { build_infos.at(idx).stat_ = ObPartitionBuildStat::BUILD_FAILED; build_infos.at(idx).ret_code_ = ret_array.at(i); build_infos.at(idx).heart_beat_time_ = ObTimeUtility::current_time(); + build_infos.at(idx).row_inserted_ = 0; + build_infos.at(idx).row_scanned_ = 0; LOG_INFO("task is failed", K(build_infos.at(idx)), K(source_tablet_ids_.at(idx)), K(dest_tablet_ids_.at(idx))); } } @@ -208,7 +215,10 @@ int ObDDLSingleReplicaExecutor::check_build_end(bool &is_end, int64_t &ret_code) return ret; } -int ObDDLSingleReplicaExecutor::set_partition_task_status(const common::ObTabletID &tablet_id, const int ret_code) +int ObDDLSingleReplicaExecutor::set_partition_task_status(const common::ObTabletID &tablet_id, + const int ret_code, + const int64_t row_scanned, + const int64_t row_inserted) { int ret = OB_SUCCESS; common::ObIArray &build_infos = partition_build_stat_; @@ -223,15 +233,34 @@ int ObDDLSingleReplicaExecutor::set_partition_task_status(const common::ObTablet if (OB_SUCCESS == ret_code) { build_infos.at(i).ret_code_ = OB_SUCCESS; build_infos.at(i).stat_ = ObPartitionBuildStat::BUILD_SUCCEED; + build_infos.at(i).row_inserted_ = row_inserted; + build_infos.at(i).row_scanned_ = row_scanned; } else if (ObIDDLTask::in_ddl_retry_white_list(ret_code)) { build_infos.at(i).ret_code_ = OB_SUCCESS; build_infos.at(i).stat_ = ObPartitionBuildStat::BUILD_RETRY; + build_infos.at(i).row_inserted_ = 0; + build_infos.at(i).row_scanned_ = 0; } else { build_infos.at(i).ret_code_ = ret_code; build_infos.at(i).stat_ = ObPartitionBuildStat::BUILD_FAILED; + build_infos.at(i).row_inserted_ = 0; + build_infos.at(i).row_scanned_ = 0; } } } } return ret; } + +int ObDDLSingleReplicaExecutor::get_progress(int64_t &row_scanned, int64_t &row_inserted) +{ + int ret = OB_SUCCESS; + row_scanned = 0; + row_inserted = 0; + common::ObIArray &build_infos = partition_build_stat_; + for (int64_t i = 0; OB_SUCC(ret) && i < build_infos.count(); ++i) { + row_scanned += build_infos.at(i).row_scanned_; + row_inserted += build_infos.at(i).row_inserted_; + } + return ret; +} diff --git a/src/rootserver/ddl_task/ob_ddl_single_replica_executor.h b/src/rootserver/ddl_task/ob_ddl_single_replica_executor.h index 66479b06b3..428095ab37 100644 --- a/src/rootserver/ddl_task/ob_ddl_single_replica_executor.h +++ b/src/rootserver/ddl_task/ob_ddl_single_replica_executor.h @@ -70,7 +70,11 @@ class ObDDLSingleReplicaExecutor public: int build(const ObDDLSingleReplicaExecutorParam ¶m); int check_build_end(bool &is_end, int64_t &ret_code); - int set_partition_task_status(const common::ObTabletID &tablet_id, const int ret_code); + int set_partition_task_status(const common::ObTabletID &tablet_id, + const int ret_code, + const int64_t row_scanned, + const int64_t row_inserted); + int get_progress(int64_t &row_scanned, int64_t &row_inserted); private: int schedule_task(); private: @@ -87,7 +91,8 @@ private: public: static const int64_t PARTITION_BUILD_HEART_BEAT_TIME = 10 * 1000 * 1000; ObPartitionBuildInfo() - : ret_code_(common::OB_SUCCESS), stat_(ObPartitionBuildStat::BUILD_INIT), heart_beat_time_(0) + : ret_code_(common::OB_SUCCESS), stat_(ObPartitionBuildStat::BUILD_INIT), heart_beat_time_(0), + row_inserted_(0), row_scanned_(0) {} ~ObPartitionBuildInfo() = default; bool need_schedule() const { @@ -95,11 +100,13 @@ private: || (ObPartitionBuildStat::BUILD_REQUESTED == stat_ && ObTimeUtility::current_time() - heart_beat_time_ > PARTITION_BUILD_HEART_BEAT_TIME); } - TO_STRING_KV(K_(ret_code), K_(stat), K_(heart_beat_time)); + TO_STRING_KV(K_(ret_code), K_(stat), K_(heart_beat_time), K_(row_inserted), K_(row_scanned)); public: int64_t ret_code_; ObPartitionBuildStat stat_; int64_t heart_beat_time_; + int64_t row_inserted_; + int64_t row_scanned_; }; private: uint64_t tenant_id_; diff --git a/src/rootserver/ddl_task/ob_ddl_task.cpp b/src/rootserver/ddl_task/ob_ddl_task.cpp index 60348ec3ee..d2855b8759 100644 --- a/src/rootserver/ddl_task/ob_ddl_task.cpp +++ b/src/rootserver/ddl_task/ob_ddl_task.cpp @@ -53,7 +53,6 @@ using namespace sql; namespace rootserver { - ObDDLTaskKey::ObDDLTaskKey() : object_id_(OB_INVALID_ID), schema_version_(0) { @@ -106,6 +105,26 @@ ObCreateDDLTaskParam::ObCreateDDLTaskParam(const uint64_t tenant_id, { } +ObDDLTaskStatInfo::ObDDLTaskStatInfo() + : start_time_(0), finish_time_(0), time_remaining_(0), percentage_(0), op_name_(), target_(), message_() +{ +} + +int ObDDLTaskStatInfo::init(const char *&ddl_type_str, const uint64_t table_id) +{ + int ret = OB_SUCCESS; + MEMSET(op_name_, 0, common::MAX_LONG_OPS_NAME_LENGTH); + MEMSET(target_, 0, common::MAX_LONG_OPS_TARGET_LENGTH); + if (OB_FAIL(databuff_printf(op_name_, common::MAX_LONG_OPS_NAME_LENGTH, "%s", ddl_type_str))) { + LOG_WARN("failed to print ddl type str", K(ret)); + } else if (OB_FAIL(databuff_printf(target_, common::MAX_LONG_OPS_TARGET_LENGTH, "%lu", table_id))) { + LOG_WARN("failed to print ddl table name", K(ret), K(table_id)); + } else { + start_time_ = ObTimeUtility::current_time(); + } + return ret; +} + int ObDDLTask::get_ddl_type_str(const int64_t ddl_type, const char *&ddl_type_str) { int ret = OB_SUCCESS; @@ -333,12 +352,15 @@ int ObDDLTask::switch_status(ObDDLTaskStatus new_status, const int ret_code) } else if (table_task_status == SUCCESS && old_status != table_task_status) { real_new_status = SUCCESS; } else if (old_status == new_status) { - // do nothing. + // do nothing } else if (OB_FAIL(ObDDLTaskRecordOperator::update_task_status( trans, tenant_id_, task_id_, static_cast(real_new_status)))) { LOG_WARN("update task status failed", K(ret), K(task_id_), K(new_status)); - } else if (OB_FAIL(ObDDLTaskRecordOperator::update_ret_code(trans, tenant_id_, task_id_, ret_code_))) { - LOG_WARN("failed to update ret code", K(ret)); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(ObDDLTaskRecordOperator::update_ret_code(trans, tenant_id_, task_id_, ret_code_))) { + LOG_WARN("failed to update ret code", K(ret)); + } } bool commit = (OB_SUCCESS == ret); @@ -590,6 +612,32 @@ int ObDDLTask::batch_release_snapshot( return ret; } +int ObDDLTask::collect_longops_stat(ObLongopsValue &value) +{ + // do nothing + int ret = OB_SUCCESS; + return ret; +}; + +int ObDDLTask::copy_longops_stat(ObLongopsValue &value) +{ + int ret = OB_SUCCESS; + value.trace_id_ = trace_id_; + value.tenant_id_ = tenant_id_; + value.start_time_ = stat_info_.start_time_; + value.finish_time_ = stat_info_.finish_time_; + value.elapsed_seconds_ = (ObTimeUtility::current_time() - stat_info_.start_time_); + value.time_remaining_ = stat_info_.time_remaining_; + value.last_update_time_ = ObTimeUtility::current_time(); + MEMCPY(value.op_name_, stat_info_.op_name_, common::MAX_LONG_OPS_NAME_LENGTH); + value.op_name_[common::MAX_LONG_OPS_NAME_LENGTH - 1] = '\0'; + MEMCPY(value.target_, stat_info_.target_, common::MAX_LONG_OPS_TARGET_LENGTH); + value.target_[common::MAX_LONG_OPS_TARGET_LENGTH - 1] = '\0'; + MEMCPY(value.message_, stat_info_.message_, common::MAX_LONG_OPS_MESSAGE_LENGTH); + value.message_[common::MAX_LONG_OPS_MESSAGE_LENGTH - 1] = '\0'; + return ret; +} + int ObDDLTask::push_execution_id() { int ret = OB_SUCCESS; @@ -706,6 +754,172 @@ int ObDDLTask::check_errsim_error() } #endif +int ObDDLTask::gather_scanned_rows( + const uint64_t tenant_id, + const int64_t task_id, + ObMySQLProxy &sql_proxy, + int64_t &row_scanned) +{ + int ret = OB_SUCCESS; + row_scanned = 0; + char trace_id_str[OB_MAX_TRACE_ID_BUFFER_SIZE] = ""; + trace_id_.to_string(trace_id_str, OB_MAX_TRACE_ID_BUFFER_SIZE); + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || task_id <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(task_id)); + } else { + ObSqlString scan_sql; + sqlclient::ObMySQLResult *scan_result = NULL; + SMART_VAR(ObMySQLProxy::MySQLResult, scan_res) { + if (OB_FAIL(scan_sql.assign_fmt( + "SELECT OUTPUT_ROWS FROM %s WHERE TENANT_ID=%lu " + "AND TRACE_ID='%s' AND PLAN_OPERATION='PHY_SUBPLAN_SCAN' AND OTHERSTAT_5_VALUE='%ld'", + OB_ALL_VIRTUAL_SQL_PLAN_MONITOR_TNAME, tenant_id, trace_id_str, task_id))) { + LOG_WARN("failed to assign sql", K(ret)); + } else if (OB_FAIL(sql_proxy.read(scan_res, tenant_id, scan_sql.ptr()))) { + LOG_WARN("fail to execute sql", K(ret)); + } else if (OB_ISNULL(scan_result = scan_res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, query result must not be NULL", K(ret)); + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(scan_result->next())) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get next row", K(ret)); + } + } else { + int64_t row_scanned_tmp = 0; + EXTRACT_INT_FIELD_MYSQL(*scan_result, "OUTPUT_ROWS", row_scanned_tmp, int64_t); + row_scanned += row_scanned_tmp; + } + } + } + } + } + return ret; +} + +int ObDDLTask::gather_sorted_rows( + const uint64_t tenant_id, + const int64_t task_id, + ObMySQLProxy &sql_proxy, + int64_t &row_sorted) +{ + int ret = OB_SUCCESS; + row_sorted = 0; + char trace_id_str[OB_MAX_TRACE_ID_BUFFER_SIZE] = ""; + trace_id_.to_string(trace_id_str, OB_MAX_TRACE_ID_BUFFER_SIZE); + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || task_id <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(task_id)); + } else { + ObSqlString sort_sql; + sqlclient::ObMySQLResult *sort_result = NULL; + SMART_VAR(ObMySQLProxy::MySQLResult, sort_res) { + if (OB_FAIL(sort_sql.assign_fmt( + "SELECT OTHERSTAT_1_VALUE AS ROW_SORTED FROM %s WHERE TENANT_ID=%lu " + "AND TRACE_ID='%s' AND PLAN_OPERATION='PHY_SORT' AND OTHERSTAT_5_VALUE='%ld'", + OB_ALL_VIRTUAL_SQL_PLAN_MONITOR_TNAME, tenant_id, trace_id_str, task_id))) { + LOG_WARN("failed to assign sql", K(ret)); + } else if (OB_FAIL(sql_proxy.read(sort_res, tenant_id, sort_sql.ptr()))) { + LOG_WARN("fail to execute sql", K(ret)); + } else if (OB_ISNULL(sort_result = sort_res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, query result must not be NULL", K(ret)); + } + while (OB_SUCC(ret)) { + if (OB_FAIL(sort_result->next())) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get next row", K(ret)); + } + } else { + int64_t row_sorted_tmp = 0; + EXTRACT_INT_FIELD_MYSQL(*sort_result, "ROW_SORTED", row_sorted_tmp, int64_t); + row_sorted += row_sorted_tmp; + } + } + } + } + return ret; +} + +int ObDDLTask::gather_inserted_rows( + const uint64_t tenant_id, + const int64_t task_id, + ObMySQLProxy &sql_proxy, + int64_t &row_inserted) +{ + int ret = OB_SUCCESS; + row_inserted = 0; + char trace_id_str[OB_MAX_TRACE_ID_BUFFER_SIZE] = ""; + trace_id_.to_string(trace_id_str, OB_MAX_TRACE_ID_BUFFER_SIZE); + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || task_id <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(task_id)); + } else { + ObSqlString insert_sql; + sqlclient::ObMySQLResult *insert_result = NULL; + SMART_VAR(ObMySQLProxy::MySQLResult, insert_res) { + if (OB_FAIL(insert_sql.assign_fmt( + "SELECT OTHERSTAT_1_VALUE AS ROW_INSERTED FROM %s WHERE TENANT_ID=%lu " + "AND TRACE_ID='%s' AND PLAN_OPERATION='PHY_PX_MULTI_PART_SSTABLE_INSERT' AND OTHERSTAT_5_VALUE='%ld'", + OB_ALL_VIRTUAL_SQL_PLAN_MONITOR_TNAME, tenant_id, trace_id_str, task_id))) { + LOG_WARN("failed to assign sql", K(ret)); + } else if (OB_FAIL(sql_proxy.read(insert_res, tenant_id, insert_sql.ptr()))) { + LOG_WARN("fail to execute sql", K(ret), K(insert_sql)); + } else if (OB_ISNULL(insert_result = insert_res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, query result must not be NULL", K(ret)); + } + while (OB_SUCC(ret)) { + if (OB_FAIL(insert_result->next())) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("failed to get next row", K(ret)); + } + } else { + int64_t row_inserted_tmp = 0; + EXTRACT_INT_FIELD_MYSQL(*insert_result, "ROW_INSERTED", row_inserted_tmp, int64_t); + row_inserted += row_inserted_tmp; + } + } + } + } + return ret; +} + +int ObDDLTask::gather_redefinition_stats(const uint64_t tenant_id, + const int64_t task_id, + ObMySQLProxy &sql_proxy, + int64_t &row_scanned, + int64_t &row_sorted, + int64_t &row_inserted) +{ + int ret = OB_SUCCESS; + row_scanned = 0; + row_sorted = 0; + row_inserted = 0; + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || task_id <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(task_id)); + } else if (OB_FAIL(gather_scanned_rows(tenant_id, task_id, sql_proxy, row_scanned))) { + LOG_WARN("gather scanned rows failed", K(ret)); + } else if (OB_FAIL(gather_sorted_rows(tenant_id, task_id, sql_proxy, row_sorted))) { + LOG_WARN("gather sorted rows failed", K(ret)); + } else if (OB_FAIL(gather_inserted_rows(tenant_id, task_id, sql_proxy, row_inserted))) { + LOG_WARN("gather inserted rows failed", K(ret)); + } + return ret; +} + /****************** ObDDLWaitTransEndCtx *************/ ObDDLWaitTransEndCtx::ObDDLWaitTransEndCtx() @@ -818,13 +1032,15 @@ int check_trans_end(const ObArray &send_array, Arg &arg, Res *res, ObIArray &ret_array, - ObIArray &snapshot_array) + ObIArray &snapshot_array, + transaction::ObTransID &pending_tx_id) { int ret = OB_SUCCESS; ret_array.reuse(); snapshot_array.reuse(); hash::ObHashMap result_map; ObArray tmp_send_array; + pending_tx_id.reset(); if (OB_UNLIKELY(send_array.empty())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret)); @@ -915,6 +1131,8 @@ int check_trans_end(const ObArray &send_array, LOG_WARN("push back return code failed", K(ret), K(send_item), K(result_item)); } else if (OB_FAIL(snapshot_array.push_back(result_item.snapshot_))) { LOG_WARN("push back snapshot failed", K(ret), K(send_item), K(result_item)); + } else if (result_item.pending_tx_id_.is_valid() && !pending_tx_id.is_valid()) { + pending_tx_id = result_item.pending_tx_id_; } } } @@ -950,7 +1168,7 @@ int ObDDLWaitTransEndCtx::check_schema_trans_end( arg.tenant_id_ = tenant_id; arg.schema_version_ = schema_version; arg.need_wait_trans_end_ = need_wait_trans_end; - if (OB_FAIL(check_trans_end(send_array, proxy, arg, res, ret_array, snapshot_array))) { + if (OB_FAIL(check_trans_end(send_array, proxy, arg, res, ret_array, snapshot_array, pending_tx_id_))) { LOG_WARN("check trans end failed", K(ret)); } } @@ -983,7 +1201,7 @@ int ObDDLWaitTransEndCtx::check_sstable_trans_end( obrpc::ObCheckModifyTimeElapsedResult *res = nullptr; arg.tenant_id_ = tenant_id; arg.sstable_exist_ts_ = sstable_exist_ts; - if (OB_FAIL(check_trans_end(send_array, proxy, arg, res, ret_array, snapshot_array))) { + if (OB_FAIL(check_trans_end(send_array, proxy, arg, res, ret_array, snapshot_array, pending_tx_id_))) { LOG_WARN("check trans end failed", K(ret)); } } @@ -2162,6 +2380,22 @@ int ObDDLTaskRecordOperator::kill_task_inner_sql( return ret; } +int ObDDLTask::init_ddl_task_monitor_info(const ObTableSchema *target_schema) +{ + int ret = OB_SUCCESS; + const char *ddl_type_str = nullptr; + const char *target_name = nullptr; + if (OB_ISNULL(target_schema)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(target_schema)); + } else if (OB_FAIL(get_ddl_type_str(task_type_, ddl_type_str))) { + LOG_WARN("failed to get ddl type str", K(ret)); + } else if (OB_FAIL(stat_info_.init(ddl_type_str, target_schema->get_table_id()))) { + LOG_WARN("failed to init stat info", K(ret)); + } + return ret; +} + } // end namespace rootserver } // end namespace oceanbase diff --git a/src/rootserver/ddl_task/ob_ddl_task.h b/src/rootserver/ddl_task/ob_ddl_task.h index 19e080dbb2..47d046f57d 100644 --- a/src/rootserver/ddl_task/ob_ddl_task.h +++ b/src/rootserver/ddl_task/ob_ddl_task.h @@ -19,6 +19,7 @@ #include "share/ob_rpc_struct.h" #include "share/schema/ob_schema_struct.h" #include "share/ob_ddl_common.h" +#include "share/longops_mgr/ob_ddl_longops.h" #include "rootserver/ddl_task/ob_ddl_single_replica_executor.h" namespace oceanbase @@ -74,6 +75,17 @@ public: ObString ddl_stmt_str_; }; +struct ObDDLTaskInfo final +{ +public: + ObDDLTaskInfo() : row_scanned_(0), row_inserted_(0) {} + ~ObDDLTaskInfo() {} + TO_STRING_KV(K_(row_scanned), K_(row_inserted)); +public: + int64_t row_scanned_; + int64_t row_inserted_; +}; + struct ObCreateDDLTaskParam final { public: @@ -223,8 +235,9 @@ public: void reset(); bool is_inited() const { return is_inited_; } int try_wait(bool &is_trans_end, int64_t &snapshot_version, const bool need_wait_trans_end = true); + transaction::ObTransID get_pending_tx_id() const { return pending_tx_id_; } TO_STRING_KV(K(is_inited_), K_(tenant_id), K(table_id_), K(is_trans_end_), K(wait_type_), - K(wait_version_), K(tablet_ids_), K(snapshot_array_)); + K(wait_version_), K_(pending_tx_id), K(tablet_ids_), K(snapshot_array_)); private: static bool is_wait_trans_type_valid(const WaitTransType wait_trans_type); @@ -261,10 +274,29 @@ private: bool is_trans_end_; WaitTransType wait_type_; int64_t wait_version_; + transaction::ObTransID pending_tx_id_; common::ObArray tablet_ids_; common::ObArray snapshot_array_; }; +struct ObDDLTaskStatInfo final +{ +public: + ObDDLTaskStatInfo(); + ~ObDDLTaskStatInfo() = default; + int init(const char *&ddl_type_str, const uint64_t table_id); + TO_STRING_KV(K_(start_time), K_(finish_time), K_(time_remaining), K_(percentage), + K_(op_name), K_(target), K_(message)); +public: + int64_t start_time_; + int64_t finish_time_; + int64_t time_remaining_; + int64_t percentage_; + char op_name_[common::MAX_LONG_OPS_NAME_LENGTH]; + char target_[common::MAX_LONG_OPS_TARGET_LENGTH]; + char message_[common::MAX_LONG_OPS_MESSAGE_LENGTH]; +}; + class ObDDLTask : public common::ObDLinkBase { public: @@ -274,7 +306,7 @@ public: target_object_id_(0), task_status_(share::ObDDLTaskStatus::PREPARE), snapshot_version_(0), ret_code_(OB_SUCCESS), task_id_(0), parent_task_id_(0), parent_task_key_(), task_version_(0), parallelism_(0), allocator_(lib::ObLabel("DdlTask")), compat_mode_(lib::Worker::CompatMode::INVALID), err_code_occurence_cnt_(0), - delay_schedule_time_(0), next_schedule_ts_(0), execution_id_(-1), sql_exec_addr_(), cluster_version_(0) + longops_stat_(nullptr), stat_info_(), delay_schedule_time_(0), next_schedule_ts_(0), execution_id_(-1), sql_exec_addr_(), cluster_version_(0) {} virtual ~ObDDLTask() {} virtual int process() = 0; @@ -300,6 +332,8 @@ public: int64_t get_task_version() const { return task_version_; } int64_t get_execution_id() const { return execution_id_; } int64_t get_parallelism() const { return parallelism_; } + void set_longops_stat(share::ObDDLLongopsStat *longops_stat) { longops_stat_ = longops_stat; } + share::ObDDLLongopsStat *get_longops_stat() const { return longops_stat_; } int64_t get_cluster_version() const { return cluster_version_; } static int deep_copy_table_arg(common::ObIAllocator &allocator, const obrpc::ObDDLArg &source_arg, obrpc::ObDDLArg &dest_arg); static int fetch_new_task_id(ObMySQLProxy &sql_proxy, int64_t &new_task_id); @@ -324,10 +358,13 @@ public: void set_sys_task_id(const TraceId &sys_task_id) { sys_task_id_ = sys_task_id; } void set_sql_exec_addr(const common::ObAddr &addr) { sql_exec_addr_ = addr; } const TraceId &get_sys_task_id() const { return sys_task_id_; } + virtual int collect_longops_stat(share::ObLongopsValue &value); + void calc_next_schedule_ts(const int ret_code, const int64_t total_task_cnt); bool need_schedule() { return next_schedule_ts_ <= ObTimeUtility::current_time(); } bool is_replica_build_need_retry(const int ret_code); int push_execution_id(); + virtual bool support_longops_monitoring() const { return false; } #ifdef ERRSIM int check_errsim_error(); #endif @@ -337,14 +374,37 @@ public: K(target_object_id_), K(task_status_), K(snapshot_version_), K_(ret_code), K_(task_id), K_(parent_task_id), K_(parent_task_key), K_(task_version), K_(parallelism), K_(ddl_stmt_str), K_(compat_mode), - K_(sys_task_id), K_(err_code_occurence_cnt), K_(next_schedule_ts), K_(delay_schedule_time), - K(execution_id_), K(sql_exec_addr_), K_(cluster_version)); + K_(sys_task_id), K_(err_code_occurence_cnt), K_(stat_info), + K_(next_schedule_ts), K_(delay_schedule_time), K(execution_id_), K(sql_exec_addr_), K_(cluster_version)); protected: + int gather_redefinition_stats(const uint64_t tenant_id, + const int64_t task_id, + ObMySQLProxy &sql_proxy, + int64_t &row_scanned, + int64_t &row_sorted, + int64_t &row_inserted); + int gather_scanned_rows( + const uint64_t tenant_id, + const int64_t task_id, + ObMySQLProxy &sql_proxy, + int64_t &row_scanned); + int gather_sorted_rows( + const uint64_t tenant_id, + const int64_t task_id, + ObMySQLProxy &sql_proxy, + int64_t &row_sorted); + int gather_inserted_rows( + const uint64_t tenant_id, + const int64_t task_id, + ObMySQLProxy &sql_proxy, + int64_t &row_inserted); + int copy_longops_stat(share::ObLongopsValue &value); virtual bool is_error_need_retry(const int ret_code) { return !share::ObIDDLTask::in_ddl_retry_black_list(ret_code) && (share::ObIDDLTask::in_ddl_retry_white_list(ret_code) || MAX_ERR_TOLERANCE_CNT > ++err_code_occurence_cnt_); } + int init_ddl_task_monitor_info(const ObTableSchema *target_schema); protected: static const int64_t MAX_ERR_TOLERANCE_CNT = 3L; // Max torlerance count for error code. bool is_inited_; @@ -369,6 +429,8 @@ protected: lib::Worker::CompatMode compat_mode_; TraceId sys_task_id_; int64_t err_code_occurence_cnt_; // occurence count for all error return codes not in white list. + share::ObDDLLongopsStat *longops_stat_; + ObDDLTaskStatInfo stat_info_; int64_t delay_schedule_time_; int64_t next_schedule_ts_; int64_t execution_id_; diff --git a/src/rootserver/ddl_task/ob_drop_primary_key_task.cpp b/src/rootserver/ddl_task/ob_drop_primary_key_task.cpp index 66576bdf23..def19d9fe6 100644 --- a/src/rootserver/ddl_task/ob_drop_primary_key_task.cpp +++ b/src/rootserver/ddl_task/ob_drop_primary_key_task.cpp @@ -31,6 +31,7 @@ using namespace oceanbase::rootserver; ObDropPrimaryKeyTask::ObDropPrimaryKeyTask() : ObTableRedefinitionTask() { + task_type_ = ObDDLType::DDL_DROP_PRIMARY_KEY; } ObDropPrimaryKeyTask::~ObDropPrimaryKeyTask() diff --git a/src/rootserver/ddl_task/ob_index_build_task.cpp b/src/rootserver/ddl_task/ob_index_build_task.cpp index 6572812e81..1e21888883 100644 --- a/src/rootserver/ddl_task/ob_index_build_task.cpp +++ b/src/rootserver/ddl_task/ob_index_build_task.cpp @@ -149,8 +149,9 @@ int ObIndexSSTableBuildTask::process() LOG_INFO("build index sstable finish", K(ret), K(*this)); ObDDLTaskKey task_key(dest_table_id_, schema_version_); + ObDDLTaskInfo info; int tmp_ret = root_service_->get_ddl_scheduler().on_sstable_complement_job_reply( - unused_tablet_id, task_key, snapshot_version_, execution_id_, ret); + unused_tablet_id, task_key, snapshot_version_, execution_id_, ret, info); if (OB_SUCCESS != tmp_ret) { LOG_WARN("report build finish failed", K(ret), K(tmp_ret)); ret = OB_SUCCESS == ret ? tmp_ret : ret; @@ -324,6 +325,11 @@ int ObIndexBuildTask::init( cluster_version_ = GET_MIN_CLUSTER_VERSION(); if (OB_SUCC(ret)) { task_status_ = static_cast(task_status); + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(init_ddl_task_monitor_info(data_table_schema))) { + LOG_WARN("init ddl task monitor info failed", K(ret)); + } else { is_inited_ = true; } } @@ -337,7 +343,10 @@ int ObIndexBuildTask::init(const ObDDLTaskRecord &task_record) const uint64_t index_table_id = task_record.target_object_id_; const int64_t schema_version = task_record.schema_version_; int64_t pos = 0; + const ObTableSchema *data_schema = nullptr; const ObTableSchema *index_schema = nullptr; + const char *ddl_type_str = nullptr; + const char *target_name = nullptr; ObSchemaGetterGuard schema_guard; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; @@ -358,11 +367,13 @@ int ObIndexBuildTask::init(const ObDDLTaskRecord &task_record) LOG_WARN("fail to get schema guard", K(ret), K(index_table_id), K(schema_version)); } else if (OB_FAIL(schema_guard.check_formal_guard())) { LOG_WARN("schema_guard is not formal", K(ret), K(index_table_id)); + } else if (OB_FAIL(schema_guard.get_table_schema(task_record.tenant_id_, data_table_id, data_schema))) { + LOG_WARN("fail to get table schema", K(ret), K(data_table_id)); } else if (OB_FAIL(schema_guard.get_table_schema(task_record.tenant_id_, index_table_id, index_schema))) { - LOG_WARN("fail to get table schema", K(ret)); - } else if (OB_ISNULL(index_schema)) { + LOG_WARN("fail to get table schema", K(ret), K(index_table_id)); + } else if (OB_ISNULL(data_schema) || OB_ISNULL(index_schema)) { ret = OB_TABLE_NOT_EXIST; - LOG_WARN("fail to get table schema", K(ret)); + LOG_WARN("fail to get table schema", K(ret), K(data_schema), K(index_schema)); } else { set_sql_exec_addr(create_index_arg_.inner_sql_exec_addr_); // set to switch_status, if task cancel, we should kill session with inner_sql_exec_addr_ is_global_index_ = index_schema->is_global_index_table(); @@ -374,13 +385,19 @@ int ObIndexBuildTask::init(const ObDDLTaskRecord &task_record) snapshot_version_ = task_record.snapshot_version_; execution_id_ = task_record.execution_id_; task_status_ = static_cast(task_record.task_status_); + if (ObDDLTaskStatus::VALIDATE_CHECKSUM == task_status_) { sstable_complete_ts_ = ObTimeUtility::current_time(); } task_id_ = task_record.task_id_; parent_task_id_ = task_record.parent_task_id_; ret_code_ = task_record.ret_code_; - is_inited_ = true; + + if (OB_FAIL(init_ddl_task_monitor_info(data_schema))) { + LOG_WARN("init ddl task monitor info failed", K(ret)); + } else { + is_inited_ = true; + } } return ret; } @@ -960,9 +977,11 @@ int ObIndexBuildTask::update_complete_sstable_job_status( const common::ObTabletID &tablet_id, const int64_t snapshot_version, const int64_t execution_id, - const int ret_code) + const int ret_code, + const ObDDLTaskInfo &addition_info) { int ret = OB_SUCCESS; + UNUSED(addition_info); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); @@ -1227,6 +1246,108 @@ int ObIndexBuildTask::cleanup() return ret; } +int ObIndexBuildTask::collect_longops_stat(ObLongopsValue &value) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + const ObDDLTaskStatus status = static_cast(task_status_); + databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "TENANT_ID: %ld, TASK_ID: %ld, ", tenant_id_, task_id_); + switch(status) { + case ObDDLTaskStatus::PREPARE: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: PREPARE"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_TRANS_END: { + if (snapshot_version_ > 0) { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: ACQUIRE SNAPSHOT, SNAPSHOT_VERSION: %ld", + snapshot_version_))) { + LOG_WARN("failed to print", K(ret)); + } + } else { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: WAIT TRANS END, PENDING_TX_ID: %ld", + wait_trans_ctx_.get_pending_tx_id().get_id()))) { + LOG_WARN("failed to print", K(ret)); + } + } + break; + } + case ObDDLTaskStatus::REDEFINITION: { + int64_t row_scanned = 0; + int64_t row_sorted = 0; + int64_t row_inserted = 0; + if (OB_FAIL(gather_redefinition_stats(tenant_id_, task_id_, *GCTX.sql_proxy_, row_scanned, row_sorted, row_inserted))) { + LOG_WARN("failed to gather redefinition stats", K(ret)); + } else if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: REPLICA BUILD, ROW_SCANNED: %ld, ROW_SORTED: %ld, ROW_INSERTED: %ld", + row_scanned, + row_sorted, + row_inserted))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::VALIDATE_CHECKSUM: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: VALIDATE CHECKSUM"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::TAKE_EFFECT: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: ENABLE INDEX"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::FAIL: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: CLEAN ON FAIL"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::SUCCESS: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: CLEAN ON SUCCESS"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + default: + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not expected status", K(ret), K(status), K(*this)); + break; + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(copy_longops_stat(value))) { + LOG_WARN("failed to collect common longops stat", K(ret)); + } + + return ret; +} + int ObIndexBuildTask::serialize_params_to_message(char *buf, const int64_t buf_len, int64_t &pos) const { int ret = OB_SUCCESS; @@ -1254,7 +1375,7 @@ int ObIndexBuildTask::deserlize_params_from_message(const char *buf, const int64 } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &task_version_))) { LOG_WARN("fail to deserialize task version", K(ret)); } else if (OB_FAIL(tmp_arg.deserialize(buf, data_len, pos))) { - LOG_WARN("serialize table failed", K(ret)); + LOG_WARN("deserialize table failed", K(ret)); } else if (OB_FAIL(deep_copy_table_arg(allocator_, tmp_arg, create_index_arg_))) { LOG_WARN("deep copy create index arg failed", K(ret)); } else { @@ -1266,7 +1387,9 @@ int ObIndexBuildTask::deserlize_params_from_message(const char *buf, const int64 int64_t ObIndexBuildTask::get_serialize_param_size() const { - return create_index_arg_.get_serialize_size() + serialization::encoded_length_i64(check_unique_snapshot_) - + serialization::encoded_length_i64(task_version_) + serialization::encoded_length_i64(parallelism_) - + serialization::encoded_length_i64(cluster_version_); + return create_index_arg_.get_serialize_size() + + serialization::encoded_length_i64(check_unique_snapshot_) + + serialization::encoded_length_i64(task_version_) + + serialization::encoded_length_i64(parallelism_) + + serialization::encoded_length_i64(cluster_version_); } diff --git a/src/rootserver/ddl_task/ob_index_build_task.h b/src/rootserver/ddl_task/ob_index_build_task.h index 4a095da2cc..a69f2b1bdf 100644 --- a/src/rootserver/ddl_task/ob_index_build_task.h +++ b/src/rootserver/ddl_task/ob_index_build_task.h @@ -98,12 +98,15 @@ public: const common::ObTabletID &tablet_id, const int64_t snapshot_version, const int64_t execution_id, - const int ret_code); + const int ret_code, + const ObDDLTaskInfo &addition_info); virtual int process() override; virtual bool is_valid() const override; + virtual int collect_longops_stat(share::ObLongopsValue &value) override; virtual int serialize_params_to_message(char *buf, const int64_t buf_size, int64_t &pos) const override; virtual int deserlize_params_from_message(const char *buf, const int64_t buf_size, int64_t &pos) override; virtual int64_t get_serialize_param_size() const override; + virtual bool support_longops_monitoring() const override { return true; } static int deep_copy_index_arg(common::ObIAllocator &allocator, const obrpc::ObCreateIndexArg &source_arg, obrpc::ObCreateIndexArg &dest_arg); INHERIT_TO_STRING_KV("ObDDLTask", ObDDLTask, K(index_table_id_),K(snapshot_held_), K(is_sstable_complete_task_submitted_), K(sstable_complete_ts_), K(check_unique_snapshot_), K_(redefinition_execution_id), K(create_index_arg_)); diff --git a/src/rootserver/ddl_task/ob_table_redefinition_task.cpp b/src/rootserver/ddl_task/ob_table_redefinition_task.cpp index cef475f14f..db54e4db9e 100644 --- a/src/rootserver/ddl_task/ob_table_redefinition_task.cpp +++ b/src/rootserver/ddl_task/ob_table_redefinition_task.cpp @@ -72,7 +72,11 @@ int ObTableRedefinitionTask::init(const uint64_t tenant_id, const int64_t task_i parallelism_ = parallelism; cluster_version_ = GET_MIN_CLUSTER_VERSION(); alter_table_arg_.exec_tenant_id_ = tenant_id_; - is_inited_ = true; + if (OB_FAIL(init_ddl_task_monitor_info(&alter_table_arg_.alter_table_schema_))) { + LOG_WARN("init ddl task monitor info failed", K(ret)); + } else { + is_inited_ = true; + } } return ret; } @@ -107,7 +111,12 @@ int ObTableRedefinitionTask::init(const ObDDLTaskRecord &task_record) tenant_id_ = task_record.tenant_id_; ret_code_ = task_record.ret_code_; alter_table_arg_.exec_tenant_id_ = tenant_id_; - is_inited_ = true; + + if (OB_FAIL(init_ddl_task_monitor_info(&alter_table_arg_.alter_table_schema_))) { + LOG_WARN("init ddl task monitor info failed", K(ret)); + } else { + is_inited_ = true; + } } return ret; } @@ -115,11 +124,13 @@ int ObTableRedefinitionTask::init(const ObDDLTaskRecord &task_record) int ObTableRedefinitionTask::update_complete_sstable_job_status(const common::ObTabletID &tablet_id, const int64_t snapshot_version, const int64_t execution_id, - const int ret_code) + const int ret_code, + const ObDDLTaskInfo &addition_info) { int ret = OB_SUCCESS; TCWLockGuard guard(lock_); UNUSED(tablet_id); + UNUSED(addition_info); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObTableRedefinitionTask has not been inited", K(ret)); @@ -289,7 +300,6 @@ int ObTableRedefinitionTask::table_redefinition(const ObDDLTaskStatus next_task_ LOG_WARN("fail to switch task status", K(ret)); } } - return ret; } @@ -387,6 +397,7 @@ int ObTableRedefinitionTask::copy_table_indexes() const uint64_t task_key = index_ids.at(i); DependTaskStatus status; status.task_id_ = task_record.task_id_; + TCWLockGuard guard(lock_); if (OB_FAIL(dependent_task_result_map_.set_refactored(task_key, status))) { if (OB_HASH_EXIST == ret) { ret = OB_SUCCESS; @@ -564,6 +575,7 @@ int ObTableRedefinitionTask::copy_table_dependent_objects(const ObDDLTaskStatus } else { // wait copy dependent objects to be finished ObAddr unused_addr; + TCRLockGuard guard(lock_); for (common::hash::ObHashMap::const_iterator iter = dependent_task_result_map_.begin(); iter != dependent_task_result_map_.end(); ++iter) { const uint64_t task_key = iter->first; @@ -765,3 +777,142 @@ int ObTableRedefinitionTask::check_modify_autoinc(bool &modify_autoinc) } return ret; } + +int ObTableRedefinitionTask::collect_longops_stat(ObLongopsValue &value) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + const ObDDLTaskStatus status = static_cast(task_status_); + databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "TENANT_ID: %ld, TASK_ID: %ld, ", tenant_id_, task_id_); + switch (status) { + case ObDDLTaskStatus::PREPARE: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + "STATUS: PREPARE"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_TRANS_END: { + if (snapshot_version_ > 0) { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: ACQUIRE SNAPSHOT, SNAPSHOT_VERSION: %ld", + snapshot_version_))) { + LOG_WARN("failed to print", K(ret)); + } + } else { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: WAIT TRANS END, PENDING_TX_ID: %ld", + wait_trans_ctx_.get_pending_tx_id().get_id()))) { + LOG_WARN("failed to print", K(ret)); + } + } + break; + } + case ObDDLTaskStatus::LOCK_TABLE: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: ACQUIRE TABLE LOCK"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::CHECK_TABLE_EMPTY: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: CHECK TABLE EMPTY"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::REDEFINITION: { + int64_t row_scanned = 0; + int64_t row_sorted = 0; + int64_t row_inserted = 0; + if (OB_FAIL(gather_redefinition_stats(tenant_id_, task_id_, *GCTX.sql_proxy_, row_scanned, row_sorted, row_inserted))) { + LOG_WARN("failed to gather redefinition stats", K(ret)); + } else if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: REPLICA BUILD, ROW_SCANNED: %ld, ROW_SORTED: %ld, ROW_INSERTED: %ld", + row_scanned, + row_sorted, + row_inserted))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::COPY_TABLE_DEPENDENT_OBJECTS: { + char child_task_ids[MAX_LONG_OPS_MESSAGE_LENGTH]; + if (OB_FAIL(get_child_task_ids(child_task_ids, MAX_LONG_OPS_MESSAGE_LENGTH))) { + if (ret == OB_SIZE_OVERFLOW) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get all child task ids", K(ret)); + } + } else if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: COPY DEPENDENT OBJECTS, CHILD TASK IDS: %s", + child_task_ids))) { + if (ret == OB_SIZE_OVERFLOW) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to print", K(ret)); + } + } + break; + } + case ObDDLTaskStatus::MODIFY_AUTOINC: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: MODIFY AUTOINC"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::TAKE_EFFECT: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: TAKE EFFECT"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::FAIL: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + "STATUS: CLEAN ON FAIL"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::SUCCESS: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: CLEAN ON SUCCESS"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + default: { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not expected status", K(ret), K(status), K(*this)); + break; + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(copy_longops_stat(value))) { + LOG_WARN("failed to collect common longops stat", K(ret)); + } + return ret; +} diff --git a/src/rootserver/ddl_task/ob_table_redefinition_task.h b/src/rootserver/ddl_task/ob_table_redefinition_task.h index 9989306d36..29fd089cd1 100644 --- a/src/rootserver/ddl_task/ob_table_redefinition_task.h +++ b/src/rootserver/ddl_task/ob_table_redefinition_task.h @@ -44,7 +44,10 @@ public: const common::ObTabletID &tablet_id, const int64_t snapshot_version, const int64_t execution_id, - const int ret_code) override; + const int ret_code, + const ObDDLTaskInfo &addition_info) override; + virtual int collect_longops_stat(share::ObLongopsValue &value) override; + virtual bool support_longops_monitoring() const override { return true; } protected: int table_redefinition(const share::ObDDLTaskStatus next_task_status); int copy_table_dependent_objects(const share::ObDDLTaskStatus next_task_status); diff --git a/src/rootserver/ob_root_service.cpp b/src/rootserver/ob_root_service.cpp index 34cb74273c..5530993134 100644 --- a/src/rootserver/ob_root_service.cpp +++ b/src/rootserver/ob_root_service.cpp @@ -9473,6 +9473,9 @@ int ObRootService::build_ddl_single_replica_response(const obrpc::ObDDLBuildSing { int ret = OB_SUCCESS; LOG_INFO("receive build ddl single replica response", K(arg)); + ObDDLTaskInfo info; + info.row_scanned_ = arg.row_scanned_; + info.row_inserted_ = arg.row_inserted_; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); @@ -9480,7 +9483,7 @@ int ObRootService::build_ddl_single_replica_response(const obrpc::ObDDLBuildSing ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), K(arg)); } else if (OB_FAIL(ddl_scheduler_.on_sstable_complement_job_reply( - arg.tablet_id_/*source tablet id*/, ObDDLTaskKey(arg.dest_schema_id_, arg.schema_version_), arg.snapshot_version_, arg.execution_id_, arg.ret_code_))) { + arg.tablet_id_/*source tablet id*/, ObDDLTaskKey(arg.dest_schema_id_, arg.schema_version_), arg.snapshot_version_, arg.execution_id_, arg.ret_code_, info))) { LOG_WARN("handle column checksum calc response failed", K(ret), K(arg)); } return ret; diff --git a/src/share/CMakeLists.txt b/src/share/CMakeLists.txt index a3cdf0f264..1170fbb196 100644 --- a/src/share/CMakeLists.txt +++ b/src/share/CMakeLists.txt @@ -272,6 +272,12 @@ ob_set_subtarget(ob_share partition_table partition_table/ob_partition_location.cpp ) +ob_set_subtarget(ob_share longops_mgr + longops_mgr/ob_ddl_longops.cpp + longops_mgr/ob_i_longops.cpp + longops_mgr/ob_longops_mgr.cpp +) + ob_set_subtarget(ob_share ls ls/ob_inmemory_ls_table.cpp ls/ob_ls_info.cpp diff --git a/src/share/diagnosis/ob_sql_monitor_statname.h b/src/share/diagnosis/ob_sql_monitor_statname.h index a7f1510f6c..98c1b6ba10 100644 --- a/src/share/diagnosis/ob_sql_monitor_statname.h +++ b/src/share/diagnosis/ob_sql_monitor_statname.h @@ -44,6 +44,14 @@ SQL_MONITOR_STATNAME_DEF(MEMORY_DUMP, sql_monitor_statname::CAPACITY, "memory du // GI SQL_MONITOR_STATNAME_DEF(FILTERED_GRANULE_COUNT, sql_monitor_statname::INT, "filtered granule count", "filtered granule count in GI op") SQL_MONITOR_STATNAME_DEF(TOTAL_GRANULE_COUNT, sql_monitor_statname::INT, "total granule count", "total granule count in GI op") +// sort +SQL_MONITOR_STATNAME_DEF(SORT_SORTED_ROW_COUNT, sql_monitor_statname::INT, "sorted row count", "sorted row count in sort op") +SQL_MONITOR_STATNAME_DEF(SORT_MERGE_SORT_ROUND, sql_monitor_statname::INT, "merge sort round", "merge sort round in sort op") +SQL_MONITOR_STATNAME_DEF(SORT_INMEM_SORT_TIME, sql_monitor_statname::INT, "in memory sort time", "time taken by in memory sort") +SQL_MONITOR_STATNAME_DEF(SORT_DUMP_DATA_TIME, sql_monitor_statname::INT, "sort dump data time", "time taken by dump data") +// SSTABLE INSERT +SQL_MONITOR_STATNAME_DEF(DDL_TASK_ID, sql_monitor_statname::INT, "ddl task id", "sort ddl task id") +SQL_MONITOR_STATNAME_DEF(SSTABLE_INSERT_ROW_COUNT, sql_monitor_statname::INT, "sstable insert row count", "sstable insert row count") //end SQL_MONITOR_STATNAME_DEF(MONITOR_STATNAME_END, sql_monitor_statname::INVALID, "monitor end", "monitor stat name end") #endif diff --git a/src/share/inner_table/ob_inner_table_schema.21051_21100.cpp b/src/share/inner_table/ob_inner_table_schema.21051_21100.cpp index 38864d4172..1ae6a70079 100644 --- a/src/share/inner_table/ob_inner_table_schema.21051_21100.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21051_21100.cpp @@ -259,7 +259,7 @@ int ObInnerTableSchema::gv_session_longops_schema(ObTableSchema &table_schema) table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); if (OB_SUCC(ret)) { - if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(sid AS SIGNED) AS SID, CAST(trace_id AS CHAR(64)) AS TRACE_ID, CAST(op_name AS CHAR(64)) AS OPNAME, CAST(TARGET AS CHAR(64)) AS TARGET, CAST(SVR_IP AS CHAR(46)) AS SVR_IP, CAST(SVR_PORT AS SIGNED) AS SVR_PORT, CAST(START_TIME AS DATE) AS START_TIME, CAST(ELAPSED_TIME/1000000 AS SIGNED) AS ELAPSED_SECONDS, CAST(REMAINING_TIME AS SIGNED) AS TIME_REMAINING, CAST(LAST_UPDATE_TIME AS DATE) AS LAST_UPDATE_TIME, CAST(MESSAGE AS CHAR(512)) AS MESSAGE FROM oceanbase.__all_virtual_long_ops_status )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(sid AS SIGNED) AS SID, CAST(trace_id AS CHAR(64)) AS TRACE_ID, CAST(op_name AS CHAR(64)) AS OPNAME, CAST(TARGET AS CHAR(64)) AS TARGET, CAST(SVR_IP AS CHAR(46)) AS SVR_IP, CAST(SVR_PORT AS SIGNED) AS SVR_PORT, CAST(USEC_TO_TIME(START_TIME) AS DATE) AS START_TIME, CAST(ELAPSED_TIME/1000000 AS SIGNED) AS ELAPSED_SECONDS, CAST(REMAINING_TIME AS SIGNED) AS TIME_REMAINING, CAST(USEC_TO_TIME(LAST_UPDATE_TIME) AS DATE) AS LAST_UPDATE_TIME, CAST(MESSAGE AS CHAR(512)) AS MESSAGE FROM oceanbase.__all_virtual_long_ops_status )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema_def.py b/src/share/inner_table/ob_inner_table_schema_def.py index 95fd1bbaec..f08211e7ab 100644 --- a/src/share/inner_table/ob_inner_table_schema_def.py +++ b/src/share/inner_table/ob_inner_table_schema_def.py @@ -13108,10 +13108,10 @@ def_table_schema( CAST(TARGET AS CHAR(64)) AS TARGET, CAST(SVR_IP AS CHAR(46)) AS SVR_IP, CAST(SVR_PORT AS SIGNED) AS SVR_PORT, - CAST(START_TIME AS DATE) AS START_TIME, + CAST(USEC_TO_TIME(START_TIME) AS DATE) AS START_TIME, CAST(ELAPSED_TIME/1000000 AS SIGNED) AS ELAPSED_SECONDS, CAST(REMAINING_TIME AS SIGNED) AS TIME_REMAINING, - CAST(LAST_UPDATE_TIME AS DATE) AS LAST_UPDATE_TIME, + CAST(USEC_TO_TIME(LAST_UPDATE_TIME) AS DATE) AS LAST_UPDATE_TIME, CAST(MESSAGE AS CHAR(512)) AS MESSAGE FROM oceanbase.__all_virtual_long_ops_status """.replace("\n", " ") diff --git a/src/share/longops_mgr/ob_ddl_longops.cpp b/src/share/longops_mgr/ob_ddl_longops.cpp new file mode 100644 index 0000000000..7dcc1b310d --- /dev/null +++ b/src/share/longops_mgr/ob_ddl_longops.cpp @@ -0,0 +1,107 @@ +// Copyright (c) 2021 OceanBase +// OceanBase 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. +#define USING_LOG_PREFIX SHARE + +#include "ob_ddl_longops.h" +#include "rootserver/ddl_task/ob_ddl_task.h" + +using namespace oceanbase::rootserver; +using namespace oceanbase::share; + +ObDDLLongopsKey::ObDDLLongopsKey() + : task_id_(OB_INVALID_ID) +{ +} + +int ObDDLLongopsKey::to_key_string() +{ + int ret = OB_SUCCESS; + int64_t name_pos = 0; + int64_t target_pos = 0; + if (OB_FAIL(databuff_printf(name_, MAX_LONG_OPS_NAME_LENGTH, name_pos, "DDL TASK"))) { + LOG_WARN("fail to set name string", K(ret)); + } else if (OB_FAIL(databuff_printf(target_, MAX_LONG_OPS_TARGET_LENGTH, target_pos, "task_id=%ld, ", task_id_))) { + LOG_WARN("fail to convert index_table_id to string", K(ret)); + } + return ret; +} + +ObDDLLongopsStatCollector::ObDDLLongopsStatCollector() + : is_inited_(false), ddl_task_(nullptr) +{ +} + +int ObDDLLongopsStatCollector::init(rootserver::ObDDLTask *ddl_task) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ObDDLLongopsStatCollector init twice", K(ret)); + } else if (OB_ISNULL(ddl_task)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(ddl_task)); + } else { + ddl_task_ = ddl_task; + is_inited_ = true; + } + return ret; +} + +int ObDDLLongopsStatCollector::collect(ObLongopsValue &value) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObDDLLongopsStatCollector is not inited", K(ret)); + } else if (OB_FAIL(ddl_task_->collect_longops_stat(value))) { + LOG_WARN("failed to collect ddl task longops stat", K(ret)); + } + return ret; +} + +ObDDLLongopsStat::ObDDLLongopsStat() + : is_inited_(false), key_(), value_(), collector_() +{ +} + +int ObDDLLongopsStat::get_longops_value(ObLongopsValue &value) +{ + int ret = OB_SUCCESS; + value.reset(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObDDLLongopsStat is not inited", K(ret)); + } else if (OB_FAIL(collector_.collect(value))) { + LOG_WARN("failed to collect longops value", K(ret)); + } else { + value_ = value; + } + return ret; +} + +int ObDDLLongopsStat::init(ObDDLTask *ddl_task) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ObDDLLongopsStat init twice", K(ret)); + } else if (OB_ISNULL(ddl_task)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(ddl_task)); + } else if (OB_FAIL(collector_.init(ddl_task))) { + LOG_WARN("failed to init collector", K(ret)); + } else { + key_.tenant_id_ = ddl_task->get_tenant_id(); + key_.task_id_ = ddl_task->get_task_id(); + key_.to_key_string(); + is_inited_ = true; + } + return ret; +} diff --git a/src/share/longops_mgr/ob_ddl_longops.h b/src/share/longops_mgr/ob_ddl_longops.h new file mode 100644 index 0000000000..1a2ed10b51 --- /dev/null +++ b/src/share/longops_mgr/ob_ddl_longops.h @@ -0,0 +1,68 @@ +// Copyright (c) 2021 OceanBase +// OceanBase 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. + +#ifndef OCEANBASE_SHARE_LONGOPS_MGR_DDL_LONGOPS_H_ +#define OCEANBASE_SHARE_LONGOPS_MGR_DDL_LONGOPS_H_ + +#include "ob_i_longops.h" + +namespace oceanbase +{ +namespace rootserver +{ +class ObDDLTask; +} +namespace share +{ +struct ObDDLLongopsKey : public ObILongopsKey +{ +public: + ObDDLLongopsKey(); + virtual ~ObDDLLongopsKey() = default; + virtual bool is_valid() const { return ObILongopsKey::is_valid() && task_id_ >= 0; } + virtual int to_key_string() override; + INHERIT_TO_STRING_KV("ObILongopsKey", ObILongopsKey, K_(task_id)); +public: + int64_t task_id_; +}; + +class ObDDLLongopsStatCollector : public ObILongopsStatCollector +{ +public: + ObDDLLongopsStatCollector(); + virtual ~ObDDLLongopsStatCollector() = default; + int init(rootserver::ObDDLTask *ddl_task); + virtual int collect(ObLongopsValue &value) override; +private: + bool is_inited_; + rootserver::ObDDLTask *ddl_task_; +}; + +class ObDDLLongopsStat : public ObILongopsStat +{ +public: + ObDDLLongopsStat(); + virtual ~ObDDLLongopsStat() = default; + int init(rootserver::ObDDLTask *ddl_task); + virtual bool is_valid() const override { return key_.is_valid(); } + virtual const ObILongopsKey &get_longops_key() const override { return key_; } + virtual int get_longops_value(ObLongopsValue &value) override; + TO_STRING_KV(K_(is_inited), K_(key), K_(value)); +private: + bool is_inited_; + ObDDLLongopsKey key_; + ObLongopsValue value_; + ObDDLLongopsStatCollector collector_; +}; + +} // end namespace share +} // end namespace oceanbase + +#endif // OCEANBASE_SHARE_LONGOPS_MGR_DDL_LONGOPS_H_ diff --git a/src/share/longops_mgr/ob_i_longops.cpp b/src/share/longops_mgr/ob_i_longops.cpp new file mode 100644 index 0000000000..0a9674a5d8 --- /dev/null +++ b/src/share/longops_mgr/ob_i_longops.cpp @@ -0,0 +1,88 @@ +// Copyright (c) 2021 OceanBase +// OceanBase 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. +#define USING_LOG_PREFIX SHARE + +#include "ob_i_longops.h" + +using namespace oceanbase::common; +using namespace oceanbase::share; + +ObILongopsKey::ObILongopsKey() + : tenant_id_(OB_INVALID_ID), + sid_(OB_INVALID_ID) +{ + MEMSET(name_, 0, sizeof(name_)); + MEMSET(target_, 0 ,sizeof(target_)); +} + +int64_t ObILongopsKey::hash() const +{ + uint64_t hash_val = 0; + hash_val = murmurhash(&tenant_id_, sizeof(tenant_id_), hash_val); + hash_val = murmurhash(&sid_, sizeof(sid_), hash_val); + hash_val = murmurhash(name_, sizeof(name_), hash_val); + hash_val = murmurhash(target_, sizeof(target_), hash_val); + return hash_val; +} + +bool ObILongopsKey::operator==(const ObILongopsKey &other) const +{ + return tenant_id_ == other.tenant_id_ && + sid_ == other.sid_ && + (0 == MEMCMP(name_, other.name_, sizeof(name_))) && + (0 == MEMCMP(target_, other.target_, sizeof(target_))); +} + +bool ObILongopsKey::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ && + '\0' != name_[0] && + '\0' != target_[0]; +} + +ObLongopsValue::ObLongopsValue() + : trace_id_(), sid_(OB_INVALID_ID), tenant_id_(OB_INVALID_ID), start_time_(-1), finish_time_(-1), elapsed_seconds_(0), + time_remaining_(0), percentage_(0), last_update_time_(0), op_name_(), target_(), message_() +{ +} + +ObLongopsValue &ObLongopsValue::operator=(const ObLongopsValue &other) +{ + if (this != &other) { + trace_id_ = other.trace_id_; + sid_ = other.sid_; + tenant_id_ = other.tenant_id_; + start_time_ = other.start_time_; + finish_time_ = other.finish_time_; + elapsed_seconds_ = other.elapsed_seconds_; + time_remaining_ = other.time_remaining_; + percentage_ = other.percentage_; + last_update_time_ = other.last_update_time_; + MEMCPY(op_name_, other.op_name_, sizeof(op_name_)); + MEMCPY(target_, other.target_, sizeof(target_)); + MEMCPY(message_, other.message_, sizeof(message_)); + } + return *this; +} + +void ObLongopsValue::reset() +{ + trace_id_.reset(); + tenant_id_ = OB_INVALID_ID; + start_time_ = -1; + finish_time_ = -1; + elapsed_seconds_ = 0; + time_remaining_ = 0; + percentage_ = 0; + last_update_time_ = 0; + memset(op_name_, 0, sizeof(op_name_)); + memset(target_, 0, sizeof(target_)); + memset(message_, 0, sizeof(message_)); +} diff --git a/src/share/longops_mgr/ob_i_longops.h b/src/share/longops_mgr/ob_i_longops.h new file mode 100644 index 0000000000..b45662fffb --- /dev/null +++ b/src/share/longops_mgr/ob_i_longops.h @@ -0,0 +1,91 @@ +// Copyright (c) 2021 OceanBase +// OceanBase 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. + +#ifndef OCEANBASE_SHARE_LONGOPS_MGR_I_LONGOPS_H_ +#define OCEANBASE_SHARE_LONGOPS_MGR_I_LONGOPS_H_ + +#include "lib/ob_define.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/profile/ob_trace_id.h" +#include "lib/utility/ob_print_utils.h" + +namespace oceanbase +{ +namespace share +{ + +struct ObILongopsKey +{ +public: + ObILongopsKey(); + virtual ~ObILongopsKey() = default; + virtual int64_t hash() const; + virtual bool is_valid() const; + virtual int to_key_string() { return common::OB_NOT_SUPPORTED; } + bool operator ==(const ObILongopsKey &other) const; + TO_STRING_KV(K_(tenant_id), K_(sid), K_(name), K_(target)); +public: + uint64_t tenant_id_; + uint64_t sid_; + char name_[common::MAX_LONG_OPS_NAME_LENGTH]; + char target_[common::MAX_LONG_OPS_TARGET_LENGTH]; +}; + +enum ObLongopsType +{ + LONGOPS_INVALID = 0, + LONGOPS_DDL = 1, + LONGOPS_MAX +}; + +struct ObLongopsValue final +{ +public: + ObLongopsValue(); + virtual ~ObLongopsValue() = default; + ObLongopsValue &operator=(const ObLongopsValue &other); + void reset(); + TO_STRING_KV(K_(tenant_id), K_(trace_id), K_(start_time), K_(finish_time),K_(elapsed_seconds), K_(time_remaining), + K_(percentage), K_(last_update_time), K_(op_name), K_(target), K_(message)); +public: + common::ObCurTraceId::TraceId trace_id_; + uint64_t sid_; + uint64_t tenant_id_; + int64_t start_time_; + int64_t finish_time_; + int64_t elapsed_seconds_; + int64_t time_remaining_; + int64_t percentage_; + int64_t last_update_time_; + char op_name_[common::MAX_LONG_OPS_NAME_LENGTH]; + char target_[common::MAX_LONG_OPS_TARGET_LENGTH]; + char message_[common::MAX_LONG_OPS_MESSAGE_LENGTH]; +}; + +class ObILongopsStatCollector +{ +public: + virtual int collect(ObLongopsValue &value) = 0; +}; + +class ObILongopsStat +{ +public: + virtual ~ObILongopsStat() {} + virtual bool is_valid() const = 0; + virtual const ObILongopsKey &get_longops_key() const = 0; + virtual int get_longops_value(ObLongopsValue &value) = 0; + virtual int64_t to_string(char* buf, const int64_t buf_len) const = 0; +}; + +} // end namespace share +} // end namespace oceanbase + +#endif // OCEANBASE_SHARE_LONGOPS_MGR_I_LONGOPS_H_ diff --git a/src/share/longops_mgr/ob_longops_mgr.cpp b/src/share/longops_mgr/ob_longops_mgr.cpp new file mode 100644 index 0000000000..44ba854109 --- /dev/null +++ b/src/share/longops_mgr/ob_longops_mgr.cpp @@ -0,0 +1,253 @@ +// Copyright (c) 2021 OceanBase +// OceanBase 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. + +#define USING_LOG_PREFIX SHARE + +#include "ob_longops_mgr.h" +#include "lib/oblog/ob_log_module.h" + +namespace oceanbase +{ + +namespace share +{ +ObLongopsMgr::ObLongopsMgr() + : is_inited_(false), allocator_(), bucket_lock_(), map_() +{ +} + +ObLongopsMgr &ObLongopsMgr::get_instance() +{ + static ObLongopsMgr longops_mgr; + return longops_mgr; +} + +int ObLongopsMgr::init() +{ + int ret = OB_SUCCESS; + const int64_t memory_limit = 100 * 1024L * 1024L; // 100MB + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("ObLongopsMgr has been inited", K(ret)); + } else if (OB_FAIL(bucket_lock_.init(DEFAULT_BUCKET_NUM))) { + LOG_WARN("failed to init bucket lock", K(ret)); + } else if (OB_FAIL(map_.create(DEFAULT_BUCKET_NUM, "ObLongopsMgr"))) { + LOG_WARN("failed to init resource map", K(ret)); + } else if (OB_FAIL(allocator_.init(DEFAULT_ALLOCATOR_PAGE_SIZE, + lib::ObLabel("LongopsMgr"), + OB_SERVER_TENANT_ID, + memory_limit))) { + LOG_WARN("failed to init allocator", K(ret)); + } else { + is_inited_ = true; + } + return ret; +} + +void ObLongopsMgr::destroy() +{ + if (map_.created()) { + map_.destroy(); + } +} + +void ObLongopsMgr::free_longops(ObILongopsStat *stat) +{ + stat->~ObILongopsStat(); + allocator_.free(stat); +} + +int ObLongopsMgr::register_longops(ObILongopsStat *stat) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLongopsMgr has not been inited", K(ret)); + } else if (OB_ISNULL(stat) || OB_UNLIKELY(!stat->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KPC(stat)); + } else { + ObBucketHashWLockGuard guard(bucket_lock_, stat->get_longops_key().hash()); + if (OB_FAIL(map_.set_refactored(stat->get_longops_key(), stat))) { + LOG_WARN("failed to set map", K(ret), KPC(stat)); + if (OB_HASH_EXIST == ret) { + ret = OB_ENTRY_EXIST; + } + } else { + LOG_INFO("register longops finish", K(ret), K(*stat)); + } + } + return ret; +} + +int ObLongopsMgr::unregister_longops(ObILongopsStat *stat) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLongopsMgr has not been inited", K(ret)); + } else if (OB_ISNULL(stat) || OB_UNLIKELY(!stat->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KPC(stat)); + } else { + ObBucketHashWLockGuard guard(bucket_lock_, stat->get_longops_key().hash()); + ObILongopsKey key = stat->get_longops_key(); + if (OB_FAIL(map_.erase_refactored(stat->get_longops_key()))) { + if (OB_HASH_NOT_EXIST != ret) { + LOG_WARN("failed to erase map", K(ret), KPC(stat)); + } else { + ret = OB_ENTRY_NOT_EXIST; + free_longops(stat); + } + } else { + free_longops(stat); + } + LOG_INFO("unregister longops finish", K(ret), K(key)); + } + return ret; +} + +int ObLongopsMgr::get_longops(const ObILongopsKey &key, ObLongopsValue &value) +{ + int ret = OB_SUCCESS; + ObILongopsStat *stat = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLongopsMgr has not been inited", K(ret)); + } else if (OB_UNLIKELY(!key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(key)); + } else { + ObBucketHashRLockGuard guard(bucket_lock_, key.hash()); + if (OB_FAIL(map_.get_refactored(key, stat))) { + LOG_WARN("failed to get key", K(ret), K(key)); + if (OB_HASH_NOT_EXIST == ret) { + ret = OB_ENTRY_NOT_EXIST; + } + } else if (OB_ISNULL(stat)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("longops stat is null", K(ret)); + } else if (OB_FAIL(stat->get_longops_value(value))) { + LOG_WARN("failed to get longops value", K(ret), KPC(stat)); + } + } + return ret; +} + +int ObLongopsMgr::begin_iter(ObLongopsIterator &iter) +{ + int ret = OB_SUCCESS; + iter.reset(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLongopsMgr has not been inited", K(ret)); + } else if (OB_FAIL(iter.init(this))) { + LOG_WARN("failed to init longops iter", K(ret)); + } + return ret; +} + +template +int ObLongopsMgr::foreach(Callback &callback) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObLongopsMgr has not been inited", K(ret)); + } else if (OB_FAIL(map_.foreach_refactored(callback))) { + LOG_WARN("fail to foreach map", K(ret)); + } + return ret; +} + +ObLongopsIterator::ObKeySnapshotCallback::ObKeySnapshotCallback( + ObIArray &key_snapshot) + : key_snapshot_(key_snapshot) +{ +} + +int ObLongopsIterator::ObKeySnapshotCallback::operator()(PAIR &pair) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(key_snapshot_.push_back(pair.first))) { + LOG_WARN("fail to push back key", K(ret)); + } + return ret; +} + + +ObLongopsIterator::ObLongopsIterator() + : is_inited_(false), key_snapshot_(), key_cursor_(0), longops_mgr_(nullptr) +{ +} + +ObLongopsIterator::~ObLongopsIterator() +{ + reset(); +} + +void ObLongopsIterator::reset() +{ + key_snapshot_.reset(); + key_cursor_ = 0; + longops_mgr_ = nullptr; + is_inited_ = false; +} + +int ObLongopsIterator::init(ObLongopsMgr *longops_mgr) +{ + int ret = OB_SUCCESS; + ObKeySnapshotCallback callback(key_snapshot_); + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("ObLongopsIterator has been inited twice", K(ret)); + } else if (OB_ISNULL(longops_mgr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(longops_mgr)); + } else if (OB_FAIL(longops_mgr->foreach(callback))) { + LOG_WARN("failed to do foreach map", K(ret)); + } else { + key_cursor_ = 0; + longops_mgr_ = longops_mgr; + is_inited_ = true; + } + return ret; +} + +int ObLongopsIterator::get_next(ObLongopsValue &value) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObLongopsIterator has not been inited", K(ret)); + } else if (OB_UNLIKELY(key_cursor_ >= key_snapshot_.count())) { + ret = OB_ITER_END; + } else { + bool need_retry = true; + while (OB_SUCC(ret) && need_retry && key_cursor_ < key_snapshot_.count()) { + const ObILongopsKey &key = key_snapshot_.at(key_cursor_); + if (OB_FAIL(longops_mgr_->get_longops(key, value))) { + if (OB_UNLIKELY(OB_ENTRY_NOT_EXIST != ret)) { + LOG_WARN("fail to get parition stat", K(ret), K(key)); + } else { + need_retry = true; + ret = OB_SUCCESS; + } + } else { + need_retry = false; + } + ++key_cursor_; + } + } + return ret; +} + +} //end namespace share +} //end namespace oceanbase diff --git a/src/share/longops_mgr/ob_longops_mgr.h b/src/share/longops_mgr/ob_longops_mgr.h new file mode 100644 index 0000000000..9d94706984 --- /dev/null +++ b/src/share/longops_mgr/ob_longops_mgr.h @@ -0,0 +1,96 @@ +// Copyright (c) 2021 OceanBase +// OceanBase 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. + +#ifndef OCEANBASE_SHARE_LONGOPS_MGR_LONGOPS_MGR_H_ +#define OCEANBASE_SHARE_LONGOPS_MGR_LONGOPS_MGR_H_ + +#include "lib/allocator/ob_concurrent_fifo_allocator.h" +#include "lib/container/ob_array.h" +#include "lib/lock/ob_bucket_lock.h" +#include "share/longops_mgr/ob_i_longops.h" + +namespace oceanbase +{ +namespace share +{ +class ObLongopsIterator; +class ObLongopsMgr final +{ +public: + static ObLongopsMgr &get_instance(); + int init(); + void destroy(); + template + int alloc_longops(T *&longops); + void free_longops(ObILongopsStat *stat); + int register_longops(ObILongopsStat *stat); + int unregister_longops(ObILongopsStat *stat); + int get_longops(const ObILongopsKey &key, ObLongopsValue &value); + int begin_iter(ObLongopsIterator &iter); + template + int foreach(Callback &callback); +private: + ObLongopsMgr(); + ~ObLongopsMgr() { destroy(); } +private: + typedef common::hash::ObHashMap LongopsMap; + static const int64_t DEFAULT_BUCKET_NUM = 1543L; + static const int64_t DEFAULT_ALLOCATOR_PAGE_SIZE = common::OB_MALLOC_NORMAL_BLOCK_SIZE; + bool is_inited_; + common::ObConcurrentFIFOAllocator allocator_; + common::ObBucketLock bucket_lock_; + LongopsMap map_; +}; + +template +int ObLongopsMgr::alloc_longops(T *&longops) +{ + int ret = OB_SUCCESS; + longops = nullptr; + void *tmp_buf = nullptr; + if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(T)))) { + ret = common::OB_ALLOCATE_MEMORY_FAILED; + RS_LOG(WARN, "alloc longops failed", K(ret)); + } else { + longops = new (tmp_buf) T; + } + return ret; +} + +using PAIR = common::hash::HashMapPair; +class ObLongopsIterator +{ +public: + class ObKeySnapshotCallback + { + public: + explicit ObKeySnapshotCallback(common::ObIArray &key_snapshot); + virtual ~ObKeySnapshotCallback() = default; + int operator()(PAIR &pair); + private: + common::ObIArray &key_snapshot_; + }; + ObLongopsIterator(); + ~ObLongopsIterator(); + void reset(); + int init(ObLongopsMgr *longops_mgr); + int get_next(ObLongopsValue &value); + inline bool is_inited() const { return is_inited_; } +private: + bool is_inited_; + common::ObArray key_snapshot_; + int64_t key_cursor_; + ObLongopsMgr *longops_mgr_; +}; + +} // end namespace share +} // end namespace oceanbase + +#endif // OCEANBASE_SHARE_LONGOPS_MGR_LONGOPS_MGR_H_ diff --git a/src/share/ob_rpc_struct.cpp b/src/share/ob_rpc_struct.cpp index dd89c46b92..d2470e46ce 100644 --- a/src/share/ob_rpc_struct.cpp +++ b/src/share/ob_rpc_struct.cpp @@ -2715,23 +2715,6 @@ void ObCalcColumnChecksumRequestArg::reset() source_table_id_ = OB_INVALID_ID; execution_id_ = -1; task_id_ = 0; - calc_items_.reset(); -} - -int ObCalcColumnChecksumRequestArg::assign(const ObCalcColumnChecksumRequestArg &other) -{ - int ret = common::OB_SUCCESS; - tenant_id_ = other.tenant_id_; - target_table_id_ = other.target_table_id_; - schema_version_ = other.schema_version_; - execution_id_ = other.execution_id_; - snapshot_version_ = other.snapshot_version_; - source_table_id_ = other.source_table_id_; - task_id_ = other.task_id_; - if (OB_FAIL(calc_items_.assign(other.calc_items_))) { - LOG_WARN("assign calc_items failed", K(ret), K(other.calc_items_.count())); - } - return ret; } OB_SERIALIZE_MEMBER(ObCalcColumnChecksumRequestRes, ret_codes_); @@ -5746,16 +5729,18 @@ int ObDDLBuildSingleReplicaRequestArg::assign(const ObDDLBuildSingleReplicaReque return ret; } -OB_SERIALIZE_MEMBER(ObDDLBuildSingleReplicaRequestResult, ret_code_); +OB_SERIALIZE_MEMBER(ObDDLBuildSingleReplicaRequestResult, ret_code_, row_inserted_, row_scanned_); int ObDDLBuildSingleReplicaRequestResult::assign(const ObDDLBuildSingleReplicaRequestResult &other) { int ret = OB_SUCCESS; ret_code_ = other.ret_code_; + row_inserted_ = other.row_inserted_; + row_scanned_ = other.row_scanned_; return ret; } -OB_SERIALIZE_MEMBER(ObDDLBuildSingleReplicaResponseArg, tenant_id_, ls_id_, tablet_id_, source_table_id_, dest_schema_id_, ret_code_, snapshot_version_, schema_version_, task_id_, execution_id_); +OB_SERIALIZE_MEMBER(ObDDLBuildSingleReplicaResponseArg, tenant_id_, ls_id_, tablet_id_, source_table_id_, dest_schema_id_, ret_code_, snapshot_version_, schema_version_, task_id_, execution_id_, row_scanned_, row_inserted_); int ObDDLBuildSingleReplicaResponseArg::assign(const ObDDLBuildSingleReplicaResponseArg &other) { @@ -5770,6 +5755,8 @@ int ObDDLBuildSingleReplicaResponseArg::assign(const ObDDLBuildSingleReplicaResp schema_version_ = other.schema_version_; task_id_ = other.task_id_; execution_id_ = other.execution_id_; + row_scanned_ = other.row_scanned_; + row_inserted_ = other.row_inserted_; return ret; } diff --git a/src/share/ob_rpc_struct.h b/src/share/ob_rpc_struct.h index baa061ac5e..6e228152c7 100644 --- a/src/share/ob_rpc_struct.h +++ b/src/share/ob_rpc_struct.h @@ -3698,11 +3698,14 @@ struct ObCheckTransElapsedResult final { OB_UNIS_VERSION(1); public: - ObCheckTransElapsedResult() : ret_code_(common::OB_SUCCESS), snapshot_(common::OB_INVALID_TIMESTAMP) {} - TO_STRING_KV(K_(ret_code), K_(snapshot), K_(pending_tx_id)); - int ret_code_; + ObCheckTransElapsedResult() + : snapshot_(common::OB_INVALID_TIMESTAMP), pending_tx_id_(), ret_code_(OB_SUCCESS) {} + bool is_valid() const { return snapshot_ != common::OB_INVALID_TIMESTAMP; } + void reuse() { snapshot_ = common::OB_INVALID_TIMESTAMP; pending_tx_id_.reset(); } + TO_STRING_KV(K_(snapshot), K_(pending_tx_id), K_(ret_code)); int64_t snapshot_; transaction::ObTransID pending_tx_id_; + int ret_code_; }; struct ObDDLCheckTabletMergeStatusResult @@ -7245,13 +7248,15 @@ struct ObDDLBuildSingleReplicaRequestResult final OB_UNIS_VERSION(1); public: ObDDLBuildSingleReplicaRequestResult() - : ret_code_(OB_SUCCESS) + : ret_code_(OB_SUCCESS), row_inserted_(0), row_scanned_(0) {} ~ObDDLBuildSingleReplicaRequestResult() = default; int assign(const ObDDLBuildSingleReplicaRequestResult &other); - TO_STRING_KV(K_(ret_code)) + TO_STRING_KV(K_(ret_code), K_(row_inserted), K_(row_scanned)) public: int64_t ret_code_; + int64_t row_inserted_; + int64_t row_scanned_; }; struct ObDDLBuildSingleReplicaResponseArg final @@ -7260,14 +7265,16 @@ struct ObDDLBuildSingleReplicaResponseArg final public: ObDDLBuildSingleReplicaResponseArg() : tenant_id_(OB_INVALID_ID), ls_id_(), tablet_id_(), source_table_id_(), dest_schema_id_(OB_INVALID_ID), - ret_code_(OB_SUCCESS), snapshot_version_(0), schema_version_(0), task_id_(0), execution_id_(-1) + ret_code_(OB_SUCCESS), snapshot_version_(0), schema_version_(0), task_id_(0), execution_id_(-1), + row_scanned_(0), row_inserted_(0) {} ~ObDDLBuildSingleReplicaResponseArg() = default; bool is_valid() const { return OB_INVALID_ID != tenant_id_ && ls_id_.is_valid() && tablet_id_.is_valid() && OB_INVALID_ID != source_table_id_ && OB_INVALID_ID != dest_schema_id_ && snapshot_version_ > 0 && schema_version_ > 0 && task_id_ > 0 && execution_id_ >= 0; } int assign(const ObDDLBuildSingleReplicaResponseArg &other); - TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(tablet_id), K_(source_table_id), K_(dest_schema_id), K_(ret_code), K_(snapshot_version), K_(schema_version), K_(task_id), K_(execution_id)); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(tablet_id), K_(source_table_id), K_(dest_schema_id), K_(ret_code), + K_(snapshot_version), K_(schema_version), K_(task_id), K_(execution_id), K_(row_scanned), K_(row_inserted)); public: uint64_t tenant_id_; share::ObLSID ls_id_; @@ -7279,6 +7286,8 @@ public: int64_t schema_version_; int64_t task_id_; int64_t execution_id_; + int64_t row_scanned_; + int64_t row_inserted_; }; struct ObLogReqLoadProxyRequest diff --git a/src/share/scheduler/ob_dag_scheduler.cpp b/src/share/scheduler/ob_dag_scheduler.cpp index bfa288a148..a048af848a 100644 --- a/src/share/scheduler/ob_dag_scheduler.cpp +++ b/src/share/scheduler/ob_dag_scheduler.cpp @@ -29,6 +29,7 @@ #include "storage/compaction/ob_tablet_merge_ctx.h" #include "storage/compaction/ob_tablet_merge_task.h" #include "storage/compaction/ob_compaction_diagnose.h" +#include "storage/ddl/ob_complement_data_task.h" #include #include @@ -2199,7 +2200,7 @@ int ObTenantDagScheduler::diagnose_dag( COMMON_LOG(WARN, "ObDagScheduler is not inited", K(ret)); } else if (OB_ISNULL(dag)) { ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "invalid arugment", KP(dag)); + COMMON_LOG(WARN, "invalid arugment", K(ret), KP(dag)); } else { ObThreadCondGuard guard(scheduler_sync_); ObIDag *stored_dag = nullptr; @@ -3374,6 +3375,35 @@ int ObTenantDagScheduler::cancel_dag_net(const ObDagId &dag_id) return ret; } +int ObTenantDagScheduler::get_complement_data_dag_progress(const ObIDag *dag, + int64_t &row_scanned, + int64_t &row_inserted) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + COMMON_LOG(WARN, "ObDagScheduler is not inited", K(ret)); + } else if (OB_ISNULL(dag) || dag->get_type() != ObDagType::DAG_TYPE_DDL) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "invalid arugment", K(ret), KP(dag)); + } else { + ObThreadCondGuard guard(scheduler_sync_); + ObIDag *stored_dag = nullptr; + if (OB_FAIL(dag_map_.get_refactored(dag, stored_dag))) { + if (OB_HASH_NOT_EXIST != ret) { + LOG_WARN("failed to get from dag map", K(ret)); + } + } else if (OB_ISNULL(stored_dag)) { + ret = OB_ERR_SYS; + LOG_WARN("dag is null", K(ret)); + } else { + row_scanned = static_cast(stored_dag)->get_context().row_scanned_; + row_inserted = static_cast(stored_dag)->get_context().row_inserted_; + } + } + return ret; +} + int ObFakeTask::process() { COMMON_LOG(INFO, "ObFakeTask process"); diff --git a/src/share/scheduler/ob_dag_scheduler.h b/src/share/scheduler/ob_dag_scheduler.h index a4e329ebb2..bf554f3145 100644 --- a/src/share/scheduler/ob_dag_scheduler.h +++ b/src/share/scheduler/ob_dag_scheduler.h @@ -810,6 +810,7 @@ public: int check_dag_net_exist( const ObDagId &dag_id, bool &exist); int cancel_dag_net(const ObDagId &dag_id); + int get_complement_data_dag_progress(const ObIDag *dag, int64_t &row_scanned, int64_t &row_inserted); private: typedef common::ObDList DagList; diff --git a/src/sql/engine/aggregate/ob_aggregate_processor.cpp b/src/sql/engine/aggregate/ob_aggregate_processor.cpp index ec2d3fe62c..f1839e9084 100644 --- a/src/sql/engine/aggregate/ob_aggregate_processor.cpp +++ b/src/sql/engine/aggregate/ob_aggregate_processor.cpp @@ -279,7 +279,7 @@ int ObAggregateProcessor::ExtraResult::init_distinct_set(const uint64_t tenant_i ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fall to alloc buff", "size", sizeof(ObUniqueSortImpl), K(ret)); } else { - new (unique_sort_op_) ObUniqueSortImpl(); + new (unique_sort_op_) ObUniqueSortImpl(op_monitor_info_); if (OB_FAIL(unique_sort_op_->init(tenant_id, &aggr_info.distinct_collations_, &aggr_info.distinct_cmp_funcs_, @@ -320,7 +320,7 @@ int ObAggregateProcessor::GroupConcatExtraResult::init(const uint64_t tenant_id, ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fall to alloc buff", "size", sizeof(ObSortOpImpl), K(ret)); } else { - new (sort_op_) ObSortOpImpl(); + new (sort_op_) ObSortOpImpl(op_monitor_info_); if (OB_FAIL(sort_op_->init(tenant_id, &aggr_info.sort_collations_, &aggr_info.sort_cmp_funcs_, diff --git a/src/sql/engine/aggregate/ob_aggregate_processor.h b/src/sql/engine/aggregate/ob_aggregate_processor.h index 9adb4f9277..03b03306d2 100644 --- a/src/sql/engine/aggregate/ob_aggregate_processor.h +++ b/src/sql/engine/aggregate/ob_aggregate_processor.h @@ -271,6 +271,7 @@ public: DECLARE_VIRTUAL_TO_STRING; protected: common::ObIAllocator &alloc_; + ObMonitorNode op_monitor_info_; public: // for distinct calculate may be replace by hash based distinct in the future. ObUniqueSortImpl *unique_sort_op_; diff --git a/src/sql/engine/aggregate/ob_merge_groupby_op.h b/src/sql/engine/aggregate/ob_merge_groupby_op.h index 586f17b56f..84489ee968 100644 --- a/src/sql/engine/aggregate/ob_merge_groupby_op.h +++ b/src/sql/engine/aggregate/ob_merge_groupby_op.h @@ -99,7 +99,7 @@ public: is_first_calc_(true), cur_group_last_row_idx_(-1), use_sort_data_(false), - inner_sort_(), + inner_sort_(op_monitor_info_), rollup_hash_vals_(nullptr), ndv_calculator_(nullptr), global_rollup_key_(), diff --git a/src/sql/engine/basic/ob_stat_collector_op.cpp b/src/sql/engine/basic/ob_stat_collector_op.cpp index 296fab7511..929cb203ee 100644 --- a/src/sql/engine/basic/ob_stat_collector_op.cpp +++ b/src/sql/engine/basic/ob_stat_collector_op.cpp @@ -39,7 +39,7 @@ OB_SERIALIZE_MEMBER((ObStatCollectorSpec, ObOpSpec), ObStatCollectorOp::ObStatCollectorOp(ObExecContext &ctx_, const ObOpSpec &spec, ObOpInput *input) : ObOperator(ctx_, spec, input), - sort_impl_(), + sort_impl_(op_monitor_info_), iter_end_(false), by_pass_(false), exist_sample_row_(false), diff --git a/src/sql/engine/ob_operator.cpp b/src/sql/engine/ob_operator.cpp index 137a1c1222..225719ad56 100644 --- a/src/sql/engine/ob_operator.cpp +++ b/src/sql/engine/ob_operator.cpp @@ -581,7 +581,7 @@ int ObOperator::open() eval_ctx_.set_batch_size(1); eval_ctx_.set_batch_idx(0); } - if (ctx_.get_my_session()->is_user_session()) { + if (ctx_.get_my_session()->is_user_session() || spec_.plan_->get_phy_plan_hint().monitor_) { IGNORE_RETURN try_register_rt_monitor_node(0); } while (OB_SUCC(ret) && open_order != OPEN_EXIT) { @@ -910,7 +910,7 @@ int ObOperator::get_next_row() LOG_WARN("too deep recusive", K(ret)); } else { begin_cpu_time_counting(); - if (ctx_.get_my_session()->is_user_session()) { + if (ctx_.get_my_session()->is_user_session() || spec_.plan_->get_phy_plan_hint().monitor_) { IGNORE_RETURN try_register_rt_monitor_node(1); } if (row_reach_end_) { @@ -1045,7 +1045,7 @@ int ObOperator::get_next_batch(const int64_t max_row_cnt, const ObBatchRows *&ba continue; } } - if (OB_SUCC(ret) && ctx_.get_my_session()->is_user_session()) { + if (OB_SUCC(ret) && (ctx_.get_my_session()->is_user_session() || spec_.plan_->get_phy_plan_hint().monitor_)) { IGNORE_RETURN try_register_rt_monitor_node(brs_.size_); } if (OB_FAIL(ret)) { diff --git a/src/sql/engine/pdml/static/ob_px_sstable_insert_op.cpp b/src/sql/engine/pdml/static/ob_px_sstable_insert_op.cpp index 220cc58557..19b05c9000 100644 --- a/src/sql/engine/pdml/static/ob_px_sstable_insert_op.cpp +++ b/src/sql/engine/pdml/static/ob_px_sstable_insert_op.cpp @@ -93,6 +93,10 @@ int ObPxMultiPartSSTableInsertOp::inner_open() LOG_WARN("fail to create row cnt map", K(ret)); } else { ddl_task_id_ = ctx_.get_px_task_id(); + op_monitor_info_.otherstat_1_id_ = ObSqlMonitorStatIds::SSTABLE_INSERT_ROW_COUNT; + op_monitor_info_.otherstat_1_value_ = 0; + op_monitor_info_.otherstat_5_id_ = ObSqlMonitorStatIds::DDL_TASK_ID; + op_monitor_info_.otherstat_5_value_ = MY_SPEC.plan_->get_ddl_task_id(); LOG_INFO("update table context", K(context_id), K(snapshot_version), K(MY_SPEC.ins_ctdef_.das_ctdef_.table_id_), K(MY_SPEC.ins_ctdef_.das_ctdef_.index_tid_)); } @@ -309,6 +313,10 @@ int ObPxMultiPartSSTableInsertOp::get_next_row_with_cache() } else { ret = child_->get_next_row(); } + if (OB_SUCC(ret)) { + op_monitor_info_.otherstat_1_id_ = ObSqlMonitorStatIds::SSTABLE_INSERT_ROW_COUNT; + op_monitor_info_.otherstat_1_value_++; + } return ret; } diff --git a/src/sql/engine/px/datahub/components/ob_dh_sample.cpp b/src/sql/engine/px/datahub/components/ob_dh_sample.cpp index 4eed2b0491..41ac416910 100644 --- a/src/sql/engine/px/datahub/components/ob_dh_sample.cpp +++ b/src/sql/engine/px/datahub/components/ob_dh_sample.cpp @@ -213,6 +213,7 @@ ObDynamicSamplePieceMsgCtx::ObDynamicSamplePieceMsgCtx( succ_count_(0), tablet_ids_(), expect_range_count_(0), + sort_impl_(op_monitor_info_), exec_ctx_(exec_ctx), last_store_row_(), coord_(coord), diff --git a/src/sql/engine/px/datahub/components/ob_dh_sample.h b/src/sql/engine/px/datahub/components/ob_dh_sample.h index 83a8f618ba..6669af4d7d 100644 --- a/src/sql/engine/px/datahub/components/ob_dh_sample.h +++ b/src/sql/engine/px/datahub/components/ob_dh_sample.h @@ -140,6 +140,7 @@ public: ObArray tablet_ids_; int64_t expect_range_count_; ObArray sample_stores_; + ObMonitorNode op_monitor_info_; ObSortOpImpl sort_impl_; ObExecContext &exec_ctx_; ObChunkDatumStore::ShadowStoredRow last_store_row_; diff --git a/src/sql/engine/sort/ob_sort_op.cpp b/src/sql/engine/sort/ob_sort_op.cpp index 11d2b208b0..65c61f8ad0 100644 --- a/src/sql/engine/sort/ob_sort_op.cpp +++ b/src/sql/engine/sort/ob_sort_op.cpp @@ -58,8 +58,8 @@ OB_SERIALIZE_MEMBER((ObSortSpec, ObOpSpec), ObSortOp::ObSortOp(ObExecContext &ctx_, const ObOpSpec &spec, ObOpInput *input) : ObOperator(ctx_, spec, input), - sort_impl_(), - prefix_sort_impl_(), + sort_impl_(op_monitor_info_), + prefix_sort_impl_(op_monitor_info_), topn_sort_(), read_func_(&ObSortOp::sort_impl_next), read_batch_func_(&ObSortOp::sort_impl_next_batch), @@ -238,6 +238,7 @@ int ObSortOp::process_sort() } else { sort_row_count_++; OZ(sort_impl_.add_row(MY_SPEC.all_exprs_, need_dump)); + sort_impl_.collect_memory_dump_info(op_monitor_info_); if (need_dump && MY_SPEC.prescan_enabled_) { break; } @@ -253,6 +254,7 @@ int ObSortOp::process_sort() ret = OB_SUCCESS; } OZ(sort_impl_.sort()); + sort_impl_.collect_memory_dump_info(op_monitor_info_); } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid read function pointer", @@ -311,6 +313,7 @@ int ObSortOp::process_sort_batch() sort_row_count_ += input_brs->size_ - input_brs->skip_->accumulate_bit_cnt(input_brs->size_); OZ(sort_impl_.add_batch(MY_SPEC.all_exprs_, *input_brs->skip_, input_brs->size_, 0, need_dump, nullptr)); + sort_impl_.collect_memory_dump_info(op_monitor_info_); } if (input_brs->end_ || (need_dump && MY_SPEC.prescan_enabled_)) { break; @@ -324,6 +327,7 @@ int ObSortOp::process_sort_batch() } } OZ(sort_impl_.sort()); + sort_impl_.collect_memory_dump_info(op_monitor_info_); } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid read function pointer", diff --git a/src/sql/engine/sort/ob_sort_op_impl.cpp b/src/sql/engine/sort/ob_sort_op_impl.cpp index 11f203f2ee..0e56e396bc 100644 --- a/src/sql/engine/sort/ob_sort_op_impl.cpp +++ b/src/sql/engine/sort/ob_sort_op_impl.cpp @@ -539,7 +539,7 @@ bool ObSortOpImpl::Compare::operator()( return less; } -ObSortOpImpl::ObSortOpImpl() +ObSortOpImpl::ObSortOpImpl(ObMonitorNode &op_monitor_info) : inited_(false), local_merge_sort_(false), need_rewind_(false), got_first_row_(false), sorted_(false), enable_encode_sortkey_(false), mem_context_(NULL), mem_entify_guard_(mem_context_), tenant_id_(OB_INVALID_ID), sort_collations_(nullptr), @@ -548,7 +548,7 @@ ObSortOpImpl::ObSortOpImpl() row_idx_(0), heap_iter_begin_(false), imms_heap_(NULL), ems_heap_(NULL), next_stored_row_func_(&ObSortOpImpl::array_next_stored_row), input_rows_(OB_INVALID_ID), - input_width_(OB_INVALID_ID), profile_(ObSqlWorkAreaType::SORT_WORK_AREA), + input_width_(OB_INVALID_ID), profile_(ObSqlWorkAreaType::SORT_WORK_AREA), op_monitor_info_(op_monitor_info), sql_mem_processor_(profile_, op_monitor_info_), op_type_(PHY_INVALID), op_id_(UINT64_MAX), exec_ctx_(nullptr), stored_rows_(nullptr), io_event_observer_(nullptr), buckets_(NULL), max_bucket_cnt_(0), part_hash_nodes_(NULL), max_node_cnt_(0), part_cnt_(0), @@ -628,6 +628,22 @@ int ObSortOpImpl::init( datum_store_.set_allocator(mem_context_->get_malloc_allocator()); datum_store_.set_io_event_observer(io_event_observer_); profile_.set_exec_ctx(exec_ctx); + op_monitor_info_.otherstat_2_id_ = ObSqlMonitorStatIds::SORT_MERGE_SORT_ROUND; + op_monitor_info_.otherstat_2_value_ = 1; + ObPhysicalPlanCtx *plan_ctx = NULL; + const ObPhysicalPlan *phy_plan = nullptr; + if (OB_ISNULL(plan_ctx = GET_PHY_PLAN_CTX(*exec_ctx))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("deserialized exec ctx without phy plan ctx set. Unexpected", K(ret)); + } else if (OB_ISNULL(phy_plan = plan_ctx->get_phy_plan())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, phy plan must not be nullptr", K(ret)); + } else if (phy_plan->get_ddl_task_id() > 0) { + op_monitor_info_.otherstat_5_id_ = ObSqlMonitorStatIds::DDL_TASK_ID; + op_monitor_info_.otherstat_5_value_ = phy_plan->get_ddl_task_id(); + } + } + if (OB_SUCC(ret)) { inited_ = true; } } @@ -721,6 +737,7 @@ template int ObSortOpImpl::build_chunk(const int64_t level, Input &input) { int ret = OB_SUCCESS; + const int64_t curr_time = ObTimeUtility::fast_current_time(); int64_t stored_row_cnt = 0; ObChunkDatumStore *datum_store = NULL; const ObChunkDatumStore::StoredRow *src_store_row = NULL; @@ -756,6 +773,8 @@ int ObSortOpImpl::build_chunk(const int64_t level, Input &input) LOG_WARN("copy row to row store failed"); } else { stored_row_cnt++; + op_monitor_info_.otherstat_1_id_ = ObSqlMonitorStatIds::SORT_SORTED_ROW_COUNT; + op_monitor_info_.otherstat_1_value_ += 1; } } @@ -766,6 +785,9 @@ int ObSortOpImpl::build_chunk(const int64_t level, Input &input) } else if (OB_FAIL(chunk->datum_store_.finish_add_row(true /*+ need dump */))) { LOG_WARN("finish add row failed", K(ret)); } else { + const int64_t sort_io_time = ObTimeUtility::fast_current_time() - curr_time; + op_monitor_info_.otherstat_4_id_ = ObSqlMonitorStatIds::SORT_DUMP_DATA_TIME; + op_monitor_info_.otherstat_4_value_ += sort_io_time; LOG_TRACE("dump sort file", "level", level, "rows", chunk->datum_store_.get_row_cnt(), @@ -1277,7 +1299,6 @@ int ObSortOpImpl::do_dump() LOG_WARN("build chunk failed", K(ret)); } } - if (OB_SUCC(ret)) { sql_mem_processor_.set_number_pass(level + 1); heap_iter_begin_ = false; @@ -1439,6 +1460,7 @@ int ObSortOpImpl::imms_heap_next(const ObChunkDatumStore::StoredRow *&store_row) int ObSortOpImpl::sort_inmem_data() { int ret = OB_SUCCESS; + const int64_t curr_time = ObTimeUtility::fast_current_time(); if (!is_inited()) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); @@ -1469,6 +1491,8 @@ int ObSortOpImpl::sort_inmem_data() ret = comp_.ret_; LOG_WARN("compare failed", K(ret)); } + op_monitor_info_.otherstat_1_id_ = ObSqlMonitorStatIds::SORT_SORTED_ROW_COUNT; + op_monitor_info_.otherstat_1_value_ += rows_.count(); } if (OB_SUCC(ret) && need_imms()) { if (NULL == imms_heap_) { @@ -1501,11 +1525,16 @@ int ObSortOpImpl::sort_inmem_data() LOG_WARN("heap push back failed", K(ret)); } } + op_monitor_info_.otherstat_1_id_ = ObSqlMonitorStatIds::SORT_SORTED_ROW_COUNT; + op_monitor_info_.otherstat_1_value_ += 1; prev = &rows_.at(i); } heap_iter_begin_ = false; } } + const int64_t sort_cpu_time = ObTimeUtility::fast_current_time() - curr_time; + op_monitor_info_.otherstat_3_id_ = ObSqlMonitorStatIds::SORT_INMEM_SORT_TIME; + op_monitor_info_.otherstat_3_value_ += sort_cpu_time; } return ret; } @@ -1567,6 +1596,8 @@ int ObSortOpImpl::sort() return ret; }; const int64_t level = sort_chunks_.get_first()->level_ + 1; + op_monitor_info_.otherstat_2_id_ = ObSqlMonitorStatIds::SORT_MERGE_SORT_ROUND; + op_monitor_info_.otherstat_2_value_ = level; if (OB_FAIL(build_chunk(level, input))) { LOG_WARN("build chunk failed", K(ret)); } else { @@ -1707,7 +1738,7 @@ int ObSortOpImpl::get_next_batch(const common::ObIArray &exprs, /************************************* end ObSortOpImpl ********************************/ /*********************************** start ObPrefixSortImpl *****************************/ -ObPrefixSortImpl::ObPrefixSortImpl() : prefix_pos_(0), +ObPrefixSortImpl::ObPrefixSortImpl(ObMonitorNode &op_monitor_info) : ObSortOpImpl(op_monitor_info), prefix_pos_(0), full_sort_collations_(nullptr), full_sort_cmp_funs_(nullptr), base_sort_collations_(), base_sort_cmp_funs_(), prev_row_(nullptr), next_prefix_row_store_(), next_prefix_row_(nullptr), diff --git a/src/sql/engine/sort/ob_sort_op_impl.h b/src/sql/engine/sort/ob_sort_op_impl.h index 5ce24f231a..079317106a 100644 --- a/src/sql/engine/sort/ob_sort_op_impl.h +++ b/src/sql/engine/sort/ob_sort_op_impl.h @@ -73,7 +73,7 @@ public: static const int64_t MAX_MERGE_WAYS = 256; static const int64_t INMEMORY_MERGE_SORT_WARN_WAYS = 10000; - ObSortOpImpl(); + explicit ObSortOpImpl(ObMonitorNode &op_monitor_info); virtual ~ObSortOpImpl(); // if rewind id not needed, we will release the resource after iterate end. @@ -175,6 +175,14 @@ public: void set_operator_id(uint64_t op_id) { op_id_ = op_id; } void collect_memory_dump_info(ObMonitorNode &info) { + info.otherstat_1_id_ = op_monitor_info_.otherstat_1_id_; + info.otherstat_1_value_ = op_monitor_info_.otherstat_1_value_; + info.otherstat_2_id_ = op_monitor_info_.otherstat_2_id_; + info.otherstat_2_value_ = op_monitor_info_.otherstat_2_value_; + info.otherstat_3_id_ = op_monitor_info_.otherstat_3_id_; + info.otherstat_3_value_ = op_monitor_info_.otherstat_3_value_; + info.otherstat_4_id_ = op_monitor_info_.otherstat_4_id_; + info.otherstat_4_value_ = op_monitor_info_.otherstat_4_value_; info.otherstat_6_id_ = op_monitor_info_.otherstat_6_id_; info.otherstat_6_value_ = op_monitor_info_.otherstat_6_value_; } @@ -455,7 +463,7 @@ protected: int64_t input_rows_; int64_t input_width_; ObSqlWorkAreaProfile profile_; - ObMonitorNode op_monitor_info_; + ObMonitorNode &op_monitor_info_; ObSqlMemMgrProcessor sql_mem_processor_; ObPhyOperatorType op_type_; uint64_t op_id_; @@ -477,7 +485,7 @@ protected: class ObPrefixSortImpl : public ObSortOpImpl { public: - ObPrefixSortImpl(); + explicit ObPrefixSortImpl(ObMonitorNode &op_monitor_info); // init && start fetch %op rows int init(const int64_t tenant_id, @@ -556,7 +564,7 @@ private: class ObUniqueSortImpl : public ObSortOpImpl { public: - ObUniqueSortImpl() : prev_row_(NULL), prev_buf_size_(0) + explicit ObUniqueSortImpl(ObMonitorNode &op_monitor_info) : ObSortOpImpl(op_monitor_info), prev_row_(NULL), prev_buf_size_(0) { } diff --git a/src/sql/engine/subquery/ob_subplan_scan_op.cpp b/src/sql/engine/subquery/ob_subplan_scan_op.cpp index 2e99055795..459e65b6f5 100644 --- a/src/sql/engine/subquery/ob_subplan_scan_op.cpp +++ b/src/sql/engine/subquery/ob_subplan_scan_op.cpp @@ -13,6 +13,8 @@ #define USING_LOG_PREFIX SQL_ENG #include "ob_subplan_scan_op.h" +#include "sql/engine/ob_physical_plan.h" +#include "sql/engine/ob_exec_context.h" namespace oceanbase { @@ -43,6 +45,8 @@ int ObSubPlanScanOp::inner_open() } else if (OB_UNLIKELY(MY_SPEC.projector_.count() % 2 != 0)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("projector array size should be multiples of 2", K(ret)); + } else if (OB_FAIL(init_monitor_info())) { + LOG_WARN("init monitor info failed", K(ret)); } return ret; } @@ -133,5 +137,25 @@ int ObSubPlanScanOp::inner_get_next_batch(const int64_t max_row_cnt) return ret; } +int ObSubPlanScanOp::init_monitor_info() +{ + int ret = OB_SUCCESS; + if (spec_.plan_->get_phy_plan_hint().monitor_) { + ObPhysicalPlanCtx *plan_ctx = NULL; + const ObPhysicalPlan *phy_plan = nullptr; + if (OB_ISNULL(plan_ctx = GET_PHY_PLAN_CTX(ctx_))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("deserialized exec ctx without phy plan ctx set. Unexpected", K(ret)); + } else if (OB_ISNULL(phy_plan = plan_ctx->get_phy_plan())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, phy plan must not be nullptr", K(ret)); + } else if (phy_plan->get_ddl_task_id() > 0) { + op_monitor_info_.otherstat_5_id_ = ObSqlMonitorStatIds::DDL_TASK_ID; + op_monitor_info_.otherstat_5_value_ = phy_plan->get_ddl_task_id(); + } + } + return ret; +} + } // end namespace sql } // end namespace oceanbase diff --git a/src/sql/engine/subquery/ob_subplan_scan_op.h b/src/sql/engine/subquery/ob_subplan_scan_op.h index 5c557c7fcb..00c6f7b181 100644 --- a/src/sql/engine/subquery/ob_subplan_scan_op.h +++ b/src/sql/engine/subquery/ob_subplan_scan_op.h @@ -46,6 +46,8 @@ public: virtual int inner_get_next_batch(const int64_t max_row_cnt) override; virtual void destroy() override { ObOperator::destroy(); } +private: + int init_monitor_info(); }; } // end namespace sql diff --git a/src/storage/CMakeLists.txt b/src/storage/CMakeLists.txt index 25391c9cfe..642e7b4953 100644 --- a/src/storage/CMakeLists.txt +++ b/src/storage/CMakeLists.txt @@ -384,7 +384,6 @@ ob_set_subtarget(ob_storage common ob_i_store.cpp ob_i_table.cpp ob_locality_manager.cpp - ob_long_ops_monitor.cpp ob_micro_block_handle_mgr.cpp ob_partition_component_factory.cpp ob_partition_range_spliter.cpp diff --git a/src/storage/ddl/ob_build_index_task.cpp b/src/storage/ddl/ob_build_index_task.cpp index 2f0fbf87a0..96805caae1 100644 --- a/src/storage/ddl/ob_build_index_task.cpp +++ b/src/storage/ddl/ob_build_index_task.cpp @@ -19,7 +19,6 @@ #include "share/ob_get_compat_mode.h" #include "share/schema/ob_tenant_schema_service.h" #include "storage/compaction/ob_column_checksum_calculator.h" -#include "storage/ob_long_ops_monitor.h" #include "storage/ddl/ob_ddl_redo_log_writer.h" #include "storage/ddl/ob_complement_data_task.h" #include "storage/ob_i_table.h" diff --git a/src/storage/ddl/ob_complement_data_task.cpp b/src/storage/ddl/ob_complement_data_task.cpp index 4b9666b164..1d0d10d1aa 100644 --- a/src/storage/ddl/ob_complement_data_task.cpp +++ b/src/storage/ddl/ob_complement_data_task.cpp @@ -29,7 +29,6 @@ #include "storage/ddl/ob_ddl_merge_task.h" #include "storage/ddl/ob_ddl_redo_log_writer.h" #include "storage/ob_i_table.h" -#include "storage/ob_long_ops_monitor.h" #include "storage/ob_parallel_external_sort.h" #include "storage/ob_partition_range_spliter.h" #include "storage/ob_row_reshape.h" @@ -552,7 +551,9 @@ int ObComplementDataDag::report_replica_build_status() arg.schema_version_ = param_.schema_version_; arg.task_id_ = param_.task_id_; arg.execution_id_ = param_.execution_id_; - FLOG_INFO("send replica build status response to RS", K(ret), K(context_.complement_data_ret_), K(arg)); + arg.row_scanned_ = context_.row_scanned_; + arg.row_inserted_ = context_.row_inserted_; + FLOG_INFO("send replica build status response to RS", K(ret), K(context_), K(arg)); if (OB_FAIL(ret)) { } else if (OB_ISNULL(GCTX.rs_rpc_proxy_) || OB_ISNULL(GCTX.rs_mgr_)) { ret = OB_ERR_SYS; @@ -967,7 +968,6 @@ int ObComplementWriteTask::append_row(ObLocalScan &local_scan) ObDDLRedoLogWriterCallback callback; ObITable::TableKey hidden_table_key; ObMacroDataSeq macro_start_seq(0); - int64_t row_cnt = 0; int64_t get_next_row_time = 0; int64_t append_row_time = 0; int64_t t1 = 0; @@ -1074,6 +1074,7 @@ int ObComplementWriteTask::append_row(ObLocalScan &local_scan) } else { t2 = ObTimeUtility::current_time(); get_next_row_time += t2 - t1; + context_->row_scanned_++; if (OB_FAIL(writer.append_row(datum_row))) { LOG_WARN("fail to append row to macro block", K(ret), K(datum_row)); } else if (OB_ISNULL(checksum_calculator = local_scan.get_checksum_calculator())) { @@ -1084,7 +1085,7 @@ int ObComplementWriteTask::append_row(ObLocalScan &local_scan) } else { t3 = ObTimeUtility::current_time(); append_row_time += t3 - t2; - row_cnt++; + context_->row_inserted_++; } if (lob_cnt % 128 == 0) { lob_allocator.reuse(); // reuse after append_row to macro block to save memory @@ -1094,7 +1095,7 @@ int ObComplementWriteTask::append_row(ObLocalScan &local_scan) if (OB_ITER_END == ret) { ret = OB_SUCCESS; } - LOG_INFO("print append row to macro block cost time", K(ret), K(task_id_), K(row_cnt), + LOG_INFO("print append row to macro block cost time", K(ret), K(task_id_), K(context_->row_inserted_), K(get_next_row_time), K(append_row_time)); ObRowReshapeUtil::free_row_reshape(allocator, reshape_ptr, 1); if (OB_FAIL(ret)) { diff --git a/src/storage/ddl/ob_complement_data_task.h b/src/storage/ddl/ob_complement_data_task.h index c9e288600e..e71ca4f8b1 100644 --- a/src/storage/ddl/ob_complement_data_task.h +++ b/src/storage/ddl/ob_complement_data_task.h @@ -114,13 +114,14 @@ struct ObComplementDataContext final public: ObComplementDataContext(): is_inited_(false), is_major_sstable_exist_(false), complement_data_ret_(common::OB_SUCCESS), - allocator_("CompleteDataCtx"), lock_(ObLatchIds::COMPLEMENT_DATA_CONTEXT_LOCK), concurrent_cnt_(0), data_sstable_redo_writer_(), index_builder_(nullptr) + allocator_("CompleteDataCtx"), lock_(ObLatchIds::COMPLEMENT_DATA_CONTEXT_LOCK), concurrent_cnt_(0), + data_sstable_redo_writer_(), index_builder_(nullptr), ddl_kv_mgr_handle_(), row_scanned_(0), row_inserted_(0) {} ~ObComplementDataContext() { destroy(); } int init(const ObComplementDataParam ¶m, const ObDataStoreDesc &desc); void destroy(); int write_start_log(const ObComplementDataParam ¶m); - TO_STRING_KV(K_(is_inited), K_(complement_data_ret), K_(concurrent_cnt), KP_(index_builder)); + TO_STRING_KV(K_(is_inited), K_(complement_data_ret), K_(concurrent_cnt), KP_(index_builder), K_(row_scanned), K_(row_inserted)); public: bool is_inited_; bool is_major_sstable_exist_; @@ -131,6 +132,8 @@ public: ObDDLSSTableRedoWriter data_sstable_redo_writer_; blocksstable::ObSSTableIndexBuilder *index_builder_; ObDDLKvMgrHandle ddl_kv_mgr_handle_; // for keeping ddl kv mgr alive + int64_t row_scanned_; + int64_t row_inserted_; }; class ObComplementPrepareTask; diff --git a/src/storage/ob_long_ops_monitor.h b/src/storage/ob_long_ops_monitor.h deleted file mode 100644 index d1bb60d325..0000000000 --- a/src/storage/ob_long_ops_monitor.h +++ /dev/null @@ -1,265 +0,0 @@ -/** - * 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. - */ - -#ifndef OCEANBASE_STORAGE_OB_CREATE_INDEX_MONITOR_H_ -#define OCEANBASE_STORAGE_OB_CREATE_INDEX_MONITOR_H_ - -#include "lib/container/ob_array.h" -#include "lib/allocator/ob_concurrent_fifo_allocator.h" -#include "lib/task/ob_timer.h" -#include "share/schema/ob_multi_version_schema_service.h" -#include "storage/ob_resource_map.h" - -namespace oceanbase -{ -namespace storage -{ - -struct ObILongOpsTaskStat -{ - enum class TaskState - { - INIT = 0, - RUNNING, - SUCCESS, - FAIL, - }; - enum class TaskType - { - INVALID = 0, - SCAN, - SORT, - }; - ObILongOpsTaskStat() - : task_id_(0), cpu_cost_(0), io_cost_(0), state_(TaskState::INIT), type_(TaskType::INVALID) - {} - virtual ~ObILongOpsTaskStat() = default; - virtual int estimate_cost() = 0; - double get_cost() { return cpu_cost_ + io_cost_; } - bool is_valid() const - { - return task_id_ >= 0; - } - virtual int assign(const ObILongOpsTaskStat &task_stat); - TO_STRING_KV(K_(task_id), K_(cpu_cost), K_(io_cost), K_(state), K_(type)); - int64_t task_id_; - double cpu_cost_; - double io_cost_; - TaskState state_; - TaskType type_; -}; - -struct ObCreateIndexScanTaskStat : public ObILongOpsTaskStat -{ - ObCreateIndexScanTaskStat() - : macro_count_(0) - {} - virtual ~ObCreateIndexScanTaskStat() = default; - virtual int estimate_cost() override { io_cost_ = static_cast(macro_count_); return common::OB_SUCCESS; } - virtual int assign(const ObILongOpsTaskStat &task_stat) override; - INHERIT_TO_STRING_KV("ObILongOpsTaskStat", ObILongOpsTaskStat, K(macro_count_)); - int64_t macro_count_; -}; - -struct ObCreateIndexSortTaskStat : public ObILongOpsTaskStat -{ - ObCreateIndexSortTaskStat() - : macro_count_(0), run_count_(0) - {} - virtual ~ObCreateIndexSortTaskStat() {} - virtual int estimate_cost() override { io_cost_ = static_cast(run_count_) * static_cast(macro_count_); return common::OB_SUCCESS; } - virtual int assign(const ObILongOpsTaskStat &task_stat) override; - INHERIT_TO_STRING_KV("ObILongOpsTaskStat", ObILongOpsTaskStat, K(macro_count_), K_(run_count)); - int64_t macro_count_; - int64_t run_count_; -}; - -struct ObILongOpsKey -{ - ObILongOpsKey(); - virtual ~ObILongOpsKey() = default; - virtual int64_t hash() const; - virtual bool is_valid() const; - bool operator ==(const ObILongOpsKey &other) const; - virtual int to_key_string() { return common::OB_NOT_SUPPORTED; } - TO_STRING_KV(K_(tenant_id), K_(sid), K_(name), K_(target)); - uint64_t tenant_id_; - uint64_t sid_; - char name_[common::MAX_LONG_OPS_NAME_LENGTH]; - char target_[common::MAX_LONG_OPS_TARGET_LENGTH]; -}; - -struct ObCreateIndexKey: public ObILongOpsKey -{ - ObCreateIndexKey() - : index_table_id_(common::OB_INVALID_ID), partition_id_(common::OB_INVALID_ID) - {} - virtual ~ObCreateIndexKey() {} - virtual int to_key_string() override; - bool is_valid() const - { - return common::OB_INVALID_ID != index_table_id_ - && common::OB_INVALID_ID != partition_id_; - } - INHERIT_TO_STRING_KV("ObILongOpsKey", ObILongOpsKey, K_(index_table_id), K_(partition_id)); - int64_t index_table_id_; - int64_t partition_id_; -}; - -struct ObCommonOpsStatValue -{ - ObCommonOpsStatValue(); - virtual ~ObCommonOpsStatValue() = default; - ObCommonOpsStatValue &operator=(const ObCommonOpsStatValue &other); - void reset(); - TO_STRING_KV(K_(start_time), K_(finish_time), K_(elapsed_time), K_(remaining_time), - K_(percentage), K_(last_update_time)); - int64_t start_time_; - int64_t finish_time_; - int64_t elapsed_time_; - int64_t remaining_time_; - int64_t percentage_; - int64_t last_update_time_; - int64_t is_updated_; - char message_[common::MAX_LONG_OPS_MESSAGE_LENGTH]; - common::SpinRWLock lock_; -}; - -struct ObILongOpsStat -{ - enum class Type - { - CREATE_INDEX = 0, - }; - ObILongOpsStat() - : common_value_() - {} - virtual ~ObILongOpsStat() {} - virtual Type get_type() const = 0; - virtual bool is_valid() const = 0; - virtual int estimate_cost() = 0; - virtual int64_t get_deep_copy_size() const { return sizeof(*this); } - virtual int deep_copy(char *buf, const int64_t buf_len, ObILongOpsStat *&value) const = 0; - virtual int update_task_stat(const ObILongOpsTaskStat &task_stat) = 0; - virtual const ObILongOpsKey &get_key() const = 0; - virtual int check_can_purge(bool &can_purge) = 0; - virtual int64_t to_string(char *buf, const int64_t buf_len) const = 0; - ObCommonOpsStatValue common_value_; -}; - -struct ObCreateIndexPartitionStat : public ObILongOpsStat -{ - ObCreateIndexPartitionStat(); - virtual ~ObCreateIndexPartitionStat(); - virtual int update_task_stat(const ObILongOpsTaskStat &task_stat) override; - void reset(); - virtual int estimate_cost() override; - int copy_task(const ObILongOpsTaskStat *src, ObILongOpsTaskStat *&dest); - virtual int64_t get_deep_copy_size() const override{ return sizeof(*this); } - virtual int deep_copy(char *buf, const int64_t buf_len, ObILongOpsStat *&value) const override; - Type get_type() const override { return ObILongOpsStat::Type::CREATE_INDEX; } - virtual bool is_valid() const override - { - return key_.is_valid(); - } - virtual int check_can_purge(bool &can_purge) override; - const ObILongOpsKey &get_key() const override { return key_; } - TO_STRING_KV(K_(key), K_(task_stats), K_(common_value)); - static const int64_t MAX_LIFE_TIME = 7 * 3600 * 1000; // 7 days - ObCreateIndexKey key_; - common::ObArray task_stats_; - common::ObArenaAllocator allocator_; -}; - -class ObILongOpsStatHandle : public ObResourceHandle -{ - friend class ObLongOpsMonitor; -public: - ObILongOpsStatHandle(); - virtual ~ObILongOpsStatHandle(); - void reset(); -private: - DISALLOW_COPY_AND_ASSIGN(ObILongOpsStatHandle); -}; - -using MAP = storage::ObResourceMap; -using PAIR = common::hash::HashMapPair; - -class ObLongOpsMonitor -{ -public: - static ObLongOpsMonitor &get_instance(); - int init(); - int add_long_ops_stat(const ObILongOpsKey &key, ObILongOpsStat &stat); - int get_long_ops_stat(const ObILongOpsKey &key, ObILongOpsStatHandle &handle); - int remove_long_ops_stat(const ObILongOpsKey &key); - int update_task_stat(const ObILongOpsKey &key, const ObILongOpsTaskStat &new_task_stat); - template - int foreach(Callback &callback); - int dec_handle_ref(ObILongOpsStatHandle &handle); -private: - ObLongOpsMonitor(); - virtual ~ObLongOpsMonitor(); -private: - static const int64_t DEFAULT_BUCKET_NUM = 1543L; - static const int64_t TOTAL_LIMIT = 10 * 1024L * 1024L * 1024L; - static const int64_t HOLD_LIMIT = 8 * 1024L * 1024L; - static const int64_t PAGE_SIZE = common::OB_MALLOC_BIG_BLOCK_SIZE; - bool is_inited_; - MAP map_; -}; - -class ObLongOpsMonitorIterator -{ -public: - class ObKeySnapshotCallback - { - public: - explicit ObKeySnapshotCallback(common::ObIArray &key_snapshot); - virtual ~ObKeySnapshotCallback() = default; - int operator()(PAIR &pair); - private: - common::ObIArray &key_snapshot_; - }; - ObLongOpsMonitorIterator(); - virtual ~ObLongOpsMonitorIterator(); - int init(); - int get_next_stat(ObILongOpsStatHandle &part_stat); -private: - int make_key_snapshot(); -private: - bool is_inited_; - common::ObArray key_snapshot_; - int64_t key_cursor_; -}; - -class ObPurgeCompletedMonitorInfoTask : public common::ObTimerTask -{ -public: - ObPurgeCompletedMonitorInfoTask(); - virtual ~ObPurgeCompletedMonitorInfoTask() {}; - int init(share::schema::ObMultiVersionSchemaService *schema_service, int tg_id); - void destroy(); - virtual void runTimerTask() override; -private: - static const int64_t MAX_BATCH_COUNT = 10000; - static const int64_t SCHEDULE_INTERVAL = 3600 * 1000; // 1h - bool is_inited_; - share::schema::ObMultiVersionSchemaService *schema_service_; -}; - -} // end namespace storage -} // end namespace oceanbase - -#define LONG_OPS_MONITOR_INSTANCE (::oceanbase::storage::ObLongOpsMonitor::get_instance()) - -#endif // OCEANBASE_STORAGE_OB_CREATE_INDEX_MONITOR_H_