Commit 93078c9c authored by Marko Mäkelä's avatar Marko Mäkelä Committed by Marko Mäkelä

Bug#24444831 MY_ERROR(ER_INNODB_ONLINE_LOG_TOO_BIG) CALLED WITH INVALID INDEX NAME

This bug was introduced in MySQL 5.6.8 with WL#6255.
When an error occurs while rebuilding a table that only has a
hidden GEN_CLUST_INDEX inside InnoDB, ha_alter_info->key_info_buffer
would be invalid and should not be dereferenced.

get_error_key_name(): Get the name of an erroneous key.
Avoid dereferencing ha_alter_info->key_info_buffer when no keys
exist in the SQL layer.

ha_innobase::inplace_alter_table(),
ha_innobase::commit_try_rebuild(): Invoke get_error_key_name()
for reporting ER_INNODB_ONLINE_LOG_TOO_BIG or ER_INDEX_CORRUPT.

RB: 13834
Reviewed-by: default avatarJimmy Yang <jimmy.yang@oracle.com>
parent 9a848ee1
......@@ -6299,6 +6299,26 @@ alter_templ_needs_rebuild(
return(false);
}
/** Get the name of an erroneous key.
@param[in] error_key_num InnoDB number of the erroneus key
@param[in] ha_alter_info changes that were being performed
@param[in] table InnoDB table
@return the name of the erroneous key */
static
const char*
get_error_key_name(
ulint error_key_num,
const Alter_inplace_info* ha_alter_info,
const dict_table_t* table)
{
if (error_key_num == ULINT_UNDEFINED) {
return(FTS_DOC_ID_INDEX_NAME);
} else if (ha_alter_info->key_count == 0) {
return(dict_table_get_first_index(table)->name);
} else {
return(ha_alter_info->key_info_buffer[error_key_num].name);
}
}
/** Alter the table structure in-place with operations
specified using Alter_inplace_info.
......@@ -6499,17 +6519,13 @@ ha_innobase::inplace_alter_table(
case DB_ONLINE_LOG_TOO_BIG:
DBUG_ASSERT(ctx->online);
my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0),
(m_prebuilt->trx->error_key_num == ULINT_UNDEFINED)
? FTS_DOC_ID_INDEX_NAME
: ha_alter_info->key_info_buffer[
m_prebuilt->trx->error_key_num].name);
get_error_key_name(m_prebuilt->trx->error_key_num,
ha_alter_info, m_prebuilt->table));
break;
case DB_INDEX_CORRUPT:
my_error(ER_INDEX_CORRUPT, MYF(0),
(m_prebuilt->trx->error_key_num == ULINT_UNDEFINED)
? FTS_DOC_ID_INDEX_NAME
: ha_alter_info->key_info_buffer[
m_prebuilt->trx->error_key_num].name);
get_error_key_name(m_prebuilt->trx->error_key_num,
ha_alter_info, m_prebuilt->table));
break;
case DB_DECRYPTION_FAILED: {
String str;
......@@ -7743,14 +7759,13 @@ commit_try_rebuild(
DBUG_RETURN(true);
case DB_ONLINE_LOG_TOO_BIG:
my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0),
ha_alter_info->key_info_buffer[0].name);
get_error_key_name(err_key, ha_alter_info,
rebuilt_table));
DBUG_RETURN(true);
case DB_INDEX_CORRUPT:
my_error(ER_INDEX_CORRUPT, MYF(0),
(err_key == ULINT_UNDEFINED)
? FTS_DOC_ID_INDEX_NAME
: ha_alter_info->key_info_buffer[err_key]
.name);
get_error_key_name(err_key, ha_alter_info,
rebuilt_table));
DBUG_RETURN(true);
default:
my_error_innodb(error, table_name, user_table->flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment