Skip to content

Commit a29ba4e

Browse files
committed
Bug#33218625: Intermittent failure in handler::ha_rnd_init when opening cursor if max_execution_time expires or KILL QUERY
The problem here is that if the killed flag is set during execution of an SQL statement that is attached to a cursor, the code that opens the cursor may check the killed flag and skip opening the table. However, since the error flag is not propagated as an error in the diagnostics area, we miss checking for this situation later and attempts to access the table which is not in an open state. The problem is within the final section of mysql_execute_command(), where the killed flag is checked only if the statement is not part of a substatement. This check is moved so that it is performed unconditionally. Any error state from this check is also handled so that a kill signal is processed like any other execution failure. In the bug case, open_tables_for_query() would exit prematurely, thus the query would not be executed, and the cursor table would not be opened for reading, but no diagnostics state would be set so execution thread would continue to access the cursor table. Change-Id: I69e8928a34823291e5464f24446940132cdca19b
1 parent bb13c24 commit a29ba4e

File tree

2 files changed

+6
-1
lines changed

2 files changed

+6
-1
lines changed

sql/sql_cursor.cc

+1
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ bool mysql_open_cursor(THD *thd, Query_result *result,
230230
parent_locker = thd->m_statement_psi;
231231
thd->m_digest = nullptr;
232232
thd->m_statement_psi = nullptr;
233+
DBUG_EXECUTE_IF("bug33218625_kill_injection", thd->killed = THD::KILL_QUERY;);
233234

234235
bool rc = mysql_execute_command(thd);
235236

sql/sql_parse.cc

+5-1
Original file line numberDiff line numberDiff line change
@@ -4762,6 +4762,11 @@ int mysql_execute_command(THD *thd, bool first_level) {
47624762

47634763
THD_STAGE_INFO(thd, stage_query_end);
47644764

4765+
// Check for receiving a recent kill signal
4766+
if (thd->killed) {
4767+
thd->send_kill_message();
4768+
res = thd->is_error();
4769+
}
47654770
if (res) {
47664771
if (thd->get_reprepare_observer() != nullptr &&
47674772
thd->get_reprepare_observer()->is_invalidated() &&
@@ -4796,7 +4801,6 @@ int mysql_execute_command(THD *thd, bool first_level) {
47964801
: "MYSQL_AUDIT_QUERY_NESTED_STATUS_END");
47974802

47984803
/* report error issued during command execution */
4799-
if (thd->killed) thd->send_kill_message();
48004804
if ((thd->is_error() && !early_error_on_rep_command) ||
48014805
(thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
48024806
trans_rollback_stmt(thd);

0 commit comments

Comments
 (0)