Commit 4235167f authored by Jon Olav Hauglid's avatar Jon Olav Hauglid

Backport of revno: 2599.169.2

Bug #42074 concurrent optimize table and 
           alter table = Assertion failed: thd->is_error()

This assertion could occur if OPTIMIZE TABLE was started on a InnoDB table
and the table was altered to different storage engine after OPTIMIZE
had started. This allowed OPTIMIZE to pass the initial checks for 
storage engine support, but fail once it reached "recreate+analyze"
if this operation was not supported by the new storage engine.
The bug had no consequences for non-debug builds of the server.

In detail, the assertion was triggered when ha_analyze() returned 
HA_ADMIN_NOT_IMPLEMENTED. This led to a code path which included an 
assert checking for diagnostics area contents. Since this area had 
not been filled, the assertion was triggered. The diagnostics area 
is in this case only used to provide more detailed information about 
why optimize failed. The triggered code path sends this information 
to the client and clears the diagnostic area.

This patch fixed the problem by adding an error message to the diagnostic 
area if ha_analyze() fails. This error message contains the error code
returned by ha_analyze().

Test case added to innodb_mysql_sync.test.
parent 19ff2445
#
# Bug 42074 concurrent optimize table and
# alter table = Assertion failed: thd->is_error()
#
DROP TABLE IF EXISTS t1;
# Create InnoDB table
CREATE TABLE t1 (id INT) engine=innodb;
# Connection 1
# Start optimizing table
SET DEBUG_SYNC='ha_admin_try_alter SIGNAL optimize_started WAIT_FOR table_altered';
OPTIMIZE TABLE t1;
# Connection 2
# Change table to engine=memory
SET DEBUG_SYNC='now WAIT_FOR optimize_started';
ALTER TABLE t1 engine=memory;
SET DEBUG_SYNC='now SIGNAL table_altered';
# Connection 1
# Complete optimization
Table Op Msg_type Msg_text
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
test.t1 optimize error Got error -1 from storage engine
test.t1 optimize status Operation failed
Warnings:
Error 1030 Got error -1 from storage engine
DROP TABLE t1;
SET DEBUG_SYNC='RESET';
#
# Test file for InnoDB tests that require the debug sync facility
#
--source include/have_innodb.inc
--source include/have_debug_sync.inc
# Save the initial number of concurrent sessions.
--source include/count_sessions.inc
--echo #
--echo # Bug 42074 concurrent optimize table and
--echo # alter table = Assertion failed: thd->is_error()
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
--echo # Create InnoDB table
CREATE TABLE t1 (id INT) engine=innodb;
connect (con2, localhost, root);
--echo # Connection 1
--echo # Start optimizing table
connection default;
SET DEBUG_SYNC='ha_admin_try_alter SIGNAL optimize_started WAIT_FOR table_altered';
--send OPTIMIZE TABLE t1
--echo # Connection 2
--echo # Change table to engine=memory
connection con2;
SET DEBUG_SYNC='now WAIT_FOR optimize_started';
ALTER TABLE t1 engine=memory;
SET DEBUG_SYNC='now SIGNAL table_altered';
--echo # Connection 1
--echo # Complete optimization
connection default;
--reap
disconnect con2;
DROP TABLE t1;
SET DEBUG_SYNC='RESET';
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
...@@ -4878,6 +4878,7 @@ send_result_message: ...@@ -4878,6 +4878,7 @@ send_result_message:
close_thread_tables(thd); close_thread_tables(thd);
if (!thd->locked_tables_mode) if (!thd->locked_tables_mode)
thd->mdl_context.release_all_locks(); thd->mdl_context.release_all_locks();
DEBUG_SYNC(thd, "ha_admin_try_alter");
protocol->store(STRING_WITH_LEN("note"), system_charset_info); protocol->store(STRING_WITH_LEN("note"), system_charset_info);
protocol->store(STRING_WITH_LEN( protocol->store(STRING_WITH_LEN(
"Table does not support optimize, doing recreate + analyze instead"), "Table does not support optimize, doing recreate + analyze instead"),
...@@ -4911,6 +4912,8 @@ send_result_message: ...@@ -4911,6 +4912,8 @@ send_result_message:
if ((table->table= open_ltable(thd, table, lock_type, 0)) && if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0)) ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
result_code= 0; // analyze went ok result_code= 0; // analyze went ok
if (result_code) // analyze failed
table->table->file->print_error(result_code, MYF(0));
} }
/* Start a new row for the final status row */ /* Start a new row for the final status row */
protocol->prepare_for_resend(); protocol->prepare_for_resend();
......
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