[FEAT MERGE][CP]parallel comment/create index
This commit is contained in:
parent
88687485ac
commit
afb6162c48
6
deps/oblib/src/lib/ob_name_id_def.h
vendored
6
deps/oblib/src/lib/ob_name_id_def.h
vendored
@ -843,6 +843,12 @@ DEF_NAME(id, "id")
|
||||
DEF_NAME(wait_ddl_trans, "wait_ddl_trans")
|
||||
DEF_NAME(end_ddl_trans, "end_ddl_trans")
|
||||
DEF_NAME_PAIR(create_view, "create view")
|
||||
DEF_NAME_PAIR(set_comment, "set comment")
|
||||
DEF_NAME(lock_common_ddl, "lock common ddl")
|
||||
DEF_NAME(check_schemas, "check schemas")
|
||||
DEF_NAME(alter_schemas, "alter schemas")
|
||||
DEF_NAME_PAIR(parallel_ddl, "parallel ddl")
|
||||
DEF_NAME(submit_task, "submit task")
|
||||
|
||||
// location cache related
|
||||
DEF_NAME_PAIR(renew_loc_by_sql, "renew loc by sql")
|
||||
|
@ -105,6 +105,7 @@ void oceanbase::observer::init_srv_xlator_for_rootserver(ObSrvRpcXlator *xlator)
|
||||
RPC_PROCESSOR(rootserver::ObRpcAbortRedefTableP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcUpdateDDLTaskActiveTimeP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcCreateHiddenTableP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcSetCommentP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcAlterTableP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcExchangePartitionP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcDropTableP, *gctx_.root_service_);
|
||||
@ -113,6 +114,7 @@ void oceanbase::observer::init_srv_xlator_for_rootserver(ObSrvRpcXlator *xlator)
|
||||
RPC_PROCESSOR(rootserver::ObRpcTruncateTableV2P, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcCreateAuxIndexP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcCreateIndexP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcParallelCreateIndexP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcDropIndexP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcDropIndexOnFailedP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcCreateMLogP, *gctx_.root_service_);
|
||||
@ -121,6 +123,7 @@ void oceanbase::observer::init_srv_xlator_for_rootserver(ObSrvRpcXlator *xlator)
|
||||
RPC_PROCESSOR(rootserver::ObRpcRefreshConfigP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcRootMinorFreezeP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObUpdateIndexTableStatusP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObUpdateIndexStatusP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcCreateOutlineP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcAlterOutlineP, *gctx_.root_service_);
|
||||
RPC_PROCESSOR(rootserver::ObRpcDropOutlineP, *gctx_.root_service_);
|
||||
|
@ -146,6 +146,9 @@ ob_set_subtarget(ob_rootserver parallel_ddl
|
||||
parallel_ddl/ob_create_view_helper.cpp
|
||||
parallel_ddl/ob_index_name_checker.cpp
|
||||
parallel_ddl/ob_tablet_balance_allocator.cpp
|
||||
parallel_ddl/ob_set_comment_helper.cpp
|
||||
parallel_ddl/ob_create_index_helper.cpp
|
||||
parallel_ddl/ob_update_index_status_helper.cpp
|
||||
)
|
||||
|
||||
ob_set_subtarget(ob_rootserver freeze
|
||||
|
@ -60,6 +60,8 @@ using namespace blocksstable;
|
||||
|
||||
namespace rootserver
|
||||
{
|
||||
|
||||
|
||||
ObDDLTaskKey::ObDDLTaskKey()
|
||||
: tenant_id_(OB_INVALID_TENANT_ID), object_id_(OB_INVALID_ID), schema_version_(0)
|
||||
{
|
||||
@ -1044,9 +1046,8 @@ int ObDDLTask::set_ddl_stmt_str(const ObString &ddl_stmt_str)
|
||||
int ObDDLTask::serialize_params_to_message(char *buf, const int64_t buf_size, int64_t &pos) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_unique_index = false;
|
||||
bool is_global_index = false;
|
||||
ObDDLTaskSerializeField serialize_field(task_version_, parallelism_, data_format_version_, consumer_group_id_, is_abort_, sub_task_trace_id_, is_unique_index, is_global_index, is_pre_split_);
|
||||
ObDDLTaskSerializeField serialize_field(task_version_, parallelism_, data_format_version_, consumer_group_id_, is_abort_,
|
||||
sub_task_trace_id_, is_unique_index_, is_global_index_, is_pre_split_);
|
||||
if (OB_UNLIKELY(nullptr == buf || buf_size <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arguments", K(ret), KP(buf), K(buf_size));
|
||||
@ -1074,6 +1075,8 @@ int ObDDLTask::deserialize_params_from_message(const uint64_t tenant_id, const c
|
||||
consumer_group_id_ = serialize_field.consumer_group_id_;
|
||||
is_abort_ = serialize_field.is_abort_;
|
||||
sub_task_trace_id_ = serialize_field.sub_task_trace_id_;
|
||||
is_unique_index_ = serialize_field.is_unique_index_;
|
||||
is_global_index_ = serialize_field.is_global_index_;
|
||||
is_pre_split_ = serialize_field.is_pre_split_;
|
||||
}
|
||||
return ret;
|
||||
@ -1081,9 +1084,8 @@ int ObDDLTask::deserialize_params_from_message(const uint64_t tenant_id, const c
|
||||
|
||||
int64_t ObDDLTask::get_serialize_param_size() const
|
||||
{
|
||||
bool is_unique_index = false;
|
||||
bool is_global_index = false;
|
||||
ObDDLTaskSerializeField serialize_field(task_version_, parallelism_, data_format_version_, consumer_group_id_, is_abort_, sub_task_trace_id_, is_unique_index, is_global_index, is_pre_split_);
|
||||
ObDDLTaskSerializeField serialize_field(task_version_, parallelism_, data_format_version_, consumer_group_id_, is_abort_,
|
||||
sub_task_trace_id_, is_unique_index_, is_global_index_, is_pre_split_);
|
||||
return serialize_field.get_serialize_size();
|
||||
}
|
||||
|
||||
@ -1117,6 +1119,7 @@ int ObDDLTask::convert_to_record(
|
||||
task_record.task_version_ = get_task_version();
|
||||
task_record.execution_id_ = get_execution_id();
|
||||
task_record.ret_code_ = get_ret_code();
|
||||
task_record.consensus_schema_version_ = get_consensus_schema_version();
|
||||
task_record.ddl_need_retry_at_executor_ = !is_ddl_retryable();
|
||||
const ObString &ddl_stmt_str = get_ddl_stmt_str();
|
||||
if (serialize_param_size > 0) {
|
||||
@ -1379,6 +1382,7 @@ int ObDDLTask::report_error_code(const ObString &forward_user_message, const int
|
||||
const int64_t buf_size = is_ddl_retry_task ? forward_user_message.length() + 1: OB_MAX_ERROR_MSG_LEN;
|
||||
error_message.ret_code_ = ret_code_;
|
||||
error_message.ddl_type_ = task_type_;
|
||||
error_message.consensus_schema_version_ = consensus_schema_version_;
|
||||
if (OB_FAIL(databuff_printf(error_message.dba_message_, OB_MAX_ERROR_MSG_LEN, "%s", "Successful ddl"))) {
|
||||
LOG_WARN("print ddl dba message failed", K(ret));
|
||||
} else if (OB_FAIL(error_message.prepare_user_message_buf(buf_size))) {
|
||||
@ -2857,6 +2861,7 @@ void ObDDLTaskRecord::reset()
|
||||
task_version_ = 0;
|
||||
ret_code_ = OB_SUCCESS;
|
||||
execution_id_ = -1; // -1 is invalid
|
||||
consensus_schema_version_ = OB_INVALID_VERSION;
|
||||
}
|
||||
|
||||
|
||||
@ -3184,6 +3189,35 @@ int ObDDLTaskRecordOperator::update_ret_code_and_message(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLTaskRecordOperator::update_consensus_schema_version(
|
||||
common::ObISQLClient &sql_client,
|
||||
const uint64_t tenant_id,
|
||||
const int64_t task_id,
|
||||
const int64_t consensus_schema_version)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSqlString sql_string;
|
||||
int64_t affected_rows = 0;
|
||||
if (OB_ISNULL(sql_client.get_pool())
|
||||
|| OB_UNLIKELY(task_id <= 0 || tenant_id == OB_INVALID_TENANT_ID
|
||||
|| consensus_schema_version <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arg", KR(ret), K(tenant_id), K(task_id));
|
||||
} else if (OB_FAIL(sql_string.assign_fmt("UPDATE %s SET consensus_schema_version=%ld WHERE task_id=%lu ",
|
||||
OB_ALL_DDL_TASK_STATUS_TNAME, consensus_schema_version, task_id))) {
|
||||
LOG_WARN("assign sql string failed", KR(ret), K(consensus_schema_version), K(task_id));
|
||||
} else if (OB_FAIL(DDL_SIM(tenant_id, task_id, TASK_STATUS_OPERATOR_SLOW))) {
|
||||
LOG_WARN("ddl sim failure: slow inner sql", KR(ret), K(tenant_id), K(task_id));
|
||||
} else if (OB_FAIL(DDL_SIM(tenant_id, task_id, UPDATE_TASK_RECORD_ON_RET_CODE_FAILED))) {
|
||||
LOG_WARN("ddl sim failure", KR(ret), K(tenant_id), K(task_id));
|
||||
} else if (OB_FAIL(sql_client.write(tenant_id, sql_string.ptr(), affected_rows))) {
|
||||
LOG_WARN("update snapshot_version of ddl task record failed", KR(ret), K(sql_string));
|
||||
} else if (OB_UNLIKELY(affected_rows < 0)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected affected_rows", KR(ret), K(affected_rows));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObDDLTaskRecordOperator::get_schedule_info_for_update(
|
||||
common::ObISQLClient &proxy,
|
||||
const uint64_t tenant_id,
|
||||
@ -3586,12 +3620,10 @@ int ObDDLTaskRecordOperator::check_is_adding_constraint(
|
||||
ObSqlString sql_string;
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
|
||||
sqlclient::ObMySQLResult *result = NULL;
|
||||
if (OB_FAIL(sql_string.assign_fmt(" SELECT time_to_usec(gmt_create) AS create_time, tenant_id, task_id, object_id, target_object_id, ddl_type, "
|
||||
"schema_version, parent_task_id, trace_id, status, snapshot_version, task_version, execution_id, "
|
||||
"UNHEX(ddl_stmt_str) as ddl_stmt_str_unhex, ret_code, UNHEX(message) as message_unhex FROM %s "
|
||||
"WHERE object_id = %" PRIu64 " && ddl_type IN (%d, %d, %d)", OB_ALL_DDL_TASK_STATUS_TNAME,
|
||||
if (OB_FAIL(sql_string.assign_fmt(GET_DDL_TASK_SQL
|
||||
" WHERE object_id = %" PRIu64 " && ddl_type IN (%d, %d, %d)", OB_ALL_DDL_TASK_STATUS_TNAME,
|
||||
object_id, DDL_CHECK_CONSTRAINT, DDL_FOREIGN_KEY_CONSTRAINT, DDL_ADD_NOT_NULL_COLUMN))) {
|
||||
LOG_WARN("assign sql string failed", K(ret));
|
||||
LOG_WARN("assign sql string failed", KR(ret));
|
||||
} else if (OB_FAIL(proxy->read(res, tenant_id, sql_string.ptr()))) {
|
||||
LOG_WARN("query ddl task record failed", K(ret), K(sql_string));
|
||||
} else if (OB_ISNULL(result = res.get_result())) {
|
||||
@ -3686,11 +3718,9 @@ int ObDDLTaskRecordOperator::check_has_conflict_ddl(
|
||||
ObSqlString sql_string;
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
|
||||
sqlclient::ObMySQLResult *result = nullptr;
|
||||
if (OB_FAIL(sql_string.assign_fmt("SELECT time_to_usec(gmt_create) AS create_time, tenant_id, task_id, object_id, target_object_id, ddl_type,"
|
||||
"schema_version, parent_task_id, trace_id, status, snapshot_version, task_version, execution_id,"
|
||||
"UNHEX(ddl_stmt_str) as ddl_stmt_str_unhex, ret_code, UNHEX(message) as message_unhex FROM %s "
|
||||
"WHERE object_id = %lu", OB_ALL_DDL_TASK_STATUS_TNAME, table_id))) {
|
||||
LOG_WARN("assign sql string failed", K(ret));
|
||||
if (OB_FAIL(sql_string.assign_fmt(GET_DDL_TASK_SQL
|
||||
" WHERE object_id = %lu", OB_ALL_DDL_TASK_STATUS_TNAME, table_id))) {
|
||||
LOG_WARN("assign sql string failed", KR(ret), K(table_id));
|
||||
} else if (OB_FAIL(DDL_SIM(tenant_id, task_id, TASK_STATUS_OPERATOR_SLOW))) {
|
||||
LOG_WARN("ddl sim failure: slow inner sql", K(ret), K(tenant_id), K(task_id));
|
||||
} else if (OB_FAIL(DDL_SIM(tenant_id, task_id, QUERY_TASK_RECORD_CHECK_CONFLICT_DDL_FAILED))) {
|
||||
@ -3962,9 +3992,8 @@ int ObDDLTaskRecordOperator::get_ddl_task_record(const uint64_t tenant_id,
|
||||
if (OB_UNLIKELY(!proxy.is_inited())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(ret), K(proxy.is_inited()));
|
||||
} else if (OB_FAIL(sql_string.assign_fmt(" SELECT time_to_usec(gmt_create) AS create_time, tenant_id, task_id, object_id, target_object_id, ddl_type, "
|
||||
"schema_version, parent_task_id, trace_id, status, snapshot_version, task_version, execution_id, "
|
||||
"UNHEX(ddl_stmt_str) as ddl_stmt_str_unhex, ret_code, UNHEX(message) as message_unhex FROM %s WHERE task_id=%lu", OB_ALL_DDL_TASK_STATUS_TNAME, task_id))) {
|
||||
} else if (OB_FAIL(sql_string.assign_fmt(GET_DDL_TASK_SQL
|
||||
" WHERE task_id=%lu ", OB_ALL_DDL_TASK_STATUS_TNAME, task_id))) {
|
||||
LOG_WARN("assign sql string failed", K(ret), K(task_id));
|
||||
} else if (OB_FAIL(get_task_record(tenant_id, sql_string, proxy, allocator, task_records))) {
|
||||
LOG_WARN("get task record failed", K(ret), K(sql_string));
|
||||
@ -3991,9 +4020,7 @@ int ObDDLTaskRecordOperator::get_all_ddl_task_record(common::ObMySQLProxy &proxy
|
||||
if (OB_UNLIKELY(!proxy.is_inited())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(ret), K(proxy.is_inited()));
|
||||
} else if (OB_FAIL(sql_string.assign_fmt(" SELECT time_to_usec(gmt_create) AS create_time, tenant_id, task_id, object_id, target_object_id, ddl_type, "
|
||||
"schema_version, parent_task_id, trace_id, status, snapshot_version, task_version, execution_id, "
|
||||
"UNHEX(ddl_stmt_str) as ddl_stmt_str_unhex, ret_code, UNHEX(message) as message_unhex FROM %s ", OB_ALL_VIRTUAL_DDL_TASK_STATUS_TNAME))) {
|
||||
} else if (OB_FAIL(sql_string.assign_fmt(GET_DDL_TASK_SQL, OB_ALL_VIRTUAL_DDL_TASK_STATUS_TNAME))) {
|
||||
LOG_WARN("assign sql string failed", K(ret));
|
||||
} else if (OB_FAIL(get_task_record(OB_INVALID_TENANT_ID, sql_string, proxy, allocator, records))) {
|
||||
LOG_WARN("get task record failed", K(ret), K(sql_string));
|
||||
@ -4126,21 +4153,63 @@ int ObDDLTaskRecordOperator::insert_record(
|
||||
}
|
||||
}
|
||||
}
|
||||
uint64_t tenant_data_version = 0;
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(to_hex_str(record.ddl_stmt_str_, ddl_stmt_string))) {
|
||||
LOG_WARN("append hex escaped ddl stmt string failed", K(ret));
|
||||
} else if (OB_FAIL(to_hex_str(record.message_, message_string))) {
|
||||
LOG_WARN("append hex escaped string failed", K(ret));
|
||||
} else if (OB_FAIL(sql_string.assign_fmt(
|
||||
" INSERT INTO %s (gmt_create, gmt_modified, task_id, parent_task_id, tenant_id, object_id, schema_version, target_object_id, ddl_type, trace_id, status, task_version, execution_id, ret_code, ddl_stmt_str, message) "
|
||||
" VALUES (usec_to_time(%lu), usec_to_time(%lu), %lu, %lu, %lu, %lu, %lu, %lu, %d, '%s', %ld, %lu, %ld, %lu, '%.*s', \"%.*s\") ",
|
||||
OB_ALL_DDL_TASK_STATUS_TNAME, record.gmt_create_, record.gmt_create_, record.task_id_, record.parent_task_id_,
|
||||
ObSchemaUtils::get_extract_tenant_id(record.tenant_id_, record.tenant_id_), record.object_id_, record.schema_version_,
|
||||
get_record_id(record.ddl_type_, record.target_object_id_), record.ddl_type_, trace_id_str, record.task_status_, record.task_version_, record.execution_id_, record.ret_code_,
|
||||
static_cast<int>(ddl_stmt_string.length()), ddl_stmt_string.ptr(), static_cast<int>(message_string.length()), message_string.ptr()))) {
|
||||
LOG_WARN("assign sql string failed", K(ret), K(record));
|
||||
} else if (OB_FAIL(DDL_SIM(record.tenant_id_, record.task_id_, TASK_STATUS_OPERATOR_SLOW))) {
|
||||
} else if (OB_FAIL(GET_MIN_DATA_VERSION(record.tenant_id_, tenant_data_version))) {
|
||||
LOG_WARN("get tenant data version failed", KR(ret), K_(record.tenant_id));
|
||||
} else if ((tenant_data_version < DATA_VERSION_4_2_2_0
|
||||
|| (tenant_data_version >= DATA_VERSION_4_3_0_0 && tenant_data_version < DATA_VERSION_4_3_5_0))
|
||||
&& record.consensus_schema_version_ != OB_INVALID_VERSION) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("consensus schema version should be invalid before 4220", KR(ret), K_(record.consensus_schema_version));
|
||||
} else {
|
||||
ObDMLSqlSplicer dml;
|
||||
if (OB_FAIL(dml.add_gmt_create(record.gmt_create_))) {
|
||||
LOG_WARN("fail to add gmt_create", KR(ret), K_(record.gmt_create));
|
||||
} else if (OB_FAIL(dml.add_gmt_modified(record.gmt_create_))) {
|
||||
LOG_WARN("fail to add gmt_modified", KR(ret), K_(record.gmt_create));
|
||||
} else if (OB_FAIL(dml.add_pk_column("task_id", record.task_id_))) {
|
||||
LOG_WARN("fail to add task_id", KR(ret), K_(record.task_id));
|
||||
} else if (OB_FAIL(dml.add_column("parent_task_id", record.parent_task_id_))) {
|
||||
LOG_WARN("fail to add parent_task_id", KR(ret), K_(record.parent_task_id));
|
||||
} else if (OB_FAIL(dml.add_column("tenant_id", ObSchemaUtils::get_extract_tenant_id(record.tenant_id_, record.tenant_id_)))) {
|
||||
LOG_WARN("fail to add tenant_id", KR(ret), K_(record.tenant_id));
|
||||
} else if (OB_FAIL(dml.add_column("object_id", record.object_id_))) {
|
||||
LOG_WARN("fail to add object_id", KR(ret), K_(record.object_id));
|
||||
} else if (OB_FAIL(dml.add_column("schema_version", record.schema_version_))) {
|
||||
LOG_WARN("fail to add schema_version", KR(ret), K_(record.schema_version));
|
||||
} else if (OB_FAIL(dml.add_column("target_object_id", get_record_id(record.ddl_type_, record.target_object_id_)))) {
|
||||
LOG_WARN("fail to add target_object_id", KR(ret), K_(record.ddl_type), K_(record.target_object_id));
|
||||
} else if (OB_FAIL(dml.add_column("ddl_type", record.ddl_type_))) {
|
||||
LOG_WARN("fail to add ddl_type", KR(ret), K_(record.ddl_type));
|
||||
} else if (OB_FAIL(dml.add_column("trace_id", trace_id_str))) {
|
||||
LOG_WARN("fail to add trace_id", KR(ret), K(trace_id_str));
|
||||
} else if (OB_FAIL(dml.add_column("status", record.task_status_))) {
|
||||
LOG_WARN("fail to add status", KR(ret), K_(record.task_status));
|
||||
} else if (OB_FAIL(dml.add_column("task_version", record.task_version_))) {
|
||||
LOG_WARN("fail to add task_version", KR(ret), K_(record.task_version));
|
||||
} else if (OB_FAIL(dml.add_column("execution_id", record.execution_id_))) {
|
||||
LOG_WARN("fail to add execution_id", KR(ret), K_(record.execution_id));
|
||||
} else if (OB_FAIL(dml.add_column("ret_code", record.ret_code_))) {
|
||||
LOG_WARN("fail to add ret_code", KR(ret), K_(record.ret_code));
|
||||
} else if (OB_FAIL(dml.add_column("ddl_stmt_str", ddl_stmt_string.string()))) {
|
||||
LOG_WARN("fail to add ddl_stmt_str", KR(ret), K(ddl_stmt_string));
|
||||
} else if (OB_FAIL(dml.add_column("message", message_string.string()))) {
|
||||
LOG_WARN("fail to add message", KR(ret), K(message_string));
|
||||
} else if (((tenant_data_version >= DATA_VERSION_4_2_2_0 && tenant_data_version < DATA_VERSION_4_3_0_0)
|
||||
|| (tenant_data_version >= DATA_VERSION_4_3_5_0))
|
||||
&& OB_FAIL(dml.add_column("consensus_schema_version", record.consensus_schema_version_))) {
|
||||
LOG_WARN("fail to add consensus_schema_version", KR(ret), K_(record.consensus_schema_version));
|
||||
} else if (OB_FAIL(dml.splice_insert_sql(OB_ALL_DDL_TASK_STATUS_TNAME, sql_string))) {
|
||||
LOG_WARN("fail to generate sql string", KR(ret));
|
||||
}
|
||||
}
|
||||
if (FAILEDx(DDL_SIM(record.tenant_id_, record.task_id_, TASK_STATUS_OPERATOR_SLOW))) {
|
||||
LOG_WARN("ddl sim failure: slow inner sql", K(ret), K(record.tenant_id_), K(record.task_id_));
|
||||
} else if (OB_FAIL(proxy.write(record.tenant_id_, sql_string.ptr(), affected_rows))) {
|
||||
LOG_WARN("insert ddl task record failed", K(ret), K(sql_string), K(record));
|
||||
@ -4186,6 +4255,9 @@ int ObDDLTaskRecordOperator::fill_task_record(
|
||||
EXTRACT_INT_FIELD_MYSQL(*result_row, "execution_id", task_record.execution_id_, int64_t);
|
||||
EXTRACT_VARCHAR_FIELD_MYSQL(*result_row, "message_unhex", task_message);
|
||||
EXTRACT_VARCHAR_FIELD_MYSQL(*result_row, "ddl_stmt_str_unhex", ddl_stmt_str);
|
||||
EXTRACT_INT_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result_row, "consensus_schema_version", task_record.consensus_schema_version_, int64_t,
|
||||
false /*skip null error*/, true /*skip column error*/, OB_INVALID_VERSION);
|
||||
|
||||
if (OB_SUCC(ret) && OB_INVALID_TENANT_ID != tenant_id) {
|
||||
if (OB_INVALID_TENANT_ID != task_record.tenant_id_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
|
@ -79,7 +79,7 @@ public:
|
||||
void reset();
|
||||
TO_STRING_KV(K_(task_id), K_(parent_task_id), K_(ddl_type), K_(trace_id), K_(task_status), K_(tenant_id), K_(object_id),
|
||||
K_(schema_version), K_(target_object_id), K_(snapshot_version), K_(message), K_(task_version), K_(ret_code), K_(execution_id),
|
||||
K_(ddl_need_retry_at_executor));
|
||||
K_(ddl_need_retry_at_executor), K_(consensus_schema_version));
|
||||
public:
|
||||
static const int64_t MAX_MESSAGE_LENGTH = 4096;
|
||||
typedef common::ObFixedLengthString<MAX_MESSAGE_LENGTH> TaskMessage;
|
||||
@ -101,8 +101,10 @@ public:
|
||||
int64_t execution_id_;
|
||||
ObString ddl_stmt_str_;
|
||||
bool ddl_need_retry_at_executor_;
|
||||
int64_t consensus_schema_version_;
|
||||
};
|
||||
|
||||
|
||||
struct ObDDLTaskInfo final
|
||||
{
|
||||
public:
|
||||
@ -279,6 +281,8 @@ public:
|
||||
|
||||
class ObDDLTaskRecordOperator final
|
||||
{
|
||||
#define GET_DDL_TASK_SQL " SELECT *, time_to_usec(gmt_create) AS create_time, " \
|
||||
" UNHEX(ddl_stmt_str) as ddl_stmt_str_unhex, UNHEX(message) as message_unhex FROM %s "
|
||||
public:
|
||||
static int update_task_status(
|
||||
common::ObISQLClient &proxy,
|
||||
@ -324,6 +328,11 @@ public:
|
||||
const int ret_code,
|
||||
ObString &message);
|
||||
|
||||
static int update_consensus_schema_version(
|
||||
common::ObISQLClient &proxy,
|
||||
const uint64_t tenant_id,
|
||||
const int64_t task_id,
|
||||
const int64_t consensus_schema_version);
|
||||
static int update_parent_task_message(
|
||||
const int64_t tenant_id,
|
||||
const int64_t parent_task_id,
|
||||
@ -678,7 +687,8 @@ public:
|
||||
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),
|
||||
longops_stat_(nullptr), gmt_create_(0), stat_info_(), delay_schedule_time_(0), next_schedule_ts_(0),
|
||||
execution_id_(-1), start_time_(0), data_format_version_(0), is_pre_split_(false), wait_trans_ctx_()
|
||||
execution_id_(-1), start_time_(0), data_format_version_(0), is_pre_split_(false), wait_trans_ctx_(), is_unique_index_(false),
|
||||
is_global_index_(false), consensus_schema_version_(OB_INVALID_VERSION)
|
||||
{}
|
||||
ObDDLTask():
|
||||
ObDDLTask(share::DDL_INVALID)
|
||||
@ -774,6 +784,9 @@ public:
|
||||
virtual bool support_longops_monitoring() const { return false; }
|
||||
int cleanup();
|
||||
int update_task_record_status_and_msg(common::ObISQLClient &proxy, const share::ObDDLTaskStatus real_new_status);
|
||||
bool is_unique_index() { return is_unique_index_; }
|
||||
bool is_global_index() { return is_global_index_; }
|
||||
int64_t get_consensus_schema_version() { return consensus_schema_version_; }
|
||||
|
||||
#ifdef ERRSIM
|
||||
int check_errsim_error();
|
||||
@ -786,7 +799,7 @@ public:
|
||||
K_(task_version), K_(parallelism), K_(ddl_stmt_str), K_(compat_mode),
|
||||
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_addrs_), K_(data_format_version), K(consumer_group_id_),
|
||||
K_(dst_tenant_id), K_(dst_schema_version), K_(is_pre_split));
|
||||
K_(dst_tenant_id), K_(dst_schema_version), K_(is_pre_split), K_(is_unique_index), K_(is_global_index), K_(consensus_schema_version));
|
||||
static const int64_t MAX_ERR_TOLERANCE_CNT = 3L; // Max torlerance count for error code.
|
||||
static const int64_t DEFAULT_TASK_IDLE_TIME_US = 10L * 1000L; // 10ms
|
||||
protected:
|
||||
@ -868,6 +881,9 @@ protected:
|
||||
int64_t consumer_group_id_;
|
||||
bool is_pre_split_;
|
||||
ObDDLWaitTransEndCtx wait_trans_ctx_;
|
||||
bool is_unique_index_;
|
||||
bool is_global_index_;
|
||||
int64_t consensus_schema_version_;
|
||||
};
|
||||
|
||||
enum ColChecksumStat
|
||||
|
@ -149,6 +149,7 @@ int ObDropIndexTask::update_index_status(const ObIndexStatus new_status)
|
||||
arg.status_ = new_status;
|
||||
arg.exec_tenant_id_ = tenant_id_;
|
||||
arg.in_offline_ddl_white_list_ = index_schema->get_table_state_flag() != TABLE_STATE_NORMAL;
|
||||
arg.data_table_id_ = index_schema->get_data_table_id();
|
||||
int64_t ddl_rpc_timeout = 0;
|
||||
int64_t table_id = index_schema->get_table_id();
|
||||
DEBUG_SYNC(BEFORE_UPDATE_GLOBAL_INDEX_STATUS);
|
||||
|
@ -258,7 +258,7 @@ ObAsyncTask *ObIndexSSTableBuildTask::deep_copy(char *buf, const int64_t buf_siz
|
||||
/*************** ObIndexBuildTask *************/
|
||||
|
||||
ObIndexBuildTask::ObIndexBuildTask()
|
||||
: ObDDLTask(ObDDLType::DDL_CREATE_INDEX), index_table_id_(target_object_id_), doc_id_col_id_(OB_INVALID_ID), is_unique_index_(false), is_global_index_(false), root_service_(nullptr), snapshot_held_(false),
|
||||
: ObDDLTask(ObDDLType::DDL_CREATE_INDEX), index_table_id_(target_object_id_), root_service_(nullptr), snapshot_held_(false),
|
||||
is_sstable_complete_task_submitted_(false), sstable_complete_request_time_(0), sstable_complete_ts_(0),
|
||||
check_unique_snapshot_(0), complete_sstable_job_ret_code_(INT64_MAX), create_index_arg_(), target_cg_cnt_(0)
|
||||
{
|
||||
@ -423,12 +423,6 @@ int ObIndexBuildTask::init(
|
||||
data_format_version_ = tenant_data_version;
|
||||
if (OB_SUCC(ret)) {
|
||||
task_status_ = static_cast<ObDDLTaskStatus>(task_status);
|
||||
if (share::schema::is_rowkey_doc_aux(create_index_arg_.index_type_) ||
|
||||
share::schema::is_doc_rowkey_aux(create_index_arg_.index_type_)) {
|
||||
if (OB_FAIL(ObFtsIndexBuilderUtil::get_doc_id_column_id(data_table_schema, doc_id_col_id_))) {
|
||||
LOG_WARN("failed to get doc id column id", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(init_ddl_task_monitor_info(index_schema->get_table_id()))) {
|
||||
@ -456,48 +450,45 @@ 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;
|
||||
LOG_WARN("init twice", K(ret));
|
||||
LOG_WARN("init twice", KR(ret));
|
||||
} else if (OB_ISNULL(root_service_ = GCTX.root_service_)) {
|
||||
ret = OB_ERR_SYS;
|
||||
LOG_WARN("root_service is null", K(ret), KP(root_service_));
|
||||
LOG_WARN("root_service is null", KR(ret), KP(root_service_));
|
||||
} else if (!root_service_->in_service()) {
|
||||
ret = OB_STATE_NOT_MATCH;
|
||||
LOG_WARN("root service not in service", K(ret));
|
||||
LOG_WARN("root service not in service", KR(ret));
|
||||
} else if (!task_record.is_valid()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arguments", K(ret), K(task_record));
|
||||
LOG_WARN("invalid arguments", KR(ret), K(task_record));
|
||||
} else if (OB_FAIL(DDL_SIM(task_record.tenant_id_, task_record.task_id_, DDL_TASK_INIT_BY_RECORD_FAILED))) {
|
||||
LOG_WARN("ddl sim failure", K(task_record.tenant_id_), K(task_record.task_id_));
|
||||
} else if (OB_FAIL(deserialize_params_from_message(task_record.tenant_id_, task_record.message_.ptr(), task_record.message_.length(), pos))) {
|
||||
LOG_WARN("deserialize params from message 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(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), 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), K(data_schema), K(index_schema));
|
||||
} else if (OB_UNLIKELY((ObIndexArg::ADD_MLOG == create_index_arg_.index_action_type_)
|
||||
&& (!index_schema->is_mlog_table()))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("index action is add_mlog but index schema is not mlog",
|
||||
KR(ret), K(create_index_arg_.index_action_type_), K(index_schema->get_table_type()));
|
||||
} else {
|
||||
LOG_WARN("deserialize params from message failed", KR(ret));
|
||||
} else if (ObIndexArg::ADD_MLOG == create_index_arg_.index_action_type_) {
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
const ObTableSchema *index_schema = nullptr;
|
||||
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", KR(ret), K(index_table_id), K(schema_version));
|
||||
} else if (OB_FAIL(schema_guard.check_formal_guard())) {
|
||||
LOG_WARN("schema_guard is not formal", KR(ret), K(index_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", KR(ret), K(index_table_id));
|
||||
} else if (OB_ISNULL(index_schema)) {
|
||||
ret = OB_TABLE_NOT_EXIST;
|
||||
LOG_WARN("fail to get table schema", KR(ret));
|
||||
} else if (OB_UNLIKELY((!index_schema->is_mlog_table()))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("index action is add_mlog but index schema is not mlog",
|
||||
KR(ret), K(create_index_arg_.index_action_type_), K(index_schema->get_table_type()));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
task_type_ = task_record.ddl_type_;
|
||||
is_global_index_ = index_schema->is_global_index_table();
|
||||
is_unique_index_ = index_schema->is_unique_index();
|
||||
tenant_id_ = task_record.tenant_id_;
|
||||
object_id_ = data_table_id;
|
||||
index_table_id_ = index_table_id;
|
||||
@ -506,7 +497,7 @@ int ObIndexBuildTask::init(const ObDDLTaskRecord &task_record)
|
||||
execution_id_ = task_record.execution_id_;
|
||||
task_status_ = static_cast<ObDDLTaskStatus>(task_record.task_status_);
|
||||
task_type_ = task_record.ddl_type_; // could be create index / mlog
|
||||
|
||||
consensus_schema_version_ = task_record.consensus_schema_version_;
|
||||
if (ObDDLTaskStatus::VALIDATE_CHECKSUM == task_status_) {
|
||||
sstable_complete_ts_ = ObTimeUtility::current_time();
|
||||
}
|
||||
@ -517,15 +508,9 @@ int ObIndexBuildTask::init(const ObDDLTaskRecord &task_record)
|
||||
|
||||
dst_tenant_id_ = tenant_id_;
|
||||
dst_schema_version_ = schema_version_;
|
||||
if (share::schema::is_rowkey_doc_aux(create_index_arg_.index_type_) ||
|
||||
share::schema::is_doc_rowkey_aux(create_index_arg_.index_type_)) {
|
||||
if (OB_FAIL(ObFtsIndexBuilderUtil::get_doc_id_column_id(data_schema, doc_id_col_id_))) {
|
||||
LOG_WARN("failed to get doc id column id", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(init_ddl_task_monitor_info(index_schema->get_table_id()))) {
|
||||
LOG_WARN("init ddl task monitor info failed", K(ret));
|
||||
} else if (OB_FAIL(init_ddl_task_monitor_info(index_table_id))) {
|
||||
LOG_WARN("init ddl task monitor info failed", KR(ret));
|
||||
} else {
|
||||
is_inited_ = true;
|
||||
|
||||
@ -601,6 +586,15 @@ int ObIndexBuildTask::check_health()
|
||||
} else if (ObIndexStatus::INDEX_STATUS_INDEX_ERROR == index_schema->get_index_status()) {
|
||||
ret = OB_SUCCESS == ret_code_ ? OB_ERR_ADD_INDEX : ret_code_;
|
||||
LOG_WARN("index status error", K(ret), K(index_table_id_), K(index_schema->get_table_name_str()), K(index_schema->get_index_status()));
|
||||
} else if (data_format_version_ < MOCK_DATA_VERSION_4_2_4_0
|
||||
|| (data_format_version_ >= DATA_VERSION_4_3_0_0 && data_format_version_ < DATA_VERSION_4_3_5_0)) {
|
||||
// Since parallel ddl do not guaranteen the local schema guard could get the index schema when do init(),
|
||||
// the initialization of is_global/unique_index in init() are modified to rely on the persistence of
|
||||
// relative field in task_record.message_.
|
||||
// However, the task_record constructed before the upgrade process do not have the persistence of relative field.
|
||||
// Thus, need to initialize is_global/unique_index here.
|
||||
is_global_index_ = index_schema->is_global_index_table();
|
||||
is_unique_index_ = index_schema->is_unique_index();
|
||||
}
|
||||
#ifdef ERRSIM
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -1041,9 +1035,9 @@ int ObIndexBuildTask::wait_data_complement()
|
||||
share::ObLSID ls_id;
|
||||
common::ObAddr leader_addr;
|
||||
ObArray<ObTabletID> index_partition_ids;
|
||||
if (OB_UNLIKELY(!is_inited_)) {
|
||||
if (OB_UNLIKELY(!is_inited_) || OB_ISNULL(root_service_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", K(ret));
|
||||
LOG_WARN("not init", KR(ret));
|
||||
} else if (ObDDLTaskStatus::REDEFINITION != task_status_) {
|
||||
LOG_WARN("task status not match", K(ret), K(task_status_));
|
||||
} else if (OB_UNLIKELY(snapshot_version_ <= 0)) {
|
||||
@ -1092,9 +1086,25 @@ int ObIndexBuildTask::wait_data_complement()
|
||||
}
|
||||
#endif
|
||||
ObArray<int64_t> ignore_col_ids;
|
||||
if (doc_id_col_id_ != OB_INVALID &&
|
||||
OB_FAIL(ignore_col_ids.push_back(doc_id_col_id_))) {
|
||||
LOG_WARN("failed to push back to ignore_col_ids", K(ret));
|
||||
const ObTableSchema *data_table_schema = nullptr;
|
||||
ObMultiVersionSchemaService &schema_service = root_service_->get_schema_service();
|
||||
share::schema::ObSchemaGetterGuard schema_guard;
|
||||
uint64_t doc_id_col_id = OB_INVALID_ID;
|
||||
if (share::schema::is_rowkey_doc_aux(create_index_arg_.index_type_) ||
|
||||
share::schema::is_doc_rowkey_aux(create_index_arg_.index_type_)) {
|
||||
if (OB_FAIL(schema_service.get_tenant_schema_guard(tenant_id_, schema_guard))) {
|
||||
LOG_WARN("get tenant schema guard failed", KR(ret));
|
||||
} else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, object_id_, data_table_schema))) {
|
||||
LOG_WARN("get table schema failed", KR(ret), K(object_id_));
|
||||
} else if (OB_ISNULL(data_table_schema)) {
|
||||
ret = OB_TABLE_NOT_EXIST;
|
||||
LOG_WARN("data table not exist", KR(ret));
|
||||
} else if (OB_FAIL(ObFtsIndexBuilderUtil::get_doc_id_column_id(data_table_schema, doc_id_col_id))) {
|
||||
LOG_WARN("failed to get doc id column id", KR(ret));
|
||||
} else if (doc_id_col_id != OB_INVALID &&
|
||||
OB_FAIL(ignore_col_ids.push_back(doc_id_col_id))) {
|
||||
LOG_WARN("failed to push back to ignore_col_ids", KR(ret));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (need_verify_checksum && OB_FAIL(ObDDLChecksumOperator::check_column_checksum(
|
||||
@ -1120,9 +1130,9 @@ int ObIndexBuildTask::wait_local_index_data_complement()
|
||||
int ret = OB_SUCCESS;
|
||||
bool state_finished = false;
|
||||
bool is_request_end = false;
|
||||
if (OB_UNLIKELY(!is_inited_)) {
|
||||
if (OB_UNLIKELY(!is_inited_) || OB_ISNULL(root_service_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", K(ret));
|
||||
LOG_WARN("not init", KR(ret));
|
||||
} else if (ObDDLTaskStatus::REDEFINITION != task_status_) {
|
||||
ret = OB_STATE_NOT_MATCH;
|
||||
LOG_WARN("task status not match", K(ret), K(task_status_));
|
||||
@ -1163,10 +1173,27 @@ int ObIndexBuildTask::wait_local_index_data_complement()
|
||||
// when the major compaction is delayed, skip verify column checksum
|
||||
need_verify_checksum = 0 == GCONF.errsim_ddl_major_delay_time;
|
||||
#endif
|
||||
|
||||
ObArray<int64_t> ignore_col_ids;
|
||||
if (doc_id_col_id_ != OB_INVALID &&
|
||||
OB_FAIL(ignore_col_ids.push_back(doc_id_col_id_))) {
|
||||
LOG_WARN("failed to push back to ignore_col_ids", K(ret));
|
||||
const ObTableSchema *data_table_schema = nullptr;
|
||||
uint64_t doc_id_col_id = OB_INVALID_ID;
|
||||
share::schema::ObSchemaGetterGuard schema_guard;
|
||||
ObMultiVersionSchemaService &schema_service = root_service_->get_schema_service();
|
||||
if (share::schema::is_rowkey_doc_aux(create_index_arg_.index_type_) ||
|
||||
share::schema::is_doc_rowkey_aux(create_index_arg_.index_type_)) {
|
||||
if (OB_FAIL(schema_service.get_tenant_schema_guard(tenant_id_, schema_guard))) {
|
||||
LOG_WARN("get tenant schema guard failed", KR(ret));
|
||||
} else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, object_id_, data_table_schema))) {
|
||||
LOG_WARN("get table schema failed", KR(ret), K(object_id_));
|
||||
} else if (OB_ISNULL(data_table_schema)) {
|
||||
ret = OB_TABLE_NOT_EXIST;
|
||||
LOG_WARN("data table not exist", KR(ret));
|
||||
} else if (OB_FAIL(ObFtsIndexBuilderUtil::get_doc_id_column_id(data_table_schema, doc_id_col_id))) {
|
||||
LOG_WARN("failed to get doc id column id", KR(ret));
|
||||
} else if (doc_id_col_id != OB_INVALID &&
|
||||
OB_FAIL(ignore_col_ids.push_back(doc_id_col_id))) {
|
||||
LOG_WARN("failed to push back to ignore_col_ids", KR(ret));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (need_verify_checksum && OB_FAIL(ObDDLChecksumOperator::check_column_checksum_without_execution_id(
|
||||
@ -1506,7 +1533,7 @@ int ObIndexBuildTask::enable_index()
|
||||
} else if ((ObIndexArg::ADD_MLOG == create_index_arg_.index_action_type_)
|
||||
&& OB_FAIL(update_mlog_last_purge_scn())) {
|
||||
LOG_WARN("failed to update mlog last purge scn", KR(ret));
|
||||
} else if (OB_FAIL(update_index_status_in_schema(*index_schema, INDEX_STATUS_AVAILABLE))) {
|
||||
} else if (OB_FAIL(update_index_status_in_schema(*index_schema, INDEX_STATUS_AVAILABLE, schema_guard))) {
|
||||
LOG_WARN("fail to try notify index take effect", K(ret), K(index_table_id_));
|
||||
} else {
|
||||
state_finished = true;
|
||||
@ -1525,12 +1552,19 @@ int ObIndexBuildTask::enable_index()
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObIndexBuildTask::update_index_status_in_schema(const ObTableSchema &index_schema, const ObIndexStatus new_status)
|
||||
int ObIndexBuildTask::update_index_status_in_schema(const ObTableSchema &index_schema, const ObIndexStatus new_status,
|
||||
ObSchemaGetterGuard &schema_guard)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObDatabaseSchema *database_schema = nullptr;
|
||||
if (OB_UNLIKELY(!is_inited_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", K(ret));
|
||||
} else if (OB_FAIL(schema_guard.get_database_schema(tenant_id_, index_schema.get_database_id(), database_schema))) {
|
||||
LOG_WARN("fail to get database schema", KR(ret), K(tenant_id_), K(index_schema.get_database_id()));
|
||||
} else if (OB_ISNULL(database_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("database schema is nullptr", KR(ret));
|
||||
} else {
|
||||
obrpc::ObUpdateIndexStatusArg arg;
|
||||
arg.index_table_id_ = index_schema.get_table_id();
|
||||
@ -1538,6 +1572,8 @@ int ObIndexBuildTask::update_index_status_in_schema(const ObTableSchema &index_s
|
||||
arg.exec_tenant_id_ = tenant_id_;
|
||||
arg.in_offline_ddl_white_list_ = true;
|
||||
arg.task_id_ = task_id_;
|
||||
arg.data_table_id_ = index_schema.get_data_table_id();
|
||||
arg.database_name_ = database_schema->get_database_name();
|
||||
int64_t ddl_rpc_timeout = 0;
|
||||
int64_t tmp_timeout = 0;
|
||||
if (INDEX_STATUS_AVAILABLE == new_status) {
|
||||
@ -1558,18 +1594,35 @@ int ObIndexBuildTask::update_index_status_in_schema(const ObTableSchema &index_s
|
||||
}
|
||||
|
||||
DEBUG_SYNC(BEFORE_UPDATE_GLOBAL_INDEX_STATUS);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(index_schema.get_all_part_num(), ddl_rpc_timeout))) {
|
||||
if (FAILEDx(ObDDLUtil::get_ddl_rpc_timeout(index_schema.get_all_part_num(), ddl_rpc_timeout))) {
|
||||
LOG_WARN("get ddl rpc timeout fail", K(ret));
|
||||
} else if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(tenant_id_, index_schema.get_data_table_id(), tmp_timeout))) {
|
||||
LOG_WARN("get ddl rpc timeout fail", K(ret));
|
||||
} else if (OB_FALSE_IT(ddl_rpc_timeout += tmp_timeout)) {
|
||||
} else if (OB_FAIL(DDL_SIM(tenant_id_, task_id_, UPDATE_INDEX_STATUS_FAILED))) {
|
||||
LOG_WARN("ddl sim failure", K(ret), K(tenant_id_), K(task_id_));
|
||||
} else if (OB_FAIL(root_service_->get_common_rpc_proxy().to(GCTX.self_addr()).timeout(ddl_rpc_timeout).update_index_status(arg))) {
|
||||
LOG_WARN("update index status failed", K(ret), K(arg));
|
||||
} else {
|
||||
LOG_INFO("notify index status changed finish", K(new_status), K(index_table_id_), K(ddl_rpc_timeout), "ddl_stmt_str", arg.ddl_stmt_str_);
|
||||
const bool is_parallel = create_index_arg_.is_parallel_;
|
||||
if (!is_parallel
|
||||
|| data_format_version_ < DATA_VERSION_4_2_2_0
|
||||
|| (data_format_version_ >= DATA_VERSION_4_3_3_0 && data_format_version_ < DATA_VERSION_4_3_5_0)) {
|
||||
if (OB_FAIL(root_service_->get_common_rpc_proxy().to(GCTX.self_addr()).timeout(ddl_rpc_timeout).update_index_status(arg))) {
|
||||
LOG_WARN("update index status failed", K(ret), K(arg));
|
||||
}
|
||||
} else {
|
||||
obrpc::ObParallelDDLRes res;
|
||||
ObTimeoutCtx ctx;
|
||||
if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, GCONF._ob_ddl_timeout))) {
|
||||
LOG_WARN("fail to set timeout ctx", KR(ret));
|
||||
} else if (OB_FAIL(root_service_->get_common_rpc_proxy().to(GCTX.self_addr()).timeout(ddl_rpc_timeout).parallel_update_index_status(arg, res))) {
|
||||
LOG_WARN("fail to parallel update index status", KR(ret), K(arg));
|
||||
} else {
|
||||
consensus_schema_version_ = res.schema_version_;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
LOG_INFO("notify index status changed finish", K(new_status), K(index_table_id_), K(ddl_rpc_timeout), "ddl_stmt_str", arg.ddl_stmt_str_);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -1592,7 +1645,7 @@ int ObIndexBuildTask::clean_on_failed()
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
bool drop_index_on_failed = true; // TODO@wenqu: index building triggered by truncate partition may need keep the failed index schema
|
||||
bool index_status_is_available = false;
|
||||
if (OB_FAIL(root_service_->get_schema_service().get_tenant_schema_guard(tenant_id_, schema_guard))) {
|
||||
if (OB_FAIL(root_service_->get_ddl_service().get_tenant_schema_guard_with_version_in_inner_table(tenant_id_, schema_guard))) {
|
||||
LOG_WARN("get tenant schema failed", K(ret), K(tenant_id_));
|
||||
} else if (OB_FAIL(schema_guard.check_table_exist(tenant_id_, index_table_id_, is_index_exist))) {
|
||||
LOG_WARN("check table exist failed", K(ret), K_(tenant_id), K(index_table_id_));
|
||||
@ -1606,7 +1659,7 @@ int ObIndexBuildTask::clean_on_failed()
|
||||
} else if (index_schema->is_in_recyclebin()) {
|
||||
// the index has been dropped, just finish this task
|
||||
} else if (ObIndexStatus::INDEX_STATUS_UNAVAILABLE == index_schema->get_index_status()
|
||||
&& OB_FAIL(update_index_status_in_schema(*index_schema, ObIndexStatus::INDEX_STATUS_INDEX_ERROR))) {
|
||||
&& OB_FAIL(update_index_status_in_schema(*index_schema, ObIndexStatus::INDEX_STATUS_INDEX_ERROR, schema_guard))) {
|
||||
LOG_WARN("update index schema failed", K(ret));
|
||||
} else if (drop_index_on_failed) {
|
||||
DEBUG_SYNC(CREATE_INDEX_FAILED);
|
||||
|
@ -124,7 +124,7 @@ public:
|
||||
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(doc_id_col_id_), K(snapshot_held_), K(is_sstable_complete_task_submitted_), K(sstable_complete_request_time_),
|
||||
INHERIT_TO_STRING_KV("ObDDLTask", ObDDLTask, K(index_table_id_), K(snapshot_held_), K(is_sstable_complete_task_submitted_), K(sstable_complete_request_time_),
|
||||
K(sstable_complete_ts_), K(check_unique_snapshot_), K(complete_sstable_job_ret_code_), K_(redefinition_execution_id), K(create_index_arg_), K(target_cg_cnt_));
|
||||
private:
|
||||
int prepare();
|
||||
@ -141,7 +141,8 @@ private:
|
||||
int release_snapshot(const int64_t snapshot);
|
||||
int update_index_status_in_schema(
|
||||
const share::schema::ObTableSchema &index_schema,
|
||||
const share::schema::ObIndexStatus new_status);
|
||||
const share::schema::ObIndexStatus new_status,
|
||||
ObSchemaGetterGuard &schema_guard);
|
||||
int check_health();
|
||||
int reap_old_replica_build_task(bool &need_exec_new_inner_sql);
|
||||
int send_build_single_replica_request(const bool &is_partitioned_local_index_task,
|
||||
@ -170,9 +171,6 @@ private:
|
||||
using ObDDLTask::schema_version_;
|
||||
using ObDDLTask::snapshot_version_;
|
||||
uint64_t &index_table_id_;
|
||||
uint64_t doc_id_col_id_;
|
||||
bool is_unique_index_;
|
||||
bool is_global_index_;
|
||||
ObRootService *root_service_;
|
||||
bool snapshot_held_;
|
||||
bool is_sstable_complete_task_submitted_;
|
||||
|
@ -485,7 +485,8 @@ ObNewTableTabletAllocator::ObNewTableTabletAllocator(
|
||||
const uint64_t tenant_id,
|
||||
share::schema::ObSchemaGetterGuard &schema_guard,
|
||||
common::ObMySQLProxy *sql_proxy,
|
||||
const bool use_parallel_ddl /*= false*/)
|
||||
const bool use_parallel_ddl /*= false*/,
|
||||
const share::schema::ObTableSchema *data_table_schema /*nullptr*/)
|
||||
: tenant_id_(tenant_id),
|
||||
schema_guard_(schema_guard),
|
||||
sql_proxy_(sql_proxy),
|
||||
@ -494,7 +495,8 @@ ObNewTableTabletAllocator::ObNewTableTabletAllocator(
|
||||
ls_id_array_(),
|
||||
inited_(false),
|
||||
is_add_partition_(false),
|
||||
use_parallel_ddl_(use_parallel_ddl)
|
||||
use_parallel_ddl_(use_parallel_ddl),
|
||||
data_table_schema_(data_table_schema)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1226,9 +1228,22 @@ int ObNewTableTabletAllocator::alloc_ls_for_local_index_tablet(
|
||||
const uint64_t tenant_id = index_schema.get_tenant_id();
|
||||
const uint64_t data_table_id = index_schema.get_data_table_id();
|
||||
const share::schema::ObTableSchema *table_schema = nullptr;
|
||||
if (OB_FAIL(schema_guard_.get_table_schema(
|
||||
tenant_id, data_table_id, table_schema))) {
|
||||
LOG_WARN("fail to get table schema", KR(ret), K(tenant_id), K(data_table_id));
|
||||
if (use_parallel_ddl_) {
|
||||
if (OB_ISNULL(data_table_schema_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("should use cached data_table_schema when alloc ls for local index tablet when doing parallel ddl", KR(ret));
|
||||
} else if (OB_UNLIKELY(data_table_schema_->get_table_id() != data_table_id)) {
|
||||
LOG_WARN("fail to get table schema", KR(ret), K(data_table_schema_->get_table_id()) ,K(data_table_id));
|
||||
} else {
|
||||
table_schema = data_table_schema_;
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(schema_guard_.get_table_schema(
|
||||
tenant_id, data_table_id, table_schema))) {
|
||||
LOG_WARN("fail to get table schema", KR(ret), K(tenant_id), K(data_table_id));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_UNLIKELY(nullptr == table_schema)) {
|
||||
ret = OB_TABLE_NOT_EXIST;
|
||||
LOG_WARN("table not exist", KR(ret), K(data_table_id));
|
||||
|
@ -156,11 +156,14 @@ private:
|
||||
class ObNewTableTabletAllocator
|
||||
{
|
||||
public:
|
||||
// when doing prepare() during parallel create local index, the data table should be the latest.
|
||||
// thus, need the data_table_schema from the latest_schema_guard.
|
||||
ObNewTableTabletAllocator(
|
||||
const uint64_t tenant_id,
|
||||
share::schema::ObSchemaGetterGuard &schema_guard,
|
||||
common::ObMySQLProxy *sql_proxy,
|
||||
const bool use_parallel_ddl = false);
|
||||
const bool use_parallel_ddl = false,
|
||||
const share::schema::ObTableSchema *data_table_schema = nullptr);
|
||||
virtual ~ObNewTableTabletAllocator();
|
||||
public:
|
||||
int init();
|
||||
@ -277,6 +280,7 @@ private:
|
||||
bool is_add_partition_;
|
||||
static int64_t alloc_tablet_ls_offset_;
|
||||
bool use_parallel_ddl_;
|
||||
const share::schema::ObTableSchema *data_table_schema_;
|
||||
};
|
||||
|
||||
}//end namespace rootserver
|
||||
|
@ -126,6 +126,7 @@
|
||||
#include "rootserver/restore/ob_tenant_clone_util.h"
|
||||
#include "rootserver/ob_split_partition_helper.h"
|
||||
#include "rootserver/mview/ob_mview_dependency_service.h"
|
||||
#include "rootserver/parallel_ddl/ob_ddl_helper.h"
|
||||
#include "storage/ddl/ob_ddl_alter_auto_part_attr.h"
|
||||
#include "share/tablet/ob_tablet_to_ls_operator.h"
|
||||
#include "share/tablet/ob_tablet_to_table_history_operator.h"
|
||||
@ -23720,17 +23721,26 @@ int ObDDLService::check_is_foreign_key_parent_table(const ObTableSchema &table_s
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLService::check_table_schema_is_legal(const ObDatabaseSchema & database_schema,
|
||||
int ObDDLService::check_table_schema_is_legal(const obrpc::ObTruncateTableArg &arg,
|
||||
const ObDatabaseSchema & database_schema,
|
||||
const ObTableSchema &table_schema,
|
||||
const bool check_foreign_key,
|
||||
ObMySQLTransaction &trans)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t table_id = table_schema.get_table_id();
|
||||
const int64_t table_id = table_schema.get_table_id();
|
||||
ObString table_name = table_schema.get_table_name();
|
||||
ObString database_name = database_schema.get_database_name();
|
||||
|
||||
if (table_schema.is_in_recyclebin() || database_schema.is_in_recyclebin()) {
|
||||
if (OB_UNLIKELY(table_schema.get_database_id() != database_schema.get_database_id())) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("table databse id not equal to database schema", KR(ret),
|
||||
K(table_schema.get_database_id()),
|
||||
K(database_schema.get_database_id()));
|
||||
} else if (OB_UNLIKELY(database_schema.get_database_name_str() != arg.database_name_)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("database_schema's database name not equal to arg", KR(ret), K(database_schema.get_database_name_str()), K_(arg.database_name));
|
||||
} else if (table_schema.is_in_recyclebin() || database_schema.is_in_recyclebin()) {
|
||||
ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
|
||||
LOG_WARN("can not truncate table in recyclebin",
|
||||
KR(ret), K(table_name), K(table_id), K(database_name));
|
||||
@ -23841,8 +23851,14 @@ int ObDDLService::new_truncate_table(const obrpc::ObTruncateTableArg &arg,
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("trans conn is NULL", KR(ret), K(arg));
|
||||
// To verify the existence of database and table
|
||||
} else if (OB_FAIL(ObDDLHelper::obj_lock_database_name(trans, tenant_id, arg.database_name_, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock database name", KR(ret), K(tenant_id), K_(arg.database_name));
|
||||
} else if (OB_FAIL(ObDDLHelper::obj_lock_obj_name(trans, tenant_id, arg.database_name_, arg.table_name_, transaction::tablelock::EXCLUSIVE))) {
|
||||
LOG_WARN("fail to lock table name", KR(ret), K(tenant_id), K_(arg.database_name), K_(arg.table_name));
|
||||
} else if (OB_FAIL(check_db_and_table_is_exist(arg, trans, database_id, table_id))) {
|
||||
LOG_WARN("failed to check database and table exist", KR(ret), K(arg.database_name_), K(arg.table_name_));
|
||||
} else if (OB_FAIL(ObDDLHelper::obj_lock_obj_id(trans, tenant_id, database_id, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock databse id", KR(ret), K(tenant_id), K(database_id));
|
||||
} else {
|
||||
// table lock
|
||||
ObTableSchema orig_table_schema;
|
||||
@ -23853,9 +23869,11 @@ int ObDDLService::new_truncate_table(const obrpc::ObTruncateTableArg &arg,
|
||||
schema_status.tenant_id_ = tenant_id;
|
||||
int64_t before_table_lock = ObTimeUtility::current_time();
|
||||
bool lock_table_not_allow = false;
|
||||
LOG_INFO("truncate cost after trans start and check_db_table_is_exist", KR(ret), "cost_ts", before_table_lock - start_time);
|
||||
LOG_INFO("truncate cost after trans start, lock database name, lock table name, and check_db_table_is_exist", KR(ret), "cost_ts", before_table_lock - start_time);
|
||||
// try lock
|
||||
if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(tenant_id,
|
||||
if (OB_FAIL(ObDDLHelper::obj_lock_obj_id(trans, tenant_id, table_id, transaction::tablelock::EXCLUSIVE))) {
|
||||
LOG_WARN("fail to lock table id", KR(ret), K(tenant_id), K(table_id));
|
||||
} else if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(tenant_id,
|
||||
table_id,
|
||||
EXCLUSIVE,
|
||||
0,
|
||||
@ -23867,29 +23885,14 @@ int ObDDLService::new_truncate_table(const obrpc::ObTruncateTableArg &arg,
|
||||
lock_table_not_allow = true;
|
||||
}
|
||||
}
|
||||
uint64_t compat_version = 0;
|
||||
int64_t after_table_lock = ObTimeUtility::current_time();
|
||||
LOG_INFO("truncate cost after lock table", KR(ret), "cost_ts", after_table_lock - before_table_lock);
|
||||
LOG_INFO("truncate cost after lock table id and lock table", KR(ret), "cost_ts", after_table_lock - before_table_lock);
|
||||
if (FAILEDx(schema_service->get_db_schema_from_inner_table(schema_status, database_id, database_schema_array, trans))){
|
||||
LOG_WARN("fail to get database schema", KR(ret), K(arg.database_name_), K(database_id));
|
||||
// get table full scehma
|
||||
} else if (OB_FAIL(schema_service->get_full_table_schema_from_inner_table(schema_status, table_id, orig_table_schema, allocator, trans))) {
|
||||
LOG_WARN("fail to get table schema", KR(ret), K(arg.table_name_), K(table_id));
|
||||
// in upgrade, check the data_version to prevent from executing wrong logical
|
||||
} else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) {
|
||||
LOG_WARN("get min data_version failed", KR(ret), K(tenant_id));
|
||||
} else if (compat_version < DATA_VERSION_4_1_0_0) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("server state is not suppported when tenant's data version is below 4.1.0.0", KR(ret), K(compat_version));
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "tenant's data version is below 4.1.0.0, truncate table is ");
|
||||
} else if (orig_table_schema.get_autoinc_column_id() != 0
|
||||
&& compat_version < DATA_VERSION_4_2_0_0) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("server state is not suppported to use_parallel_truncate when tenant's data version is below 4.2.0.0 "
|
||||
"and table has autoinc column", KR(ret), K(compat_version), K(tenant_id), K(arg.table_name_));
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "tenant's data version is below 4.2.0.0, truncate table with autoinc column is ");
|
||||
// To verify the args are legal
|
||||
} else if (OB_FAIL(check_table_schema_is_legal(database_schema_array.at(0), orig_table_schema, arg.foreign_key_checks_, trans))) {
|
||||
} else if (OB_FAIL(check_table_schema_is_legal(arg, database_schema_array.at(0), orig_table_schema, arg.foreign_key_checks_, trans))) {
|
||||
LOG_WARN("failed to check table schema is legal",
|
||||
KR(ret), K(arg.table_name_), K(table_id), K(orig_table_schema.get_schema_version()));
|
||||
} else if (lock_table_not_allow) {
|
||||
|
@ -500,7 +500,8 @@ public:
|
||||
common::ObArray<const ObTableSchema*> &table_schemas,
|
||||
ObArenaAllocator &allocator,
|
||||
ObMySQLTransaction &trans);
|
||||
int check_table_schema_is_legal(const ObDatabaseSchema & databae_schema,
|
||||
int check_table_schema_is_legal(const obrpc::ObTruncateTableArg &arg,
|
||||
const ObDatabaseSchema & databae_schema,
|
||||
const ObTableSchema &table_schema,
|
||||
const bool check_foreign_key,
|
||||
ObMySQLTransaction &trans);
|
||||
|
@ -121,6 +121,9 @@
|
||||
|
||||
#include "parallel_ddl/ob_create_table_helper.h" // ObCreateTableHelper
|
||||
#include "parallel_ddl/ob_create_view_helper.h" // ObCreateViewHelper
|
||||
#include "parallel_ddl/ob_set_comment_helper.h" //ObCommentHelper
|
||||
#include "parallel_ddl/ob_create_index_helper.h" // ObCreateIndexHelper
|
||||
#include "parallel_ddl/ob_update_index_status_helper.h" // ObUpdateIndexStatusHelper
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -4539,6 +4542,33 @@ int ObRootService::recover_restore_table_ddl(const obrpc::ObRecoverRestoreTableD
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRootService::set_comment(const obrpc::ObSetCommentArg &arg, obrpc::ObParallelDDLRes &res)
|
||||
{
|
||||
LOG_TRACE("receive set comment arg", K(arg));
|
||||
int64_t begin_time = ObTimeUtility::current_time();
|
||||
const uint64_t tenant_id = arg.exec_tenant_id_;
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!inited_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", KR(ret));
|
||||
} else if (OB_UNLIKELY(!arg.is_valid())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arg", KR(ret), K(arg));
|
||||
} else if (OB_FAIL(parallel_ddl_pre_check_(tenant_id))) {
|
||||
LOG_WARN("fail to pre check parallel ddl", KR(ret), K(tenant_id));
|
||||
} else {
|
||||
ObSetCommentHelper comment_helper(schema_service_, tenant_id, arg, res);
|
||||
if (OB_FAIL(comment_helper.init(ddl_service_))) {
|
||||
LOG_WARN("fail to init comment helper", KR(ret), K(tenant_id));
|
||||
} else if (OB_FAIL(comment_helper.execute())) {
|
||||
LOG_WARN("fail to execute comment", KR(ret), K(tenant_id));
|
||||
}
|
||||
}
|
||||
int64_t cost = ObTimeUtility::current_time() - begin_time;
|
||||
LOG_TRACE("finish set comment", KR(ret), K(arg), K(cost));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRootService::alter_table(const obrpc::ObAlterTableArg &arg, obrpc::ObAlterTableRes &res)
|
||||
{
|
||||
LOG_DEBUG("receive alter table arg", K(arg));
|
||||
@ -4784,6 +4814,52 @@ int ObRootService::create_mlog(const obrpc::ObCreateMLogArg &arg, obrpc::ObCreat
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRootService::parallel_create_index(const ObCreateIndexArg &arg, obrpc::ObAlterTableRes &res)
|
||||
{
|
||||
LOG_TRACE("receive parallel create index arg", K(arg));
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t begin_time = ObTimeUtility::current_time();
|
||||
const uint64_t tenant_id = arg.exec_tenant_id_;
|
||||
uint64_t data_version = 0;
|
||||
if (!inited_) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", KR(ret));
|
||||
} else if (!arg.is_valid()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arg", KR(ret), K(arg));
|
||||
} else if (OB_FAIL(parallel_ddl_pre_check_(tenant_id))) {
|
||||
LOG_WARN("pre check failed before parallel ddl execute", KR(ret), K(tenant_id));
|
||||
} else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, data_version))) {
|
||||
LOG_WARN("fail to get data version", KR(ret), K(tenant_id));
|
||||
} else if (data_version < DATA_VERSION_4_2_2_0
|
||||
|| (data_version >= DATA_VERSION_4_3_0_0 && data_version < DATA_VERSION_4_3_5_0)
|
||||
|| share::schema::is_fts_or_multivalue_index(arg.index_type_)
|
||||
|| share::schema::is_vec_index(arg.index_type_)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("not supported", KR(ret), K(data_version), K(arg.index_type_));
|
||||
} else {
|
||||
ObCreateIndexHelper create_index_helper(schema_service_, tenant_id, ddl_service_, arg, res);
|
||||
if (OB_FAIL(create_index_helper.init(ddl_service_))) {
|
||||
LOG_WARN("fail to init create index helper", KR(ret), K(tenant_id));
|
||||
} else if (OB_FAIL(create_index_helper.execute())) {
|
||||
LOG_WARN("fail to execute create index table", KR(ret), K(tenant_id));
|
||||
}
|
||||
}
|
||||
int64_t cost = ObTimeUtility::current_time() - begin_time;
|
||||
char table_id_buffer[256];
|
||||
snprintf(table_id_buffer, sizeof(table_id_buffer), "data_table_id:%ld, index_table_id:%ld",
|
||||
arg.data_table_id_, arg.index_table_id_);
|
||||
ROOTSERVICE_EVENT_ADD("ddl scheduler", "parallel create index",
|
||||
"tenant_id", arg.tenant_id_,
|
||||
"ret", ret,
|
||||
"trace_id", *ObCurTraceId::get_trace_id(),
|
||||
"task_id", res.task_id_,
|
||||
"table_id", table_id_buffer,
|
||||
"schema_version", res.schema_version_);
|
||||
LOG_TRACE("finish parallel create index", KR(ret), K(arg), K(cost), "ddl_event_info", ObDDLEventInfo());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRootService::drop_table(const obrpc::ObDropTableArg &arg, obrpc::ObDDLRes &res)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -5737,6 +5813,33 @@ int ObRootService::clone_tenant(const obrpc::ObCloneTenantArg &arg,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRootService::parallel_update_index_status(const obrpc::ObUpdateIndexStatusArg &arg, obrpc::ObParallelDDLRes &res)
|
||||
{
|
||||
LOG_TRACE("receive update index status arg", K(arg));
|
||||
int64_t begin_time = ObTimeUtility::current_time();
|
||||
int ret = OB_SUCCESS;
|
||||
const uint64_t tenant_id = arg.exec_tenant_id_;
|
||||
if (!inited_) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", KR(ret));
|
||||
} else if (OB_UNLIKELY(!arg.is_valid() || OB_INVALID_ID == arg.data_table_id_)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arg", KR(ret), K(arg));
|
||||
} else if (OB_FAIL(parallel_ddl_pre_check_(tenant_id))) {
|
||||
LOG_WARN("pre check failed before parallel ddl execute", KR(ret), K(tenant_id));
|
||||
} else {
|
||||
ObUpdateIndexStatusHelper update_index_status_helper(schema_service_, tenant_id, arg, res);
|
||||
if (OB_FAIL(update_index_status_helper.init(ddl_service_))) {
|
||||
LOG_WARN("fail to init create table helper", KR(ret), K(tenant_id));
|
||||
} else if (OB_FAIL(update_index_status_helper.execute())) {
|
||||
LOG_WARN("fail to execute update index status helper", KR(ret));
|
||||
}
|
||||
}
|
||||
int64_t cost = ObTimeUtility::current_time() - begin_time;
|
||||
LOG_TRACE("finish update index status", KR(ret), K(arg), K(cost));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRootService::init_debug_database()
|
||||
{
|
||||
const schema_create_func *creator_ptr_array[] = {
|
||||
|
@ -509,6 +509,7 @@ public:
|
||||
int parallel_create_table(const obrpc::ObCreateTableArg &arg, obrpc::ObCreateTableRes &res);
|
||||
int create_table(const obrpc::ObCreateTableArg &arg, obrpc::ObCreateTableRes &res);
|
||||
int alter_database(const obrpc::ObAlterDatabaseArg &arg);
|
||||
int set_comment(const obrpc::ObSetCommentArg &arg, obrpc::ObParallelDDLRes &res);
|
||||
int alter_table(const obrpc::ObAlterTableArg &arg, obrpc::ObAlterTableRes &res);
|
||||
int start_redef_table(const obrpc::ObStartRedefTableArg &arg, obrpc::ObStartRedefTableRes &res);
|
||||
int copy_table_dependents(const obrpc::ObCopyTableDependentsArg &arg);
|
||||
@ -539,6 +540,7 @@ public:
|
||||
const obrpc::ObCreateAuxIndexArg &arg,
|
||||
obrpc::ObCreateAuxIndexRes &result);
|
||||
int create_index(const obrpc::ObCreateIndexArg &arg, obrpc::ObAlterTableRes &res);
|
||||
int parallel_create_index(const obrpc::ObCreateIndexArg &arg, obrpc::ObAlterTableRes &res);
|
||||
int drop_table(const obrpc::ObDropTableArg &arg, obrpc::ObDDLRes &res);
|
||||
int drop_database(const obrpc::ObDropDatabaseArg &arg, obrpc::ObDropDatabaseRes &drop_database_res);
|
||||
int drop_tablegroup(const obrpc::ObDropTablegroupArg &arg);
|
||||
@ -559,6 +561,7 @@ public:
|
||||
int root_minor_freeze(const obrpc::ObRootMinorFreezeArg &arg);
|
||||
int update_index_status(const obrpc::ObUpdateIndexStatusArg &arg);
|
||||
int update_mview_status(const obrpc::ObUpdateMViewStatusArg &arg);
|
||||
int parallel_update_index_status(const obrpc::ObUpdateIndexStatusArg &arg, obrpc::ObParallelDDLRes &res);
|
||||
int purge_table(const obrpc::ObPurgeTableArg &arg);
|
||||
int flashback_table_from_recyclebin(const obrpc::ObFlashBackTableFromRecyclebinArg &arg);
|
||||
int flashback_table_to_time_point(const obrpc::ObFlashBackTableToScnArg &arg);
|
||||
|
@ -30,7 +30,10 @@ namespace rootserver
|
||||
inline bool is_parallel_ddl(const obrpc::ObRpcPacketCode pcode)
|
||||
{
|
||||
return obrpc::OB_TRUNCATE_TABLE_V2 == pcode
|
||||
|| obrpc::OB_PARALLEL_CREATE_TABLE == pcode;
|
||||
|| obrpc::OB_PARALLEL_CREATE_TABLE == pcode
|
||||
|| obrpc::OB_PARALLEL_SET_COMMENT == pcode
|
||||
|| obrpc::OB_PARALLEL_CREATE_INDEX == pcode
|
||||
|| obrpc::OB_PARALLEL_UPDATE_INDEX_STATUS == pcode;
|
||||
}
|
||||
|
||||
// precondition: enable_ddl = false
|
||||
@ -335,6 +338,7 @@ DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_ALTER_TABLEGROUP, ObRpcAlterTablegroupP, a
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_CREATE_TABLE, ObRpcCreateTableP, create_table(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_RECOVER_RESTORE_TABLE_DDL, ObRpcRecoverRestoreTableDDLP, recover_restore_table_ddl(arg_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_PARALLEL_CREATE_TABLE, ObRpcParallelCreateTableP, parallel_create_table(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_PARALLEL_SET_COMMENT, ObRpcSetCommentP, set_comment(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_ALTER_TABLE, ObRpcAlterTableP, alter_table(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_EXCHANGE_PARTITION, ObRpcExchangePartitionP, exchange_partition(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_SPLIT_GLOBAL_INDEX_TABLET, ObSplitGlobalIndexTabletTaskP, split_global_index_tablet(arg_));
|
||||
@ -344,6 +348,7 @@ DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_TRUNCATE_TABLE, ObRpcTruncateTableP, trunc
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_TRUNCATE_TABLE_V2, ObRpcTruncateTableV2P, truncate_table_v2(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_CREATE_AUX_INDEX, ObRpcCreateAuxIndexP, create_aux_index(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_CREATE_INDEX, ObRpcCreateIndexP, create_index(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_PARALLEL_CREATE_INDEX, ObRpcParallelCreateIndexP, parallel_create_index(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_DROP_INDEX, ObRpcDropIndexP, drop_index(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_DROP_INDEX_ON_FAILED, ObRpcDropIndexOnFailedP, drop_index_on_failed(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_REBUILD_VEC_INDEX, ObRpcRebuildVecIndexP, rebuild_vec_index(arg_, result_));
|
||||
@ -364,6 +369,7 @@ DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_REVOKE_ROUTINE, ObRpcRevokeRoutineP, revok
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_REVOKE_SYSPRIV, ObRpcRevokeSysPrivP, revoke_syspriv(arg_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_UPDATE_INDEX_TABLE_STATUS, ObUpdateIndexTableStatusP, update_index_status(arg_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_UPDATE_MVIEW_TABLE_STATUS, ObRpcUpdateMViewTableStatusP, update_mview_status(arg_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_PARALLEL_UPDATE_INDEX_STATUS, ObUpdateIndexStatusP, parallel_update_index_status(arg_, result_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_FLASHBACK_TABLE_FROM_RECYCLEBIN, ObRpcFlashBackTableFromRecyclebinP, flashback_table_from_recyclebin(arg_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_FLASHBACK_INDEX, ObRpcFlashBackIndexP, flashback_index(arg_));
|
||||
DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_PURGE_TABLE, ObRpcPurgeTableP, purge_table(arg_));
|
||||
|
808
src/rootserver/parallel_ddl/ob_create_index_helper.cpp
Normal file
808
src/rootserver/parallel_ddl/ob_create_index_helper.cpp
Normal file
@ -0,0 +1,808 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX RS
|
||||
#include "rootserver/ob_root_service.h"
|
||||
#include "rootserver/parallel_ddl/ob_create_index_helper.h"
|
||||
#include "rootserver/ob_table_creator.h"
|
||||
#include "rootserver/freeze/ob_major_freeze_helper.h"
|
||||
#include "rootserver/ob_balance_group_ls_stat_operator.h"
|
||||
#include "rootserver/ddl_task/ob_ddl_scheduler.h"
|
||||
#include "share/ob_index_builder_util.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
#include "share/ob_debug_sync_point.h"
|
||||
#include "share/schema/ob_multi_version_schema_service.h"
|
||||
#include "share/schema/ob_table_sql_service.h"
|
||||
#include "sql/resolver/ob_resolver_utils.h"
|
||||
using namespace oceanbase::lib;
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::share;
|
||||
using namespace oceanbase::share::schema;
|
||||
using namespace oceanbase::rootserver;
|
||||
|
||||
ObCreateIndexHelper::ObCreateIndexHelper(
|
||||
share::schema::ObMultiVersionSchemaService *schema_service,
|
||||
const uint64_t tenant_id,
|
||||
rootserver::ObDDLService &ddl_service,
|
||||
const obrpc::ObCreateIndexArg &arg,
|
||||
obrpc::ObAlterTableRes &res)
|
||||
: ObDDLHelper(schema_service, tenant_id),
|
||||
arg_(arg),
|
||||
new_arg_(nullptr),
|
||||
res_(res),
|
||||
orig_data_table_schema_(nullptr),
|
||||
new_data_table_schema_(nullptr),
|
||||
index_schemas_(),
|
||||
gen_columns_(),
|
||||
index_builder_(ddl_service),
|
||||
task_record_()
|
||||
{
|
||||
}
|
||||
|
||||
ObCreateIndexHelper::~ObCreateIndexHelper()
|
||||
{
|
||||
if (OB_NOT_NULL(new_arg_)) {
|
||||
new_arg_->~ObCreateIndexArg();
|
||||
new_arg_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int ObCreateIndexHelper::execute()
|
||||
{
|
||||
RS_TRACE(parallel_ddl_begin);
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(start_ddl_trans_())) {
|
||||
LOG_WARN("fail to start ddl trans", KR(ret));
|
||||
} else if (OB_FAIL(lock_objects_())) {
|
||||
LOG_WARN("fail to lock objects", KR(ret));
|
||||
} else if (OB_FAIL(check_table_legitimacy_())) {
|
||||
LOG_WARN("fail to check create index", KR(ret));
|
||||
} else if (OB_FAIL(generate_index_schema_())) {
|
||||
LOG_WARN("fail to generate index schema");
|
||||
} else if (OB_FAIL(calc_schema_version_cnt_())) {
|
||||
LOG_WARN("fail to calc schema version cnt", KR(ret));
|
||||
} else if (OB_FAIL(gen_task_id_and_schema_versions_())) {
|
||||
LOG_WARN("fail to gen task id and schema versions", KR(ret));
|
||||
} else if (OB_FAIL(create_index_())) {
|
||||
LOG_WARN("fail to create index", KR(ret));
|
||||
} else if (OB_FAIL(serialize_inc_schema_dict_())) {
|
||||
LOG_WARN("fail to serialize inc schema dict", KR(ret));
|
||||
} else if (OB_FAIL(wait_ddl_trans_())) {
|
||||
LOG_WARN("fail to wait ddl trans", KR(ret));
|
||||
} else if (OB_FAIL(add_index_name_to_cache_())) {
|
||||
LOG_WARN("fail to add index name to cache", KR(ret));
|
||||
}
|
||||
const bool commit = OB_SUCC(ret);
|
||||
if (OB_FAIL(end_ddl_trans_(ret))) {
|
||||
LOG_WARN("fail to end ddl trans", KR(ret));
|
||||
if (commit) {
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(ddl_service_)) {
|
||||
tmp_ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("ddl_service_ is null", KR(tmp_ret));
|
||||
} else if (OB_TMP_FAIL(ddl_service_->get_index_name_checker().reset_cache(tenant_id_))) {
|
||||
LOG_WARN("fail to reset cache", K(ret), KR(tmp_ret), K_(tenant_id));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ObSchemaVersionGenerator *tsi_generator = GET_TSI(TSISchemaVersionGenerator);
|
||||
int64_t last_schema_version = OB_INVALID_VERSION;
|
||||
int64_t end_schema_version = OB_INVALID_VERSION;
|
||||
if (OB_ISNULL(tsi_generator)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("tsi generator is null", KR(ret));
|
||||
} else if (OB_FAIL(tsi_generator->get_current_version(last_schema_version))) {
|
||||
LOG_WARN("fail to get current version", KR(ret), K_(tenant_id), K_(arg));
|
||||
} else if (OB_FAIL(tsi_generator->get_end_version(end_schema_version))) {
|
||||
LOG_WARN("fail to get end version", KR(ret), K_(tenant_id), K_(arg));
|
||||
} else if (OB_UNLIKELY(last_schema_version != end_schema_version)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("too much schema versions may be allocated", KR(ret), KPC(tsi_generator));
|
||||
} else if (OB_UNLIKELY(index_schemas_.count() != 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("index schemas count unexpected", KR(ret), K(index_schemas_.count()));
|
||||
} else {
|
||||
res_.index_table_id_ = index_schemas_.at(0).get_table_id();
|
||||
res_.schema_version_ = last_schema_version;
|
||||
res_.task_id_ = task_record_.task_id_;
|
||||
if (OB_FAIL(GCTX.root_service_->get_ddl_task_scheduler().schedule_ddl_task(task_record_))) {
|
||||
LOG_WARN("fail to schedule ddl task", KR(ret), K_(task_record));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_ERR_KEY_NAME_DUPLICATE == ret) {
|
||||
if (true == arg_.if_not_exist_) {
|
||||
ret = OB_SUCCESS;
|
||||
LOG_USER_WARN(OB_ERR_KEY_NAME_DUPLICATE, arg_.index_name_.length(), arg_.index_name_.ptr());
|
||||
} else {
|
||||
LOG_USER_ERROR(OB_ERR_KEY_NAME_DUPLICATE, arg_.index_name_.length(), arg_.index_name_.ptr());
|
||||
}
|
||||
}
|
||||
RS_TRACE(parallel_ddl_end);
|
||||
FORCE_PRINT_TRACE(THE_RS_TRACE, "[parallel create index]");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// the online ddl lock and table lock will be locked when submit ddl task
|
||||
int ObCreateIndexHelper::lock_objects_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObDatabaseSchema *database_schema = NULL;
|
||||
DEBUG_SYNC(BEFORE_PARALLEL_DDL_LOCK);
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(lock_database_by_obj_name_())) {
|
||||
LOG_WARN("fail to lock databases by obj name", KR(ret));
|
||||
} else if (OB_FAIL(check_database_legitimacy_())) {
|
||||
LOG_WARN("fail to prefech schemas", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(lock_objects_by_name_())) {
|
||||
LOG_WARN("fail to prefech schemas", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(lock_objects_by_id_())) {
|
||||
LOG_WARN("fail to lock objects by id", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(check_parallel_ddl_conflict_(arg_.based_schema_object_infos_))) {
|
||||
LOG_WARN("fail to check parallel ddl conflict", KR(ret));
|
||||
} else if (OB_ISNULL(orig_data_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("orig_data_table_schema", KR(ret));
|
||||
} else if (OB_UNLIKELY(database_id_ != orig_data_table_schema_->get_database_id())) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("database_id_ is not equal to table schema's databse_id",
|
||||
KR(ret), K_(database_id), K(orig_data_table_schema_->get_database_id()));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_database_schema(database_id_, database_schema))) {
|
||||
LOG_WARN("fail to get database schema", KR(ret), K_(tenant_id), K_(database_id));
|
||||
} else if (OB_ISNULL(database_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("databse_schema is null", KR(ret));
|
||||
} else if (OB_UNLIKELY(database_schema->get_database_name_str() != arg_.database_name_)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("database_schema's database name not equal to arg",
|
||||
KR(ret), K(database_schema->get_database_name_str()), K_(arg_.database_name));
|
||||
}
|
||||
DEBUG_SYNC(AFTER_PARALLEL_DDL_LOCK);
|
||||
RS_TRACE(lock_objects);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexHelper::lock_database_by_obj_name_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObString &database_name = arg_.database_name_;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(add_lock_object_by_database_name_(database_name, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock database by name", KR(ret), K_(tenant_id), K(database_name));
|
||||
} else if (OB_FAIL(lock_databases_by_name_())) {
|
||||
LOG_WARN("fail to lock databases by name", KR(ret), K_(tenant_id));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//lock table name and index name (x)
|
||||
int ObCreateIndexHelper::lock_objects_by_name_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_oracle_mode = false;
|
||||
const ObString &database_name = arg_.database_name_;
|
||||
const ObString &table_name = arg_.table_name_;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(ObCompatModeGetter::check_is_oracle_mode_with_tenant_id(
|
||||
tenant_id_, is_oracle_mode))) {
|
||||
LOG_WARN("fail to check is oracle mode", KR(ret));
|
||||
} else if (OB_FAIL(add_lock_object_by_name_(database_name, table_name,
|
||||
share::schema::TABLE_SCHEMA, transaction::tablelock::EXCLUSIVE))) {
|
||||
LOG_WARN("fail to add lock object by name", KR(ret), K_(tenant_id), K(database_name), K(table_name));
|
||||
} else if (is_oracle_mode) {
|
||||
const ObString &index_name = arg_.index_name_;
|
||||
if (OB_FAIL(add_lock_object_by_name_(database_name, index_name,
|
||||
share::schema::TABLE_SCHEMA, transaction::tablelock::EXCLUSIVE))) {
|
||||
LOG_WARN("fail to lock object by index name", KR(ret), K_(tenant_id), K(database_name), K(index_name));
|
||||
}
|
||||
}
|
||||
if (FAILEDx(lock_existed_objects_by_name_())) {
|
||||
LOG_WARN("fail to lock objects by name", KR(ret), K_(tenant_id));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexHelper::check_database_legitimacy_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObString &database_name = arg_.database_name_;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(ObDDLHelper::check_database_legitimacy_(database_name, database_id_))) {
|
||||
LOG_WARN("fail to check database legitimacy", KR(ret), K(database_name));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// lock data table id and foreign table id
|
||||
// the foreign table need to aware the related table have created an index
|
||||
// thus, need to push foreign table schema_version
|
||||
int ObCreateIndexHelper::lock_objects_by_id_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
uint64_t table_id = OB_INVALID_ID;
|
||||
ObTableType table_type;
|
||||
int64_t schema_version = OB_INVALID_VERSION;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_ID == database_id_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("database is not exist", KR(ret), K_(tenant_id), K_(arg_.database_name));
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(database_id_,
|
||||
share::schema::DATABASE_SCHEMA, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock database id", KR(ret), K_(database_id));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_table_id(database_id_, arg_.session_id_, arg_.table_name_, table_id, table_type, schema_version))) {
|
||||
LOG_WARN("fail to get table id", KR(ret), K_(database_id), K_(arg_.session_id), K_(arg_.table_name));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_ID == table_id)) {
|
||||
ret = OB_ERR_OBJECT_NOT_EXIST;
|
||||
LOG_WARN("table not exist", KR(ret), K_(database_id), K_(arg_.session_id), K_(arg_.table_name));
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(table_id,
|
||||
share::schema::TABLE_SCHEMA, transaction::tablelock::EXCLUSIVE))) {
|
||||
LOG_WARN("fail to lock table id", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_table_schema(table_id, orig_data_table_schema_))) {
|
||||
LOG_WARN("fail to get orig table schema", KR(ret), K(table_id));
|
||||
} else if (OB_ISNULL(orig_data_table_schema_)) {
|
||||
ret = OB_TABLE_NOT_EXIST;
|
||||
LOG_USER_ERROR(OB_TABLE_NOT_EXIST, to_cstring(arg_.database_name_), to_cstring(arg_.table_name_));
|
||||
LOG_WARN("table not exist", KR(ret), K_(arg));
|
||||
} else if (OB_FAIL(add_lock_table_udt_id_(*orig_data_table_schema_))) {
|
||||
LOG_WARN("fail to add lock table udt id", KR(ret));
|
||||
} else {
|
||||
const ObIArray<ObForeignKeyInfo> &foreign_key_infos = orig_data_table_schema_->get_foreign_key_infos();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < foreign_key_infos.count(); i++) {
|
||||
const ObForeignKeyInfo &foreign_key_info = foreign_key_infos.at(i);
|
||||
const uint64_t related_table_id = table_id == foreign_key_info.parent_table_id_
|
||||
? foreign_key_info.child_table_id_
|
||||
: foreign_key_info.parent_table_id_;
|
||||
if (related_table_id == table_id) {
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(related_table_id,
|
||||
share::schema::TABLE_SCHEMA, transaction::tablelock::EXCLUSIVE))) {
|
||||
LOG_WARN("fail to lock table id", KR(ret), K_(tenant_id));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && (i < arg_.based_schema_object_infos_.count()); ++i) {
|
||||
const ObBasedSchemaObjectInfo &info = arg_.based_schema_object_infos_.at(i);
|
||||
if (info.schema_id_ == table_id) {
|
||||
// already have x lock
|
||||
} else if (is_inner_pl_udt_id(info.schema_id_) || is_inner_pl_object_id(info.schema_id_)) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(info.schema_id_,
|
||||
info.schema_type_,
|
||||
transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock based object schema id", KR(ret), K_(tenant_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FAILEDx(lock_existed_objects_by_id_())) {
|
||||
LOG_WARN("fail to lock objects by id", KR(ret));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexHelper::check_table_legitimacy_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
uint64_t table_id = OB_INVALID_ID;
|
||||
bool in_tenant_space = true;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_ISNULL(orig_data_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("data table schea is null", KR(ret), KP(orig_data_table_schema_));
|
||||
} else if (FALSE_IT(table_id = orig_data_table_schema_->get_table_id())) {
|
||||
} else if (OB_FAIL(ObSysTableChecker::is_tenant_space_table_id(table_id, in_tenant_space))) {
|
||||
LOG_WARN("fail to check table in tenant space", KR(ret), K(table_id));
|
||||
} else if (OB_UNLIKELY(is_inner_table(table_id))) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("create index on inner table not support", KR(ret), K(table_id));
|
||||
} else if (OB_UNLIKELY(!arg_.is_inner_ && orig_data_table_schema_->is_in_recyclebin())) {
|
||||
ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
|
||||
LOG_WARN("can not add index on table in recyclebin", KR(ret), K_(arg));
|
||||
} else if (OB_UNLIKELY(orig_data_table_schema_->is_in_splitting())) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN( "con not create index during splitting", KR(ret), K_(arg));
|
||||
// There used to be check_restore_point_allow() here, but it is currently useless.
|
||||
// Meanwhile, the frequent addition and deletion of __all_acquired_snapshot during the index creation
|
||||
// will cause it's buffer table to bloat,
|
||||
// resulting in performance decline during long periods of concentrated index building.
|
||||
} else if (!orig_data_table_schema_->check_can_do_ddl()) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "execute ddl while table is executing offline ddl");
|
||||
LOG_WARN("offline ddl is being executed, other ddl operations are not allowed", KR(ret), KPC(orig_data_table_schema_));
|
||||
} else if (OB_UNLIKELY(orig_data_table_schema_->get_index_tid_count() >= OB_MAX_INDEX_PER_TABLE)) {
|
||||
ret = OB_ERR_TOO_MANY_KEYS;
|
||||
LOG_USER_ERROR(OB_ERR_TOO_MANY_KEYS, OB_MAX_INDEX_PER_TABLE);
|
||||
LOG_WARN("too many index for table", KR(ret), K(OB_MAX_INDEX_PER_TABLE), K(orig_data_table_schema_->get_index_tid_count()));
|
||||
} else if (OB_FAIL(check_table_udt_exist_(*orig_data_table_schema_))) {
|
||||
LOG_WARN("fail to check table udt exist", KR(ret));
|
||||
} else if (OB_FAIL(check_fk_related_table_ddl_(*orig_data_table_schema_, ObDDLType::DDL_CREATE_INDEX))) {
|
||||
LOG_WARN("check whether the forign key related table is executing ddl failed", KR(ret));
|
||||
}
|
||||
RS_TRACE(check_schemas);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexHelper::is_local_generate_schema_(bool &is_local_generate)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(orig_data_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("orig data table schema is nullptr", KR(ret));
|
||||
} else if (INDEX_TYPE_NORMAL_LOCAL == arg_.index_type_
|
||||
|| INDEX_TYPE_UNIQUE_LOCAL == arg_.index_type_
|
||||
|| INDEX_TYPE_DOMAIN_CTXCAT_DEPRECATED == arg_.index_type_
|
||||
|| INDEX_TYPE_SPATIAL_LOCAL == arg_.index_type_
|
||||
|| is_fts_index(arg_.index_type_)
|
||||
|| is_multivalue_index(arg_.index_type_)) {
|
||||
is_local_generate = true;
|
||||
} else if (INDEX_TYPE_NORMAL_GLOBAL == arg_.index_type_
|
||||
|| INDEX_TYPE_UNIQUE_GLOBAL == arg_.index_type_
|
||||
|| INDEX_TYPE_SPATIAL_GLOBAL == arg_.index_type_) {
|
||||
if (!orig_data_table_schema_->is_partitioned_table() && !arg_.index_schema_.is_partitioned_table()) {
|
||||
is_local_generate = true;
|
||||
} else {
|
||||
is_local_generate = false;
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected index type", KR(ret), K_(arg_.index_type));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexHelper::generate_index_schema_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_local_generate = false;
|
||||
bool global_index_without_column_info = false;
|
||||
ObTableSchema *index_schema = nullptr;
|
||||
void *new_arg_ptr = nullptr;
|
||||
// not used when is global generate
|
||||
HEAP_VAR(ObTableSchema, tmp_index_schema){
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_ISNULL(new_arg_ptr = allocator_.alloc(sizeof(obrpc::ObCreateIndexArg)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail alloc memory", KR(ret), KP(new_arg_ptr));
|
||||
} else if (FALSE_IT(new_arg_ = new (new_arg_ptr)obrpc::ObCreateIndexArg)) {
|
||||
} else if (OB_ISNULL(new_arg_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("new_arg_ is null", KR(ret));
|
||||
} else if (OB_FAIL(new_arg_->assign(arg_))) {
|
||||
LOG_WARN("fail to assign arg", KR(ret));
|
||||
} else if (OB_UNLIKELY(!new_arg_->is_valid())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("new arg invalid", KR(ret), KP_(new_arg));
|
||||
} else if (OB_FAIL(is_local_generate_schema_(is_local_generate))) {
|
||||
LOG_WARN("fail to check is local generate schema", KR(ret));
|
||||
} else if (OB_ISNULL(orig_data_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("data table schema is nullptr", KR(ret));
|
||||
} else if (OB_FAIL(ObSchemaUtils::alloc_schema(allocator_, *orig_data_table_schema_, new_data_table_schema_))) {
|
||||
LOG_WARN("fail to allocate new table schema", KR(ret), K_(tenant_id));
|
||||
} else if (OB_ISNULL(new_data_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("new_data_table_schema_ is null", KR(ret));
|
||||
} else if (is_local_generate) {
|
||||
global_index_without_column_info = true;
|
||||
index_schema = &tmp_index_schema;
|
||||
if (INDEX_TYPE_NORMAL_GLOBAL == new_arg_->index_type_) {
|
||||
new_arg_->index_type_ = INDEX_TYPE_NORMAL_GLOBAL_LOCAL_STORAGE;
|
||||
new_arg_->index_schema_.set_index_type(INDEX_TYPE_NORMAL_GLOBAL_LOCAL_STORAGE);
|
||||
} else if (INDEX_TYPE_UNIQUE_GLOBAL == new_arg_->index_type_) {
|
||||
new_arg_->index_type_ = INDEX_TYPE_UNIQUE_GLOBAL_LOCAL_STORAGE;
|
||||
new_arg_->index_schema_.set_index_type(INDEX_TYPE_UNIQUE_GLOBAL_LOCAL_STORAGE);
|
||||
} else if (INDEX_TYPE_SPATIAL_GLOBAL == new_arg_->index_type_) {
|
||||
new_arg_->index_type_ = INDEX_TYPE_SPATIAL_GLOBAL_LOCAL_STORAGE;
|
||||
new_arg_->index_schema_.set_index_type(INDEX_TYPE_SPATIAL_GLOBAL_LOCAL_STORAGE);
|
||||
}
|
||||
} else {
|
||||
global_index_without_column_info = false;
|
||||
index_schema = &new_arg_->index_schema_;
|
||||
}
|
||||
|
||||
if (FAILEDx(ObIndexBuilderUtil::adjust_expr_index_args(
|
||||
*new_arg_, *new_data_table_schema_, allocator_, gen_columns_))) {
|
||||
LOG_WARN("fail to adjust expr index args", KR(ret));
|
||||
} else if (OB_ISNULL(index_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("index schema is null", KR(ret));
|
||||
} else if (OB_FAIL(index_builder_.generate_schema(*new_arg_, *new_data_table_schema_, global_index_without_column_info,
|
||||
false/*generate_id*/, *index_schema))) {
|
||||
LOG_WARN("fail to generate schema", KR(ret));
|
||||
} else if (gen_columns_.empty() || is_local_generate) {
|
||||
if (OB_FAIL(new_data_table_schema_->check_create_index_on_hidden_primary_key(*index_schema))) {
|
||||
LOG_WARN("fail to check create index on hidden primary key", KR(ret), KPC(index_schema));
|
||||
}
|
||||
}
|
||||
bool is_oracle_mode = false;
|
||||
if (FAILEDx(ObCompatModeGetter::check_is_oracle_mode_with_tenant_id(
|
||||
tenant_id_, is_oracle_mode))) {
|
||||
LOG_WARN("fail to check is oracle mode", KR(ret));
|
||||
} else if (OB_FAIL(index_schema->generate_origin_index_name())) {
|
||||
LOG_WARN("fail to generate origin index name", KR(ret), KPC(index_schema));
|
||||
} else if (!is_oracle_mode) {
|
||||
ObIndexSchemaInfo index_info;
|
||||
if (OB_FAIL(latest_schema_guard_.get_coded_index_name_info_mysql(
|
||||
allocator_,
|
||||
database_id_,
|
||||
orig_data_table_schema_->get_table_id(),
|
||||
index_schema->get_table_name(),
|
||||
false /*is built in index*/,
|
||||
index_info))) {
|
||||
LOG_WARN("fail to get index info", KR(ret), K(database_id_), K(index_schema->get_table_name()));
|
||||
} else if (index_info.is_valid()) {
|
||||
if (arg_.if_not_exist_) {
|
||||
// executor rely on invalid index id when arg_.if_not_exists_
|
||||
res_.schema_version_ = index_info.get_schema_version();
|
||||
}
|
||||
ret = OB_ERR_KEY_NAME_DUPLICATE;
|
||||
LOG_WARN("duplicate index name", KR(ret), K_(tenant_id),
|
||||
"database_id", orig_data_table_schema_->get_database_id(),
|
||||
"data_table_id", orig_data_table_schema_->get_table_id(),
|
||||
"index_name", arg_.index_name_);
|
||||
}
|
||||
} else {
|
||||
bool name_exist = false;
|
||||
if (OB_FAIL(ddl_service_->get_index_name_checker().check_index_name_exist(tenant_id_,
|
||||
index_schema->get_database_id(),
|
||||
index_schema->get_table_name_str(),
|
||||
name_exist))) {
|
||||
LOG_WARN("fail to check index name exist", KR(ret), K_(tenant_id), K(index_schema->get_table_name_str()));
|
||||
} else if (name_exist) {
|
||||
ret = OB_ERR_KEY_NAME_DUPLICATE;
|
||||
LOG_WARN("duplicate index name", KR(ret), K_(tenant_id),
|
||||
"database_id", orig_data_table_schema_->get_database_id(),
|
||||
"data_table_id", orig_data_table_schema_->get_table_id(),
|
||||
"index_name", arg_.index_name_);
|
||||
}
|
||||
}
|
||||
uint64_t object_id = OB_INVALID_ID;
|
||||
ObIDGenerator id_generator;
|
||||
if (FAILEDx(index_schemas_.push_back(*index_schema))) {
|
||||
LOG_WARN("fail to push back index schema", KR(ret));
|
||||
} else if (OB_FAIL(gen_partition_object_and_tablet_ids_(index_schemas_))) {
|
||||
LOG_WARN("fail to gen partition object and tablet ids", KR(ret));
|
||||
} else if (OB_FAIL(gen_object_ids_(1/*object_cnt*/, id_generator))) {
|
||||
LOG_WARN("fail to gen object ids", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(id_generator.next(object_id))) {
|
||||
LOG_WARN("fail to get next object id", KR(ret));
|
||||
} else {
|
||||
index_schemas_.at(0).set_table_id(object_id);
|
||||
}
|
||||
} // end heapvar
|
||||
RS_TRACE(generate_schemas);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ObCreateIndexHelper::calc_schema_version_cnt_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_ISNULL(orig_data_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("orig_data_table_schema is null", KR(ret));
|
||||
} else {
|
||||
schema_version_cnt_ = 0;
|
||||
if (!gen_columns_.empty()) {
|
||||
// gen columns & alter table option
|
||||
schema_version_cnt_++;
|
||||
uint64_t table_id = orig_data_table_schema_->get_table_id();
|
||||
const ObIArray<ObForeignKeyInfo> &foreign_key_infos = orig_data_table_schema_->get_foreign_key_infos();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < foreign_key_infos.count(); i++) {
|
||||
const ObForeignKeyInfo &foreign_key_info = foreign_key_infos.at(i);
|
||||
const uint64_t related_table_id = table_id == foreign_key_info.parent_table_id_
|
||||
? foreign_key_info.child_table_id_
|
||||
: foreign_key_info.parent_table_id_;
|
||||
if (related_table_id == table_id) {
|
||||
schema_version_cnt_++;
|
||||
} else if (foreign_key_info.is_parent_table_mock_) {
|
||||
schema_version_cnt_++; // for now, when parent table is mock
|
||||
schema_version_cnt_++; // update table option will push schema version twice
|
||||
} else {
|
||||
schema_version_cnt_++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// index table
|
||||
schema_version_cnt_++;
|
||||
// data table
|
||||
schema_version_cnt_++;
|
||||
// 1503
|
||||
schema_version_cnt_++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexHelper::create_index_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSchemaService *schema_service_impl = nullptr;
|
||||
int64_t new_schema_version = OB_INVALID_VERSION;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check iner stat", KR(ret));
|
||||
} else if (OB_ISNULL(schema_service_impl = schema_service_->get_schema_service())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("schema_service impl is null", KR(ret));
|
||||
} else if (OB_UNLIKELY(index_schemas_.count() != 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("index schemas count not expected", KR(ret), K(index_schemas_.count()));
|
||||
} else if (OB_ISNULL(new_data_table_schema_) || OB_ISNULL(orig_data_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("new/orig table schema is nullptr", KR(ret), KP(new_data_table_schema_), KP(orig_data_table_schema_));
|
||||
} else {
|
||||
ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_);
|
||||
ObTableSchema &index_schema = index_schemas_.at(0);
|
||||
if (!gen_columns_.empty()) {
|
||||
if (OB_FAIL(schema_service_->gen_new_schema_version(tenant_id_, new_schema_version))) {
|
||||
LOG_WARN("fail to gen new schema_version", KR(ret), K_(tenant_id));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < gen_columns_.count(); ++i) {
|
||||
ObColumnSchemaV2 *new_column_schema = gen_columns_.at(i);
|
||||
if (OB_ISNULL(new_column_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("new column schema is null", KR(ret));
|
||||
} else if (FALSE_IT(new_column_schema->set_schema_version(new_schema_version))) {
|
||||
} else if (OB_FAIL(schema_service_impl->get_table_sql_service().insert_single_column(
|
||||
trans_, *new_data_table_schema_, *new_column_schema, false/*record_ddl_option*/))) {
|
||||
LOG_WARN("insert single column failed", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (FALSE_IT(new_data_table_schema_->set_schema_version(new_schema_version))) {
|
||||
} else if (OB_FAIL(schema_service_impl->get_table_sql_service().update_table_options(
|
||||
trans_, *orig_data_table_schema_, *new_data_table_schema_, OB_DDL_ALTER_TABLE))) {
|
||||
LOG_WARN("fail to alter table option", KR(ret));
|
||||
}
|
||||
}
|
||||
uint64_t tenant_data_version = OB_INVALID_VERSION;
|
||||
if (FAILEDx(create_table_())) {
|
||||
LOG_WARN("fail to create table", KR(ret));
|
||||
} else if (index_schema.has_tablet() && OB_FAIL(create_tablets_())) {
|
||||
LOG_WARN("fail to create tablets", KR(ret));
|
||||
} else if (OB_ISNULL(new_arg_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("new arg is null", KR(ret));
|
||||
} else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id_, tenant_data_version))) {
|
||||
LOG_WARN("fail to get data version", K(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(index_builder_.submit_build_index_task(trans_,
|
||||
*new_arg_,
|
||||
new_data_table_schema_,
|
||||
nullptr/*inc_data_tablet_ids*/,
|
||||
nullptr/*del_data_tablet_ids*/,
|
||||
&index_schema,
|
||||
arg_.parallelism_,
|
||||
arg_.consumer_group_id_,
|
||||
tenant_data_version,
|
||||
allocator_,
|
||||
task_record_))) {
|
||||
LOG_WARN("fail to submit build local index task", KR(ret));
|
||||
}
|
||||
}
|
||||
RS_TRACE(submit_task);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexHelper::create_table_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t new_schema_version = OB_INVALID_VERSION;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_UNLIKELY(index_schemas_.count() != 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("index schemas count not expected", KR(ret));
|
||||
} else {
|
||||
ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_);
|
||||
ObSchemaService *schema_service_impl = schema_service_->get_schema_service();
|
||||
int64_t last_schema_version = OB_INVALID_VERSION;
|
||||
ObSchemaVersionGenerator *tsi_generator = GET_TSI(TSISchemaVersionGenerator);
|
||||
ObTableSchema &index_schema = index_schemas_.at(0);
|
||||
if (OB_ISNULL(tsi_generator)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("tsi generator is null", KR(ret));
|
||||
} else if (OB_ISNULL(schema_service_impl)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("schema service must not by null", KR(ret));
|
||||
} else if (OB_FAIL(schema_service_->gen_new_schema_version(tenant_id_, new_schema_version))) {
|
||||
LOG_WARN("fail to gen new schema version", KR(ret), K_(tenant_id));
|
||||
} else if (FALSE_IT(index_schema.set_schema_version(new_schema_version))) {
|
||||
} else if (OB_FAIL(schema_service_impl->get_table_sql_service().create_table(
|
||||
index_schema, trans_,
|
||||
nullptr/*ddl_stmt_str*/, true/*need_sync_schema_version*/, false/*is_truncate_table*/))) {
|
||||
LOG_WARN("fail to create table", KR(ret));
|
||||
} else if (OB_FAIL(schema_service_impl->get_table_sql_service().insert_temp_table_info(trans_, index_schema))) {
|
||||
LOG_WARN("insert temp table info", KR(ret), K(index_schema));
|
||||
} else if (OB_FAIL(tsi_generator->get_current_version(last_schema_version))) {
|
||||
LOG_WARN("fail to get end version", KR(ret), K_(tenant_id), K_(arg));
|
||||
} else if (OB_UNLIKELY(last_schema_version <= 0)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("last schema version is invalid", KR(ret), K_(tenant_id), K(last_schema_version));
|
||||
} else if (OB_FAIL(ddl_operator.insert_ori_schema_version(trans_, tenant_id_, index_schema.get_table_id(), last_schema_version))) {
|
||||
LOG_WARN("fail to insert ori schema version", KR(ret), K_(tenant_id), K(new_schema_version));
|
||||
}
|
||||
}
|
||||
RS_TRACE(create_schemas);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexHelper::create_tablets_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
SCN frozen_scn;
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("check inner stat failed", KR(ret));
|
||||
} else if (OB_UNLIKELY(index_schemas_.count() != 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("index schemas count not expected", KR(ret), K(index_schemas_.count()));
|
||||
} else if (OB_ISNULL(orig_data_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("orig_data_table_schema is null", KR(ret));
|
||||
} else if(OB_FAIL(ObMajorFreezeHelper::get_frozen_scn(tenant_id_, frozen_scn))) {
|
||||
LOG_WARN("fail to get frozen status for create tablet", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(tenant_id_, schema_guard))) {
|
||||
LOG_WARN("fail to get tenant schema guard", KR(ret), K_(tenant_id));
|
||||
} else {
|
||||
ObTableSchema &index_schema = index_schemas_.at(0);
|
||||
ObTableCreator table_creator(tenant_id_, frozen_scn, trans_);
|
||||
ObNewTableTabletAllocator new_table_tablet_allocator(
|
||||
tenant_id_,
|
||||
schema_guard,
|
||||
sql_proxy_,
|
||||
true /*use parallel ddl*/,
|
||||
orig_data_table_schema_);
|
||||
common::ObArray<share::ObLSID> ls_id_array;
|
||||
const ObTablegroupSchema *data_tablegroup_schema = NULL; // keep NULL if no tablegroup
|
||||
ObSEArray<bool, 1> need_create_empty_majors;
|
||||
uint64_t tenant_data_version = 0;
|
||||
if (OB_FAIL(table_creator.init(true/*need_tablet_cnt_check*/))) {
|
||||
LOG_WARN("fail to init table craetor", KR(ret));
|
||||
} else if (OB_FAIL(new_table_tablet_allocator.init())) {
|
||||
LOG_WARN("fail to init new table tablet allocator", KR(ret));
|
||||
} else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id_, tenant_data_version))) {
|
||||
LOG_WARN("fail to get data version", K(ret), K_(tenant_id));
|
||||
} else if (OB_INVALID_ID != orig_data_table_schema_->get_tablegroup_id()) {
|
||||
if (OB_FAIL(latest_schema_guard_.get_tablegroup_schema(
|
||||
orig_data_table_schema_->get_tablegroup_id(),
|
||||
data_tablegroup_schema))) {
|
||||
LOG_WARN("get tablegroup_schema failed", KR(ret), KPC(orig_data_table_schema_));
|
||||
} else if (OB_ISNULL(data_tablegroup_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("data_tablegroup_schema is null", KR(ret), KPC(orig_data_table_schema_));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (index_schema.is_index_local_storage()) {
|
||||
ObSEArray<const share::schema::ObTableSchema*, 1> schemas;
|
||||
if (OB_FAIL(schemas.push_back(&index_schema))
|
||||
|| OB_FAIL(need_create_empty_majors.push_back(false))) {
|
||||
LOG_WARN("fail to push back index schema", KR(ret), K(index_schema));
|
||||
} else if (OB_FAIL(new_table_tablet_allocator.prepare(trans_, index_schema, data_tablegroup_schema))) {
|
||||
LOG_WARN("fail to prepare ls for index schema tablets", KR(ret));
|
||||
} else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array(ls_id_array))) {
|
||||
LOG_WARN("fail to get ls id array", KR(ret));
|
||||
} else if (OB_FAIL(table_creator.add_create_tablets_of_local_aux_tables_arg(
|
||||
schemas,
|
||||
orig_data_table_schema_,
|
||||
ls_id_array,
|
||||
tenant_data_version,
|
||||
need_create_empty_majors))) {
|
||||
LOG_WARN("create table tablet failed", KR(ret), K(index_schema), K(ls_id_array));
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(new_table_tablet_allocator.prepare(trans_, index_schema, data_tablegroup_schema))) {
|
||||
LOG_WARN("fail to prepare ls for index schema tablets", KR(ret));
|
||||
} else if (OB_FAIL(new_table_tablet_allocator.get_ls_id_array(ls_id_array))) {
|
||||
LOG_WARN("fail to get ls id array", KR(ret));
|
||||
} else if (OB_FAIL(table_creator.add_create_tablets_of_table_arg(index_schema, ls_id_array,
|
||||
tenant_data_version, false/*need create major sstable*/))) {
|
||||
LOG_WARN("create table tablet failed", KR(ret), K(index_schema));
|
||||
}
|
||||
}
|
||||
if (FAILEDx(table_creator.execute())) {
|
||||
LOG_WARN("execute create partition failed", KR(ret));
|
||||
}
|
||||
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
if (OB_SUCCESS != (tmp_ret = new_table_tablet_allocator.finish(OB_SUCCESS == ret))) {
|
||||
LOG_WARN("fail to finish new table tablet allocator", KR(tmp_ret));
|
||||
}
|
||||
}
|
||||
RS_TRACE(create_tablets);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexHelper::add_index_name_to_cache_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObIndexNameChecker &checker = ddl_service_->get_index_name_checker();
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_UNLIKELY(index_schemas_.count() != 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("index schemas count not expected", KR(ret), K(index_schemas_.count()));
|
||||
} else {
|
||||
ObTableSchema &index_schema = index_schemas_.at(0);
|
||||
if (OB_FAIL(checker.add_index_name(index_schema))) {
|
||||
LOG_WARN("fail to add index name", KR(ret), K(index_schema));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// self ref table no need to check
|
||||
// for mock fk table, should check it is exist
|
||||
// for fk table, should check not doing long ddl
|
||||
int ObCreateIndexHelper::check_fk_related_table_ddl_(const share::schema::ObTableSchema &data_table_schema,
|
||||
const share::ObDDLType &ddl_type)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id_ || share::ObDDLType::DDL_INVALID == ddl_type)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arg", KR(ret), K_(tenant_id), K(ddl_type));
|
||||
} else {
|
||||
const ObIArray<ObForeignKeyInfo> &foreign_key_infos = data_table_schema.get_foreign_key_infos();
|
||||
const ObCheckExistedDDLMode check_mode = is_double_table_long_running_ddl(ddl_type) ?
|
||||
ObCheckExistedDDLMode::ALL_LONG_RUNNING_DDL : ObCheckExistedDDLMode::DOUBLE_TABLE_RUNNING_DDL;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < foreign_key_infos.count(); ++i) {
|
||||
const ObForeignKeyInfo &foreign_key_info = foreign_key_infos.at(i);
|
||||
const uint64_t related_table_id = data_table_schema.get_table_id() == foreign_key_info.parent_table_id_?
|
||||
foreign_key_info.child_table_id_ : foreign_key_info.parent_table_id_;
|
||||
if (data_table_schema.get_table_id() == related_table_id) {
|
||||
// self no need to check
|
||||
} else if (foreign_key_info.is_parent_table_mock_) {
|
||||
const ObMockFKParentTableSchema *related_schema = nullptr;
|
||||
if (OB_FAIL(latest_schema_guard_.get_mock_fk_parent_table_schema(related_table_id, related_schema))) {
|
||||
LOG_WARN("fail to get related mock fk parent table schema", KR(ret), K_(tenant_id), K(related_table_id));
|
||||
} else if (OB_ISNULL(related_schema)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("mock fk parent table schema is null ptr, may be dropped", KR(ret), K_(tenant_id), K(related_table_id), K(foreign_key_info));
|
||||
}
|
||||
} else {
|
||||
const ObTableSchema *related_schema = nullptr;
|
||||
bool has_long_running_ddl = false;
|
||||
if (OB_FAIL(latest_schema_guard_.get_table_schema(related_table_id, related_schema))) {
|
||||
LOG_WARN("fail to get related table schema", KR(ret), K_(tenant_id), K(related_table_id));
|
||||
} else if (OB_ISNULL(related_schema)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("related schema is null ptr, may be dropped", KR(ret), K_(tenant_id), K(related_table_id), K(foreign_key_info));
|
||||
} else if (!related_schema->check_can_do_ddl()) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "execute ddl while foreign key related table is executing long running ddl");
|
||||
} else if (OB_FAIL(ObDDLTaskRecordOperator::check_has_long_running_ddl(sql_proxy_,
|
||||
tenant_id_,
|
||||
related_table_id,
|
||||
check_mode,
|
||||
has_long_running_ddl))) {
|
||||
LOG_WARN("check has long running ddl failed", KR(ret), K_(tenant_id), K(related_table_id));
|
||||
} else if (has_long_running_ddl) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("foreign key related table is executing offline ddl", KR(ret), K(check_mode), K_(tenant_id), K(related_table_id));
|
||||
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "execute ddl while foreign key related table is executing long running ddl");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
78
src/rootserver/parallel_ddl/ob_create_index_helper.h
Normal file
78
src/rootserver/parallel_ddl/ob_create_index_helper.h
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* 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_ROOTSERVER_OB_CREATE_INDEX_HELPER_H_
|
||||
#define OCEANBASE_ROOTSERVER_OB_CREATE_INDEX_HELPER_H_
|
||||
|
||||
#include "rootserver/parallel_ddl/ob_ddl_helper.h"
|
||||
#include "rootserver/ob_index_builder.h"
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace share
|
||||
{
|
||||
namespace schema
|
||||
{
|
||||
class ObMultiVersionSchemaService;
|
||||
}
|
||||
}
|
||||
namespace obrpc
|
||||
{
|
||||
class ObCreateIndexArg;
|
||||
class ObAlterTableRes;
|
||||
}
|
||||
namespace rootserver
|
||||
{
|
||||
class ObCreateIndexHelper : public ObDDLHelper
|
||||
{
|
||||
public:
|
||||
ObCreateIndexHelper(
|
||||
share::schema::ObMultiVersionSchemaService *schema_service,
|
||||
const uint64_t tenant_id,
|
||||
rootserver::ObDDLService &ddl_service,
|
||||
const obrpc::ObCreateIndexArg &arg,
|
||||
obrpc::ObAlterTableRes &res);
|
||||
virtual ~ObCreateIndexHelper();
|
||||
virtual int execute() override;
|
||||
private:
|
||||
int lock_objects_();
|
||||
int lock_database_by_obj_name_();
|
||||
int lock_objects_by_name_();
|
||||
int check_database_legitimacy_();
|
||||
int lock_objects_by_id_();
|
||||
int check_table_legitimacy_();
|
||||
int generate_index_schema_();
|
||||
int calc_schema_version_cnt_();
|
||||
int create_index_();
|
||||
int is_local_generate_schema_(bool &is_local_generate);
|
||||
int create_table_();
|
||||
int create_tablets_();
|
||||
int add_index_name_to_cache_();
|
||||
int check_fk_related_table_ddl_(const share::schema::ObTableSchema &data_table_schema,
|
||||
const share::ObDDLType &ddl_type);
|
||||
private:
|
||||
const obrpc::ObCreateIndexArg &arg_;
|
||||
obrpc::ObCreateIndexArg *new_arg_;
|
||||
obrpc::ObAlterTableRes &res_;
|
||||
uint64_t database_id_;
|
||||
const ObTableSchema *orig_data_table_schema_;
|
||||
ObTableSchema* new_data_table_schema_;
|
||||
ObArray<ObTableSchema> index_schemas_;
|
||||
ObSEArray<ObColumnSchemaV2*, 1> gen_columns_;
|
||||
ObIndexBuilder index_builder_;
|
||||
ObDDLTaskRecord task_record_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateIndexHelper);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif//OCEANBASE_ROOTSERVER_OB_CREATE_TABLE_HELPER_H_
|
@ -139,7 +139,7 @@ int ObCreateTableHelper::execute()
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
auto *tsi_generator = GET_TSI(TSISchemaVersionGenerator);
|
||||
ObSchemaVersionGenerator *tsi_generator = GET_TSI(TSISchemaVersionGenerator);
|
||||
int64_t last_schema_version = OB_INVALID_VERSION;
|
||||
int64_t end_schema_version = OB_INVALID_VERSION;
|
||||
if (OB_UNLIKELY(new_tables_.count() <= 0)) {
|
||||
@ -149,7 +149,7 @@ int ObCreateTableHelper::execute()
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("tsi schema version generator is null", KR(ret));
|
||||
} else if (OB_FAIL(tsi_generator->get_current_version(last_schema_version))) {
|
||||
LOG_WARN("fail to get end version", KR(ret), K_(tenant_id), K_(arg));
|
||||
LOG_WARN("fail to get current version", KR(ret), K_(tenant_id), K_(arg));
|
||||
} else if (OB_FAIL(tsi_generator->get_end_version(end_schema_version))) {
|
||||
LOG_WARN("fail to get end version", KR(ret), K_(tenant_id), K_(arg));
|
||||
} else if (OB_UNLIKELY(last_schema_version != end_schema_version)) {
|
||||
@ -204,11 +204,11 @@ int ObCreateTableHelper::lock_objects_()
|
||||
DEBUG_SYNC(AFTER_PARALLEL_DDL_LOCK_OBJ_BY_NAME);
|
||||
// 3. prefetch schemas
|
||||
if (FAILEDx(prefetch_schemas_())) {
|
||||
LOG_WARN("fail to prefech schemas", KR(ret), K_(tenant_id));
|
||||
LOG_WARN("fail to prefetch schemas", KR(ret), K_(tenant_id));
|
||||
}
|
||||
// 4. lock objects by id
|
||||
if (FAILEDx(lock_objects_by_id_())) {
|
||||
LOG_WARN("fail to lock objects by name", KR(ret), K_(tenant_id));
|
||||
LOG_WARN("fail to lock objects by id", KR(ret), K_(tenant_id));
|
||||
}
|
||||
// 5. lock objects by id after related objects are locked.
|
||||
if (FAILEDx(post_lock_objects_by_id_())) {
|
||||
@ -355,6 +355,7 @@ int ObCreateTableHelper::lock_objects_by_name_()
|
||||
}
|
||||
|
||||
// lock related objects' id for create table (`X` for EXCLUSIVE, `S` for SHARE):
|
||||
// 0. database (S)
|
||||
// 1. tablegroup (S)
|
||||
// 2. audit (S)
|
||||
// - add share lock for OB_AUDIT_MOCK_USER_ID
|
||||
@ -377,6 +378,11 @@ int ObCreateTableHelper::lock_objects_by_id_()
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
}
|
||||
// 0. database
|
||||
if (FAILEDx(add_lock_object_by_id_(arg_.schema_.get_database_id(),
|
||||
share::schema::DATABASE_SCHEMA, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock database id", KR(ret), K(arg_.schema_.get_database_id()));
|
||||
}
|
||||
// 1. tablegroup
|
||||
const uint64_t tablegroup_id = table.get_tablegroup_id();
|
||||
if (OB_SUCC(ret) && OB_INVALID_ID != tablegroup_id) {
|
||||
@ -430,35 +436,8 @@ int ObCreateTableHelper::lock_objects_by_id_()
|
||||
}
|
||||
}
|
||||
// 6. udt
|
||||
if (OB_SUCC(ret)) {
|
||||
ObTableSchema::const_column_iterator begin = table.column_begin();
|
||||
ObTableSchema::const_column_iterator end = table.column_end();
|
||||
ObSchemaGetterGuard guard;
|
||||
if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, guard))) {
|
||||
LOG_WARN("fail to get schema guard", KR(ret));
|
||||
}
|
||||
for (; OB_SUCC(ret) && begin != end; begin++) {
|
||||
ObColumnSchemaV2 *col = (*begin);
|
||||
if (OB_ISNULL(col)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get column schema failed", KR(ret));
|
||||
} else if (col->get_meta_type().is_user_defined_sql_type()) {
|
||||
const uint64_t udt_id = col->get_sub_data_type();
|
||||
if (is_inner_object_id(udt_id) && !is_sys_tenant(tenant_id_)) {
|
||||
// can't add object lock across tenant, assumed that sys inner udt won't be changed.
|
||||
const ObUDTTypeInfo *udt_info = NULL;
|
||||
if (OB_FAIL(guard.get_udt_info(OB_SYS_TENANT_ID, udt_id, udt_info))) {
|
||||
LOG_WARN("fail to get udt info", KR(ret), K(udt_id));
|
||||
} else if (OB_ISNULL(udt_info)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("inner udt not found", KR(ret), K(udt_id));
|
||||
}
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(udt_id,
|
||||
share::schema::UDT_SCHEMA, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock udt id", KR(ret), K_(tenant_id), K(udt_id));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
if (FAILEDx(add_lock_table_udt_id_(table))) {
|
||||
LOG_WARN("fail to add lock table udt id", KR(ret));
|
||||
}
|
||||
|
||||
if (FAILEDx(lock_existed_objects_by_id_())) {
|
||||
@ -537,8 +516,6 @@ int ObCreateTableHelper::check_ddl_conflict_()
|
||||
} else if (!arg_.is_need_check_based_schema_objects()) {
|
||||
// skip
|
||||
} else {
|
||||
ObArray<uint64_t> parent_table_ids;
|
||||
ObArray<uint64_t> mock_fk_parent_table_ids;
|
||||
// check schema object infos are all existed.
|
||||
for (int64_t i = 0; OB_SUCC(ret) && (i < arg_.based_schema_object_infos_.count()); ++i) {
|
||||
const ObBasedSchemaObjectInfo &info = arg_.based_schema_object_infos_.at(i);
|
||||
@ -562,86 +539,11 @@ int ObCreateTableHelper::check_ddl_conflict_()
|
||||
LOG_WARN("parent table may change, ddl need retry",
|
||||
KR(ret), K_(tenant_id), K(info));
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (MOCK_FK_PARENT_TABLE_SCHEMA == info.schema_type_) {
|
||||
if (!has_exist_in_array(mock_fk_parent_table_ids, info.schema_id_)
|
||||
&& OB_FAIL(mock_fk_parent_table_ids.push_back(info.schema_id_))) {
|
||||
LOG_WARN("fail to push back mock fk parent table id", KR(ret), K(info));
|
||||
}
|
||||
} else if (TABLE_SCHEMA == info.schema_type_) {
|
||||
if (!has_exist_in_array(parent_table_ids, info.schema_id_)
|
||||
&& OB_FAIL(parent_table_ids.push_back(info.schema_id_))) {
|
||||
LOG_WARN("fail to push back parent table id", KR(ret), K(info));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
|
||||
ObArray<ObSchemaIdVersion> parent_table_versions;
|
||||
if (OB_SUCC(ret) && parent_table_ids.count() > 0) {
|
||||
if (OB_FAIL(parent_table_versions.reserve(parent_table_ids.count()))) {
|
||||
LOG_WARN("fail to reserve array", KR(ret));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_table_schema_versions(
|
||||
parent_table_ids, parent_table_versions))) {
|
||||
LOG_WARN("fail to get table schema versions", KR(ret));
|
||||
} else if (parent_table_ids.count() != parent_table_versions.count()) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("parent table may be deleted, ddl need retry",
|
||||
KR(ret), K_(tenant_id), "base_objs_cnt", parent_table_ids.count(),
|
||||
"fetch_cnt", parent_table_versions.count());
|
||||
}
|
||||
}
|
||||
|
||||
ObArray<ObSchemaIdVersion> mock_fk_parent_table_versions;
|
||||
if (OB_SUCC(ret) && mock_fk_parent_table_ids.count() > 0) {
|
||||
if (OB_FAIL(mock_fk_parent_table_versions.reserve(mock_fk_parent_table_ids.count()))) {
|
||||
LOG_WARN("fail to reserve array", KR(ret));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_mock_fk_parent_table_schema_versions(
|
||||
mock_fk_parent_table_ids, mock_fk_parent_table_versions))) {
|
||||
LOG_WARN("fail to get table schema versions", KR(ret));
|
||||
} else if (mock_fk_parent_table_ids.count() != mock_fk_parent_table_versions.count()) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("mock fk parent table may be deleted, ddl need retry",
|
||||
KR(ret), K_(tenant_id), "base_objs_cnt", mock_fk_parent_table_ids.count(),
|
||||
"fetch_cnt", mock_fk_parent_table_versions.count());
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && (i < arg_.based_schema_object_infos_.count()); ++i) {
|
||||
const ObBasedSchemaObjectInfo &info = arg_.based_schema_object_infos_.at(i);
|
||||
if (MOCK_FK_PARENT_TABLE_SCHEMA == info.schema_type_
|
||||
|| TABLE_SCHEMA == info.schema_type_) {
|
||||
bool find = false;
|
||||
for (int64_t j = 0; OB_SUCC(ret) && !find && j < parent_table_versions.count(); j++) {
|
||||
const ObSchemaIdVersion &version = parent_table_versions.at(j);
|
||||
if (version.get_schema_id() == info.schema_id_) {
|
||||
find = true;
|
||||
if (version.get_schema_version() != info.schema_version_) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("parent table may be changed, ddl need retry",
|
||||
KR(ret), K_(tenant_id), K(info), K(version));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
for (int64_t j = 0; OB_SUCC(ret) && !find && j < mock_fk_parent_table_versions.count(); j++) {
|
||||
const ObSchemaIdVersion &version = mock_fk_parent_table_versions.at(j);
|
||||
if (version.get_schema_id() == info.schema_id_) {
|
||||
find = true;
|
||||
if (version.get_schema_version() != info.schema_version_) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("mock fk parent table may be changed, ddl need retry",
|
||||
KR(ret), K_(tenant_id), K(info), K(version));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
if (OB_SUCC(ret) && !find) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("parent table may be deleted, ddl need retry",
|
||||
KR(ret), K_(tenant_id), K(info));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
if (FAILEDx(check_parallel_ddl_conflict_(arg_.based_schema_object_infos_))) {
|
||||
LOG_WARN("fail to check parallel ddl conflict", KR(ret));
|
||||
}
|
||||
|
||||
// for replace mock fk parent table:
|
||||
@ -671,25 +573,6 @@ int ObCreateTableHelper::check_ddl_conflict_()
|
||||
} // end for
|
||||
}
|
||||
|
||||
// check udt exist & not changed
|
||||
for (int64_t i = 0; OB_SUCC(ret) && (i < arg_.based_schema_object_infos_.count()); ++i) {
|
||||
const ObBasedSchemaObjectInfo &info = arg_.based_schema_object_infos_.at(i);
|
||||
if (UDT_SCHEMA == info.schema_type_) {
|
||||
const uint64_t udt_id = info.schema_id_;
|
||||
const ObUDTTypeInfo *udt_info = NULL;
|
||||
if (is_inner_object_id(udt_id) && !is_sys_tenant(tenant_id_)) {
|
||||
// can't add object lock across tenant, assumed that sys inner udt won't be changed.
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_udt_info(udt_id, udt_info))) {
|
||||
LOG_WARN("fail to get udt info", KR(ret), K_(tenant_id), K(udt_id), K(info));
|
||||
} else if (OB_ISNULL(udt_info)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("udt doesn't exist", KR(ret), K_(tenant_id), K(udt_id));
|
||||
} else if (udt_info->get_schema_version() != info.schema_version_) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("udt changed", KR(ret), K(info), KPC(udt_info));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
const int64_t cost_ts = ObTimeUtility::current_time() - start_ts;
|
||||
LOG_INFO("check ddl confict", KR(ret), K_(tenant_id), K(cost_ts));
|
||||
@ -1038,37 +921,8 @@ int ObCreateTableHelper::generate_table_schema_()
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
ObTableSchema::const_column_iterator begin = new_table.column_begin();
|
||||
ObTableSchema::const_column_iterator end = new_table.column_end();
|
||||
ObSchemaGetterGuard guard;
|
||||
if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, guard))) {
|
||||
LOG_WARN("fail to get schema guard", KR(ret));
|
||||
}
|
||||
for (; OB_SUCC(ret) && begin != end; begin++) {
|
||||
ObColumnSchemaV2 *col = (*begin);
|
||||
if (OB_ISNULL(col)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get column schema failed", KR(ret));
|
||||
} else if (col->get_meta_type().is_user_defined_sql_type()) {
|
||||
const uint64_t udt_id = col->get_sub_data_type();
|
||||
const ObUDTTypeInfo *udt_info = NULL;
|
||||
if (is_inner_object_id(udt_id) && !is_sys_tenant(tenant_id_)) {
|
||||
// can't add object lock across tenant, assumed that sys inner udt won't be changed.
|
||||
if (OB_FAIL(guard.get_udt_info(OB_SYS_TENANT_ID, udt_id, udt_info))) {
|
||||
LOG_WARN("fail to get udt info", KR(ret), K(udt_id));
|
||||
} else if (OB_ISNULL(udt_info)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("inner udt not found", KR(ret), K(udt_id));
|
||||
}
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_udt_info(udt_id, udt_info))) {
|
||||
LOG_WARN("fail to get udt info", KR(ret), K_(tenant_id), K(udt_id));
|
||||
} else if (OB_ISNULL(udt_info)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("udt doesn't exist", KR(ret), K_(tenant_id), K(udt_id));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
if (FAILEDx(check_table_udt_exist_(new_table))) {
|
||||
LOG_WARN("fail to check table udt exist", KR(ret));
|
||||
}
|
||||
|
||||
// check if constraint name duplicated
|
||||
@ -2380,7 +2234,7 @@ int ObCreateTableHelper::create_tablets_()
|
||||
true /*use parallel ddl*/);
|
||||
const ObTablegroupSchema *data_tablegroup_schema = NULL; // keep NULL if no tablegroup
|
||||
int64_t last_schema_version = OB_INVALID_VERSION;
|
||||
auto *tsi_generator = GET_TSI(TSISchemaVersionGenerator);
|
||||
ObSchemaVersionGenerator *tsi_generator = GET_TSI(TSISchemaVersionGenerator);
|
||||
if (OB_FAIL(table_creator.init(true/*need_tablet_cnt_check*/))) {
|
||||
LOG_WARN("fail to init table creator", KR(ret));
|
||||
} else if (OB_FAIL(new_table_tablet_allocator.init())) {
|
||||
|
@ -70,7 +70,7 @@ private:
|
||||
|
||||
int lock_objects_();
|
||||
int generate_schemas_();
|
||||
int calc_schema_version_cnt_();
|
||||
virtual int calc_schema_version_cnt_() override;
|
||||
int create_schemas_();
|
||||
int create_tablets_();
|
||||
int add_index_name_to_cache_();
|
||||
|
@ -83,6 +83,16 @@ int ObCreateViewHelper::generate_schemas_()
|
||||
return ret;
|
||||
}
|
||||
|
||||
//TODO:(wenyu.ffz) to implement
|
||||
int ObCreateViewHelper::calc_schema_version_cnt_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//TODO:(yanmu.ztl) to implement
|
||||
int ObCreateViewHelper::create_schemas_()
|
||||
{
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
private:
|
||||
int lock_objects_();
|
||||
int generate_schemas_();
|
||||
virtual int calc_schema_version_cnt_() override;
|
||||
int create_schemas_();
|
||||
private:
|
||||
const obrpc::ObCreateTableArg &arg_;
|
||||
|
@ -126,6 +126,34 @@ int ObDDLHelper::init(rootserver::ObDDLService &ddl_service)
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t ObDDLHelper::cast_database_name_to_id_(const ObString &database_name)
|
||||
{
|
||||
// use OB_ORIGIN_AND_INSENSITIVE and ignore end space to make more conficts for safety.
|
||||
common::ObCollationType cs_type = ObSchema::get_cs_type_with_cmp_mode(OB_ORIGIN_AND_INSENSITIVE);
|
||||
bool calc_end_space = false;
|
||||
uint64_t lock_obj_id = 0;
|
||||
lock_obj_id = common::ObCharset::hash(
|
||||
cs_type, database_name.ptr(), database_name.length(),
|
||||
lock_obj_id, calc_end_space, NULL);
|
||||
return lock_obj_id;
|
||||
}
|
||||
|
||||
uint64_t ObDDLHelper::cast_obj_name_to_id_(const ObString &database_name, const ObString &obj_name)
|
||||
{
|
||||
// 1. use OB_ORIGIN_AND_INSENSITIVE and ignore end space to make more conficts for safety.
|
||||
// 2. encoded with database name to make less conficts between different databases/users.
|
||||
common::ObCollationType cs_type = ObSchema::get_cs_type_with_cmp_mode(OB_ORIGIN_AND_INSENSITIVE);
|
||||
bool calc_end_space = false;
|
||||
uint64_t lock_obj_id = 0;
|
||||
lock_obj_id = common::ObCharset::hash(
|
||||
cs_type, database_name.ptr(), database_name.length(),
|
||||
lock_obj_id, calc_end_space, NULL);
|
||||
lock_obj_id = common::ObCharset::hash(
|
||||
cs_type, obj_name.ptr(), obj_name.length(),
|
||||
lock_obj_id, calc_end_space, NULL);
|
||||
return lock_obj_id;
|
||||
}
|
||||
|
||||
int ObDDLHelper::check_inner_stat_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -461,13 +489,7 @@ int ObDDLHelper::add_lock_object_by_database_name_(
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("database_name is invalid", KR(ret), K(database_name));
|
||||
} else {
|
||||
// use OB_ORIGIN_AND_INSENSITIVE and ignore end space to make more conficts for safety.
|
||||
common::ObCollationType cs_type = ObSchema::get_cs_type_with_cmp_mode(OB_ORIGIN_AND_INSENSITIVE);
|
||||
bool calc_end_space = false;
|
||||
uint64_t lock_obj_id = 0;
|
||||
lock_obj_id = common::ObCharset::hash(
|
||||
cs_type, database_name.ptr(), database_name.length(),
|
||||
lock_obj_id, calc_end_space, NULL);
|
||||
uint64_t lock_obj_id = cast_database_name_to_id_(database_name);
|
||||
if (OB_FAIL(add_lock_object_to_map_(lock_obj_id, lock_mode, lock_database_name_map_))) {
|
||||
LOG_WARN("fail to add lock object to map", KR(ret), K(lock_obj_id), K(lock_mode));
|
||||
}
|
||||
@ -494,17 +516,7 @@ int ObDDLHelper::add_lock_object_by_name_(
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("database_name/object_name is invalid", KR(ret), K(database_name), K(object_name));
|
||||
} else {
|
||||
// 1. use OB_ORIGIN_AND_INSENSITIVE and ignore end space to make more conficts for safety.
|
||||
// 2. encoded with database name to make less conficts between different databases/users.
|
||||
common::ObCollationType cs_type = ObSchema::get_cs_type_with_cmp_mode(OB_ORIGIN_AND_INSENSITIVE);
|
||||
bool calc_end_space = false;
|
||||
uint64_t lock_obj_id = 0;
|
||||
lock_obj_id = common::ObCharset::hash(
|
||||
cs_type, database_name.ptr(), database_name.length(),
|
||||
lock_obj_id, calc_end_space, NULL);
|
||||
lock_obj_id = common::ObCharset::hash(
|
||||
cs_type, object_name.ptr(), object_name.length(),
|
||||
lock_obj_id, calc_end_space, NULL);
|
||||
uint64_t lock_obj_id = cast_obj_name_to_id_(database_name, object_name);
|
||||
if (OB_FAIL(add_lock_object_to_map_(lock_obj_id, lock_mode, lock_object_name_map_))) {
|
||||
LOG_WARN("fail to add lock object to map", KR(ret), K(lock_obj_id), K(lock_mode));
|
||||
}
|
||||
@ -635,3 +647,328 @@ int ObDDLHelper::gen_partition_object_and_tablet_ids_(
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLHelper::obj_lock_database_name(
|
||||
ObDDLSQLTransaction &trans,
|
||||
const uint64_t tenant_id,
|
||||
const ObString &name,
|
||||
const transaction::tablelock::ObTableLockMode lock_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || name.empty())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("parallel ddl lock name is invalid", KR(ret), K(name));
|
||||
} else {
|
||||
uint64_t lock_obj_id = cast_database_name_to_id_(name);
|
||||
if (OB_FAIL(obj_lock_with_lock_id_(trans, tenant_id, lock_obj_id, lock_mode, ObLockOBJType::OBJ_TYPE_DATABASE_NAME))) {
|
||||
LOG_WARN("fail to lock id", KR(ret), K(lock_obj_id), K(lock_mode));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObDDLHelper::obj_lock_obj_name(
|
||||
ObDDLSQLTransaction &trans,
|
||||
const uint64_t tenant_id,
|
||||
const ObString &database_name,
|
||||
const ObString &obj_name,
|
||||
const transaction::tablelock::ObTableLockMode lock_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || database_name.empty() || obj_name.empty())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("parallel ddl lock name is invalid", KR(ret), K(database_name), K(obj_name));
|
||||
} else {
|
||||
uint64_t lock_obj_id = cast_obj_name_to_id_(database_name, obj_name);
|
||||
if (OB_FAIL(obj_lock_with_lock_id_(trans, tenant_id, lock_obj_id, lock_mode, ObLockOBJType::OBJ_TYPE_OBJECT_NAME))) {
|
||||
LOG_WARN("fail to lock id", KR(ret), K(lock_obj_id), K(lock_mode));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLHelper::obj_lock_obj_id(
|
||||
ObDDLSQLTransaction &trans,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t obj_id,
|
||||
const transaction::tablelock::ObTableLockMode lock_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || OB_INVALID_ID == obj_id)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("parallel ddl lock name is invalid", KR(ret), K(obj_id));
|
||||
} else if (OB_FAIL(obj_lock_with_lock_id_(trans, tenant_id, obj_id, lock_mode, ObLockOBJType::OBJ_TYPE_COMMON_OBJ))) {
|
||||
LOG_WARN("fail to lock id", KR(ret), K(obj_id), K(lock_mode));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObDDLHelper::obj_lock_with_lock_id_(
|
||||
ObDDLSQLTransaction &trans,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t obj_id,
|
||||
const transaction::tablelock::ObTableLockMode lock_mode,
|
||||
const ObLockOBJType obj_type)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
observer::ObInnerSQLConnection *conn = nullptr;
|
||||
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || OB_INVALID_ID == obj_id)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("parallel ddl lock name is invalid", KR(ret), K(obj_id));
|
||||
} else if (OB_ISNULL(conn = dynamic_cast<observer::ObInnerSQLConnection *>
|
||||
(trans.get_connection()))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("trans conn is NULL", KR(ret));
|
||||
} else {
|
||||
ObTimeoutCtx ctx;
|
||||
transaction::tablelock::ObLockObjRequest lock_arg;
|
||||
lock_arg.obj_type_ = obj_type;
|
||||
lock_arg.owner_id_ = ObTableLockOwnerID::default_owner();
|
||||
lock_arg.obj_id_ = obj_id;
|
||||
lock_arg.lock_mode_ = lock_mode;
|
||||
lock_arg.op_type_ = ObTableLockOpType::IN_TRANS_COMMON_LOCK;
|
||||
if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, GCONF.rpc_timeout))) {
|
||||
LOG_WARN("fail to set timeout ctx", KR(ret));
|
||||
} else if (FALSE_IT(lock_arg.timeout_us_ = ctx.get_timeout())) {
|
||||
} else if (OB_FAIL(ObInnerConnectionLockUtil::lock_obj(tenant_id, lock_arg, conn))) {
|
||||
LOG_WARN("lock obj failed", KR(ret), K(tenant_id), K(lock_arg));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObDDLHelper::check_database_legitimacy_(const ObString &database_name, uint64_t &database_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObDatabaseSchema *database_schema = NULL;
|
||||
database_id = OB_INVALID_ID;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_database_id(database_name, database_id))) {
|
||||
LOG_WARN("fail to get database id", KR(ret), K_(tenant_id), K(database_name));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_ID == database_id)) {
|
||||
ret = OB_ERR_BAD_DATABASE;
|
||||
LOG_WARN("database not exist", KR(ret), K_(tenant_id), K(database_name));
|
||||
LOG_USER_ERROR(OB_ERR_BAD_DATABASE, database_name.length(), database_name.ptr());
|
||||
} else if (OB_UNLIKELY(OB_RECYCLEBIN_SCHEMA_ID == database_id)) {
|
||||
ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
|
||||
LOG_WARN("can not do parallel ddl in recyclebin database" , KR(ret));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_database_schema(database_id, database_schema))) {
|
||||
LOG_WARN("fail to get database schema", KR(ret), K_(tenant_id), K(database_id), K(database_name));
|
||||
} else if (OB_ISNULL(database_schema)) {
|
||||
ret = OB_ERR_BAD_DATABASE;
|
||||
LOG_WARN("database not exist", KR(ret), K_(tenant_id), K(database_id), K(database_name));
|
||||
LOG_USER_ERROR(OB_ERR_BAD_DATABASE, database_name.length(), database_name.ptr());
|
||||
} else if (OB_UNLIKELY(database_schema->is_in_recyclebin())) {
|
||||
ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
|
||||
LOG_WARN("can not do parallel ddl on table in database which is in recyclebin",
|
||||
KR(ret), K_(tenant_id), K(database_id), K(database_name));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLHelper::check_parallel_ddl_conflict_(const common::ObIArray<share::schema::ObBasedSchemaObjectInfo> &based_schema_object_infos)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else {
|
||||
|
||||
ObArray<uint64_t> parent_table_ids;
|
||||
ObArray<uint64_t> mock_fk_parent_table_ids;
|
||||
ObSchemaGetterGuard local_guard;
|
||||
if (OB_FAIL(schema_service_->get_tenant_schema_guard(tenant_id_, local_guard))) {
|
||||
LOG_WARN("fail to get local guard", KR(ret), K_(tenant_id));
|
||||
}
|
||||
// check schema object infos are all existed.
|
||||
for (int64_t i = 0; OB_SUCC(ret) && (i < based_schema_object_infos.count()); ++i) {
|
||||
const ObBasedSchemaObjectInfo &info = based_schema_object_infos.at(i);
|
||||
if (MOCK_FK_PARENT_TABLE_SCHEMA == info.schema_type_) {
|
||||
if (!has_exist_in_array(mock_fk_parent_table_ids, info.schema_id_)
|
||||
&& OB_FAIL(mock_fk_parent_table_ids.push_back(info.schema_id_))) {
|
||||
LOG_WARN("fail to push back mock fk parent table id", KR(ret), K(info));
|
||||
}
|
||||
} else if (TABLE_SCHEMA == info.schema_type_) {
|
||||
if (!has_exist_in_array(parent_table_ids, info.schema_id_)
|
||||
&& OB_FAIL(parent_table_ids.push_back(info.schema_id_))) {
|
||||
LOG_WARN("fail to push back parent table id", KR(ret), K(info));
|
||||
}
|
||||
} else if (UDT_SCHEMA == info.schema_type_) {
|
||||
const uint64_t udt_id = info.schema_id_;
|
||||
const ObUDTTypeInfo *udt_info = NULL;
|
||||
const ObUDTTypeInfo *local_udt_info = nullptr;
|
||||
if (is_inner_object_id(udt_id) && !is_sys_tenant(tenant_id_)) {
|
||||
// can't add object lock across tenant, assumed that sys inner udt won't be changed.
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_udt_info(udt_id, udt_info))) {
|
||||
LOG_WARN("fail to get udt info", KR(ret), K_(tenant_id), K(udt_id), K(info));
|
||||
} else if (OB_ISNULL(udt_info)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("udt doesn't exist", KR(ret), K_(tenant_id), K(udt_id));
|
||||
} else if (udt_info->get_schema_version() != info.schema_version_) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("udt changed", KR(ret), K(info), KPC(udt_info));
|
||||
} else if (OB_FAIL(local_guard.get_udt_info(tenant_id_, udt_id, local_udt_info))) {
|
||||
LOG_WARN("fail to get local udt info", KR(ret), K_(tenant_id), K(udt_id), K(info));
|
||||
} else if (OB_ISNULL(local_udt_info)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("udt doesn't exist", KR(ret), K_(tenant_id), K(udt_id));
|
||||
} else if (local_udt_info->get_schema_version() != info.schema_version_) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("udt changed", KR(ret), K(info), KPC(local_udt_info));
|
||||
}
|
||||
} else {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("not supported schema type", KR(ret), K_(tenant_id), K(info));
|
||||
}
|
||||
}// end for
|
||||
|
||||
ObArray<ObSchemaIdVersion> parent_table_versions;
|
||||
if (OB_SUCC(ret) && parent_table_ids.count() > 0) {
|
||||
if (OB_FAIL(parent_table_versions.reserve(parent_table_ids.count()))) {
|
||||
LOG_WARN("fail to reserve array", KR(ret));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_table_schema_versions(
|
||||
parent_table_ids, parent_table_versions))) {
|
||||
LOG_WARN("fail to get table schema versions", KR(ret));
|
||||
} else if (parent_table_ids.count() != parent_table_versions.count()) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("parent table may be deleted, ddl need retry",
|
||||
KR(ret), K_(tenant_id), "base_objs_cnt", parent_table_ids.count(),
|
||||
"fetch_cnt", parent_table_versions.count());
|
||||
}
|
||||
}
|
||||
|
||||
ObArray<ObSchemaIdVersion> mock_fk_parent_table_versions;
|
||||
if (OB_SUCC(ret) && mock_fk_parent_table_ids.count() > 0) {
|
||||
if (OB_FAIL(mock_fk_parent_table_versions.reserve(mock_fk_parent_table_ids.count()))) {
|
||||
LOG_WARN("fail to reserve array", KR(ret));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_mock_fk_parent_table_schema_versions(
|
||||
mock_fk_parent_table_ids, mock_fk_parent_table_versions))) {
|
||||
LOG_WARN("fail to get table schema versions", KR(ret));
|
||||
} else if (mock_fk_parent_table_ids.count() != mock_fk_parent_table_versions.count()) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("mock fk parent table may be deleted, ddl need retry",
|
||||
KR(ret), K_(tenant_id), "base_objs_cnt", mock_fk_parent_table_ids.count(),
|
||||
"fetch_cnt", mock_fk_parent_table_versions.count());
|
||||
}
|
||||
}
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && (i < based_schema_object_infos.count()); ++i) {
|
||||
const ObBasedSchemaObjectInfo &info = based_schema_object_infos.at(i);
|
||||
if (MOCK_FK_PARENT_TABLE_SCHEMA == info.schema_type_
|
||||
|| TABLE_SCHEMA == info.schema_type_) {
|
||||
bool find = false;
|
||||
for (int64_t j = 0; OB_SUCC(ret) && !find && j < parent_table_versions.count(); j++) {
|
||||
const ObSchemaIdVersion &version = parent_table_versions.at(j);
|
||||
if (version.get_schema_id() == info.schema_id_) {
|
||||
find = true;
|
||||
if (version.get_schema_version() != info.schema_version_) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("parent table may be changed, ddl need retry",
|
||||
KR(ret), K_(tenant_id), K(info), K(version));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
for (int64_t j = 0; OB_SUCC(ret) && !find && j < mock_fk_parent_table_versions.count(); j++) {
|
||||
const ObSchemaIdVersion &version = mock_fk_parent_table_versions.at(j);
|
||||
if (version.get_schema_id() == info.schema_id_) {
|
||||
find = true;
|
||||
if (version.get_schema_version() != info.schema_version_) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("mock fk parent table may be changed, ddl need retry",
|
||||
KR(ret), K_(tenant_id), K(info), K(version));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
if (OB_SUCC(ret) && !find) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("parent table may be deleted, ddl need retry",
|
||||
KR(ret), K_(tenant_id), K(info));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLHelper::add_lock_table_udt_id_(const ObTableSchema &table_schema)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else {
|
||||
ObTableSchema::const_column_iterator begin = table_schema.column_begin();
|
||||
ObTableSchema::const_column_iterator end = table_schema.column_end();
|
||||
ObSchemaGetterGuard guard;
|
||||
if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, guard))) {
|
||||
LOG_WARN("fail to get schema guard", KR(ret));
|
||||
}
|
||||
for (; OB_SUCC(ret) && begin != end; begin++) {
|
||||
ObColumnSchemaV2 *col = (*begin);
|
||||
if (OB_ISNULL(col)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get column schema failed", KR(ret));
|
||||
} else if (col->is_extend()) {
|
||||
const uint64_t udt_id = col->get_sub_data_type();
|
||||
if (is_inner_object_id(udt_id) && !is_sys_tenant(tenant_id_)) {
|
||||
// can't add object lock across tenant, assumed that sys inner udt won't be changed.
|
||||
const ObUDTTypeInfo *udt_info = NULL;
|
||||
if (OB_FAIL(guard.get_udt_info(OB_SYS_TENANT_ID, udt_id, udt_info))) {
|
||||
LOG_WARN("fail to get udt info", KR(ret), K(udt_id));
|
||||
} else if (OB_ISNULL(udt_info)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("inner udt not found", KR(ret), K(udt_id));
|
||||
}
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(udt_id,
|
||||
share::schema::UDT_SCHEMA, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock udt id", KR(ret), K_(tenant_id), K(udt_id));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObDDLHelper::check_table_udt_exist_(const ObTableSchema &table_schema)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else {
|
||||
ObTableSchema::const_column_iterator begin = table_schema.column_begin();
|
||||
ObTableSchema::const_column_iterator end = table_schema.column_end();
|
||||
ObSchemaGetterGuard guard;
|
||||
ObSchemaGetterGuard local_guard;
|
||||
if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, guard))) {
|
||||
LOG_WARN("fail to get schema guard", KR(ret));
|
||||
} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(tenant_id_, local_guard))) {
|
||||
LOG_WARN("fail to get local guard", KR(ret), K_(tenant_id));
|
||||
}
|
||||
for (; OB_SUCC(ret) && begin != end; begin++) {
|
||||
ObColumnSchemaV2 *col = (*begin);
|
||||
if (OB_ISNULL(col)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get column schema failed", KR(ret));
|
||||
} else if (col->is_extend()) {
|
||||
const uint64_t udt_id = col->get_sub_data_type();
|
||||
const ObUDTTypeInfo *udt_info = NULL;
|
||||
const ObUDTTypeInfo *local_udt_info = nullptr;
|
||||
if (is_inner_object_id(udt_id) && !is_sys_tenant(tenant_id_)) {
|
||||
// can't add object lock across tenant, assumed that sys inner udt won't be changed.
|
||||
if (OB_FAIL(guard.get_udt_info(OB_SYS_TENANT_ID, udt_id, udt_info))) {
|
||||
LOG_WARN("fail to get udt info", KR(ret), K(udt_id));
|
||||
} else if (OB_ISNULL(udt_info)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("inner udt not found", KR(ret), K(udt_id));
|
||||
}
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_udt_info(udt_id, udt_info))) {
|
||||
LOG_WARN("fail to get udt info", KR(ret), K_(tenant_id), K(udt_id));
|
||||
} else if (OB_ISNULL(udt_info)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("udt doesn't exist", KR(ret), K_(tenant_id), K(udt_id));
|
||||
} else if (OB_FAIL(local_guard.get_udt_info(tenant_id_, udt_id, local_udt_info))) {
|
||||
LOG_WARN("fail to get udt info in local guard", KR(ret), K_(tenant_id), K(udt_id));
|
||||
} else if (OB_ISNULL(local_udt_info)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("udt doesn't exist in local guard", KR(ret), K_(tenant_id), K(udt_id));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -68,11 +68,28 @@ public:
|
||||
int init(rootserver::ObDDLService &ddl_service);
|
||||
|
||||
virtual int execute();
|
||||
static int obj_lock_database_name(
|
||||
ObDDLSQLTransaction &trans,
|
||||
const uint64_t tenant_id,
|
||||
const ObString &name,
|
||||
const transaction::tablelock::ObTableLockMode lock_mode);
|
||||
static int obj_lock_obj_name(
|
||||
ObDDLSQLTransaction &trans,
|
||||
const uint64_t tenant_id,
|
||||
const ObString &database_name,
|
||||
const ObString &obj_name,
|
||||
const transaction::tablelock::ObTableLockMode lock_mode);
|
||||
static int obj_lock_obj_id(
|
||||
ObDDLSQLTransaction &trans,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t obj_id,
|
||||
const transaction::tablelock::ObTableLockMode lock_mode);
|
||||
protected:
|
||||
virtual int check_inner_stat_();
|
||||
|
||||
/* main actions */
|
||||
int start_ddl_trans_();
|
||||
virtual int calc_schema_version_cnt_() = 0;
|
||||
int gen_task_id_and_schema_versions_();
|
||||
int serialize_inc_schema_dict_();
|
||||
int wait_ddl_trans_();
|
||||
@ -109,6 +126,11 @@ protected:
|
||||
const common::ObString &constraint_name,
|
||||
const bool is_foreign_key,
|
||||
bool &exist);
|
||||
int check_database_legitimacy_(const ObString &database_name, uint64_t &database_id);
|
||||
|
||||
int check_parallel_ddl_conflict_(const common::ObIArray<share::schema::ObBasedSchemaObjectInfo> &based_schema_object_infos);
|
||||
int add_lock_table_udt_id_(const ObTableSchema &table_schema);
|
||||
int check_table_udt_exist_(const ObTableSchema &table_schema);
|
||||
private:
|
||||
int add_lock_object_to_map_(
|
||||
const uint64_t lock_obj_id,
|
||||
@ -117,6 +139,14 @@ private:
|
||||
int lock_objects_in_map_(
|
||||
const transaction::tablelock::ObLockOBJType obj_type,
|
||||
ObjectLockMap &lock_map);
|
||||
static uint64_t cast_database_name_to_id_(const ObString &database_name);
|
||||
static uint64_t cast_obj_name_to_id_(const ObString &database_name, const ObString &obj_name);
|
||||
static int obj_lock_with_lock_id_(
|
||||
ObDDLSQLTransaction &trans,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t obj_id,
|
||||
const transaction::tablelock::ObTableLockMode lock_mode,
|
||||
const ObLockOBJType obj_type);
|
||||
protected:
|
||||
bool inited_;
|
||||
share::schema::ObMultiVersionSchemaService *schema_service_;
|
||||
|
@ -77,7 +77,7 @@ int ObIndexNameCache::check_index_name_exist(
|
||||
data_table_id = OB_INVALID_ID;
|
||||
} else {
|
||||
uint64_t data_table_id = ObSimpleTableSchemaV2::extract_data_table_id_from_index_name(index_name);
|
||||
if (OB_INVALID_ID == database_id) {
|
||||
if (OB_INVALID_ID == data_table_id) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid index name", KR(ret), K(index_name));
|
||||
} else if (OB_FAIL(ObSimpleTableSchemaV2::get_index_name(index_name, idx_name))) {
|
||||
|
392
src/rootserver/parallel_ddl/ob_set_comment_helper.cpp
Normal file
392
src/rootserver/parallel_ddl/ob_set_comment_helper.cpp
Normal file
@ -0,0 +1,392 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX RS
|
||||
#include "rootserver/parallel_ddl/ob_set_comment_helper.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
#include "share/schema/ob_table_sql_service.h"
|
||||
#include "share/schema/ob_multi_version_schema_service.h"
|
||||
#include "rootserver/ob_snapshot_info_manager.h"
|
||||
#include "storage/ddl/ob_ddl_lock.h"
|
||||
#include "share/ob_debug_sync.h"
|
||||
|
||||
using namespace oceanbase::lib;
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::share;
|
||||
using namespace oceanbase::share::schema;
|
||||
using namespace oceanbase::rootserver;
|
||||
|
||||
|
||||
ObSetCommentHelper::ObSetCommentHelper(
|
||||
share::schema::ObMultiVersionSchemaService *schema_service,
|
||||
const uint64_t tenant_id,
|
||||
const obrpc::ObSetCommentArg &arg,
|
||||
obrpc::ObParallelDDLRes &res)
|
||||
: ObDDLHelper(schema_service, tenant_id),
|
||||
arg_(arg),
|
||||
res_(res),
|
||||
database_id_(OB_INVALID_ID),
|
||||
table_id_(OB_INVALID_ID),
|
||||
orig_table_schema_(nullptr),
|
||||
new_table_schema_(nullptr),
|
||||
new_column_schemas_()
|
||||
{}
|
||||
|
||||
ObSetCommentHelper::~ObSetCommentHelper()
|
||||
{
|
||||
}
|
||||
|
||||
int ObSetCommentHelper::check_inner_stat_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(ObDDLHelper::check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (!arg_.is_valid()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("arg is invalid", KR(ret), K(arg_));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSetCommentHelper::execute()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
RS_TRACE(parallel_ddl_begin);
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(start_ddl_trans_())) {
|
||||
LOG_WARN("fail to start ddl trans", KR(ret));
|
||||
} else if (OB_FAIL(lock_objects_())) {
|
||||
LOG_WARN("fail to lock objects", KR(ret));
|
||||
} else if (OB_FAIL(check_table_legitimacy_())) {
|
||||
LOG_WARN("fail to check comment", KR(ret));
|
||||
} else if (OB_FAIL(generate_schemas_())) {
|
||||
LOG_WARN("fail to generate schemas", KR(ret));
|
||||
} else if (OB_FAIL(calc_schema_version_cnt_())) {
|
||||
LOG_WARN("fail to calc schema version cnt", KR(ret));
|
||||
} else if (OB_FAIL(gen_task_id_and_schema_versions_())) {
|
||||
LOG_WARN("fail to gen task id and schema versions", KR(ret));
|
||||
} else if (OB_FAIL(alter_schema_())) {
|
||||
LOG_WARN("fail to create schemas", KR(ret));
|
||||
} else if (OB_FAIL(serialize_inc_schema_dict_())) {
|
||||
LOG_WARN("fail to serialize inc schema dict", KR(ret));
|
||||
} else if (OB_FAIL(wait_ddl_trans_())) {
|
||||
LOG_WARN("fail to wait ddl trans", KR(ret));
|
||||
}
|
||||
if (OB_FAIL(end_ddl_trans_(ret))) { //won't overwrite ret
|
||||
LOG_WARN("fail to end ddl trans", KR(ret));
|
||||
} else {
|
||||
ObSchemaVersionGenerator *tsi_generator = GET_TSI(TSISchemaVersionGenerator);
|
||||
int64_t last_schema_version = OB_INVALID_VERSION;
|
||||
int64_t end_schema_version = OB_INVALID_VERSION;
|
||||
if (OB_ISNULL(tsi_generator)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("tsi generator is null", KR(ret));
|
||||
} else if (OB_FAIL(tsi_generator->get_current_version(last_schema_version))) {
|
||||
LOG_WARN("fail to get current version", KR(ret), K_(tenant_id), K_(arg));
|
||||
} else if (OB_FAIL(tsi_generator->get_end_version(end_schema_version))) {
|
||||
LOG_WARN("fail to get end version", KR(ret), K_(tenant_id), K_(arg));
|
||||
} else if (OB_UNLIKELY(last_schema_version != end_schema_version)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("too much schema versions may be allocated", KR(ret), KPC(tsi_generator));
|
||||
} else {
|
||||
res_.schema_version_ = last_schema_version;
|
||||
}
|
||||
}
|
||||
RS_TRACE(parallel_ddl_end);
|
||||
FORCE_PRINT_TRACE(THE_RS_TRACE, "[parallel set comment]");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSetCommentHelper::lock_objects_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
DEBUG_SYNC(BEFORE_PARALLEL_DDL_LOCK);
|
||||
const ObDatabaseSchema *database_schema = nullptr;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(lock_databases_by_obj_name_())) { // lock database name
|
||||
LOG_WARN("fail to lock databases by obj name", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(check_database_legitimacy_())) { // check database legitimacy
|
||||
LOG_WARN("fail to check database legitimacy", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(lock_objects_by_name_())) { // lock object name
|
||||
LOG_WARN("fail to lock objects by name", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(lock_objects_by_id_())) { // lock objects by id
|
||||
LOG_WARN("fail to lock objects by id" , KR(ret), K_(tenant_id));
|
||||
}
|
||||
DEBUG_SYNC(AFTER_PARALLEL_DDL_LOCK);
|
||||
RS_TRACE(lock_objects);
|
||||
if (FAILEDx(lock_for_common_ddl_())) { // online ddl lock & table lock
|
||||
LOG_WARN("fail to lock for common ddl", KR(ret));
|
||||
} else if (OB_UNLIKELY(database_id_ != orig_table_schema_->get_database_id())) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("database_id_ is not equal to table schema's databse_id",
|
||||
KR(ret), K_(database_id), K(orig_table_schema_->get_database_id()));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_database_schema(database_id_, database_schema))) {
|
||||
LOG_WARN("fail to get database schema", KR(ret), K_(tenant_id), K_(database_id));
|
||||
} else if (OB_ISNULL(database_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("databse_schema is null", KR(ret));
|
||||
} else if (OB_UNLIKELY(database_schema->get_database_name_str() != arg_.database_name_)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("database_schema's database name not equal to arg",
|
||||
KR(ret), K(database_schema->get_database_name_str()), K_(arg_.database_name));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Lock ddl related database by name
|
||||
// 1. database (S)
|
||||
// - to alter table
|
||||
int ObSetCommentHelper::lock_databases_by_obj_name_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else {
|
||||
const ObString &database_name = arg_.database_name_;
|
||||
if (OB_FAIL(add_lock_object_by_database_name_(database_name, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to add lock database by name", KR(ret), K_(tenant_id), K(database_name));
|
||||
} else if (OB_FAIL(lock_databases_by_name_())) {
|
||||
LOG_WARN("fail to lock databases by name", KR(ret), K_(tenant_id));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// check database not in recyclebin
|
||||
int ObSetCommentHelper::check_database_legitimacy_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObString &database_name = arg_.database_name_;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(ObDDLHelper::check_database_legitimacy_(database_name, database_id_))) {
|
||||
LOG_WARN("fail to check database legitimacy", KR(ret), K(database_name));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// lock table's name object lock (x)
|
||||
int ObSetCommentHelper::lock_objects_by_name_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObString &database_name = arg_.database_name_;
|
||||
const ObString &table_name = arg_.table_name_;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(add_lock_object_by_name_(database_name, table_name,
|
||||
share::schema::TABLE_SCHEMA, transaction::tablelock::EXCLUSIVE))) {
|
||||
LOG_WARN("fail to lock object by table name", KR(ret), K_(tenant_id), K(database_name), K(table_name));
|
||||
} else if (OB_FAIL(lock_existed_objects_by_name_())) {
|
||||
LOG_WARN("fail to lock objects by name", KR(ret), K_(tenant_id));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// lock table' id for comment (x)
|
||||
int ObSetCommentHelper::lock_objects_by_id_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTableType table_type;
|
||||
int64_t schema_version = OB_INVALID_VERSION;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_ID == database_id_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("database is not exist", KR(ret), K_(tenant_id), K_(arg_.database_name));
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(database_id_,
|
||||
share::schema::DATABASE_SCHEMA, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock database id", KR(ret), K_(database_id));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_table_id(database_id_, arg_.session_id_, arg_.table_name_, table_id_, table_type, schema_version))) {
|
||||
LOG_WARN("fail to get table id", KR(ret), K_(database_id), K_(arg_.session_id), K_(arg_.table_name));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_ID == table_id_)) {
|
||||
ret = OB_ERR_OBJECT_NOT_EXIST;
|
||||
LOG_WARN("table not exist", KR(ret), K_(database_id), K_(arg_.session_id), K_(arg_.table_name));
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(table_id_,
|
||||
share::schema::TABLE_SCHEMA, transaction::tablelock::EXCLUSIVE))) {
|
||||
LOG_WARN("fail to lock table id", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(lock_existed_objects_by_id_())) {
|
||||
LOG_WARN("fail to lock objects by id", KR(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSetCommentHelper::check_table_legitimacy_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_oracle_mode = false;
|
||||
int64_t schema_version = OB_INVALID_VERSION;
|
||||
bool is_exist = false;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_ISNULL(orig_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("orig_table_schema_ is nullptr", KR(ret), K_(table_id));
|
||||
} else if (OB_UNLIKELY(orig_table_schema_->is_materialized_view())) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("alter materialized view is not supported", KR(ret));
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter materialized view is");
|
||||
} else if (OB_UNLIKELY(orig_table_schema_->is_ctas_tmp_table())) {
|
||||
ret = OB_ERR_WRONG_OBJECT;
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_OBJECT,
|
||||
to_cstring(arg_.database_name_), to_cstring(arg_.table_name_), "BASE TABLE");
|
||||
} else if (OB_UNLIKELY((!orig_table_schema_->is_user_table()
|
||||
&& !orig_table_schema_->is_tmp_table()
|
||||
&& !orig_table_schema_->is_view_table()
|
||||
&& !orig_table_schema_->is_external_table()))) {
|
||||
ret = OB_ERR_WRONG_OBJECT;
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_OBJECT,
|
||||
to_cstring(arg_.database_name_), to_cstring(arg_.table_name_), "BASE TABLE");
|
||||
} else if (OB_UNLIKELY(orig_table_schema_->is_sys_view() && !GCONF.enable_sys_table_ddl)) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("comment on sys view is not allowed", KR(ret), K(orig_table_schema_->get_table_id()));
|
||||
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "alter system view");
|
||||
} else if (OB_UNLIKELY(orig_table_schema_->is_in_recyclebin())) {
|
||||
ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT;
|
||||
LOG_WARN("can not comment table in recyclebin", KR(ret), K(orig_table_schema_->is_in_recyclebin()));
|
||||
} else if (OB_UNLIKELY(orig_table_schema_->is_in_splitting())) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("table is physical or logical split can not split", KR(ret), KPC(orig_table_schema_));
|
||||
} else if (OB_FAIL(orig_table_schema_->check_if_oracle_compat_mode(is_oracle_mode))) {
|
||||
LOG_WARN("fail to check oracle compat mode", KR(ret));
|
||||
} else if (OB_UNLIKELY(!is_oracle_mode)) {
|
||||
// if need to support parallel comment on mysql mode,
|
||||
// should check column name not duplicate to prevent modify the same column in one sql
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("not support parallel comment on mysql mode right know", KR(ret));
|
||||
} else if (OB_FAIL(ddl_service_->get_snapshot_mgr().check_restore_point(
|
||||
ddl_service_->get_sql_proxy(), tenant_id_, orig_table_schema_->get_table_id(), is_exist))) {
|
||||
LOG_WARN("failed to check restore point", KR(ret), K_(tenant_id));
|
||||
} else if (OB_UNLIKELY(is_exist)) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("restore point exist, cannot alter ", KR(ret), K_(tenant_id), K(orig_table_schema_->get_table_id()));
|
||||
}
|
||||
RS_TRACE(check_schemas);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// here get the table schema before lock it. it is rely on mutex between parallel ddl and serial ddl
|
||||
int ObSetCommentHelper::lock_for_common_ddl_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t schema_version = OB_INVALID_VERSION;
|
||||
uint64_t tenant_data_version = 0;
|
||||
if (OB_UNLIKELY(OB_INVALID_ID == database_id_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("database is not exist", KR(ret), K_(tenant_id), K_(arg_.database_name));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_ID == table_id_)) {
|
||||
ret = OB_ERR_OBJECT_NOT_EXIST;
|
||||
LOG_WARN("table not exist", KR(ret), K_(database_id), K_(arg_.session_id), K_(arg_.table_name));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_table_schema(table_id_, orig_table_schema_))) {
|
||||
LOG_WARN("fail to get orig table schema", KR(ret), K_(table_id));
|
||||
} else if (OB_ISNULL(orig_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("orig_table_schema_ is nullptr", KR(ret), K_(table_id));
|
||||
} else if (OB_UNLIKELY(!orig_table_schema_->check_can_do_ddl())) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("offline ddl is being executed, other ddl operations are not allowed", KR(ret), KP(orig_table_schema_));
|
||||
} else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id_, tenant_data_version))) {
|
||||
LOG_WARN("get min data version failed", KR(ret), K_(tenant_id));
|
||||
} else {
|
||||
if (OB_FAIL(ObDDLLock::lock_for_common_ddl_in_trans(*orig_table_schema_, false/*require_strict_binary_format*/,trans_))) {
|
||||
LOG_WARN("fail to lock for common ddl", KR(ret));
|
||||
}
|
||||
}
|
||||
RS_TRACE(lock_common_ddl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSetCommentHelper::generate_schemas_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_ISNULL(orig_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("orig table schema is nullptr", KR(ret));
|
||||
} else if (OB_FAIL(ObSchemaUtils::alloc_schema(allocator_, *orig_table_schema_, new_table_schema_))) {
|
||||
LOG_WARN("fail to alloc schema", KR(ret));
|
||||
} else {
|
||||
if (obrpc::ObSetCommentArg::COMMENT_TABLE == arg_.op_type_) {
|
||||
if (OB_FAIL(new_table_schema_->set_comment(arg_.table_comment_))) {
|
||||
LOG_WARN("fail to set table comment", KR(ret));
|
||||
}
|
||||
} else if (obrpc::ObSetCommentArg::COMMENT_COLUMN == arg_.op_type_) {
|
||||
for (uint64_t column_idx = 0; OB_SUCC(ret) && column_idx < arg_.column_name_list_.size(); column_idx++) {
|
||||
const ObString &orig_column_name = arg_.column_name_list_.at(column_idx);
|
||||
ObColumnSchemaV2 *new_column_schema = nullptr;
|
||||
new_column_schema = new_table_schema_->get_column_schema(orig_column_name);
|
||||
if (OB_ISNULL(new_column_schema)) {
|
||||
ret = OB_ERR_BAD_FIELD_ERROR;
|
||||
LOG_USER_ERROR(OB_ERR_BAD_FIELD_ERROR, orig_column_name.length(), orig_column_name.ptr(),
|
||||
orig_table_schema_->get_table_name_str().length(),
|
||||
orig_table_schema_->get_table_name_str().ptr());
|
||||
LOG_WARN("failed to find old column schema", KR(ret), K(orig_column_name));
|
||||
} else if (FALSE_IT(new_column_schema->set_comment(arg_.column_comment_list_.at(column_idx)))){
|
||||
} else if (OB_FAIL(new_column_schemas_.push_back(new_column_schema))) {
|
||||
LOG_WARN("fail to assign column schema", KR(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RS_TRACE(generate_schemas);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSetCommentHelper::calc_schema_version_cnt_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else {
|
||||
// 0. data table
|
||||
// for now just one comment at a once
|
||||
schema_version_cnt_ = 1;
|
||||
// 1503
|
||||
schema_version_cnt_++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSetCommentHelper::alter_schema_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const int64_t start_ts = ObTimeUtility::current_time();
|
||||
ObSchemaService *schema_service_impl = nullptr;
|
||||
int64_t new_schema_version = OB_INVALID_VERSION;
|
||||
const ObString *ddl_stmt_str = &arg_.ddl_stmt_str_;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_ISNULL(schema_service_impl = schema_service_->get_schema_service())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("schema_service impl is null", KR(ret));
|
||||
} else if (OB_FAIL(schema_service_->gen_new_schema_version(tenant_id_, new_schema_version))) {
|
||||
LOG_WARN("fail to gen new schema version", KR(ret), K_(tenant_id));
|
||||
} else {
|
||||
for (uint64_t column_idx = 0; OB_SUCC(ret) && column_idx < arg_.column_name_list_.size(); column_idx++) {
|
||||
new_column_schemas_.at(column_idx)->set_schema_version(new_schema_version);
|
||||
if (OB_FAIL(schema_service_impl->get_table_sql_service().update_single_column(
|
||||
trans_, *orig_table_schema_, *new_table_schema_, *new_column_schemas_.at(column_idx), false /* record ddl operation*/))) {
|
||||
LOG_WARN("fail to update single column", KR(ret));
|
||||
}
|
||||
}
|
||||
new_table_schema_->set_schema_version(new_schema_version);
|
||||
if (FAILEDx(schema_service_impl->get_table_sql_service().only_update_table_options(
|
||||
trans_,
|
||||
*new_table_schema_,
|
||||
OB_DDL_ALTER_TABLE,
|
||||
ddl_stmt_str))) {
|
||||
LOG_WARN("fail to alter table option", KR(ret));
|
||||
}
|
||||
}
|
||||
RS_TRACE(alter_schemas);
|
||||
return ret;
|
||||
}
|
72
src/rootserver/parallel_ddl/ob_set_comment_helper.h
Normal file
72
src/rootserver/parallel_ddl/ob_set_comment_helper.h
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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_ROOTSERVER_OB_COMMENT_H_
|
||||
#define OCEANBASE_ROOTSERVER_OB_COMMENT_H_
|
||||
|
||||
#include "rootserver/parallel_ddl/ob_ddl_helper.h"
|
||||
#include "lib/hash/ob_hashmap.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace share
|
||||
{
|
||||
namespace schema
|
||||
{
|
||||
class ObMultiVersionSchemaService;
|
||||
}
|
||||
}
|
||||
namespace obrpc
|
||||
{
|
||||
class ObSetCommentArg;
|
||||
class ObSetCommenttRes;
|
||||
}
|
||||
namespace rootserver
|
||||
{
|
||||
class ObSetCommentHelper : public ObDDLHelper
|
||||
{
|
||||
public:
|
||||
ObSetCommentHelper(
|
||||
share::schema::ObMultiVersionSchemaService *schema_service,
|
||||
const uint64_t tenant_id,
|
||||
const obrpc::ObSetCommentArg &arg,
|
||||
obrpc::ObParallelDDLRes &res);
|
||||
virtual ~ObSetCommentHelper();
|
||||
virtual int execute() override;
|
||||
private:
|
||||
virtual int check_inner_stat_() override;
|
||||
int lock_objects_();
|
||||
int check_database_legitimacy_();
|
||||
int generate_schemas_();
|
||||
virtual int calc_schema_version_cnt_() override;
|
||||
int alter_schema_();
|
||||
int lock_databases_by_obj_name_();
|
||||
int lock_objects_by_id_();
|
||||
int lock_objects_by_name_();
|
||||
int lock_for_common_ddl_();
|
||||
int check_table_legitimacy_();
|
||||
private:
|
||||
const obrpc::ObSetCommentArg &arg_;
|
||||
obrpc::ObParallelDDLRes &res_;
|
||||
uint64_t database_id_;
|
||||
uint64_t table_id_;
|
||||
const ObTableSchema* orig_table_schema_;
|
||||
ObTableSchema* new_table_schema_;
|
||||
common::ObSArray<ObColumnSchemaV2*> new_column_schemas_;
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObSetCommentHelper);
|
||||
|
||||
};
|
||||
|
||||
} // end namespace rootserver
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif//OCEANBASE_ROOTSERVER_OB_COMMENT_H_
|
262
src/rootserver/parallel_ddl/ob_update_index_status_helper.cpp
Normal file
262
src/rootserver/parallel_ddl/ob_update_index_status_helper.cpp
Normal file
@ -0,0 +1,262 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
#define USING_LOG_PREFIX RS
|
||||
|
||||
#include "rootserver/parallel_ddl/ob_update_index_status_helper.h"
|
||||
#include "share/schema/ob_table_sql_service.h"
|
||||
#include "src/storage/ddl/ob_ddl_lock.h"
|
||||
|
||||
using namespace oceanbase::lib;
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::share;
|
||||
using namespace oceanbase::share::schema;
|
||||
using namespace oceanbase::rootserver;
|
||||
|
||||
ObUpdateIndexStatusHelper::ObUpdateIndexStatusHelper(
|
||||
share::schema::ObMultiVersionSchemaService *schema_service,
|
||||
const uint64_t tenant_id,
|
||||
const obrpc::ObUpdateIndexStatusArg &arg,
|
||||
obrpc::ObParallelDDLRes &res)
|
||||
: ObDDLHelper(schema_service, tenant_id),
|
||||
arg_(arg),
|
||||
res_(res),
|
||||
orig_index_table_schema_(nullptr),
|
||||
new_data_table_schema_(nullptr),
|
||||
new_status_(arg_.status_),
|
||||
index_table_exist_(true),
|
||||
database_id_(OB_INVALID_ID)
|
||||
{}
|
||||
|
||||
ObUpdateIndexStatusHelper::~ObUpdateIndexStatusHelper()
|
||||
{
|
||||
}
|
||||
int ObUpdateIndexStatusHelper::execute()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
RS_TRACE(parallel_ddl_begin);
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(start_ddl_trans_())) {
|
||||
LOG_WARN("fail to start ddl trans", KR(ret));
|
||||
} else if (OB_FAIL(lock_objects_())) {
|
||||
LOG_WARN("fail to lock objects", KR(ret));
|
||||
} else if (OB_FAIL(check_and_set_schema_())) {
|
||||
LOG_WARN("fail to check update status", KR(ret));
|
||||
} else if (OB_FAIL(calc_schema_version_cnt_())) {
|
||||
LOG_WARN("fail to calc schema version cnt");
|
||||
} else if (OB_FAIL(gen_task_id_and_schema_versions_())) {
|
||||
LOG_WARN("fail to gen task id and schema versions");
|
||||
} else if (OB_FAIL(update_status_())) {
|
||||
LOG_WARN("fail to update status", KR(ret));
|
||||
} else if (OB_FAIL(serialize_inc_schema_dict_())) {
|
||||
LOG_WARN("fail to serialize inc schema dict", KR(ret));
|
||||
} else if (OB_FAIL(wait_ddl_trans_())) {
|
||||
LOG_WARN("fail to wait ddl trans", KR(ret));
|
||||
}
|
||||
|
||||
if (OB_FAIL(end_ddl_trans_(ret))) { // won't lose err code
|
||||
//overwrite ret
|
||||
LOG_WARN("fail to end ddl trans", KR(ret));
|
||||
} else {
|
||||
ObSchemaVersionGenerator *tsi_generator = GET_TSI(TSISchemaVersionGenerator);
|
||||
int64_t last_schema_version = OB_INVALID_VERSION;
|
||||
int64_t end_schema_version = OB_INVALID_VERSION;
|
||||
if (OB_ISNULL(tsi_generator)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("tsi schema version generator is null", KR(ret));
|
||||
} else if (OB_FAIL(tsi_generator->get_current_version(last_schema_version))) {
|
||||
LOG_WARN("fail to get current version", KR(ret), K_(tenant_id), K_(arg));
|
||||
} else if (OB_FAIL(tsi_generator->get_end_version(end_schema_version))) {
|
||||
LOG_WARN("fail to get end version", KR(ret), K_(tenant_id), K_(arg));
|
||||
} else if (OB_UNLIKELY(last_schema_version != end_schema_version)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("too much schema versions may be allocated", KR(ret), KPC(tsi_generator));
|
||||
} else {
|
||||
res_.schema_version_ = end_schema_version;
|
||||
}
|
||||
}
|
||||
if (!index_table_exist_) {
|
||||
// regard as the index table has been dropped and scheduler will clean up the task record in success state.
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
RS_TRACE(parallel_ddl_end);
|
||||
FORCE_PRINT_TRACE(THE_RS_TRACE, "[parallel update index status]");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObUpdateIndexStatusHelper::lock_objects_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(lock_database_by_obj_name_())) {
|
||||
LOG_WARN("fail to lock databse by obj name", KR(ret));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_database_id(arg_.database_name_, database_id_))) {
|
||||
LOG_WARN("fail to get database id", KR(ret), K_(tenant_id), K_(arg_.database_name));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_ID == database_id_)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("invalid database_id, database name may changed", KR(ret), K_(tenant_id), K_(arg_.database_name));
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(database_id_,
|
||||
share::schema::DATABASE_SCHEMA, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock database id", KR(ret), K_(database_id));
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(arg_.data_table_id_,
|
||||
share::schema::TABLE_SCHEMA, transaction::tablelock::EXCLUSIVE))) {
|
||||
LOG_WARN("fail to lock data table", KR(ret), K_(arg_.data_table_id));
|
||||
} else if (OB_FAIL(add_lock_object_by_id_(arg_.index_table_id_,
|
||||
share::schema::TABLE_SCHEMA, transaction::tablelock::EXCLUSIVE))) {
|
||||
LOG_WARN("fail to lock index table id", KR(ret), K_(arg_.index_table_id));
|
||||
} else if (OB_FAIL(lock_existed_objects_by_id_())) {
|
||||
LOG_WARN("fail to lock objects by id", KR(ret));
|
||||
}
|
||||
RS_TRACE(lock_objects);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObUpdateIndexStatusHelper::lock_database_by_obj_name_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObString &database_name = arg_.database_name_;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_FAIL(add_lock_object_by_database_name_(database_name, transaction::tablelock::SHARE))) {
|
||||
LOG_WARN("fail to lock database by name", KR(ret), K_(tenant_id), K(database_name));
|
||||
} else if (OB_FAIL(lock_databases_by_name_())) {
|
||||
LOG_WARN("fail to lock databases by name", KR(ret), K_(tenant_id));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObUpdateIndexStatusHelper::check_and_set_schema_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObTableSchema *orig_data_table_schema = nullptr;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (INDEX_STATUS_INDEX_ERROR == new_status_ && arg_.convert_status_) {
|
||||
const ObTenantSchema *tenant_schema = nullptr;
|
||||
if (OB_FAIL(latest_schema_guard_.get_tenant_schema(tenant_id_, tenant_schema))) {
|
||||
LOG_WARN("fail to get tenant schema", KR(ret));
|
||||
} else if (OB_ISNULL(tenant_schema)) {
|
||||
ret = OB_TENANT_NOT_EXIST;
|
||||
LOG_WARN("tenant not exist", KR(ret), K_(tenant_id));
|
||||
} else if (tenant_schema->is_restore()) {
|
||||
new_status_ = INDEX_STATUS_RESTORE_INDEX_ERROR;
|
||||
LOG_INFO("conver error index status", KR(ret), K_(new_status));
|
||||
}
|
||||
}
|
||||
const ObDatabaseSchema *database_schema = NULL;
|
||||
if (FAILEDx(latest_schema_guard_.get_table_schema(arg_.index_table_id_, orig_index_table_schema_))) {
|
||||
LOG_WARN("fail to get index table schema", KR(ret), K_(arg_.index_table_id));
|
||||
} else if (OB_ISNULL(orig_index_table_schema_)) {
|
||||
ret = OB_ERR_OBJECT_NOT_EXIST;
|
||||
index_table_exist_ = false;
|
||||
LOG_WARN("index table schema is null, may be droped", KR(ret), K_(arg_.index_table_id));
|
||||
} else if (OB_UNLIKELY(database_id_ != orig_index_table_schema_->get_database_id())) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("databse_id_ is not euqal to index_table's database_id",
|
||||
KR(ret), K_(database_id), K(orig_index_table_schema_->get_database_id()));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_database_schema(database_id_, database_schema))) {
|
||||
LOG_WARN("fail to get database schema", KR(ret), K_(tenant_id), K_(database_id));
|
||||
} else if (OB_ISNULL(database_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("databse_schema is null", KR(ret));
|
||||
} else if (OB_UNLIKELY(database_schema->get_database_name_str() != arg_.database_name_)) {
|
||||
ret = OB_ERR_PARALLEL_DDL_CONFLICT;
|
||||
LOG_WARN("database_schema's database name not equal to arg",
|
||||
KR(ret), K(database_schema->get_database_name_str()), K_(arg_.database_name));
|
||||
} else if (is_available_index_status(new_status_) && !orig_index_table_schema_->is_unavailable_index()) {
|
||||
ret = OB_EAGAIN;
|
||||
LOG_WARN("set index status to available, but previous status is not unavailable, which is not expected", KR(ret));
|
||||
} else if (OB_FAIL(latest_schema_guard_.get_table_schema(arg_.data_table_id_, orig_data_table_schema))) {
|
||||
LOG_WARN("fail to get data table schema", KR(ret), K_(arg_.data_table_id));
|
||||
} else if (OB_ISNULL(orig_data_table_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail data table is null", KR(ret));
|
||||
} else if (OB_FAIL(ObSchemaUtils::alloc_schema(allocator_, *orig_data_table_schema, new_data_table_schema_))) {
|
||||
LOG_WARN("fail to alloc new table schema", KR(ret));
|
||||
} else {
|
||||
new_data_table_schema_->set_in_offline_ddl_white_list(arg_.in_offline_ddl_white_list_);
|
||||
}
|
||||
RS_TRACE(check_schemas);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObUpdateIndexStatusHelper::calc_schema_version_cnt_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else {
|
||||
// update index status
|
||||
schema_version_cnt_ = 1;
|
||||
// update data table schema version
|
||||
schema_version_cnt_++;
|
||||
// 1503
|
||||
schema_version_cnt_++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObUpdateIndexStatusHelper::update_status_()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t new_schema_version = OB_INVALID_VERSION;
|
||||
ObSchemaService *schema_service = schema_service_->get_schema_service();
|
||||
const ObString *ddl_stmt_str = arg_.ddl_stmt_str_.empty() ? nullptr : &arg_.ddl_stmt_str_;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_ISNULL(schema_service)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("schema service is nullptr", KR(ret));
|
||||
} else if (OB_ISNULL(orig_index_table_schema_)
|
||||
|| OB_ISNULL(new_data_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("table schema is null", KR(ret), KP(orig_index_table_schema_), KP(new_data_table_schema_));
|
||||
} else {
|
||||
ObSchemaService *schema_service = schema_service_->get_schema_service();
|
||||
if (OB_ISNULL(schema_service)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("schema service is nullptr", KR(ret));
|
||||
} else if (OB_FAIL(schema_service_->gen_new_schema_version(tenant_id_, new_schema_version))) {
|
||||
LOG_WARN("fail to gen new schema version", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(schema_service->get_table_sql_service().update_index_status(
|
||||
*new_data_table_schema_, arg_.index_table_id_, new_status_, new_schema_version, trans_, ddl_stmt_str))) {
|
||||
LOG_WARN("fail to update index status", KR(ret), K_(arg_.index_table_id), K_(arg_.data_table_id), K_(new_status));
|
||||
} else if (arg_.task_id_ != 0) {
|
||||
ObSchemaVersionGenerator *tsi_generator = GET_TSI(TSISchemaVersionGenerator);
|
||||
int64_t consensus_schema_version = OB_INVALID_VERSION;
|
||||
if (OB_FAIL(tsi_generator->get_end_version(consensus_schema_version))) {
|
||||
LOG_WARN("fail to get end version", KR(ret), K_(tenant_id), K_(arg));
|
||||
} else if (OB_FAIL(ObDDLTaskRecordOperator::update_consensus_schema_version(
|
||||
trans_, tenant_id_, arg_.task_id_, consensus_schema_version))) {
|
||||
LOG_WARN("fail to update consensus_schema_version", KR(ret), K_(tenant_id), K_(arg_.task_id), K(consensus_schema_version));
|
||||
} else if (orig_index_table_schema_->get_index_status() != new_status_ && new_status_ == INDEX_STATUS_AVAILABLE) {
|
||||
ObTableLockOwnerID owner_id;
|
||||
if (OB_ISNULL(new_data_table_schema_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("data_table_schema is null", KR(ret));
|
||||
} else if (OB_FAIL(owner_id.convert_from_value(ObLockOwnerType::DEFAULT_OWNER_TYPE,
|
||||
arg_.task_id_))) {
|
||||
LOG_WARN("failed to get owner id", K(ret), K_(arg_.task_id));
|
||||
} else if (OB_FAIL(ObDDLLock::unlock_for_add_drop_index(*new_data_table_schema_,
|
||||
orig_index_table_schema_->get_table_id(),
|
||||
orig_index_table_schema_->is_global_index_table(),
|
||||
owner_id,
|
||||
trans_))) {
|
||||
LOG_WARN("failed to unlock ddl lock", KR(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RS_TRACE(alter_schemas);
|
||||
return ret;
|
||||
}
|
60
src/rootserver/parallel_ddl/ob_update_index_status_helper.h
Normal file
60
src/rootserver/parallel_ddl/ob_update_index_status_helper.h
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 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_ROOTSERVER_OB_UPDATE_INDEX_STATUS_HELPER_H_
|
||||
#define OCEANBASE_ROOTSERVER_OB_UPDATE_INDEX_STATUS_HELPER_H_
|
||||
|
||||
#include "rootserver/parallel_ddl/ob_ddl_helper.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace share
|
||||
{
|
||||
namespace schema
|
||||
{
|
||||
class ObMultiVersionSchemaService;
|
||||
}
|
||||
}
|
||||
namespace obrpc
|
||||
{
|
||||
class ObUpdateIndexStatusArg;
|
||||
}
|
||||
namespace rootserver
|
||||
{
|
||||
class ObUpdateIndexStatusHelper : public ObDDLHelper
|
||||
{
|
||||
public:
|
||||
ObUpdateIndexStatusHelper(
|
||||
share::schema::ObMultiVersionSchemaService *schema_service,
|
||||
const uint64_t tenant_id,
|
||||
const obrpc::ObUpdateIndexStatusArg &arg,
|
||||
obrpc::ObParallelDDLRes &res);
|
||||
virtual ~ObUpdateIndexStatusHelper();
|
||||
virtual int execute() override;
|
||||
private:
|
||||
int lock_objects_();
|
||||
int check_and_set_schema_();
|
||||
int calc_schema_version_cnt_();
|
||||
int update_status_();
|
||||
int lock_database_by_obj_name_();
|
||||
private:
|
||||
const obrpc::ObUpdateIndexStatusArg &arg_;
|
||||
obrpc::ObParallelDDLRes &res_;
|
||||
const ObTableSchema *orig_index_table_schema_;
|
||||
ObTableSchema* new_data_table_schema_;
|
||||
share::schema::ObIndexStatus new_status_;
|
||||
bool index_table_exist_;
|
||||
uint64_t database_id_;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
@ -67,6 +67,7 @@ public:
|
||||
RPC_S(PRD recover_restore_table_ddl, obrpc::OB_RECOVER_RESTORE_TABLE_DDL, (ObRecoverRestoreTableDDLArg));
|
||||
RPC_S(PRD parallel_create_table, obrpc::OB_PARALLEL_CREATE_TABLE, (ObCreateTableArg), ObCreateTableRes);
|
||||
RPC_S(PRD alter_table, obrpc::OB_ALTER_TABLE, (ObAlterTableArg), ObAlterTableRes);
|
||||
RPC_S(PRD set_comment, obrpc::OB_PARALLEL_SET_COMMENT, (ObSetCommentArg), ObParallelDDLRes);
|
||||
RPC_S(PRD split_global_index_tablet, obrpc::OB_SPLIT_GLOBAL_INDEX_TABLET, (ObAlterTableArg));
|
||||
RPC_S(PRD create_hidden_table, obrpc::OB_CREATE_HIDDEN_TABLE, (obrpc::ObCreateHiddenTableArg), ObCreateHiddenTableRes);
|
||||
RPC_S(PRD alter_database, obrpc::OB_ALTER_DATABASE, (ObAlterDatabaseArg));
|
||||
@ -79,6 +80,7 @@ public:
|
||||
RPC_S(PRD truncate_table_v2, obrpc::OB_TRUNCATE_TABLE_V2, (ObTruncateTableArg), ObDDLRes);
|
||||
RPC_S(PRD create_aux_index, obrpc::OB_CREATE_AUX_INDEX, (obrpc::ObCreateAuxIndexArg), obrpc::ObCreateAuxIndexRes);
|
||||
RPC_S(PRD create_index, obrpc::OB_CREATE_INDEX, (ObCreateIndexArg), ObAlterTableRes);
|
||||
RPC_S(PRD parallel_create_index, obrpc::OB_PARALLEL_CREATE_INDEX, (ObCreateIndexArg), ObAlterTableRes);
|
||||
RPC_S(PRD drop_index, obrpc::OB_DROP_INDEX, (ObDropIndexArg), ObDropIndexRes);
|
||||
RPC_S(PRD drop_index_on_failed, obrpc::OB_DROP_INDEX_ON_FAILED, (ObDropIndexArg), ObDropIndexRes);
|
||||
RPC_S(PRD rebuild_vec_index, obrpc::OB_REBUILD_VEC_INDEX, (ObRebuildIndexArg), ObAlterTableRes);
|
||||
@ -208,6 +210,7 @@ public:
|
||||
RPC_S(PRD alter_resource_tenant, obrpc::OB_ALTER_RESOURCE_TENANT, (ObAlterResourceTenantArg));
|
||||
RPC_S(PRD update_index_status, obrpc::OB_UPDATE_INDEX_TABLE_STATUS, (ObUpdateIndexStatusArg));
|
||||
RPC_S(PRD update_mview_status, obrpc::OB_UPDATE_MVIEW_TABLE_STATUS, (ObUpdateMViewStatusArg));
|
||||
RPC_S(PRD parallel_update_index_status, obrpc::OB_PARALLEL_UPDATE_INDEX_STATUS, (ObUpdateIndexStatusArg), ObParallelDDLRes);
|
||||
|
||||
// define system admin rpc (alter system ...)
|
||||
RPC_S(PR5 root_minor_freeze, obrpc::OB_ROOT_MINOR_FREEZE, (ObRootMinorFreezeArg));
|
||||
|
@ -48,7 +48,8 @@ int ObDDLErrorMessageTableOperator::ObBuildDDLErrorMessage::prepare_user_message
|
||||
bool ObDDLErrorMessageTableOperator::ObBuildDDLErrorMessage::operator==(const ObBuildDDLErrorMessage &other) const
|
||||
{
|
||||
bool equal = ret_code_ == other.ret_code_ && ddl_type_ == other.ddl_type_
|
||||
&& 0 == STRNCMP(dba_message_, other.dba_message_, OB_MAX_ERROR_MSG_LEN);
|
||||
&& consensus_schema_version_ == other.consensus_schema_version_
|
||||
&& 0 == STRNCMP(dba_message_, other.dba_message_, OB_MAX_ERROR_MSG_LEN);
|
||||
if (equal) {
|
||||
if (nullptr == user_message_ && nullptr == other.user_message_) {
|
||||
} else if (nullptr == user_message_ || nullptr == other.user_message_) {
|
||||
@ -219,6 +220,7 @@ int ObDDLErrorMessageTableOperator::get_ddl_error_message(
|
||||
int ret = OB_SUCCESS;
|
||||
ObSqlString sql;
|
||||
forward_user_msg_len = 0;
|
||||
uint64_t tenant_data_version = 0;
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
|
||||
const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id);
|
||||
sqlclient::ObMySQLResult *result = NULL;
|
||||
@ -226,18 +228,24 @@ int ObDDLErrorMessageTableOperator::get_ddl_error_message(
|
||||
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || task_id <= 0 || target_object_id < -1)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arguments", K(ret), K(tenant_id), K(task_id), K(target_object_id), K(addr));
|
||||
} else if (!is_ddl_retry_task && OB_FAIL(sql.assign_fmt(
|
||||
"SELECT ret_code, ddl_type, affected_rows, dba_message, user_message from %s "
|
||||
"WHERE tenant_id = %ld AND task_id = %ld AND target_object_id = %ld "
|
||||
, OB_ALL_DDL_ERROR_MESSAGE_TNAME,
|
||||
ObSchemaUtils::get_extract_tenant_id(exec_tenant_id, tenant_id), task_id, target_object_id))) {
|
||||
LOG_WARN("fail to assign sql", K(ret));
|
||||
} else if (is_ddl_retry_task && OB_FAIL(sql.assign_fmt(
|
||||
"SELECT ret_code, ddl_type, affected_rows, dba_message, UNHEX(user_message) as user_message from %s "
|
||||
"WHERE tenant_id = %ld AND task_id = %ld AND target_object_id = %ld "
|
||||
, OB_ALL_DDL_ERROR_MESSAGE_TNAME,
|
||||
ObSchemaUtils::get_extract_tenant_id(exec_tenant_id, tenant_id), task_id, target_object_id))) {
|
||||
LOG_WARN("fail to assign sql", K(ret));
|
||||
} else if (OB_FAIL(sql.append("SELECT ret_code, ddl_type, affected_rows, dba_message "))) {
|
||||
LOG_WARN("fail to append sql", KR(ret));
|
||||
} else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, tenant_data_version))) {
|
||||
LOG_WARN("get tenant data version failed", KR(ret), K(tenant_id));
|
||||
} else if (((tenant_data_version >= DATA_VERSION_4_2_2_0 && tenant_data_version < DATA_VERSION_4_3_0_0)
|
||||
|| (tenant_data_version >= DATA_VERSION_4_3_5_0))
|
||||
&& OB_FAIL(sql.append(" ,consensus_schema_version "))) {
|
||||
LOG_WARN("fail to append sql", KR(ret));
|
||||
} else if (!is_ddl_retry_task && OB_FAIL(sql.append(" ,user_message "))) {
|
||||
LOG_WARN("fail to append sql", KR(ret));
|
||||
} else if (is_ddl_retry_task && OB_FAIL(sql.append(" ,UNHEX(user_message) as user_message "))) {
|
||||
LOG_WARN("fail to append sql", KR(ret));
|
||||
} else if (OB_FAIL(sql.append_fmt(" from %s "
|
||||
" WHERE tenant_id = %ld AND task_id = %ld AND target_object_id = %ld ",
|
||||
OB_ALL_DDL_ERROR_MESSAGE_TNAME,
|
||||
ObSchemaUtils::get_extract_tenant_id(exec_tenant_id, tenant_id),
|
||||
task_id, target_object_id))) {
|
||||
LOG_WARN("fail to append sql", KR(ret));
|
||||
} else if (addr.is_valid()) {
|
||||
if (!addr.ip_to_string(ip, sizeof(ip))) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
@ -273,6 +281,9 @@ int ObDDLErrorMessageTableOperator::get_ddl_error_message(
|
||||
EXTRACT_INT_FIELD_MYSQL(*result, "ret_code", error_message.ret_code_, int);
|
||||
EXTRACT_VARCHAR_FIELD_MYSQL(*result, "dba_message", str_dba_message);
|
||||
EXTRACT_VARCHAR_FIELD_MYSQL(*result, "user_message", str_user_message);
|
||||
EXTRACT_INT_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result, "consensus_schema_version",
|
||||
error_message.consensus_schema_version_, int64_t, false /*skip null error*/,
|
||||
true /*skip column error*/, OB_INVALID_VERSION);
|
||||
forward_user_msg_len = str_user_message.length();
|
||||
const int64_t buf_size = str_user_message.length() + 1;
|
||||
if (OB_FAIL(ret)) {
|
||||
@ -337,6 +348,9 @@ int ObDDLErrorMessageTableOperator::get_ddl_error_message(
|
||||
EXTRACT_INT_FIELD_MYSQL(*result, "ret_code", error_message.ret_code_, int);
|
||||
EXTRACT_VARCHAR_FIELD_MYSQL(*result, "dba_message", str_dba_message);
|
||||
EXTRACT_VARCHAR_FIELD_MYSQL(*result, "user_message", str_user_message);
|
||||
EXTRACT_INT_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result, "consensus_schema_version",
|
||||
error_message.consensus_schema_version_, int64_t, false /*skip null error*/,
|
||||
true /*skip column error*/, OB_INVALID_VERSION);
|
||||
forward_user_msg_len = str_user_message.length();
|
||||
const int64_t buf_size = str_user_message.length() + 1;
|
||||
if (OB_FAIL(ret)) {
|
||||
@ -413,6 +427,12 @@ int ObDDLErrorMessageTableOperator::report_ddl_error_message(const ObBuildDDLErr
|
||||
LOG_WARN("convert ip to string failed", K(ret), K(addr));
|
||||
} else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, tenant_data_version))) {
|
||||
LOG_WARN("get tenant data version failed", K(ret));
|
||||
} else if (OB_UNLIKELY((tenant_data_version < DATA_VERSION_4_2_2_0
|
||||
|| (tenant_data_version >= DATA_VERSION_4_3_0_0 && tenant_data_version < DATA_VERSION_4_3_5_0))
|
||||
&& OB_INVALID_VERSION != error_message.consensus_schema_version_)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("consensus schema version should be invalid before 4220", KR(ret), K(tenant_data_version),
|
||||
K_(error_message.consensus_schema_version));
|
||||
} else {
|
||||
ObDMLSqlSplicer dml_splicer;
|
||||
if (OB_FAIL(dml_splicer.add_pk_column("tenant_id", ObSchemaUtils::get_extract_tenant_id(exec_tenant_id, tenant_id)))) {
|
||||
@ -444,6 +464,11 @@ int ObDDLErrorMessageTableOperator::report_ddl_error_message(const ObBuildDDLErr
|
||||
LOG_WARN("failed to add column trace_id", KR(ret), K(trace_id));
|
||||
} else if (OB_FAIL(dml_splicer.add_column(K(parent_task_id)))) {
|
||||
LOG_WARN("failed to add column parent_task_id", KR(ret), K(parent_task_id));
|
||||
} else if (((tenant_data_version >= DATA_VERSION_4_2_2_0 && tenant_data_version < DATA_VERSION_4_3_0_0)
|
||||
|| (tenant_data_version >= DATA_VERSION_4_3_5_0))
|
||||
&& 0 < error_message.consensus_schema_version_ // prevent of reset to invalid after been valid
|
||||
&& OB_FAIL(dml_splicer.add_column("consensus_schema_version", error_message.consensus_schema_version_))) {
|
||||
LOG_WARN("fail to add column consensus_schema_version", KR(ret), K_(error_message.consensus_schema_version));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
|
@ -35,13 +35,13 @@ public:
|
||||
public:
|
||||
ObBuildDDLErrorMessage()
|
||||
: ret_code_(common::OB_NOT_INIT), ddl_type_(ObDDLType::DDL_INVALID), affected_rows_(0),
|
||||
user_message_(nullptr), dba_message_("\0"), allocator_()
|
||||
user_message_(nullptr), dba_message_("\0"), allocator_(), consensus_schema_version_(OB_INVALID_VERSION)
|
||||
{}
|
||||
virtual ~ObBuildDDLErrorMessage();
|
||||
int prepare_user_message_buf(const int64_t len);
|
||||
bool operator==(const ObBuildDDLErrorMessage &other) const;
|
||||
bool operator!=(const ObBuildDDLErrorMessage &other) const;
|
||||
TO_STRING_KV(K_(ret_code), K_(ddl_type), K_(affected_rows), K_(user_message), K_(dba_message));
|
||||
TO_STRING_KV(K_(ret_code), K_(ddl_type), K_(affected_rows), K_(user_message), K_(dba_message), K_(consensus_schema_version));
|
||||
public:
|
||||
int ret_code_;
|
||||
ObDDLType ddl_type_;
|
||||
@ -49,6 +49,7 @@ public:
|
||||
char *user_message_;
|
||||
char dba_message_[common::OB_MAX_ERROR_MSG_LEN];
|
||||
common::ObArenaAllocator allocator_;
|
||||
int64_t consensus_schema_version_;
|
||||
};
|
||||
|
||||
//for add_column in ddl_error_message
|
||||
|
@ -640,6 +640,8 @@ class ObString;
|
||||
ACT(BEFORE_SEND_ALTER_TABLE,)\
|
||||
ACT(BEFOR_EXEC_REBUILD_TASK,)\
|
||||
ACT(BEFORE_CREATE_HIDDEN_TABLE_IN_LOAD,)\
|
||||
ACT(BEFORE_PARALLEL_DDL_LOCK,)\
|
||||
ACT(AFTER_PARALLEL_DDL_LOCK,)\
|
||||
ACT(BEFORE_START_TRANSFER_IN_ON_PREPARE,)\
|
||||
ACT(BEFORE_TRANSFER_SERVICE_RUNNING,)\
|
||||
ACT(BEFORE_RESTORE_CREATE_TABLETS_SSTABLE,)\
|
||||
|
@ -2217,6 +2217,55 @@ OB_SERIALIZE_MEMBER((ObCreateTableLikeArg, ObDDLArg),
|
||||
session_id_,
|
||||
define_user_id_);
|
||||
|
||||
int ObSetCommentArg::assign(const ObSetCommentArg &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(ObDDLArg::assign(other))) {
|
||||
LOG_WARN("fail to assign ObDDLArg", KR(ret));
|
||||
} else if (OB_FAIL(column_name_list_.assign(other.column_name_list_))) {
|
||||
LOG_WARN("fail to assign column name list", KR(ret), K(other));
|
||||
} else if (OB_FAIL(column_comment_list_.assign(other.column_comment_list_))) {
|
||||
LOG_WARN("fail to assign column comment list", KR(ret), K(other));
|
||||
} else {
|
||||
session_id_ = other.session_id_;
|
||||
database_name_ = other.database_name_;
|
||||
table_name_ = other.table_name_;
|
||||
table_comment_ = other.table_comment_;
|
||||
op_type_ = other.op_type_;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObSetCommentArg::reset()
|
||||
{
|
||||
session_id_ = OB_INVALID_ID;
|
||||
database_name_.reset();
|
||||
table_name_.reset();
|
||||
table_comment_.reset();
|
||||
column_name_list_.reset();
|
||||
column_comment_list_.reset();
|
||||
op_type_ = MIN_OP_TYPE;
|
||||
ObDDLArg::reset();
|
||||
}
|
||||
|
||||
bool ObSetCommentArg::is_valid() const
|
||||
{
|
||||
return OB_INVALID_ID != exec_tenant_id_
|
||||
&& !database_name_.empty()
|
||||
&& !table_name_.empty()
|
||||
&& op_type_ > MIN_OP_TYPE
|
||||
&& op_type_ < MAX_OP_TYPE;
|
||||
}
|
||||
|
||||
OB_SERIALIZE_MEMBER((ObSetCommentArg, ObDDLArg),
|
||||
session_id_,
|
||||
database_name_,
|
||||
table_name_,
|
||||
column_name_list_,
|
||||
column_comment_list_,
|
||||
table_comment_,
|
||||
op_type_);
|
||||
|
||||
bool ObAlterTableArg::is_valid() const
|
||||
{
|
||||
// TODO(shaohang.lsh): add more check if needed
|
||||
@ -7898,6 +7947,12 @@ int ObDDLRes::assign(const ObDDLRes &other)
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObDDLRes, tenant_id_, schema_id_, task_id_);
|
||||
|
||||
void ObParallelDDLRes::reset()
|
||||
{
|
||||
schema_version_ = OB_INVALID_VERSION;
|
||||
}
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObParallelDDLRes, schema_version_);
|
||||
void ObAlterTableRes::reset()
|
||||
{
|
||||
index_table_id_ = OB_INVALID_ID;
|
||||
|
@ -2199,6 +2199,51 @@ public:
|
||||
int64_t start_time_;
|
||||
bool is_mview_complete_refresh_;
|
||||
};
|
||||
struct ObSetCommentArg : public ObDDLArg
|
||||
{
|
||||
OB_UNIS_VERSION(1);
|
||||
public:
|
||||
enum OP_TYPE {
|
||||
MIN_OP_TYPE = 1,
|
||||
COMMENT_TABLE,
|
||||
COMMENT_COLUMN,
|
||||
MAX_OP_TYPE = 1000
|
||||
};
|
||||
ObSetCommentArg():
|
||||
ObDDLArg(),
|
||||
session_id_(common::OB_INVALID_ID),
|
||||
database_name_(),
|
||||
table_name_(),
|
||||
table_comment_(),
|
||||
column_name_list_(),
|
||||
column_comment_list_(),
|
||||
op_type_(MIN_OP_TYPE)
|
||||
{
|
||||
}
|
||||
virtual ~ObSetCommentArg() {
|
||||
}
|
||||
void reset();
|
||||
bool is_valid() const;
|
||||
int assign(const ObSetCommentArg &other);
|
||||
TO_STRING_KV(K(ObDDLArg()),
|
||||
K_(session_id),
|
||||
K_(database_name),
|
||||
K_(table_name),
|
||||
K_(column_name_list),
|
||||
K_(column_comment_list),
|
||||
K_(table_comment),
|
||||
K_(op_type));
|
||||
public:
|
||||
uint64_t session_id_;
|
||||
common::ObString database_name_;
|
||||
common::ObString table_name_;
|
||||
common::ObString table_comment_;
|
||||
common::ObSArray<common::ObString> column_name_list_;
|
||||
common::ObSArray<common::ObString> column_comment_list_;
|
||||
OP_TYPE op_type_;
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObSetCommentArg);
|
||||
};
|
||||
|
||||
struct ObAlterTableArg : public ObDDLArg
|
||||
{
|
||||
@ -9556,6 +9601,24 @@ public:
|
||||
int64_t task_id_;
|
||||
};
|
||||
|
||||
struct ObParallelDDLRes
|
||||
{
|
||||
OB_UNIS_VERSION(1);
|
||||
public:
|
||||
ObParallelDDLRes():
|
||||
schema_version_(common::OB_INVALID_VERSION)
|
||||
{}
|
||||
void reset();
|
||||
int assign(const ObParallelDDLRes &other) {
|
||||
int ret = common::OB_SUCCESS;
|
||||
schema_version_ = other.schema_version_;
|
||||
return ret;
|
||||
}
|
||||
public:
|
||||
TO_STRING_KV(K_(schema_version));
|
||||
int64_t schema_version_;
|
||||
};
|
||||
|
||||
struct ObAlterTableRes
|
||||
{
|
||||
OB_UNIS_VERSION(1);
|
||||
|
@ -804,3 +804,46 @@ int ObLatestSchemaGuard::get_udt_info(
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLatestSchemaGuard::get_coded_index_name_info_mysql(
|
||||
common::ObIAllocator &allocator,
|
||||
const uint64_t database_id,
|
||||
const uint64_t data_table_id,
|
||||
const ObString &index_name,
|
||||
const bool is_built_in,
|
||||
ObIndexSchemaInfo &index_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObMySQLProxy *sql_proxy = nullptr;
|
||||
ObSchemaService *schema_service_impl = nullptr;
|
||||
bool is_oracle_mode = false;
|
||||
ObArray<ObIndexSchemaInfo> index_infos;
|
||||
if (OB_FAIL(check_inner_stat_())) {
|
||||
LOG_WARN("fail to check inner stat", KR(ret));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_ID == database_id
|
||||
|| OB_INVALID_ID == data_table_id
|
||||
|| index_name.empty())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("should use in mysql mode", KR(ret), K_(tenant_id));
|
||||
} else if (OB_FAIL(check_and_get_service_(schema_service_impl, sql_proxy))) {
|
||||
LOG_WARN("fail to check and get service", KR(ret));
|
||||
} else if (OB_FAIL(schema_service_impl->get_table_index_infos(allocator, *sql_proxy, tenant_id_, database_id,
|
||||
data_table_id, index_infos))) {
|
||||
LOG_WARN("fail to get table index name in mysql", KR(ret), K_(tenant_id), K(data_table_id), K(data_table_id));
|
||||
}
|
||||
for (uint64_t i = 0; OB_SUCC(ret) && i < index_infos.count(); ++i)
|
||||
{
|
||||
if (schema_service_impl->schema_name_is_equal(index_name,
|
||||
index_infos.at(i).get_index_name(),
|
||||
true/*case_compare*/,
|
||||
true/*collation*/)) {
|
||||
if (is_built_in == schema::is_built_in_index(index_infos.at(i).get_index_type())) {
|
||||
if (OB_FAIL(index_info.assign(index_infos.at(i)))) {
|
||||
LOG_WARN("fail to assign index info", KR(ret));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -289,6 +289,17 @@ public:
|
||||
const ObRoutineType &routine_type,
|
||||
const bool is_or_replace);
|
||||
|
||||
// get index info by index name, database_id, data_table_id in mysql mode
|
||||
// index name should be encoded and will be compared with CS_TYPE_UTF8MB4_GENERAL_CI (case insensitive)
|
||||
// @param [out] index_info: invalid means index not exist
|
||||
int get_coded_index_name_info_mysql(
|
||||
common::ObIAllocator &allocator,
|
||||
const uint64_t database_id,
|
||||
const uint64_t data_table_id,
|
||||
const ObString &index_name,
|
||||
const bool is_built_in,
|
||||
ObIndexSchemaInfo &index_info);
|
||||
|
||||
/* -------------- interfaces without cache end ---------------*/
|
||||
|
||||
/* -------------- interfaces with cache ---------------*/
|
||||
|
@ -373,6 +373,7 @@ int ObMultiVersionSchemaService::get_latest_schema(
|
||||
ObTableSchema *new_table = static_cast<ObTableSchema *>(new_schema);
|
||||
if (MATERIALIZED_VIEW == new_table->get_table_type()) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter materialized view is");
|
||||
LOG_WARN("not support to fetch latest mv", KR(ret), "table_id", schema_id);
|
||||
} else if (OB_ALL_CORE_TABLE_TID == schema_id) {
|
||||
// do-nothing
|
||||
|
@ -1327,6 +1327,18 @@ public:
|
||||
const common::ObIArray<uint64_t> &table_ids,
|
||||
common::ObIArray<ObSchemaIdVersion> &versions) = 0;
|
||||
|
||||
virtual int get_table_index_infos(
|
||||
common::ObIAllocator &allocator,
|
||||
common::ObISQLClient &sql_client,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t database_id,
|
||||
const uint64_t data_table_id,
|
||||
common::ObIArray<ObIndexSchemaInfo> &index_infos) = 0;
|
||||
virtual bool schema_name_is_equal(
|
||||
const ObString &src,
|
||||
const ObString &dst,
|
||||
const bool case_compare,
|
||||
const bool compare_with_collation) = 0;
|
||||
/*----------- interfaces for latest schema end -------------*/
|
||||
|
||||
};
|
||||
|
@ -10041,7 +10041,7 @@ int ObSchemaServiceSQLImpl::retrieve_schema_id_with_name_(
|
||||
EXTRACT_INT_FIELD_MYSQL(*result, id_col_name, tmp_schema_id, uint64_t);
|
||||
EXTRACT_VARCHAR_FIELD_MYSQL(*result, name_col_name, tmp_schema_name);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (schema_name_is_equal_(
|
||||
} else if (schema_name_is_equal(
|
||||
schema_name, tmp_schema_name,
|
||||
case_compare, compare_with_collation)) {
|
||||
schema_id = tmp_schema_id;
|
||||
@ -10054,7 +10054,7 @@ int ObSchemaServiceSQLImpl::retrieve_schema_id_with_name_(
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObSchemaServiceSQLImpl::schema_name_is_equal_(
|
||||
bool ObSchemaServiceSQLImpl::schema_name_is_equal(
|
||||
const ObString &src,
|
||||
const ObString &dst,
|
||||
const bool case_compare,
|
||||
@ -10301,7 +10301,7 @@ int ObSchemaServiceSQLImpl::get_table_id(
|
||||
// try fetch inner table id
|
||||
if (is_system_table && OB_INVALID_ID == candidate_inner_table_id) { // case 3.3
|
||||
bool tmp_case_compare = is_mysql_sys_database_id(database_id) ? true : case_compare;
|
||||
if (schema_name_is_equal_(
|
||||
if (schema_name_is_equal(
|
||||
table_name, tmp_table_name,
|
||||
case_compare, compare_with_collation)
|
||||
&& 0 == tmp_session_id) {
|
||||
@ -10311,7 +10311,7 @@ int ObSchemaServiceSQLImpl::get_table_id(
|
||||
}
|
||||
}
|
||||
|
||||
if (schema_name_is_equal_(
|
||||
if (schema_name_is_equal(
|
||||
table_name, tmp_table_name,
|
||||
case_compare, compare_with_collation)) {
|
||||
table_id = tmp_table_id;
|
||||
@ -10355,6 +10355,9 @@ int ObSchemaServiceSQLImpl::get_index_id(
|
||||
bool case_compare = false;
|
||||
const bool compare_with_collation = true;
|
||||
index_id = OB_INVALID_ID;
|
||||
#define GET_INDEX_ID_SQL "SELECT table_id, table_name FROM %s " \
|
||||
"WHERE tenant_id = %lu AND database_id = %lu AND table_name = '%s' " \
|
||||
"AND table_type = %d "
|
||||
if (OB_UNLIKELY(!check_inner_stat())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("check inner stat fail", KR(ret));
|
||||
@ -10371,18 +10374,32 @@ int ObSchemaServiceSQLImpl::get_index_id(
|
||||
LOG_WARN("fail to check oracle mode", KR(ret), K(tenant_id));
|
||||
} else if (FALSE_IT(case_compare = (!is_oracle_mode
|
||||
|| is_mysql_sys_database_id(database_id)))) {
|
||||
} else if (OB_FAIL(sql.assign_fmt(
|
||||
"SELECT table_id, table_name FROM %s "
|
||||
"WHERE tenant_id = 0 AND database_id = %lu AND table_name = '%s' "
|
||||
"AND table_type = %d ",
|
||||
OB_ALL_TABLE_TNAME, database_id, idx_name, USER_INDEX))) {
|
||||
LOG_WARN("fail to assign fmt", KR(ret), K(tenant_id), K(database_id),
|
||||
K(index_name), "idx_name", idx_name);
|
||||
} else if (OB_FAIL(retrieve_schema_id_with_name_(
|
||||
sql_client, tenant_id, sql,
|
||||
"table_id", "table_name",
|
||||
index_name, case_compare,
|
||||
compare_with_collation, index_id))) {
|
||||
} else if (is_oceanbase_sys_database_id(database_id)) {
|
||||
if (OB_FAIL(sql.assign_fmt(
|
||||
"SELECT * FROM "
|
||||
"( "
|
||||
GET_INDEX_ID_SQL
|
||||
"UNION ALL "
|
||||
GET_INDEX_ID_SQL
|
||||
") ",
|
||||
OB_ALL_VIRTUAL_CORE_ALL_TABLE_TNAME, tenant_id, database_id, idx_name, USER_INDEX,
|
||||
OB_ALL_TABLE_TNAME, OB_INVALID_TENANT_ID, database_id, idx_name, USER_INDEX))) {
|
||||
LOG_WARN("fail to assign fmt", KR(ret), K(tenant_id), K(database_id),
|
||||
K(index_name), "idx_name", idx_name);
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(sql.assign_fmt(
|
||||
GET_INDEX_ID_SQL,
|
||||
OB_ALL_TABLE_TNAME, OB_INVALID_TENANT_ID, database_id, idx_name, USER_INDEX))) {
|
||||
LOG_WARN("fail to assign fmt", KR(ret), K(tenant_id), K(database_id),
|
||||
K(index_name), "idx_name", idx_name);
|
||||
}
|
||||
}
|
||||
if (FAILEDx(retrieve_schema_id_with_name_(
|
||||
sql_client, tenant_id, sql,
|
||||
"table_id", "table_name",
|
||||
index_name, case_compare,
|
||||
compare_with_collation, index_id))) {
|
||||
LOG_WARN("fail to retrieve schema id with name",
|
||||
KR(ret), K(tenant_id), K(database_id),
|
||||
K(index_name), "idx_name", idx_name);
|
||||
@ -10566,7 +10583,7 @@ int ObSchemaServiceSQLImpl::get_constraint_id(
|
||||
// skip
|
||||
// (TODO):for mysql tmp table, it may has risk that constraint name duplicated in one table?
|
||||
// here just make the logic same with int ObSchemaMgr::add_constraints_in_table().
|
||||
} else if (schema_name_is_equal_(
|
||||
} else if (schema_name_is_equal(
|
||||
constraint_name, tmp_constraint_name,
|
||||
case_compare, compare_with_collation)) {
|
||||
constraint_id = tmp_constraint_id;
|
||||
@ -10655,7 +10672,7 @@ int ObSchemaServiceSQLImpl::get_foreign_key_id(
|
||||
|| is_index_table(tmp_table_type)
|
||||
|| is_aux_lob_table(tmp_table_type)) {
|
||||
// skip
|
||||
} else if (schema_name_is_equal_(
|
||||
} else if (schema_name_is_equal(
|
||||
foreign_key_name, tmp_foreign_key_name,
|
||||
case_compare, compare_with_collation)) {
|
||||
foreign_key_id = tmp_foreign_key_id;
|
||||
@ -10732,7 +10749,7 @@ int ObSchemaServiceSQLImpl::get_sequence_id(
|
||||
EXTRACT_VARCHAR_FIELD_MYSQL(*result, "sequence_name", tmp_sequence_name);
|
||||
EXTRACT_BOOL_FIELD_MYSQL(*result, "is_system_generated", tmp_is_system_generated);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (schema_name_is_equal_(
|
||||
} else if (schema_name_is_equal(
|
||||
sequence_name, tmp_sequence_name,
|
||||
case_compare, compare_with_collation)) {
|
||||
sequence_id = tmp_sequence_id;
|
||||
@ -10879,7 +10896,7 @@ int ObSchemaServiceSQLImpl::get_routine_id(
|
||||
EXTRACT_INT_FIELD_MYSQL(*result, "routine_type", tmp_routine_type, ObRoutineType);
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (schema_name_is_equal_(
|
||||
} else if (schema_name_is_equal(
|
||||
routine_name, tmp_routine_name,
|
||||
case_compare, compare_with_collation)) {
|
||||
if (OB_FAIL(routine_pairs.push_back(
|
||||
@ -11164,6 +11181,91 @@ int ObSchemaServiceSQLImpl::get_audits_in_owner(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSchemaServiceSQLImpl::get_table_index_infos(
|
||||
common::ObIAllocator &allocator,
|
||||
common::ObISQLClient &sql_client,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t database_id,
|
||||
const uint64_t data_table_id,
|
||||
common::ObIArray<ObIndexSchemaInfo> &index_infos)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSqlString sql;
|
||||
index_infos.reset();
|
||||
#define GET_INDEX_INFO_SQL "SELECT table_name, table_id, schema_version, index_type FROM %s " \
|
||||
"WHERE tenant_id = %lu AND database_id = %lu AND data_table_id = %lu " \
|
||||
"AND table_type = %d "
|
||||
if (OB_UNLIKELY(!check_inner_stat())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("check inner stat fail", KR(ret));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id
|
||||
|| OB_INVALID_ID == database_id
|
||||
|| OB_INVALID_ID == data_table_id)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arg", KR(ret), KR(ret), K(tenant_id), K(database_id), K(data_table_id));
|
||||
} else if (is_oceanbase_sys_database_id(database_id)) {
|
||||
if (OB_FAIL(sql.assign_fmt(
|
||||
"SELECT * FROM "
|
||||
"( "
|
||||
GET_INDEX_INFO_SQL
|
||||
"UNION ALL "
|
||||
GET_INDEX_INFO_SQL
|
||||
") ",
|
||||
OB_ALL_VIRTUAL_CORE_ALL_TABLE_TNAME, tenant_id, database_id, data_table_id, USER_INDEX,
|
||||
OB_ALL_TABLE_TNAME, OB_INVALID_TENANT_ID, database_id, data_table_id, USER_INDEX))) {
|
||||
LOG_WARN("fail to assign fmt", KR(ret), K(tenant_id), K(database_id), K(data_table_id));
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(sql.assign_fmt(
|
||||
GET_INDEX_INFO_SQL,
|
||||
OB_ALL_TABLE_TNAME, OB_INVALID_TENANT_ID, database_id, data_table_id, USER_INDEX))) {
|
||||
LOG_WARN("fail to assign fmt", KR(ret), K(tenant_id), K(database_id), K(data_table_id));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
|
||||
ObMySQLResult *result = nullptr;
|
||||
if (OB_FAIL(sql_client.read(res, tenant_id, sql.ptr()))) {
|
||||
LOG_WARN("fail to read", KR(ret), K(tenant_id), K(sql));
|
||||
} else if (OB_ISNULL(result = res.get_result())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("result is null", KR(ret), K(tenant_id));
|
||||
}
|
||||
ObString tmp_schema_name;
|
||||
uint64_t tmp_index_id = OB_INVALID_ID;
|
||||
int64_t tmp_schema_version = OB_INVALID_VERSION;
|
||||
ObIndexType tmp_index_type = INDEX_TYPE_IS_NOT;
|
||||
while (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(result->next())) {
|
||||
if (OB_ITER_END == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
break;
|
||||
} else {
|
||||
LOG_WARN("fail to get next", KR(ret));
|
||||
}
|
||||
} else {
|
||||
EXTRACT_VARCHAR_FIELD_MYSQL(*result, "table_name", tmp_schema_name);
|
||||
EXTRACT_INT_FIELD_MYSQL(*result, "table_id", tmp_index_id, uint64_t);
|
||||
EXTRACT_INT_FIELD_MYSQL(*result, "schema_version", tmp_schema_version, int64_t);
|
||||
EXTRACT_INT_FIELD_MYSQL(*result, "index_type", tmp_index_type, ObIndexType);
|
||||
ObIndexSchemaInfo tmp_index_info;
|
||||
ObString tmp_index_name;
|
||||
if (FAILEDx(ob_write_string(allocator, tmp_schema_name, tmp_index_name, true/*c_style*/))) {
|
||||
LOG_WARN("fail to write string", KR(ret));
|
||||
} else if (OB_FAIL(tmp_index_info.init(tmp_index_name, tmp_index_id, tmp_schema_version, tmp_index_type))) {
|
||||
LOG_WARN("fail to init tmp index info", KR(ret), K(tmp_schema_name), K(tmp_index_id), K(tmp_schema_version));
|
||||
} else if (OB_FAIL(index_infos.push_back(tmp_index_info))) {
|
||||
LOG_WARN("fail to push back tmp index info", KR(ret), K(tenant_id), K(tmp_schema_name));
|
||||
}
|
||||
}
|
||||
}// end while
|
||||
}// end smart_var
|
||||
}
|
||||
LOG_TRACE("get table index name", KR(ret), K(tenant_id), K(database_id), K(data_table_id));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}//namespace schema
|
||||
}//namespace share
|
||||
}//namespace oceanbase
|
||||
|
@ -822,6 +822,19 @@ public:
|
||||
const uint64_t owner_id,
|
||||
common::ObIArray<ObSAuditSchema> &audit_schemas) override;
|
||||
|
||||
virtual int get_table_index_infos(
|
||||
common::ObIAllocator &allocator,
|
||||
common::ObISQLClient &sql_client,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t database_id,
|
||||
const uint64_t data_table_id,
|
||||
common::ObIArray<ObIndexSchemaInfo> &index_infos) override;
|
||||
|
||||
virtual bool schema_name_is_equal(
|
||||
const ObString &src,
|
||||
const ObString &dst,
|
||||
const bool case_compare,
|
||||
const bool compare_with_collation) override;
|
||||
/*----------- interfaces for latest schema end -------------*/
|
||||
|
||||
private:
|
||||
@ -1238,11 +1251,6 @@ private:
|
||||
const bool compare_with_collation,
|
||||
uint64_t &schema_id);
|
||||
|
||||
bool schema_name_is_equal_(
|
||||
const ObString &src,
|
||||
const ObString &dst,
|
||||
const bool case_compare,
|
||||
const bool compare_with_collation);
|
||||
|
||||
int fetch_table_latest_schema_versions_(
|
||||
common::ObISQLClient &sql_client,
|
||||
|
@ -85,6 +85,49 @@ lib::Worker::CompatMode get_worker_compat_mode(const ObCompatibilityMode &mode)
|
||||
return worker_mode;
|
||||
}
|
||||
|
||||
int ObIndexSchemaInfo::init(
|
||||
const ObString &index_name,
|
||||
const uint64_t index_id,
|
||||
const int64_t schema_version,
|
||||
const ObIndexType index_type)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(index_name.empty()
|
||||
|| OB_INVALID_ID == index_id
|
||||
|| schema_version <= 0
|
||||
|| index_type <= INDEX_TYPE_IS_NOT)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("index_name, index_id, schema_version invalid", KR(ret), K(index_name),
|
||||
K(index_id), K(schema_version), K(index_type));
|
||||
} else {
|
||||
index_name_ = index_name;
|
||||
index_id_ = index_id;
|
||||
schema_version_ = schema_version;
|
||||
index_type_ = index_type;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void ObIndexSchemaInfo::reset()
|
||||
{
|
||||
index_name_.reset();
|
||||
index_id_ = OB_INVALID_ID;
|
||||
schema_version_ = OB_INVALID_VERSION;
|
||||
index_type_ = INDEX_TYPE_IS_NOT;
|
||||
}
|
||||
bool ObIndexSchemaInfo::is_valid() const
|
||||
{
|
||||
return !index_name_.empty() && OB_INVALID_ID != index_id_ && schema_version_ > 0 && index_type_ != INDEX_TYPE_IS_NOT;
|
||||
}
|
||||
int ObIndexSchemaInfo::assign(const ObIndexSchemaInfo &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
index_name_ = other.get_index_name();
|
||||
index_id_ = other.get_index_id();
|
||||
schema_version_ = other.get_schema_version();
|
||||
index_type_ = other.get_index_type();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSchemaIdVersion::init(
|
||||
const uint64_t schema_id,
|
||||
const int64_t schema_version)
|
||||
|
@ -494,6 +494,28 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class ObIndexSchemaInfo
|
||||
{
|
||||
public:
|
||||
ObIndexSchemaInfo()
|
||||
: index_name_(), index_id_(common::OB_INVALID_ID), schema_version_(common::OB_INVALID_VERSION), index_type_(INDEX_TYPE_IS_NOT) {}
|
||||
~ObIndexSchemaInfo() {}
|
||||
int init(const ObString &index_name, const uint64_t index_id, const int64_t schema_version, const ObIndexType index_type);
|
||||
void reset();
|
||||
bool is_valid() const;
|
||||
int assign(const ObIndexSchemaInfo &other);
|
||||
const ObString &get_index_name() const { return index_name_; }
|
||||
uint64_t get_index_id() const { return index_id_; }
|
||||
int64_t get_schema_version() const {return schema_version_; }
|
||||
ObIndexType get_index_type() const {return index_type_;}
|
||||
TO_STRING_KV(K_(index_name), K_(index_id), K_(schema_version), K_(index_type));
|
||||
private:
|
||||
ObString index_name_;
|
||||
uint64_t index_id_;
|
||||
int64_t schema_version_;
|
||||
ObIndexType index_type_;
|
||||
};
|
||||
|
||||
class ObSchemaIdVersion
|
||||
{
|
||||
public:
|
||||
@ -775,6 +797,8 @@ inline bool is_vec_index(const ObIndexType index_type)
|
||||
return is_vec_delta_buffer_type(index_type) || is_built_in_vec_index(index_type);
|
||||
}
|
||||
|
||||
|
||||
// new built in index type should add case in built_in_index_not_visible.test
|
||||
inline bool is_built_in_index(const ObIndexType index_type)
|
||||
{
|
||||
return is_built_in_vec_index(index_type) ||
|
||||
|
@ -1336,8 +1336,6 @@ const char* DDLType[]
|
||||
|
||||
const char* NOT_SUPPORT_DDLType[]
|
||||
{
|
||||
"SET_COMMENT",
|
||||
"CREATE_INDEX",
|
||||
"CREATE_VIEW",
|
||||
"DROP_TABLE"
|
||||
};
|
||||
|
@ -2130,33 +2130,8 @@ int ObTableSqlService::update_table_options(ObISQLClient &sql_client,
|
||||
bool is_oracle_mode = false;
|
||||
const uint64_t tenant_id = table_schema.get_tenant_id();
|
||||
uint64_t table_id = table_schema.get_table_id();
|
||||
ObDMLSqlSplicer dml;
|
||||
const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id);
|
||||
const bool update_object_status_ignore_version = false;
|
||||
if (OB_FAIL(check_ddl_allowed(new_table_schema))) {
|
||||
LOG_WARN("check ddl allowd failed", K(ret), K(new_table_schema));
|
||||
} else if (OB_FAIL(gen_table_options_dml(exec_tenant_id, new_table_schema, update_object_status_ignore_version, dml))) {
|
||||
LOG_WARN("gen table options dml failed", K(ret));
|
||||
} else {
|
||||
int64_t affected_rows = 0;
|
||||
const char *table_name = NULL;
|
||||
if (OB_FAIL(ObSchemaUtils::get_all_table_name(exec_tenant_id, table_name))) {
|
||||
LOG_WARN("fail to get all table name", K(ret), K(exec_tenant_id));
|
||||
} else if (OB_FAIL(exec_update(sql_client, tenant_id, table_id,
|
||||
table_name, dml, affected_rows))) {
|
||||
LOG_WARN("exec update failed", K(ret));
|
||||
} else if (affected_rows > 1) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected value", K(ret), K(affected_rows));
|
||||
}
|
||||
}
|
||||
|
||||
// add to __all_table_history table
|
||||
if (OB_SUCC(ret)) {
|
||||
const bool only_history = true;
|
||||
if (OB_FAIL(add_table(sql_client, new_table_schema, update_object_status_ignore_version, only_history))) {
|
||||
LOG_WARN("add_table failed", K(new_table_schema), K(only_history), K(ret));
|
||||
}
|
||||
if (OB_FAIL(inner_update_table_options_(sql_client, new_table_schema))) {
|
||||
LOG_WARN("fail to do inner update table option", KR(ret), KPC(ddl_stmt_str));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -5491,7 +5466,7 @@ int ObTableSqlService::check_table_options(const ObTableSchema &table)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// for now, this interface is just used for parallel_set_comment
|
||||
// this interface have been used by parallel set comment
|
||||
// since parallel ddl have to allocate schema version previously
|
||||
// any modification of this interface should think the times of generate schema version carefully
|
||||
int ObTableSqlService::only_update_table_options(ObISQLClient &sql_client,
|
||||
|
@ -90,6 +90,27 @@ int ObDDLExecutorUtil::wait_ddl_finish(
|
||||
} else {
|
||||
FORWARD_USER_ERROR(ret, error_message.user_message_);
|
||||
}
|
||||
} else if (error_message.consensus_schema_version_ != OB_INVALID_VERSION) {
|
||||
ObTimeoutCtx ctx;
|
||||
int64_t consensus_timeout = 30 * 1000 * 1000L; // 30s;
|
||||
omt::ObTenantConfigGuard tenant_config(OTC_MGR.get_tenant_config_with_lock(tenant_id));
|
||||
if (tenant_config.is_valid()) {
|
||||
consensus_timeout = tenant_config->_wait_interval_after_parallel_ddl;
|
||||
}
|
||||
if (THIS_WORKER.is_timeout_ts_valid()) {
|
||||
consensus_timeout = min(consensus_timeout, THIS_WORKER.get_timeout_remain());
|
||||
}
|
||||
int64_t start_time = ObTimeUtility::current_time();
|
||||
if (OB_FAIL(ctx.set_timeout(consensus_timeout))) {
|
||||
LOG_WARN("fail to set timeout ctx", KR(ret));
|
||||
} else if (OB_FAIL(ObSchemaUtils::try_check_parallel_ddl_schema_in_sync(
|
||||
ctx, session, tenant_id, error_message.consensus_schema_version_, false /*skip_consensus*/))) {
|
||||
LOG_WARN("fail to check parallel ddl schema in sync", KR(ret), K_(error_message.consensus_schema_version));
|
||||
} else {
|
||||
int64_t refresh_time = ObTimeUtility::current_time() - start_time;
|
||||
LOG_INFO("parallel ddl wait schema", KR(ret), K(tenant_id), K(refresh_time),
|
||||
K_(error_message.consensus_schema_version));
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
|
@ -57,6 +57,12 @@ int ObCreateIndexExecutor::execute(ObExecContext &ctx, ObCreateIndexStmt &stmt)
|
||||
obrpc::ObAlterTableRes res;
|
||||
ObString first_stmt;
|
||||
bool is_sync_ddl_user = false;
|
||||
uint64_t tenant_id = create_index_arg.exec_tenant_id_;
|
||||
uint64_t data_version = 0;
|
||||
int64_t start_time = 0;
|
||||
int64_t refresh_time = 0;
|
||||
int64_t ddl_task_time = 0;
|
||||
int64_t end_time = 0;
|
||||
ObSArray<ObIndexArg *> index_arg_list;
|
||||
ObPartitionPreSplit pre_split;
|
||||
ObArenaAllocator allocator("CreateIndexExec");
|
||||
@ -83,23 +89,59 @@ int ObCreateIndexExecutor::execute(ObExecContext &ctx, ObCreateIndexStmt &stmt)
|
||||
} else if (OB_INVALID_ID == create_index_arg.session_id_
|
||||
&& FALSE_IT(create_index_arg.session_id_ = my_session->get_sessid_for_table())) {
|
||||
//impossible
|
||||
} else if (FALSE_IT(create_index_arg.is_inner_ = my_session->is_inner())) {
|
||||
} else if (FALSE_IT(create_index_arg.parallelism_ = stmt.get_parallelism())) {
|
||||
} else if (FALSE_IT(create_index_arg.consumer_group_id_ = THIS_WORKER.get_group_id())) {
|
||||
} else if (OB_FAIL(index_arg_list.push_back(&create_index_arg))) {
|
||||
LOG_WARN("fail to push back create index arg", K(ret));
|
||||
} else if (OB_FAIL(pre_split.get_global_index_pre_split_schema_if_need(
|
||||
create_index_arg.tenant_id_, create_index_arg.session_id_, create_index_arg.database_name_, create_index_arg.table_name_, index_arg_list))) {
|
||||
LOG_WARN("fail to get global index pre split schema if need", K(ret));
|
||||
//overwrite ret code
|
||||
ret = OB_SUCCESS;
|
||||
} else {
|
||||
create_index_arg.is_inner_ = my_session->is_inner();
|
||||
create_index_arg.parallelism_ = stmt.get_parallelism();
|
||||
create_index_arg.consumer_group_id_ = THIS_WORKER.get_group_id();
|
||||
if (OB_FAIL(index_arg_list.push_back(&create_index_arg))) {
|
||||
LOG_WARN("fail to push back create index arg", KR(ret));
|
||||
} else if (OB_FAIL(pre_split.get_global_index_pre_split_schema_if_need(
|
||||
create_index_arg.tenant_id_, create_index_arg.session_id_, create_index_arg.database_name_,
|
||||
create_index_arg.table_name_, index_arg_list))) {
|
||||
LOG_WARN("fail to get global index pre split schema if need", K(ret));
|
||||
//overwrite ret code
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(common_rpc_proxy->create_index(create_index_arg, res))) { //send the signal of creating index to rs
|
||||
LOG_WARN("rpc proxy create index failed", K(create_index_arg),
|
||||
"dst", common_rpc_proxy->get_server(), K(ret));
|
||||
} else if (OB_FAIL(ObResolverUtils::check_sync_ddl_user(my_session, is_sync_ddl_user))) {
|
||||
if (FAILEDx(GET_MIN_DATA_VERSION(tenant_id, data_version))) {
|
||||
LOG_WARN("fail to get data version", KR(ret), K(tenant_id));
|
||||
} else {
|
||||
bool is_parallel_ddl = true;
|
||||
if (OB_FAIL(ObParallelDDLControlMode::is_parallel_ddl_enable(
|
||||
ObParallelDDLControlMode::CREATE_INDEX,
|
||||
tenant_id, is_parallel_ddl))) {
|
||||
LOG_WARN("fail to get whether create index is parallel", KR(ret), K(tenant_id));
|
||||
} else if (!is_parallel_ddl
|
||||
|| data_version < DATA_VERSION_4_2_2_0
|
||||
|| (data_version >= DATA_VERSION_4_3_0_0 && data_version < DATA_VERSION_4_3_5_0)
|
||||
|| share::schema::is_fts_or_multivalue_index(create_index_arg.index_type_)
|
||||
|| share::schema::is_vec_index(create_index_arg.index_type_)) {
|
||||
start_time = ObTimeUtility::current_time();
|
||||
if (OB_FAIL(common_rpc_proxy->create_index(create_index_arg, res))) { //send the signal of creating index to rs
|
||||
LOG_WARN("rpc proxy create index failed", K(create_index_arg),
|
||||
"dst", common_rpc_proxy->get_server(), K(ret));
|
||||
}
|
||||
refresh_time = ObTimeUtility::current_time();
|
||||
ddl_task_time = refresh_time;
|
||||
} else {
|
||||
ObTimeoutCtx ctx;
|
||||
start_time = ObTimeUtility::current_time();
|
||||
const int64_t rpc_timeout = (static_cast<obrpc::ObRpcProxy*>(common_rpc_proxy))->timeout();
|
||||
if (OB_FAIL(ctx.set_timeout(rpc_timeout))) {
|
||||
LOG_WARN("fail to set timeout ctx", KR(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->parallel_create_index(create_index_arg, res))) {
|
||||
LOG_WARN("fail to parallel create index", KR(ret), "dst", common_rpc_proxy->get_server());
|
||||
} else {
|
||||
refresh_time = ObTimeUtility::current_time();
|
||||
if (OB_FAIL(ObSchemaUtils::try_check_parallel_ddl_schema_in_sync(
|
||||
ctx, my_session, tenant_id, res.schema_version_, false /*skip_consensus*/))) {
|
||||
LOG_WARN("fail to check parallel ddl schema in sync", KR(ret), K(res));
|
||||
}
|
||||
ddl_task_time = ObTimeUtility::current_time();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FAILEDx(ObResolverUtils::check_sync_ddl_user(my_session, is_sync_ddl_user))) {
|
||||
LOG_WARN("Failed to check sync_dll_user", K(ret));
|
||||
} else if (!is_sys_index && !is_sync_ddl_user) {
|
||||
// 只考虑非系统表和非备份恢复时的索引同步检查
|
||||
@ -124,6 +166,14 @@ int ObCreateIndexExecutor::execute(ObExecContext &ctx, ObCreateIndexStmt &stmt)
|
||||
"table_id", res.index_table_id_,
|
||||
"schema_version", res.schema_version_);
|
||||
SQL_ENG_LOG(INFO, "finish create index execute.", K(ret), "ddl_event_info", ObDDLEventInfo());
|
||||
end_time = ObTimeUtility::current_time();
|
||||
LOG_INFO("[create_index]", KR(ret),
|
||||
"tenant_id", tenant_id,
|
||||
"cost", end_time - start_time,
|
||||
"execute_time", refresh_time - start_time,
|
||||
"wait_schema", ddl_task_time - refresh_time,
|
||||
"wait_ddl_task", end_time - ddl_task_time,
|
||||
"index_name", create_index_arg.index_name_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1988,6 +1988,104 @@ int ObAlterTableExecutor::set_index_arg_list(ObExecContext &ctx, ObAlterTableStm
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObCommentExecutor::ObCommentExecutor()
|
||||
{
|
||||
}
|
||||
|
||||
ObCommentExecutor::~ObCommentExecutor()
|
||||
{
|
||||
}
|
||||
|
||||
int ObCommentExecutor::execute(ObExecContext &ctx, ObAlterTableStmt &stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx *task_exec_ctx = nullptr;
|
||||
obrpc::ObCommonRpcProxy *common_rpc_proxy = nullptr;
|
||||
obrpc::ObAlterTableArg &alter_table_arg = stmt.get_alter_table_arg();
|
||||
LOG_TRACE("start of comment execute", K(alter_table_arg));
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", KR(ret));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("task_exec_ctx is null", KR(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("fail to get common rpc", KR(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common_rpc_proxy is nullptr", KR(ret));
|
||||
} else {
|
||||
ObSQLSessionInfo *my_session = nullptr;
|
||||
obrpc::ObSetCommentArg set_comment_arg;
|
||||
obrpc::ObParallelDDLRes set_comment_res;
|
||||
const int64_t tenant_id = alter_table_arg.alter_table_schema_.get_tenant_id();
|
||||
alter_table_arg.ddl_stmt_str_ = first_stmt;
|
||||
alter_table_arg.is_parallel_ = true;
|
||||
my_session = ctx.get_my_session();
|
||||
int64_t start_time = ObTimeUtility::current_time();
|
||||
ObTimeoutCtx tctx;
|
||||
const int64_t rpc_timeout = (static_cast<obrpc::ObRpcProxy*>(common_rpc_proxy))->timeout();
|
||||
if (OB_ISNULL(my_session)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to get my session", KR(ret));
|
||||
} else if (OB_INVALID_ID == alter_table_arg.session_id_
|
||||
&& FALSE_IT(alter_table_arg.session_id_ = my_session->get_sessid_for_table())) {
|
||||
// should not in this field
|
||||
} else if (OB_FAIL(tctx.set_timeout(rpc_timeout))) {
|
||||
LOG_WARN("fail to set timeout ctx", KR(ret));
|
||||
} else if (OB_FAIL(assign_alter_to_comment_(alter_table_arg, set_comment_arg))) {
|
||||
LOG_WARN("fail to assign alter table arg to set comment arg", KR(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->set_comment(set_comment_arg, set_comment_res))) {
|
||||
LOG_WARN("rpc proxy set comment failed", KR(ret), K(common_rpc_proxy->get_server()), K(set_comment_arg));
|
||||
} else {
|
||||
int64_t refresh_time = ObTimeUtility::current_time();
|
||||
if (OB_FAIL(ObSchemaUtils::try_check_parallel_ddl_schema_in_sync(
|
||||
tctx, my_session, tenant_id, set_comment_res.schema_version_, false /*skip_consensus*/))) {
|
||||
LOG_WARN("fail to check paralleld ddl schema in sync", KR(ret), K(set_comment_res));
|
||||
}
|
||||
int64_t end_time = ObTimeUtility::current_time();
|
||||
LOG_INFO("[parallel_comment_table]", KR(ret),
|
||||
"tenant_id", tenant_id,
|
||||
"cost", end_time - start_time,
|
||||
"execute_time", refresh_time - start_time,
|
||||
"wait_schema", end_time - refresh_time,
|
||||
"table_name", set_comment_arg.table_name_);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCommentExecutor::assign_alter_to_comment_(const obrpc::ObAlterTableArg &alter_table_arg, obrpc::ObSetCommentArg &set_comment_arg)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const AlterTableSchema &alter_table_schema = alter_table_arg.alter_table_schema_;
|
||||
set_comment_arg.session_id_ = alter_table_arg.session_id_;
|
||||
set_comment_arg.database_name_ = alter_table_schema.get_origin_database_name();
|
||||
set_comment_arg.table_name_ = alter_table_schema.get_origin_table_name();
|
||||
if (OB_FAIL(set_comment_arg.ObDDLArg::assign(alter_table_arg))) {
|
||||
LOG_WARN("fail to assign ob ddl arg", KR(ret));
|
||||
} else if (alter_table_arg.alter_table_schema_.alter_option_bitset_.has_member(obrpc::ObAlterTableArg::COMMENT)) {
|
||||
set_comment_arg.op_type_ = ObSetCommentArg::COMMENT_TABLE;
|
||||
set_comment_arg.table_comment_ = alter_table_schema.get_comment();
|
||||
} else {
|
||||
set_comment_arg.op_type_ = ObSetCommentArg::COMMENT_COLUMN;
|
||||
ObTableSchema::const_column_iterator it_begin = alter_table_schema.column_begin();
|
||||
ObTableSchema::const_column_iterator it_end = alter_table_schema.column_end();
|
||||
for(; OB_SUCC(ret) && it_begin != it_end; it_begin++) {
|
||||
ObColumnSchemaV2 *column_schema = static_cast<ObColumnSchemaV2 *>(*it_begin);
|
||||
if (OB_ISNULL(column_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("column schema is null ptr", KR(ret));
|
||||
} else if (OB_FAIL(set_comment_arg.column_name_list_.push_back(column_schema->get_column_name()))) {
|
||||
LOG_WARN("fail to push back column name", KR(ret));
|
||||
} else if (OB_FAIL(set_comment_arg.column_comment_list_.push_back(column_schema->get_comment()))) {
|
||||
LOG_WARN("fail to push back column comment", KR(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -200,6 +200,18 @@ private:
|
||||
//DISALLOW_COPY_AND_ASSIGN(ObAlterTableExecutor);
|
||||
};
|
||||
|
||||
class ObCommentExecutor
|
||||
{
|
||||
public:
|
||||
ObCommentExecutor();
|
||||
virtual ~ObCommentExecutor();
|
||||
int execute(ObExecContext &ctx, ObAlterTableStmt &stmt);
|
||||
private:
|
||||
// because of the lack of the assign in alter table schema and alter column schema, this function is implemented for
|
||||
// assigning args needed for parallel comment.
|
||||
int assign_alter_to_comment_(const obrpc::ObAlterTableArg &alter_table_arg, obrpc::ObSetCommentArg &set_comment_arg);
|
||||
};
|
||||
|
||||
class ObDropTableStmt;
|
||||
class ObDropTableExecutor
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#define USING_LOG_PREFIX SQL_EXE
|
||||
|
||||
#include "share/ob_cluster_version.h"
|
||||
#include "sql/resolver/ob_cmd.h"
|
||||
#include "sql/executor/ob_cmd_executor.h"
|
||||
#include "lib/ob_name_def.h"
|
||||
@ -879,7 +880,22 @@ int ObCmdExecutor::execute(ObExecContext &ctx, ObICmd &cmd)
|
||||
}
|
||||
case stmt::T_SET_TABLE_COMMENT:
|
||||
case stmt::T_SET_COLUMN_COMMENT: {
|
||||
DEFINE_EXECUTE_CMD(ObAlterTableStmt, ObAlterTableExecutor);
|
||||
ObAlterTableStmt &stmt = *(static_cast<ObAlterTableStmt*>(&cmd));
|
||||
const uint64_t tenant_id = stmt.get_tenant_id();
|
||||
uint64_t data_version = OB_INVALID_VERSION;
|
||||
bool is_parallel_ddl = true;
|
||||
if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, data_version))) {
|
||||
LOG_WARN("fail to get data version", KR(ret), K(tenant_id));
|
||||
} else if (OB_FAIL(ObParallelDDLControlMode::is_parallel_ddl_enable(
|
||||
ObParallelDDLControlMode::SET_COMMENT, tenant_id, is_parallel_ddl))) {
|
||||
LOG_WARN("fail to get whether is parallel set comment", KR(ret), K(tenant_id));
|
||||
} else if (!(data_version >= DATA_VERSION_4_3_5_0
|
||||
|| (data_version >= DATA_VERSION_4_2_2_0 && data_version <= DATA_VERSION_4_3_0_0))
|
||||
|| !is_parallel_ddl) {
|
||||
DEFINE_EXECUTE_CMD(ObAlterTableStmt, ObAlterTableExecutor);
|
||||
} else {
|
||||
DEFINE_EXECUTE_CMD(ObAlterTableStmt, ObCommentExecutor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case stmt::T_XA_START: {
|
||||
|
@ -774,6 +774,8 @@ int ObCreateIndexResolver::resolve(const ParseNode &parse_tree)
|
||||
SQL_RESV_LOG(WARN, "failed to add based_schema_object_info to arg",
|
||||
K(ret), K(tbl_schema->get_table_id()),
|
||||
K(tbl_schema->get_schema_version()));
|
||||
} else if (OB_FAIL(add_based_udt_info(*tbl_schema))) {
|
||||
SQL_RESV_LOG(WARN, "failed to add based_schema_object_info to arg", KR(ret));
|
||||
}
|
||||
}
|
||||
DEBUG_SYNC(HANG_BEFORE_RESOLVER_FINISH);
|
||||
@ -934,5 +936,45 @@ int ObCreateIndexResolver::set_table_option_to_stmt(const uint64_t data_table_id
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexResolver::add_based_udt_info(const share::schema::ObTableSchema &tbl_schema)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObCreateIndexStmt *create_index_stmt = static_cast<ObCreateIndexStmt*>(stmt_);
|
||||
if (OB_ISNULL(create_index_stmt) || OB_ISNULL(session_info_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("create index stmt is nullptr", KR(ret));
|
||||
} else {
|
||||
ObTableSchema::const_column_iterator begin = tbl_schema.column_begin();
|
||||
ObTableSchema::const_column_iterator end = tbl_schema.column_end();
|
||||
ObCreateIndexArg &arg = create_index_stmt->get_create_index_arg();
|
||||
for (; OB_SUCC(ret) && begin != end; begin++) {
|
||||
ObColumnSchemaV2 *col = (*begin);
|
||||
if (OB_ISNULL(col)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get column schema failed", KR(ret));
|
||||
} else if (col->is_extend()) {
|
||||
const ObUDTTypeInfo *udt_info = nullptr;
|
||||
const uint64_t udt_id = col->get_sub_data_type();
|
||||
const uint64_t tenant_id = pl::get_tenant_id_by_object_id(udt_id);
|
||||
if (OB_FAIL(schema_checker_->get_udt_info(tenant_id,
|
||||
udt_id,
|
||||
udt_info))) {
|
||||
LOG_WARN("fail to get udt info", KR(ret), K(tenant_id), K(udt_id));
|
||||
} else if (OB_ISNULL(udt_info)) {
|
||||
ret = OB_ERR_OBJECT_NOT_EXIST;
|
||||
LOG_WARN("udt not exist", KR(ret), K(tenant_id), K(udt_id));
|
||||
} else if (OB_FAIL(ob_udt_check_and_add_ddl_dependency(udt_id, UDT_SCHEMA,
|
||||
udt_info->get_schema_version(),
|
||||
udt_info->get_tenant_id(),
|
||||
arg))) {
|
||||
LOG_WARN("fail to push back udt info", KR(ret), K(udt_id), K(tenant_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
@ -60,6 +60,7 @@ protected:
|
||||
int add_new_indexkey_for_oracle_temp_table();
|
||||
int fill_session_info_into_arg(const sql::ObSQLSessionInfo *session,
|
||||
ObCreateIndexStmt *crt_idx_stmt);
|
||||
int add_based_udt_info(const share::schema::ObTableSchema &tbl_schema);
|
||||
private:
|
||||
bool is_oracle_temp_table_; //是否创建oracle的临时表上索引
|
||||
bool is_spec_block_size; //是否指定block size
|
||||
|
@ -3659,6 +3659,9 @@ int ObDDLResolver::resolve_column_definition(ObColumnSchemaV2 &column,
|
||||
if (OB_ISNULL(ddl_arg)) {
|
||||
} else if (OB_FAIL(schema_checker_->get_udt_info(tenant_id, udt_id, udt_info))) {
|
||||
LOG_WARN("failed to get udt info", K(ret));
|
||||
} else if (OB_ISNULL(udt_info)) {
|
||||
ret = OB_ERR_OBJECT_NOT_EXIST;
|
||||
LOG_WARN("udt not exist", KR(ret), K(tenant_id), K(udt_id));
|
||||
} else if (OB_FAIL(ob_udt_check_and_add_ddl_dependency(udt_id,
|
||||
UDT_SCHEMA,
|
||||
udt_info->get_schema_version(),
|
||||
|
@ -133,6 +133,7 @@ int ObSetCommentResolver::resolve(const ParseNode &parse_tree)
|
||||
LOG_WARN("version before 4.3.1 or 4.2.2 not support comment on view", K(ret));
|
||||
} else {
|
||||
alter_table_stmt->set_table_id(table_schema->get_table_id());
|
||||
alter_table_stmt->set_stmt_type(stmt::T_SET_TABLE_COMMENT);
|
||||
}
|
||||
} else if (T_SET_COLUMN_COMMENT == parse_tree.type_) {
|
||||
// COMMENT ON COLUMN
|
||||
@ -202,6 +203,7 @@ int ObSetCommentResolver::resolve(const ParseNode &parse_tree)
|
||||
SQL_RESV_LOG(WARN, "column doesn't exist", K(ret), K(col_name));
|
||||
} else {
|
||||
alter_table_stmt->set_table_id(table_schema->get_table_id());
|
||||
alter_table_stmt->set_stmt_type(stmt::T_SET_COLUMN_COMMENT);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user