diff --git a/deps/oblib/src/lib/utility/ob_tracepoint_def.h b/deps/oblib/src/lib/utility/ob_tracepoint_def.h index 977f614bd..36dbdf48c 100644 --- a/deps/oblib/src/lib/utility/ob_tracepoint_def.h +++ b/deps/oblib/src/lib/utility/ob_tracepoint_def.h @@ -347,6 +347,7 @@ GLOBAL_ERRSIM_POINT_DEF(515, EN_DDL_REPORT_CHECKSUM_FAIL, ""); GLOBAL_ERRSIM_POINT_DEF(516, EN_DDL_REPORT_REPLICA_BUILD_STATUS_FAIL, ""); GLOBAL_ERRSIM_POINT_DEF(517, EN_DDL_DIRECT_LOAD_WAIT_TABLE_LOCK_FAIL, ""); GLOBAL_ERRSIM_POINT_DEF(518, EN_DDL_LOBID_CACHE_SIZE_INJECTED, ""); +GLOBAL_ERRSIM_POINT_DEF(519, EN_DDL_EXECUTE_FAILED, ""); // SQL Optimizer related 551-599 GLOBAL_ERRSIM_POINT_DEF(551, EN_EXPLAIN_GENERATE_PLAN_WITH_OUTLINE, "Used to enable outline validity check for explain query"); diff --git a/src/observer/mysql/ob_query_retry_ctrl.cpp b/src/observer/mysql/ob_query_retry_ctrl.cpp index d134db188..4b4ca276d 100644 --- a/src/observer/mysql/ob_query_retry_ctrl.cpp +++ b/src/observer/mysql/ob_query_retry_ctrl.cpp @@ -300,10 +300,6 @@ public: v.retry_type_ = RETRY_TYPE_NONE; } v.no_more_test_ = true; - } else if (v.session_.get_ddl_info().is_retryable_ddl()) { - v.client_ret_ = err; - v.retry_type_ = RETRY_TYPE_NONE; - v.no_more_test_ = true; } else if (is_load_local(v)) { v.client_ret_ = err; v.retry_type_ = RETRY_TYPE_NONE; @@ -629,9 +625,14 @@ public: virtual void test(ObRetryParam &v) const override { int ret = OB_SUCCESS; + if (v.session_.get_ddl_info().is_ddl() && !v.session_.get_ddl_info().is_retryable_ddl()) { + v.client_ret_ = v.err_; + v.retry_type_ = RETRY_TYPE_NONE; + v.no_more_test_ = true; + } // nested transaction already supported In 32x and can only rollback nested sql. // for forigen key, we keep old logic and do not retry. for pl will retry current nested sql. - if (is_nested_conn(v) && !is_static_engine_retry(v.err_) && !v.is_from_pl_) { + else if (is_nested_conn(v) && !is_static_engine_retry(v.err_) && !v.is_from_pl_) { // right now, top session will retry, bug we can do something here like refresh XXX cache. // in future, nested session can retry if nested transaction is supported. v.no_more_test_ = true; diff --git a/src/rootserver/ddl_task/ob_ddl_scheduler.cpp b/src/rootserver/ddl_task/ob_ddl_scheduler.cpp index 4cb8230ea..9775bc921 100755 --- a/src/rootserver/ddl_task/ob_ddl_scheduler.cpp +++ b/src/rootserver/ddl_task/ob_ddl_scheduler.cpp @@ -1052,6 +1052,7 @@ int ObDDLScheduler::create_ddl_task(const ObCreateDDLTaskParam ¶m, param.sub_task_trace_id_, static_cast(param.ddl_arg_), param.tenant_data_version_, + param.ddl_need_retry_at_executor_, *param.allocator_, task_record))) { LOG_WARN("fail to create table redefinition task", K(ret)); @@ -1734,6 +1735,7 @@ int ObDDLScheduler::create_table_redefinition_task( const int32_t sub_task_trace_id, const obrpc::ObAlterTableArg *alter_table_arg, const uint64_t tenant_data_version, + const bool ddl_need_retry_at_executor, ObIAllocator &allocator, ObDDLTaskRecord &task_record) { @@ -1757,7 +1759,8 @@ int ObDDLScheduler::create_table_redefinition_task( consumer_group_id, sub_task_trace_id, *alter_table_arg, - tenant_data_version))) { + tenant_data_version, + ddl_need_retry_at_executor))) { LOG_WARN("fail to init redefinition task", K(ret)); } else if (OB_FAIL(redefinition_task.set_trace_id(*ObCurTraceId::get_trace_id()))) { LOG_WARN("set trace id failed", K(ret)); diff --git a/src/rootserver/ddl_task/ob_ddl_scheduler.h b/src/rootserver/ddl_task/ob_ddl_scheduler.h index 4567cc8ab..182fecd21 100755 --- a/src/rootserver/ddl_task/ob_ddl_scheduler.h +++ b/src/rootserver/ddl_task/ob_ddl_scheduler.h @@ -399,6 +399,7 @@ private: const int32_t sub_task_trace_id, const obrpc::ObAlterTableArg *alter_table_arg, const uint64_t tenant_data_version, + const bool ddl_need_retry_at_executor, ObIAllocator &allocator, ObDDLTaskRecord &task_record); diff --git a/src/rootserver/ddl_task/ob_ddl_task.cpp b/src/rootserver/ddl_task/ob_ddl_task.cpp index 04cb36b5c..1341b2d1d 100644 --- a/src/rootserver/ddl_task/ob_ddl_task.cpp +++ b/src/rootserver/ddl_task/ob_ddl_task.cpp @@ -166,7 +166,7 @@ ObCreateDDLTaskParam::ObCreateDDLTaskParam() consumer_group_id_(0), parent_task_id_(0), task_id_(0), type_(DDL_INVALID), src_table_schema_(nullptr), dest_table_schema_(nullptr), ddl_arg_(nullptr), allocator_(nullptr), aux_rowkey_doc_schema_(nullptr), aux_doc_rowkey_schema_(nullptr), aux_doc_word_schema_(nullptr), - tenant_data_version_(0) + tenant_data_version_(0), ddl_need_retry_at_executor_(false) { } @@ -181,11 +181,12 @@ ObCreateDDLTaskParam::ObCreateDDLTaskParam(const uint64_t tenant_id, ObIAllocator *allocator, const obrpc::ObDDLArg *ddl_arg, const int64_t parent_task_id, - const int64_t task_id) + const int64_t task_id, + const bool ddl_need_retry_at_executor) : sub_task_trace_id_(0), tenant_id_(tenant_id), object_id_(object_id), schema_version_(schema_version), parallelism_(parallelism), consumer_group_id_(consumer_group_id), parent_task_id_(parent_task_id), task_id_(task_id), type_(type), src_table_schema_(src_table_schema), dest_table_schema_(dest_table_schema), ddl_arg_(ddl_arg), allocator_(allocator), aux_rowkey_doc_schema_(nullptr), aux_doc_rowkey_schema_(nullptr), - aux_doc_word_schema_(nullptr) + aux_doc_word_schema_(nullptr), ddl_need_retry_at_executor_(ddl_need_retry_at_executor) { } diff --git a/src/rootserver/ddl_task/ob_ddl_task.h b/src/rootserver/ddl_task/ob_ddl_task.h index 4aa2c7eee..b5a0927e3 100755 --- a/src/rootserver/ddl_task/ob_ddl_task.h +++ b/src/rootserver/ddl_task/ob_ddl_task.h @@ -173,14 +173,15 @@ public: ObIAllocator *allocator, const obrpc::ObDDLArg *ddl_arg = nullptr, const int64_t parent_task_id = 0, - const int64_t task_id = 0); + const int64_t task_id = 0, + const bool ddl_need_retry_at_executor = false); ~ObCreateDDLTaskParam() = default; bool is_valid() const { return OB_INVALID_ID != tenant_id_ && type_ > share::DDL_INVALID && type_ < share::DDL_MAX && nullptr != allocator_; } TO_STRING_KV(K_(tenant_id), K_(object_id), K_(schema_version), K_(parallelism), K_(consumer_group_id), K_(parent_task_id), K_(task_id), K_(type), KPC_(src_table_schema), KPC_(dest_table_schema), KPC_(ddl_arg), K_(tenant_data_version), - K_(sub_task_trace_id), KPC_(aux_rowkey_doc_schema), KPC_(aux_doc_rowkey_schema), KPC_(aux_doc_word_schema)); - + K_(sub_task_trace_id), KPC_(aux_rowkey_doc_schema), KPC_(aux_doc_rowkey_schema), KPC_(aux_doc_word_schema), + K_(ddl_need_retry_at_executor)); public: int32_t sub_task_trace_id_; uint64_t tenant_id_; @@ -199,6 +200,7 @@ public: const ObTableSchema *aux_doc_rowkey_schema_; const ObTableSchema *aux_doc_word_schema_; uint64_t tenant_data_version_; + bool ddl_need_retry_at_executor_; }; class ObDDLTaskRecordOperator final diff --git a/src/rootserver/ddl_task/ob_table_redefinition_task.cpp b/src/rootserver/ddl_task/ob_table_redefinition_task.cpp index 82a5c5b23..eff61ded1 100755 --- a/src/rootserver/ddl_task/ob_table_redefinition_task.cpp +++ b/src/rootserver/ddl_task/ob_table_redefinition_task.cpp @@ -58,6 +58,7 @@ int ObTableRedefinitionTask::init(const ObTableSchema* src_table_schema, const int32_t sub_task_trace_id, const ObAlterTableArg &alter_table_arg, const uint64_t tenant_data_version, + const bool ddl_need_retry_at_executor, const int64_t task_status, const int64_t snapshot_version) { @@ -115,7 +116,7 @@ int ObTableRedefinitionTask::init(const ObTableSchema* src_table_schema, LOG_WARN("fail to get target cg cnt", K(ret), KPC(dst_table_schema)); } else if (OB_FAIL(init_ddl_task_monitor_info(target_object_id_))) { LOG_WARN("init ddl task monitor info failed", K(ret)); - } else if (OB_FAIL(check_ddl_can_retry(dst_table_schema))) { + } else if (OB_FAIL(check_ddl_can_retry(ddl_need_retry_at_executor, dst_table_schema))) { LOG_WARN("check use heap table ddl plan failed", K(ret)); } else { is_inited_ = true; @@ -346,7 +347,7 @@ int ObTableRedefinitionTask::check_build_replica_end(bool &is_end) return ret; } -int ObTableRedefinitionTask::check_ddl_can_retry(const ObTableSchema *table_schema) +int ObTableRedefinitionTask::check_ddl_can_retry(const bool ddl_need_retry_at_executor, const ObTableSchema *table_schema) { int ret = OB_SUCCESS; is_ddl_retryable_ = true; @@ -361,8 +362,10 @@ int ObTableRedefinitionTask::check_ddl_can_retry(const ObTableSchema *table_sche if (ObDDLUtil::use_idempotent_mode(data_format_version_)) { if (use_heap_table_ddl_plan_) { is_ddl_retryable_ = false; - } else if (DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION == task_type_) { - is_ddl_retryable_ = false; + LOG_INFO("ddl schedule will not retry for heap table", K(use_heap_table_ddl_plan_), K_(task_id)); + } else if (ddl_need_retry_at_executor) { + is_ddl_retryable_ = false; // do not retry at ddl scheduler when ddl need retry at executor + LOG_INFO("ddl schedule will not retry for ddl which will retry at table executor level", K(use_heap_table_ddl_plan_), K_(task_id)); } } } diff --git a/src/rootserver/ddl_task/ob_table_redefinition_task.h b/src/rootserver/ddl_task/ob_table_redefinition_task.h index ba72eaf98..af43c7795 100644 --- a/src/rootserver/ddl_task/ob_table_redefinition_task.h +++ b/src/rootserver/ddl_task/ob_table_redefinition_task.h @@ -42,6 +42,7 @@ public: const int32_t sub_task_trace_id, const obrpc::ObAlterTableArg &alter_table_arg, const uint64_t tenant_data_version, + const bool ddl_need_retry_at_executor, const int64_t task_status = share::ObDDLTaskStatus::PREPARE, const int64_t snapshot_version = 0); int init(const ObDDLTaskRecord &task_record); @@ -80,7 +81,7 @@ protected: const int64_t row_scanned, const int64_t row_inserted); int repending(const share::ObDDLTaskStatus next_task_status); - virtual bool task_can_retry() const override { return is_ddl_retryable_; } + virtual bool task_can_retry() const override { return share::ObDDLTaskStatus::REDEFINITION == task_status_ ? is_ddl_retryable_ : true; } private: inline bool get_is_copy_indexes() const {return is_copy_indexes_;} inline bool get_is_copy_triggers() const {return is_copy_triggers_;} @@ -99,7 +100,7 @@ private: int check_use_heap_table_ddl_plan(const share::schema::ObTableSchema *target_table_schema); int get_direct_load_job_stat(common::ObArenaAllocator &allocator, sql::ObLoadDataStat &job_stat); int check_target_cg_cnt(); - int check_ddl_can_retry(const share::schema::ObTableSchema *table_schema); + int check_ddl_can_retry(const bool ddl_need_retry_at_executor, const share::schema::ObTableSchema *table_schema); private: static const int64_t OB_TABLE_REDEFINITION_TASK_VERSION = 1L; bool has_rebuild_index_; diff --git a/src/rootserver/ob_ddl_service.cpp b/src/rootserver/ob_ddl_service.cpp index 2764d54e8..0539319b4 100755 --- a/src/rootserver/ob_ddl_service.cpp +++ b/src/rootserver/ob_ddl_service.cpp @@ -4067,7 +4067,8 @@ int ObDDLService::check_alter_table_column(obrpc::ObAlterTableArg &alter_table_a const ObTableSchema &orig_table_schema, ObSchemaGetterGuard &schema_guard, const bool is_oracle_mode, - ObDDLType &ddl_type) + ObDDLType &ddl_type, + bool &ddl_need_retry_at_executor) { int ret = OB_SUCCESS; bool is_modify_partition_key = false; @@ -4077,6 +4078,7 @@ int ObDDLService::check_alter_table_column(obrpc::ObAlterTableArg &alter_table_a AlterColumnSchema *alter_column_schema = NULL; ObTableSchema::const_column_iterator it_begin = alter_table_schema.column_begin(); ObTableSchema::const_column_iterator it_end = alter_table_schema.column_end(); + ddl_need_retry_at_executor = false; for (; OB_SUCC(ret) && it_begin != it_end; it_begin++) { if (OB_ISNULL(alter_column_schema = static_cast(*it_begin))) { ret = OB_ERR_UNEXPECTED; @@ -4183,7 +4185,12 @@ int ObDDLService::check_alter_table_column(obrpc::ObAlterTableArg &alter_table_a } else if (orig_table_schema.get_autoinc_column_id() == 0) { if (orig_column_schema->is_nullable()) { // if the original table has null, we need to do double write to fill the nulls - ddl_type = ObDDLType::DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION; + if (ObDDLType::DDL_INVALID == ddl_type || ObDDLType::DDL_MODIFY_COLUMN == ddl_type) { + ddl_type = ObDDLType::DDL_MODIFY_COLUMN; + } else { + ddl_type = ObDDLType::DDL_TABLE_REDEFINITION; + } + ddl_need_retry_at_executor = true; } else { if (ObDDLType::DDL_INVALID == ddl_type) { ddl_type = ObDDLType::DDL_MODIFY_AUTO_INCREMENT; @@ -12143,7 +12150,7 @@ int ObDDLService::alter_table_sess_active_time_in_trans(obrpc::ObAlterTableArg & alter_table_schema.set_origin_database_name(database_schema->get_database_name()); alter_table_schema.set_origin_table_name(table_schema->get_table_name()); alter_table_schema.set_tenant_id(table_schema->get_tenant_id()); - if (OB_FAIL(check_is_offline_ddl(alter_table_arg, res.ddl_type_))) { + if (OB_FAIL(check_is_offline_ddl(alter_table_arg, res.ddl_type_, res.ddl_need_retry_at_executor_))) { LOG_WARN("failed to to check is offline ddl", K(ret)); } else { // offline ddl cannot appear at the same time with other ddl types @@ -13014,7 +13021,8 @@ int ObDDLService::check_alter_column_group(const obrpc::ObAlterTableArg &alter_t int ObDDLService::check_is_offline_ddl(ObAlterTableArg &alter_table_arg, - ObDDLType &ddl_type) + ObDDLType &ddl_type, + bool &ddl_need_retry_at_executor) { int ret = OB_SUCCESS; ddl_type = ObDDLType::DDL_INVALID; @@ -13042,7 +13050,8 @@ int ObDDLService::check_is_offline_ddl(ObAlterTableArg &alter_table_arg, *orig_table_schema, schema_guard, is_oracle_mode, - ddl_type))) { + ddl_type, + ddl_need_retry_at_executor))) { LOG_WARN("fail to check alter table column", K(ret)); } if (OB_SUCC(ret) && alter_table_arg.is_alter_indexs_ @@ -13568,7 +13577,8 @@ int ObDDLService::do_offline_ddl_in_trans(obrpc::ObAlterTableArg &alter_table_ar &alter_table_arg.allocator_, &alter_table_arg, 0/*parent_task_id*/, - task_id); + task_id, + res.ddl_need_retry_at_executor_); param.tenant_data_version_ = tenant_data_version; if (orig_table_schema->is_external_table()) { ret = OB_OP_NOT_ALLOW; @@ -15224,6 +15234,7 @@ int ObDDLService::alter_table(obrpc::ObAlterTableArg &alter_table_arg, const uint64_t tenant_id = alter_table_schema.get_tenant_id(); int64_t &task_id = res.task_id_; ObDDLType &ddl_type = res.ddl_type_; + bool &ddl_need_retry_at_executor = res.ddl_need_retry_at_executor_; ddl_type = DDL_INVALID; if (OB_FAIL(check_inner_stat())) { LOG_WARN("variable is not init", K(ret)); @@ -15306,7 +15317,7 @@ int ObDDLService::alter_table(obrpc::ObAlterTableArg &alter_table_arg, } else { LOG_INFO("refresh session active time of temp tables succeed!", K(ret)); } - } else if (OB_FAIL(check_is_offline_ddl(alter_table_arg, ddl_type))) { + } else if (OB_FAIL(check_is_offline_ddl(alter_table_arg, ddl_type, ddl_need_retry_at_executor))) { LOG_WARN("failed to check is offline ddl", K(ret)); } else { // offline ddl cannot appear at the same time with other ddl types diff --git a/src/rootserver/ob_ddl_service.h b/src/rootserver/ob_ddl_service.h index fb721f656..8bc159a49 100644 --- a/src/rootserver/ob_ddl_service.h +++ b/src/rootserver/ob_ddl_service.h @@ -1485,7 +1485,8 @@ private: // offline ddl cannot appear at the same time with other ddl types // Offline ddl cannot appear at the same time as offline ddl int check_is_offline_ddl(obrpc::ObAlterTableArg &alter_table_arg, - share::ObDDLType &ddl_type); + share::ObDDLType &ddl_type, + bool &ddl_need_retry_at_executor); int check_can_bind_tablets(const share::ObDDLType ddl_type, bool &bind_tablets); int check_ddl_with_primary_key_operation(const obrpc::ObAlterTableArg &alter_table_arg, @@ -1609,7 +1610,8 @@ private: const share::schema::ObTableSchema &orig_table_schema, share::schema::ObSchemaGetterGuard &schema_guard, const bool is_oracle_mode, - share::ObDDLType &ddl_type); + share::ObDDLType &ddl_type, + bool &ddl_need_retry_at_executor); int check_alter_table_partition(const obrpc::ObAlterTableArg &alter_table_arg, const share::schema::ObTableSchema &orig_table_schema, const bool is_oracle_mode, 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 7ae43ca62..afa104f60 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 @@ -136,7 +136,16 @@ int ObPxMultiPartSSTableInsertOp::inner_get_next_row() int64_t notify_idx = 0; ObTenantDirectLoadMgr *tenant_direct_load_mgr = MTL(ObTenantDirectLoadMgr *); ObInsertMonitor insert_monitor(op_monitor_info_.otherstat_2_value_, op_monitor_info_.otherstat_1_value_); - if (OB_UNLIKELY(nullptr == child_ || nullptr == tenant_direct_load_mgr)) { +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = OB_E(EventTable::EN_DDL_EXECUTE_FAILED) OB_SUCCESS; + if (OB_FAIL(ret)) { + LOG_WARN("errsim ddl execute get next row failed", KR(ret)); + } + } +#endif + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(nullptr == child_ || nullptr == tenant_direct_load_mgr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the child op is null", K(ret), K(MTL_ID()), KP(child_), KP(tenant_direct_load_mgr)); } else if (get_spec().is_returning_) {