Commit 313215f1 authored by jyang's avatar jyang

branches/5.1: Add a special case to handle the Duplicated Key error

and return DB_ERROR instead. This is to avoid a possible SIGSEGV
by mysql error handling re-entering the storage layer for dup key
info without proper table handle.
This is to prevent a server crash when error situation in bug
#45961 "DDL on partitioned innodb tables leaves data dictionary
in an inconsistent state" happens.

rb://157 approved by Sunny Bains.
parent 9c9c6832
...@@ -662,6 +662,12 @@ convert_error_code_to_mysql( ...@@ -662,6 +662,12 @@ convert_error_code_to_mysql(
} else if (error == (int) DB_DUPLICATE_KEY) { } else if (error == (int) DB_DUPLICATE_KEY) {
/* Be cautious with returning this error, since
mysql could re-enter the storage layer to get
duplicated key info, the operation requires a
valid table handle and/or transaction information,
which might not always be available in the error
handling stage. */
return(HA_ERR_FOUND_DUPP_KEY); return(HA_ERR_FOUND_DUPP_KEY);
} else if (error == (int) DB_FOREIGN_DUPLICATE_KEY) { } else if (error == (int) DB_FOREIGN_DUPLICATE_KEY) {
...@@ -6038,6 +6044,25 @@ ha_innobase::rename_table( ...@@ -6038,6 +6044,25 @@ ha_innobase::rename_table(
innobase_commit_low(trx); innobase_commit_low(trx);
trx_free_for_mysql(trx); trx_free_for_mysql(trx);
/* Add a special case to handle the Duplicated Key error
and return DB_ERROR instead.
This is to avoid a possible SIGSEGV error from mysql error
handling code. Currently, mysql handles the Duplicated Key
error by re-entering the storage layer and getting dup key
info by calling get_dup_key(). This operation requires a valid
table handle ('row_prebuilt_t' structure) which could no
longer be available in the error handling stage. The suggested
solution is to report a 'table exists' error message (since
the dup key error here is due to an existing table whose name
is the one we are trying to rename to) and return the generic
error code. */
if (error == (int) DB_DUPLICATE_KEY)
{
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to);
error = DB_ERROR;
}
error = convert_error_code_to_mysql(error, NULL); error = convert_error_code_to_mysql(error, NULL);
DBUG_RETURN(error); DBUG_RETURN(error);
......
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