persist execution id and protect ddl start using execution id
This commit is contained in:
committed by
wangzelin.wzl
parent
798d3f50d6
commit
6fc4bc4a26
@ -96,6 +96,7 @@ int ObColumnRedefinitionTask::init(const ObDDLTaskRecord &task_record)
|
||||
schema_version_ = schema_version;
|
||||
task_status_ = static_cast<ObDDLTaskStatus>(task_record.task_status_);
|
||||
snapshot_version_ = task_record.snapshot_version_;
|
||||
execution_id_ = task_record.execution_id_;
|
||||
tenant_id_ = task_record.tenant_id_;
|
||||
ret_code_ = task_record.ret_code_;
|
||||
is_inited_ = true;
|
||||
@ -140,7 +141,6 @@ int ObColumnRedefinitionTask::send_build_single_replica_request()
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("ObColumnRedefinitionTask has not been inited", K(ret));
|
||||
} else {
|
||||
redefinition_execution_id_ = ObTimeUtility::fast_current_time();
|
||||
ObDDLSingleReplicaExecutorParam param;
|
||||
param.tenant_id_ = tenant_id_;
|
||||
param.type_ = task_type_;
|
||||
@ -150,7 +150,7 @@ int ObColumnRedefinitionTask::send_build_single_replica_request()
|
||||
param.snapshot_version_ = snapshot_version_;
|
||||
param.task_id_ = task_id_;
|
||||
param.parallelism_ = alter_table_arg_.parallelism_;
|
||||
param.execution_id_ = redefinition_execution_id_;
|
||||
param.execution_id_ = execution_id_;
|
||||
if (OB_FAIL(ObDDLUtil::get_tablets(tenant_id_, object_id_, param.source_tablet_ids_))) {
|
||||
LOG_WARN("fail to get tablets", K(ret), K(tenant_id_), K(object_id_));
|
||||
} else if (OB_FAIL(ObDDLUtil::get_tablets(tenant_id_, target_object_id_, param.dest_tablet_ids_))) {
|
||||
@ -192,6 +192,7 @@ int ObColumnRedefinitionTask::update_complete_sstable_job_status(const common::O
|
||||
const int ret_code)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_latest_execution_id = false;
|
||||
if (OB_UNLIKELY(!is_inited_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("ObColumnRedefinitionTask has not been inited", K(ret));
|
||||
@ -200,8 +201,10 @@ int ObColumnRedefinitionTask::update_complete_sstable_job_status(const common::O
|
||||
} else if (snapshot_version != snapshot_version_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("snapshot version not match", K(ret), K(snapshot_version), K(snapshot_version_));
|
||||
} else if (execution_id != redefinition_execution_id_) {
|
||||
LOG_INFO("receive a mismatch execution result, ignore", K(execution_id), K(redefinition_execution_id_));
|
||||
} else if (OB_FAIL(check_is_latest_execution_id(execution_id, is_latest_execution_id))) {
|
||||
LOG_WARN("failed to check latest execution id", K(ret), K(execution_id));
|
||||
} else if (!is_latest_execution_id) {
|
||||
LOG_INFO("receive a mismatch execution result, ignore", K(execution_id), K(execution_id_));
|
||||
} else if (OB_FAIL(replica_builder_.set_partition_task_status(tablet_id, ret_code))) {
|
||||
LOG_WARN("fail to set partition task status", K(ret));
|
||||
}
|
||||
|
||||
@ -217,7 +217,6 @@ protected:
|
||||
int64_t update_autoinc_job_time_;
|
||||
int64_t check_table_empty_job_ret_code_;
|
||||
int64_t check_table_empty_job_time_;
|
||||
int64_t redefinition_execution_id_;
|
||||
};
|
||||
|
||||
} // end namespace rootserver
|
||||
|
||||
@ -581,11 +581,12 @@ int ObDDLRetryTask::update_task_status_succ(
|
||||
int64_t affected_rows = 0;
|
||||
ObSqlString sql_string;
|
||||
int64_t curr_task_status = 0;
|
||||
int64_t execution_id = 0; /*unused*/
|
||||
const int64_t new_task_status = ObDDLTaskStatus::SUCCESS;
|
||||
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || task_id <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(ret), K(tenant_id), K(task_id));
|
||||
} else if (OB_FAIL(ObDDLTaskRecordOperator::select_for_update(trans, tenant_id, task_id, curr_task_status))) {
|
||||
} else if (OB_FAIL(ObDDLTaskRecordOperator::select_for_update(trans, tenant_id, task_id, curr_task_status, execution_id))) {
|
||||
LOG_WARN("select for update failed", K(ret), K(tenant_id), K(task_id));
|
||||
} else if (OB_FAIL(ObDDLTaskRecordOperator::update_task_status(trans, tenant_id, task_id, new_task_status))) {
|
||||
LOG_WARN("update task status failed", K(ret));
|
||||
|
||||
@ -902,6 +902,7 @@ int ObDDLScheduler::recover_task()
|
||||
const ObDDLTaskRecord &cur_record = task_records.at(i);
|
||||
int64_t tenant_schema_version = 0;
|
||||
int64_t table_task_status = 0;
|
||||
int64_t execution_id = 0;
|
||||
ObMySQLTransaction trans;
|
||||
if (OB_FAIL(schema_service.get_tenant_schema_version(cur_record.tenant_id_, tenant_schema_version))) {
|
||||
LOG_WARN("failed to get tenant schema version", K(ret), K(cur_record));
|
||||
@ -912,7 +913,8 @@ int ObDDLScheduler::recover_task()
|
||||
} else if (OB_FAIL(ObDDLTaskRecordOperator::select_for_update(trans,
|
||||
cur_record.tenant_id_,
|
||||
cur_record.task_id_,
|
||||
table_task_status))) {
|
||||
table_task_status,
|
||||
execution_id))) {
|
||||
LOG_WARN("select for update failed", K(ret), K(cur_record));
|
||||
} else if (OB_FAIL(schedule_ddl_task(cur_record))) {
|
||||
LOG_WARN("failed to schedule ddl task", K(ret), K(cur_record));
|
||||
@ -1111,6 +1113,8 @@ int ObDDLScheduler::schedule_column_redefinition_task(const ObDDLTaskRecord &tas
|
||||
if (OB_ENTRY_EXIST != ret) {
|
||||
LOG_WARN("inner schedule task failed", K(ret), K(*redefinition_task));
|
||||
}
|
||||
} else if (OB_FAIL(redefinition_task->push_execution_id())) {
|
||||
LOG_WARN("failed to push execution id", K(ret));
|
||||
}
|
||||
if (OB_FAIL(ret) && nullptr != redefinition_task) {
|
||||
redefinition_task->~ObColumnRedefinitionTask();
|
||||
|
||||
@ -259,6 +259,7 @@ int ObDDLTask::convert_to_record(
|
||||
task_record.task_id_ = get_task_id();
|
||||
task_record.parent_task_id_ = get_parent_task_id();
|
||||
task_record.task_version_ = get_task_version();
|
||||
task_record.execution_id_ = get_execution_id();
|
||||
task_record.ret_code_ = get_ret_code();
|
||||
const ObString &ddl_stmt_str = get_ddl_stmt_str();
|
||||
if (serialize_param_size > 0) {
|
||||
@ -313,7 +314,8 @@ int ObDDLTask::switch_status(ObDDLTaskStatus new_status, const int ret_code)
|
||||
LOG_WARN("start transaction failed", K(ret));
|
||||
} else {
|
||||
int64_t table_task_status = 0;
|
||||
if (OB_FAIL(ObDDLTaskRecordOperator::select_for_update(trans, tenant_id_, task_id_, table_task_status))) {
|
||||
int64_t execution_id = 0;
|
||||
if (OB_FAIL(ObDDLTaskRecordOperator::select_for_update(trans, tenant_id_, task_id_, table_task_status, execution_id))) {
|
||||
LOG_WARN("select for update failed", K(ret), K(task_id_));
|
||||
} else if (old_status != task_status_) {
|
||||
ret = OB_EAGAIN;
|
||||
@ -551,6 +553,60 @@ int ObDDLTask::batch_release_snapshot(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLTask::check_is_latest_execution_id(const int64_t execution_id, bool &is_latest)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_latest = true;
|
||||
ObMySQLTransaction trans;
|
||||
ObRootService *root_service = nullptr;
|
||||
int64_t table_task_status = 0;
|
||||
int64_t table_execution_id = 0;
|
||||
if (OB_ISNULL(root_service = GCTX.root_service_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("error unexpected, root service must not be nullptr", K(ret));
|
||||
} else if (OB_FAIL(trans.start(&root_service->get_sql_proxy(), tenant_id_))) {
|
||||
LOG_WARN("start transaction failed", K(ret));
|
||||
} else {
|
||||
if (OB_FAIL(ObDDLTaskRecordOperator::select_for_update(trans, tenant_id_, task_id_, table_task_status, table_execution_id))) {
|
||||
LOG_WARN("select for update failed", K(ret), K(task_id_));
|
||||
} else if (table_execution_id > execution_id) {
|
||||
is_latest = false;
|
||||
}
|
||||
trans.end(false);// abort
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLTask::push_execution_id()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObMySQLTransaction trans;
|
||||
ObRootService *root_service = nullptr;
|
||||
int64_t table_task_status = 0;
|
||||
int64_t table_execution_id = 0;
|
||||
if (OB_ISNULL(root_service = GCTX.root_service_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("error unexpected, root service must not be nullptr", K(ret));
|
||||
} else if (OB_FAIL(trans.start(&root_service->get_sql_proxy(), tenant_id_))) {
|
||||
LOG_WARN("start transaction failed", K(ret));
|
||||
} else {
|
||||
if (OB_FAIL(ObDDLTaskRecordOperator::select_for_update(trans, tenant_id_, task_id_, table_task_status, table_execution_id))) {
|
||||
LOG_WARN("select for update failed", K(ret), K(task_id_));
|
||||
} else if (OB_FAIL(ObDDLTaskRecordOperator::update_execution_id(trans, tenant_id_, task_id_, table_execution_id + 1))) {
|
||||
LOG_WARN("update task status failed", K(ret));
|
||||
} else {
|
||||
execution_id_ = table_execution_id + 1;
|
||||
}
|
||||
bool commit = (OB_SUCCESS == ret);
|
||||
int tmp_ret = trans.end(commit);
|
||||
if (OB_SUCCESS != tmp_ret) {
|
||||
LOG_WARN("fail to end trans", K(tmp_ret));
|
||||
ret = (OB_SUCCESS == ret) ? tmp_ret : ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObDDLTask::calc_next_schedule_ts(int ret_code)
|
||||
{
|
||||
if (OB_TIMEOUT == ret_code) {
|
||||
@ -1382,7 +1438,8 @@ bool ObDDLTaskRecord::is_valid() const
|
||||
&& task_version_ > 0
|
||||
&& OB_INVALID_ID != object_id_
|
||||
&& schema_version_ > 0
|
||||
&& ret_code_ >= 0;
|
||||
&& ret_code_ >= 0
|
||||
&& execution_id_ >= 0;
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
@ -1401,6 +1458,7 @@ void ObDDLTaskRecord::reset()
|
||||
message_.reset();
|
||||
task_version_ = 0;
|
||||
ret_code_ = OB_SUCCESS;
|
||||
execution_id_ = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1477,6 +1535,30 @@ int ObDDLTaskRecordOperator::update_ret_code(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLTaskRecordOperator::update_execution_id(
|
||||
common::ObISQLClient &sql_client,
|
||||
const uint64_t tenant_id,
|
||||
const int64_t task_id,
|
||||
const int64_t execution_id)
|
||||
{
|
||||
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 <= 0 || execution_id <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arg", K(ret), K(tenant_id), K(task_id));
|
||||
} else if (OB_FAIL(sql_string.assign_fmt(" UPDATE %s SET execution_id=%lu WHERE task_id=%lu ",
|
||||
OB_ALL_DDL_TASK_STATUS_TNAME, execution_id, task_id))) {
|
||||
LOG_WARN("assign sql string failed", K(ret), K(execution_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", K(ret), K(sql_string));
|
||||
} else if (OB_UNLIKELY(affected_rows < 0)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected affected_rows", K(ret), K(affected_rows));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLTaskRecordOperator::update_message(
|
||||
common::ObISQLClient &proxy,
|
||||
const uint64_t tenant_id,
|
||||
@ -1541,7 +1623,7 @@ int ObDDLTaskRecordOperator::check_is_adding_constraint(
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
|
||||
sqlclient::ObMySQLResult *result = NULL;
|
||||
if (OB_FAIL(sql_string.assign_fmt(" SELECT tenant_id, task_id, object_id, target_object_id, ddl_type, "
|
||||
"schema_version, parent_task_id, trace_id, status, snapshot_version, task_version,"
|
||||
"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_VIRTUAL_DDL_TASK_STATUS_TNAME,
|
||||
object_id, DDL_CHECK_CONSTRAINT, DDL_FOREIGN_KEY_CONSTRAINT, DDL_ADD_NOT_NULL_COLUMN))) {
|
||||
@ -1633,7 +1715,7 @@ int ObDDLTaskRecordOperator::check_has_conflict_ddl(
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
|
||||
sqlclient::ObMySQLResult *result = nullptr;
|
||||
if (OB_FAIL(sql_string.assign_fmt("SELECT tenant_id, task_id, object_id, target_object_id, ddl_type,"
|
||||
"schema_version, parent_task_id, trace_id, status, snapshot_version, task_version,"
|
||||
"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 tenant_id = %lu AND object_id = %lu", OB_ALL_VIRTUAL_DDL_TASK_STATUS_TNAME,
|
||||
tenant_id, table_id))) {
|
||||
@ -1689,7 +1771,7 @@ int ObDDLTaskRecordOperator::get_all_record(
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
|
||||
sqlclient::ObMySQLResult *result = NULL;
|
||||
if (OB_FAIL(sql_string.assign_fmt(" SELECT tenant_id, task_id, object_id, target_object_id, ddl_type, "
|
||||
"schema_version, parent_task_id, trace_id, status, snapshot_version, task_version,"
|
||||
"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))) {
|
||||
LOG_WARN("assign sql string failed", K(ret));
|
||||
} else if (OB_FAIL(proxy.read(res, sql_string.ptr()))) {
|
||||
@ -1758,11 +1840,11 @@ int ObDDLTaskRecordOperator::insert_record(
|
||||
} 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 (task_id, parent_task_id, tenant_id, object_id, schema_version, target_object_id, ddl_type, trace_id, status, task_version, ret_code, ddl_stmt_str, message) "
|
||||
" VALUES (%lu, %lu, %lu, %lu, %lu, %lu, %d, '%s', %ld, %lu, %lu, '%.*s', \"%.*s\") ",
|
||||
" INSERT INTO %s (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 (%lu, %lu, %lu, %lu, %lu, %lu, %d, '%s', %ld, %lu, %lu, %lu, '%.*s', \"%.*s\") ",
|
||||
OB_ALL_DDL_TASK_STATUS_TNAME, 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.ret_code_,
|
||||
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(proxy.write(record.tenant_id_, sql_string.ptr(), affected_rows))) {
|
||||
@ -1803,6 +1885,7 @@ int ObDDLTaskRecordOperator::fill_task_record(
|
||||
EXTRACT_UINT_FIELD_MYSQL(*result_row, "snapshot_version", task_record.snapshot_version_, uint64_t);
|
||||
EXTRACT_INT_FIELD_MYSQL(*result_row, "task_version", task_record.task_version_, int64_t);
|
||||
EXTRACT_INT_FIELD_MYSQL(*result_row, "ret_code", task_record.ret_code_, int64_t);
|
||||
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);
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -1849,18 +1932,20 @@ int ObDDLTaskRecordOperator::select_for_update(
|
||||
common::ObMySQLTransaction &trans,
|
||||
const uint64_t tenant_id,
|
||||
const int64_t task_id,
|
||||
int64_t &task_status)
|
||||
int64_t &task_status,
|
||||
int64_t &execution_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSqlString sql_string;
|
||||
task_status = 0;
|
||||
execution_id = 0;
|
||||
if (OB_UNLIKELY(task_id <= 0 || tenant_id <= 0)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", K(ret), K(tenant_id), K(task_id));
|
||||
} else {
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
|
||||
sqlclient::ObMySQLResult *result = NULL;
|
||||
if (OB_FAIL(sql_string.assign_fmt("SELECT status FROM %s WHERE task_id = %lu FOR UPDATE",
|
||||
if (OB_FAIL(sql_string.assign_fmt("SELECT status, execution_id FROM %s WHERE task_id = %lu FOR UPDATE",
|
||||
OB_ALL_DDL_TASK_STATUS_TNAME, task_id))) {
|
||||
LOG_WARN("assign sql string failed", K(ret), K(task_id), K(tenant_id));
|
||||
} else if (OB_FAIL(trans.read(res, tenant_id, sql_string.ptr()))) {
|
||||
@ -1872,6 +1957,7 @@ int ObDDLTaskRecordOperator::select_for_update(
|
||||
LOG_WARN("fail to get next row", K(ret));
|
||||
} else {
|
||||
EXTRACT_INT_FIELD_MYSQL(*result, "status", task_status, int64_t);
|
||||
EXTRACT_INT_FIELD_MYSQL(*result, "execution_id", execution_id, int64_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ public:
|
||||
bool is_valid() const;
|
||||
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_(schema_version), K_(target_object_id), K_(snapshot_version), K_(message), K_(task_version), K_(ret_code), K_(execution_id));
|
||||
public:
|
||||
static const int64_t MAX_MESSAGE_LENGTH = 4096;
|
||||
typedef common::ObFixedLengthString<MAX_MESSAGE_LENGTH> TaskMessage;
|
||||
@ -70,6 +70,7 @@ public:
|
||||
ObString message_;
|
||||
int64_t task_version_;
|
||||
int64_t ret_code_;
|
||||
int64_t execution_id_;
|
||||
ObString ddl_stmt_str_;
|
||||
};
|
||||
|
||||
@ -126,6 +127,12 @@ public:
|
||||
const int64_t task_id,
|
||||
const int64_t ret_code);
|
||||
|
||||
static int update_execution_id(
|
||||
common::ObISQLClient &sql_client,
|
||||
const uint64_t tenant_id,
|
||||
const int64_t task_id,
|
||||
const int64_t execution_id);
|
||||
|
||||
static int update_message(
|
||||
common::ObISQLClient &proxy,
|
||||
const uint64_t tenant_id,
|
||||
@ -141,7 +148,8 @@ public:
|
||||
common::ObMySQLTransaction &trans,
|
||||
const uint64_t tenant_id,
|
||||
const int64_t task_id,
|
||||
int64_t &task_status);
|
||||
int64_t &task_status,
|
||||
int64_t &execution_id);
|
||||
|
||||
static int get_all_record(
|
||||
common::ObMySQLProxy &proxy,
|
||||
@ -255,7 +263,7 @@ public:
|
||||
target_object_id_(0), task_status_(share::ObDDLTaskStatus::PREPARE), snapshot_version_(0), ret_code_(OB_SUCCESS), task_id_(0),
|
||||
parent_task_id_(0), parent_task_key_(), task_version_(0), parallelism_(0),
|
||||
allocator_(lib::ObLabel("DdlTask")), compat_mode_(lib::Worker::CompatMode::INVALID), err_code_occurence_cnt_(0),
|
||||
delay_schedule_time_(0), next_schedule_ts_(0)
|
||||
delay_schedule_time_(0), next_schedule_ts_(0), execution_id_(0)
|
||||
{}
|
||||
virtual ~ObDDLTask() {}
|
||||
virtual int process() = 0;
|
||||
@ -279,6 +287,7 @@ public:
|
||||
ObDDLTaskKey get_task_key() const { return ObDDLTaskKey(target_object_id_, schema_version_); }
|
||||
int64_t get_parent_task_id() const { return parent_task_id_; }
|
||||
int64_t get_task_version() const { return task_version_; }
|
||||
int64_t get_execution_id() const { return execution_id_; }
|
||||
int64_t get_parallelism() const { return parallelism_; }
|
||||
static int deep_copy_table_arg(common::ObIAllocator &allocator, const obrpc::ObDDLArg &source_arg, obrpc::ObDDLArg &dest_arg);
|
||||
static int fetch_new_task_id(ObMySQLProxy &sql_proxy, int64_t &new_task_id);
|
||||
@ -303,6 +312,7 @@ public:
|
||||
const TraceId &get_sys_task_id() const { return sys_task_id_; }
|
||||
void calc_next_schedule_ts(int ret_code);
|
||||
bool need_schedule() { return next_schedule_ts_ <= ObTimeUtility::current_time(); }
|
||||
int push_execution_id();
|
||||
#ifdef ERRSIM
|
||||
int check_errsim_error();
|
||||
#endif
|
||||
@ -312,8 +322,9 @@ public:
|
||||
K(target_object_id_), K(task_status_), K(snapshot_version_),
|
||||
K_(ret_code), K_(task_id), K_(parent_task_id), K_(parent_task_key),
|
||||
K_(task_version), K_(parallelism), K_(ddl_stmt_str), K_(compat_mode),
|
||||
K_(sys_task_id), K_(err_code_occurence_cnt), K_(next_schedule_ts), K_(delay_schedule_time));
|
||||
K_(sys_task_id), K_(err_code_occurence_cnt), K_(next_schedule_ts), K_(delay_schedule_time), K(execution_id_));
|
||||
protected:
|
||||
int check_is_latest_execution_id(const int64_t execution_id, bool &is_latest);
|
||||
virtual bool is_error_need_retry(const int ret_code)
|
||||
{
|
||||
return !share::ObIDDLTask::in_ddl_retry_black_list(ret_code) && (share::ObIDDLTask::in_ddl_retry_white_list(ret_code)
|
||||
@ -345,6 +356,7 @@ protected:
|
||||
int64_t err_code_occurence_cnt_; // occurence count for all error return codes not in white list.
|
||||
int64_t delay_schedule_time_;
|
||||
int64_t next_schedule_ts_;
|
||||
int64_t execution_id_;
|
||||
};
|
||||
|
||||
enum ColChecksumStat
|
||||
|
||||
@ -162,8 +162,7 @@ ObIndexBuildTask::ObIndexBuildTask()
|
||||
: ObDDLTask(ObDDLType::DDL_CREATE_INDEX), index_table_id_(target_object_id_),
|
||||
is_unique_index_(false), is_global_index_(false), 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),
|
||||
redefinition_execution_id_(0), create_index_arg_()
|
||||
check_unique_snapshot_(0), complete_sstable_job_ret_code_(INT64_MAX), create_index_arg_()
|
||||
{
|
||||
|
||||
}
|
||||
@ -343,6 +342,7 @@ int ObIndexBuildTask::init(const ObDDLTaskRecord &task_record)
|
||||
index_table_id_ = index_table_id;
|
||||
schema_version_ = schema_version;
|
||||
snapshot_version_ = task_record.snapshot_version_;
|
||||
execution_id_ = task_record.execution_id_;
|
||||
task_status_ = static_cast<ObDDLTaskStatus>(task_record.task_status_);
|
||||
if (ObDDLTaskStatus::VALIDATE_CHECKSUM == task_status_) {
|
||||
sstable_complete_ts_ = ObTimeUtility::current_time();
|
||||
@ -641,7 +641,7 @@ int ObIndexBuildTask::send_build_single_replica_request()
|
||||
target_object_id_,
|
||||
schema_version_,
|
||||
snapshot_version_,
|
||||
redefinition_execution_id_,
|
||||
execution_id_,
|
||||
trace_id_,
|
||||
parallelism_,
|
||||
root_service_);
|
||||
@ -706,8 +706,9 @@ int ObIndexBuildTask::wait_data_complement()
|
||||
|
||||
// submit a job to complete sstable for the index table on snapshot_version
|
||||
if (OB_SUCC(ret) && !state_finished && !is_sstable_complete_task_submitted_) {
|
||||
redefinition_execution_id_ = ObTimeUtility::current_time();
|
||||
if (OB_FAIL(send_build_single_replica_request())) {
|
||||
if (OB_FAIL(push_execution_id())) {
|
||||
LOG_WARN("failed to push execution id", K(ret));
|
||||
} else if (OB_FAIL(send_build_single_replica_request())) {
|
||||
LOG_WARN("fail to send build single replica request", K(ret));
|
||||
}
|
||||
}
|
||||
@ -725,7 +726,7 @@ int ObIndexBuildTask::wait_data_complement()
|
||||
if (OB_SUCC(ret) && state_finished) {
|
||||
bool dummy_equal = false;
|
||||
if (OB_FAIL(ObDDLChecksumOperator::check_column_checksum(
|
||||
tenant_id_, redefinition_execution_id_, object_id_, index_table_id_, task_id_, dummy_equal, root_service_->get_sql_proxy()))) {
|
||||
tenant_id_, execution_id_, object_id_, index_table_id_, task_id_, dummy_equal, root_service_->get_sql_proxy()))) {
|
||||
if (OB_ITER_END != ret) {
|
||||
LOG_WARN("fail to check column checksum", K(ret), K(index_table_id_), K(object_id_), K(task_id_));
|
||||
state_finished = true;
|
||||
@ -866,7 +867,7 @@ int ObIndexBuildTask::verify_checksum()
|
||||
bool is_column_checksum_ready = false;
|
||||
bool dummy_equal = false;
|
||||
if (!wait_column_checksum_ctx_.is_inited() && OB_FAIL(wait_column_checksum_ctx_.init(
|
||||
task_id_, tenant_id_, object_id_, index_table_id_, schema_version_, check_unique_snapshot_, redefinition_execution_id_, checksum_wait_timeout))) {
|
||||
task_id_, tenant_id_, object_id_, index_table_id_, schema_version_, check_unique_snapshot_, execution_id_, checksum_wait_timeout))) {
|
||||
LOG_WARN("init context of wait column checksum failed", K(ret), K(object_id_), K(index_table_id_));
|
||||
} else {
|
||||
if (OB_FAIL(wait_column_checksum_ctx_.try_wait(is_column_checksum_ready))) {
|
||||
@ -879,7 +880,7 @@ int ObIndexBuildTask::verify_checksum()
|
||||
// do nothing
|
||||
} else {
|
||||
if (OB_FAIL(ObDDLChecksumOperator::check_column_checksum(
|
||||
tenant_id_, redefinition_execution_id_, object_id_, index_table_id_, task_id_, dummy_equal, root_service_->get_sql_proxy()))) {
|
||||
tenant_id_, execution_id_, object_id_, index_table_id_, task_id_, dummy_equal, root_service_->get_sql_proxy()))) {
|
||||
if (OB_CHECKSUM_ERROR == ret && is_unique_index_) {
|
||||
ret = OB_ERR_DUPLICATED_UNIQUE_KEY;
|
||||
}
|
||||
@ -901,6 +902,7 @@ int ObIndexBuildTask::update_column_checksum_calc_status(
|
||||
const int ret_code)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_latest_execution_id = false;
|
||||
if (OB_UNLIKELY(!is_inited_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", K(ret));
|
||||
@ -925,6 +927,7 @@ int ObIndexBuildTask::update_complete_sstable_job_status(
|
||||
const int ret_code)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_latest_execution_id = false;
|
||||
if (OB_UNLIKELY(!is_inited_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", K(ret));
|
||||
@ -937,8 +940,10 @@ int ObIndexBuildTask::update_complete_sstable_job_status(
|
||||
} else if (snapshot_version != snapshot_version_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("snapshot version not match", K(ret), K(snapshot_version), K(snapshot_version_));
|
||||
} else if (execution_id != redefinition_execution_id_) {
|
||||
LOG_INFO("receive a mismatch execution result, ignore", K(execution_id), K(redefinition_execution_id_));
|
||||
} else if (OB_FAIL(check_is_latest_execution_id(execution_id, is_latest_execution_id))) {
|
||||
LOG_WARN("failed to check latest execution id", K(ret), K(execution_id));
|
||||
} else if (!is_latest_execution_id) {
|
||||
LOG_INFO("receive a mismatch execution result, ignore", K(execution_id), K(execution_id_));
|
||||
} else {
|
||||
complete_sstable_job_ret_code_ = ret_code;
|
||||
sstable_complete_ts_ = ObTimeUtility::current_time();
|
||||
|
||||
@ -97,6 +97,7 @@ int ObTableRedefinitionTask::init(const ObDDLTaskRecord &task_record)
|
||||
schema_version_ = schema_version;
|
||||
task_status_ = static_cast<ObDDLTaskStatus>(task_record.task_status_);
|
||||
snapshot_version_ = task_record.snapshot_version_;
|
||||
execution_id_ = task_record.execution_id_;
|
||||
tenant_id_ = task_record.tenant_id_;
|
||||
ret_code_ = task_record.ret_code_;
|
||||
alter_table_arg_.exec_tenant_id_ = tenant_id_;
|
||||
@ -113,6 +114,7 @@ int ObTableRedefinitionTask::update_complete_sstable_job_status(const common::Ob
|
||||
int ret = OB_SUCCESS;
|
||||
TCWLockGuard guard(lock_);
|
||||
UNUSED(tablet_id);
|
||||
bool is_latest_execution_id = false;
|
||||
if (OB_UNLIKELY(!is_inited_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("ObTableRedefinitionTask has not been inited", K(ret));
|
||||
@ -121,8 +123,10 @@ int ObTableRedefinitionTask::update_complete_sstable_job_status(const common::Ob
|
||||
} else if (OB_UNLIKELY(snapshot_version_ != snapshot_version)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("error unexpected, snapshot version is not equal", K(ret), K(snapshot_version_), K(snapshot_version));
|
||||
} else if (execution_id != redefinition_execution_id_) {
|
||||
LOG_INFO("receive a mismatch execution result, ignore", K(execution_id), K(redefinition_execution_id_));
|
||||
} else if (OB_FAIL(check_is_latest_execution_id(execution_id, is_latest_execution_id))) {
|
||||
LOG_WARN("failed to check latest execution id", K(ret), K(execution_id));
|
||||
} else if (!is_latest_execution_id) {
|
||||
LOG_INFO("receive a mismatch execution result, ignore", K(execution_id), K(execution_id_));
|
||||
} else {
|
||||
complete_sstable_job_ret_code_ = ret_code;
|
||||
LOG_INFO("table redefinition task callback", K(complete_sstable_job_ret_code_));
|
||||
@ -157,7 +161,7 @@ int ObTableRedefinitionTask::send_build_replica_request()
|
||||
target_object_id_,
|
||||
schema_version_,
|
||||
snapshot_version_,
|
||||
redefinition_execution_id_,
|
||||
execution_id_,
|
||||
sql_mode,
|
||||
trace_id_,
|
||||
parallelism_,
|
||||
@ -250,8 +254,9 @@ int ObTableRedefinitionTask::table_redefinition(const ObDDLTaskStatus next_task_
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && !is_build_replica_end && 0 == build_replica_request_time_) {
|
||||
redefinition_execution_id_ = ObTimeUtility::current_time();
|
||||
if (OB_FAIL(send_build_replica_request())) {
|
||||
if (OB_FAIL(push_execution_id())) {
|
||||
LOG_WARN("failed to push execution id", K(ret));
|
||||
} else if (OB_FAIL(send_build_replica_request())) {
|
||||
LOG_WARN("fail to send build replica request", K(ret));
|
||||
} else {
|
||||
build_replica_request_time_ = ObTimeUtility::current_time();
|
||||
@ -273,7 +278,7 @@ int ObTableRedefinitionTask::table_redefinition(const ObDDLTaskStatus next_task_
|
||||
if (is_build_replica_end) {
|
||||
ret = complete_sstable_job_ret_code_;
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(check_data_dest_tables_columns_checksum(redefinition_execution_id_))) {
|
||||
if (OB_FAIL(check_data_dest_tables_columns_checksum(execution_id_))) {
|
||||
LOG_WARN("fail to check the columns checksum of data table and destination table", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user