Skip to content

Commit

Permalink
[BUGFIX] fix insert table failed after truncate and alter table
Browse files Browse the repository at this point in the history
  • Loading branch information
obdev authored and ob-robot committed Nov 28, 2023
1 parent 469131e commit 542cb51
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 2 deletions.
22 changes: 22 additions & 0 deletions src/rootserver/ob_ddl_operator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1842,6 +1842,28 @@ int ObDDLOperator::reinit_autoinc_row(const ObTableSchema &table_schema,
return ret;
}

int ObDDLOperator::try_reinit_autoinc_row(const ObTableSchema &table_schema,
common::ObMySQLTransaction &trans)
{
int ret = OB_SUCCESS;
bool need_reinit_inner_table = false;
const uint64_t table_id = table_schema.get_table_id();
const uint64_t tenant_id = table_schema.get_tenant_id();
const int64_t truncate_version = table_schema.get_truncate_version();
const uint64_t column_id = table_schema.get_autoinc_column_id();
ObAutoincrementService &autoinc_service = share::ObAutoincrementService::get_instance();
if (OB_FAIL(autoinc_service.try_lock_autoinc_row(tenant_id, table_id, column_id, truncate_version,
need_reinit_inner_table, trans))) {
LOG_WARN("fail to check inner autoinc version", KR(ret), K(tenant_id), K(table_id), K(column_id));
} else if (need_reinit_inner_table) {
if (OB_FAIL(autoinc_service.reset_autoinc_row(tenant_id, table_id, column_id,
truncate_version, trans))) {
LOG_WARN("fail to reinit autoinc row", KR(ret), K(tenant_id), K(table_id), K(column_id));
}
}
return ret;
}

// Notice: this function process index.
int ObDDLOperator::alter_table_drop_aux_column(
ObTableSchema &new_table_schema,
Expand Down
3 changes: 3 additions & 0 deletions src/rootserver/ob_ddl_operator.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ class ObDDLOperator
const common::ObString *ddl_stmt_str = NULL);
int reinit_autoinc_row(const ObTableSchema &table_schema,
common::ObMySQLTransaction &trans);
// for alter table autoinc to check __all_auto_increment
int try_reinit_autoinc_row(const ObTableSchema &table_schema,
common::ObMySQLTransaction &trans);
int create_sequence_in_create_table(share::schema::ObTableSchema &table_schema,
common::ObMySQLTransaction &trans,
share::schema::ObSchemaGetterGuard &schema_guard,
Expand Down
17 changes: 15 additions & 2 deletions src/rootserver/ob_ddl_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5017,16 +5017,29 @@ int ObDDLService::update_autoinc_schema(obrpc::ObAlterTableArg &alter_table_arg)
LOG_WARN("unexpected alter_column_num or iter is NULL", K(ret), K(alter_column_num));
} else {
const ObString &orig_column_name = alter_column_schema->get_origin_column_name();
const ObColumnSchemaV2 *curr_column_schema = curr_table_schema->get_column_schema(orig_column_name);
new_column_schema = new_table_schema.get_column_schema(orig_column_name);
if (OB_ISNULL(new_column_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("alter column schema is null");
LOG_WARN("alter column schema is null", KR(ret), K(new_table_schema.get_table_id()),
K(orig_column_name));
} else if (OB_ISNULL(curr_column_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("cur column schema is null", KR(ret), K(curr_table_schema->get_table_id()),
K(orig_column_name));
} else {
new_column_schema->set_autoincrement(alter_column_schema->is_autoincrement());
new_column_schema->set_nullable(alter_column_schema->is_nullable());
new_table_schema.set_auto_increment(alter_table_schema.get_auto_increment());
new_table_schema.set_autoinc_column_id(alter_column_schema->get_column_id());
if (OB_FAIL(ddl_operator.update_single_column(trans,

// we need clear inner autoinc when add autoinc attribute bug/53305960
if (new_column_schema->is_autoincrement() && !curr_column_schema->is_autoincrement()) {
if (OB_FAIL(ddl_operator.try_reinit_autoinc_row(new_table_schema, trans))) {
LOG_WARN("fail to reinit autoinc row", KR(ret), K(new_table_schema));
}
}
if (FAILEDx(ddl_operator.update_single_column(trans,
*curr_table_schema,
new_table_schema,
*new_column_schema))) {
Expand Down
60 changes: 60 additions & 0 deletions src/share/ob_autoincrement_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,66 @@ int ObAutoincrementService::reinit_autoinc_row(const uint64_t &tenant_id,
return ret;
}

// use for alter table add autoincrement
int ObAutoincrementService::try_lock_autoinc_row(const uint64_t &tenant_id,
const uint64_t &table_id,
const uint64_t &column_id,
const int64_t &autoinc_version,
bool &need_update_inner_table,
common::ObMySQLTransaction &trans)
{
int ret = OB_SUCCESS;
ObSqlString lock_sql;
need_update_inner_table = false;
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
ObMySQLResult *result = NULL;
if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id
|| OB_INVALID_ID == table_id
|| 0 == column_id)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("arg is not invalid", KR(ret), K(tenant_id), K(table_id), K(column_id));
} else if (OB_FAIL(lock_sql.assign_fmt("SELECT truncate_version "
"FROM %s WHERE tenant_id = %lu AND sequence_key = %lu "
"AND column_id = %lu FOR UPDATE",
OB_ALL_AUTO_INCREMENT_TNAME,
ObSchemaUtils::get_extract_tenant_id(tenant_id, tenant_id),
ObSchemaUtils::get_extract_schema_id(tenant_id, table_id),
column_id))) {
LOG_WARN("failed to assign sql", KR(ret));
} else if (OB_FAIL(trans.read(res, tenant_id, lock_sql.ptr()))) {
LOG_WARN("failded to execute sql", KR(ret), K(lock_sql));
} else if (OB_ISNULL(result = res.get_result())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("failed to get result, result is NULL", KR(ret));
} else if (OB_FAIL(result->next())) {
if (OB_ITER_END == ret) {
ret = OB_SUCCESS;
LOG_INFO("autoinc row not exist", K(tenant_id), K(table_id), K(column_id));
} else {
LOG_WARN("iterate next result fail", KR(ret), K(lock_sql));
}
} else {
int64_t inner_autoinc_version = OB_INVALID_VERSION;
if (OB_FAIL(result->get_int(0l, inner_autoinc_version))) {
LOG_WARN("fail to get truncate_version", KR(ret));
} else if (inner_autoinc_version > autoinc_version) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("autoincrement's newest version can not less than inner version",
KR(ret), K(tenant_id), K(table_id), K(column_id),
K(inner_autoinc_version), K(autoinc_version));
} else if (inner_autoinc_version < autoinc_version) {
need_update_inner_table = true;
LOG_INFO("inner autoinc version is old, we need to update inner table",
K(tenant_id), K(table_id), K(column_id), K(inner_autoinc_version), K(autoinc_version));
} else {
LOG_TRACE("inner autoinc version is equal, not need to update inner table",
K(tenant_id), K(table_id), K(column_id));
}
}
}
return ret;
}

int ObAutoincrementService::clear_autoinc_cache_all(const uint64_t tenant_id,
const uint64_t table_id,
const uint64_t column_id,
Expand Down
7 changes: 7 additions & 0 deletions src/share/ob_autoincrement_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,13 @@ class ObAutoincrementService
const uint64_t &column_id,
const int64_t &autoinc_version,
common::ObMySQLTransaction &trans);
// for alter table autoinc to recognize old autoincrement value in inner table
int try_lock_autoinc_row(const uint64_t &tenant_id,
const uint64_t &table_id,
const uint64_t &column_id,
const int64_t &autoinc_version,
bool &need_update_inner_table,
common::ObMySQLTransaction &trans);
static int calc_next_value(const uint64_t last_next_value,
const uint64_t offset,
const uint64_t increment,
Expand Down

0 comments on commit 542cb51

Please sign in to comment.