Skip to content

Commit

Permalink
Bug#24444831 MY_ERROR(ER_INNODB_ONLINE_LOG_TOO_BIG) CALLED WITH INVAL…
Browse files Browse the repository at this point in the history
…ID 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: Jimmy Yang <jimmy.yang@oracle.com>
  • Loading branch information
Marko Mäkelä authored and dr-m committed Apr 26, 2017
1 parent 9a848ee commit 93078c9
Showing 1 changed file with 28 additions and 13 deletions.
41 changes: 28 additions & 13 deletions storage/innobase/handler/handler0alter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 93078c9

Please sign in to comment.