MDEV-13179 main.errors fails with wrong errno

The problem was that the introduction of max-thread-mem-used can cause
an allocation error very early, even before mysql_parse() is called.
As mysql_parse() calls thd->reset_for_next_command(), which called
clear_error(), the error number was lost.

Fixed by adding an option to have unique messages for each KILL
signal and change max-thread-mem-used to use this new feature.
This removes a lot of problems with the original approach, where
one could get errors signaled silenty almost any time.

ixed by moving clear_error() from reset_for_next_command() to
do_command(), before any memory allocation for the thread.

Related changes:
- reset_for_next_command() now have an optional parameter if we should
  call clear_error() or not. By default it's called, but not anymore from
  dispatch_command() which was the original problem.
- Added optional paramater to clear_error() to force calling of
  reset_diagnostics_area(). Before clear_error() only called
  reset_diagnostics_area() if there was no error, so we normally
  called reset_diagnostics_area() twice.
- This change removed several duplicated calls to clear_error()
  when starting a query.
- Reset max_mem_used on COM_QUIT, to protect against kill during
  quit.
- Use fatal_error() instead of setting is_fatal_error (cleanup)
- Set fatal_error if max_thead_mem_used is signaled.
  (Same logic we use for other places where we are out of resources)
This commit is contained in:
Monty 2017-08-05 19:26:10 +03:00
parent 008786aedb
commit 74543698a7
24 changed files with 177 additions and 101 deletions

View File

@ -140,8 +140,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
} }
/* Clear result variables */ /* Clear result variables */
thd->clear_error(); thd->clear_error(1);
thd->get_stmt_da()->reset_diagnostics_area();
mysql->affected_rows= ~(my_ulonglong) 0; mysql->affected_rows= ~(my_ulonglong) 0;
mysql->field_count= 0; mysql->field_count= 0;
net_clear_error(net); net_clear_error(net);

View File

@ -168,7 +168,7 @@ UPDATE t1 SET a = 'new'
WHERE COLUMN_CREATE( 1, 'v', 1, 'w' ) IS NULL; WHERE COLUMN_CREATE( 1, 'v', 1, 'w' ) IS NULL;
ERROR 22007: Illegal value used as argument of dynamic column function ERROR 22007: Illegal value used as argument of dynamic column function
drop table t1; drop table t1;
set max_session_mem_used = 50000;
select * from seq_1_to_1000;
set max_session_mem_used = 8192; set max_session_mem_used = 8192;
select * from seq_1_to_1000; select * from seq_1_to_1000;
Got one of the listed errors
set global max_session_mem_used = default;

View File

@ -203,7 +203,13 @@ drop table t1;
# #
# errors caused by max_session_mem_used # errors caused by max_session_mem_used
# #
set max_session_mem_used = 8192; --disable_result_log
--error ER_SQL_DISCOVER_ERROR,ER_OPTION_PREVENTS_STATEMENT set max_session_mem_used = 50000;
--error 0,ER_OPTION_PREVENTS_STATEMENT
select * from seq_1_to_1000; select * from seq_1_to_1000;
set global max_session_mem_used = default; set max_session_mem_used = 8192;
--error 0,ER_OPTION_PREVENTS_STATEMENT
select * from seq_1_to_1000;
--enable_result_log
# We may not be able to execute any more queries with this connection
# because of too little memory#

View File

@ -1502,7 +1502,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
{ {
if (!--action->hit_limit) if (!--action->hit_limit)
{ {
thd->killed= KILL_QUERY; thd->set_killed(KILL_QUERY);
my_error(ER_DEBUG_SYNC_HIT_LIMIT, MYF(0)); my_error(ER_DEBUG_SYNC_HIT_LIMIT, MYF(0));
} }
DBUG_PRINT("debug_sync_exec", ("hit_limit: %lu at: '%s'", DBUG_PRINT("debug_sync_exec", ("hit_limit: %lu at: '%s'",

View File

@ -371,12 +371,6 @@ static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
static void clear_all_errors(THD *thd, Relay_log_info *rli)
{
thd->is_slave_error = 0;
thd->clear_error();
}
inline int idempotent_error_code(int err_code) inline int idempotent_error_code(int err_code)
{ {
int ret= 0; int ret= 0;
@ -4255,7 +4249,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos)); DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); thd->clear_error(1);
current_stmt_is_commit= is_commit(); current_stmt_is_commit= is_commit();
DBUG_ASSERT(!current_stmt_is_commit || !rgi->tables_to_lock); DBUG_ASSERT(!current_stmt_is_commit || !rgi->tables_to_lock);
@ -4475,7 +4469,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
to check/fix it. to check/fix it.
*/ */
if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length())) if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length()))
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */ thd->clear_error(1);
else else
{ {
rli->report(ERROR_LEVEL, expected_error, rgi->gtid_info(), rli->report(ERROR_LEVEL, expected_error, rgi->gtid_info(),
@ -4556,7 +4550,7 @@ compare_errors:
ignored_error_code(actual_error)) ignored_error_code(actual_error))
{ {
DBUG_PRINT("info",("error ignored")); DBUG_PRINT("info",("error ignored"));
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); thd->clear_error(1);
if (actual_error == ER_QUERY_INTERRUPTED || if (actual_error == ER_QUERY_INTERRUPTED ||
actual_error == ER_CONNECTION_KILLED) actual_error == ER_CONNECTION_KILLED)
thd->reset_killed(); thd->reset_killed();
@ -6025,8 +6019,7 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length); new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
thd->set_db(new_db.str, new_db.length); thd->set_db(new_db.str, new_db.length);
DBUG_ASSERT(thd->query() == 0); DBUG_ASSERT(thd->query() == 0);
thd->is_slave_error= 0; thd->clear_error(1);
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
/* see Query_log_event::do_apply_event() and BUG#13360 */ /* see Query_log_event::do_apply_event() and BUG#13360 */
DBUG_ASSERT(!rgi->m_table_map.count()); DBUG_ASSERT(!rgi->m_table_map.count());
@ -6036,7 +6029,7 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
*/ */
lex_start(thd); lex_start(thd);
thd->lex->local_file= local_fname; thd->lex->local_file= local_fname;
thd->reset_for_next_command(); thd->reset_for_next_command(0); // Errors are cleared above
/* /*
We test replicate_*_db rules. Note that we have already prepared We test replicate_*_db rules. Note that we have already prepared
@ -10091,7 +10084,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table, slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table,
get_type_str(), get_type_str(),
RPL_LOG_NAME, (ulong) log_pos); RPL_LOG_NAME, (ulong) log_pos);
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); thd->clear_error(1);
error= 0; error= 0;
if (idempotent_error == 0) if (idempotent_error == 0)
break; break;
@ -10143,7 +10136,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table, slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table,
get_type_str(), get_type_str(),
RPL_LOG_NAME, (ulong) log_pos); RPL_LOG_NAME, (ulong) log_pos);
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); thd->clear_error(1);
error= 0; error= 0;
} }
} // if (table) } // if (table)

View File

@ -878,7 +878,7 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_LOCK_prepared_stmt_count, key_LOCK_prepared_stmt_count,
key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_rpl_status, key_LOCK_server_started,
key_LOCK_status, key_LOCK_show_status, key_LOCK_status, key_LOCK_show_status,
key_LOCK_system_variables_hash, key_LOCK_thd_data, key_LOCK_system_variables_hash, key_LOCK_thd_data, key_LOCK_thd_kill,
key_LOCK_user_conn, key_LOCK_uuid_short_generator, key_LOG_LOCK_log, key_LOCK_user_conn, key_LOCK_uuid_short_generator, key_LOG_LOCK_log,
key_master_info_data_lock, key_master_info_run_lock, key_master_info_data_lock, key_master_info_run_lock,
key_master_info_sleep_lock, key_master_info_start_stop_lock, key_master_info_sleep_lock, key_master_info_start_stop_lock,
@ -949,6 +949,7 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_LOCK_wait_commit, "wait_for_commit::LOCK_wait_commit", 0}, { &key_LOCK_wait_commit, "wait_for_commit::LOCK_wait_commit", 0},
{ &key_LOCK_gtid_waiting, "gtid_waiting::LOCK_gtid_waiting", 0}, { &key_LOCK_gtid_waiting, "gtid_waiting::LOCK_gtid_waiting", 0},
{ &key_LOCK_thd_data, "THD::LOCK_thd_data", 0}, { &key_LOCK_thd_data, "THD::LOCK_thd_data", 0},
{ &key_LOCK_thd_kill, "THD::LOCK_thd_kill", 0},
{ &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL}, { &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL},
{ &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL}, { &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL},
{ &key_LOG_LOCK_log, "LOG::LOCK_log", 0}, { &key_LOG_LOCK_log, "LOG::LOCK_log", 0},
@ -1650,7 +1651,7 @@ static void close_connections(void)
if (WSREP(tmp) && (tmp->wsrep_exec_mode==REPL_RECV || tmp->wsrep_applier)) if (WSREP(tmp) && (tmp->wsrep_exec_mode==REPL_RECV || tmp->wsrep_applier))
continue; continue;
#endif #endif
tmp->killed= KILL_SERVER_HARD; tmp->set_killed(KILL_SERVER_HARD);
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp)); MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
mysql_mutex_lock(&tmp->LOCK_thd_data); mysql_mutex_lock(&tmp->LOCK_thd_data);
if (tmp->mysys_var) if (tmp->mysys_var)
@ -1738,7 +1739,7 @@ static void close_connections(void)
if (WSREP(tmp) && tmp->wsrep_exec_mode==REPL_RECV) if (WSREP(tmp) && tmp->wsrep_exec_mode==REPL_RECV)
{ {
sql_print_information("closing wsrep system thread"); sql_print_information("closing wsrep system thread");
tmp->killed= KILL_CONNECTION; tmp->set_killed(KILL_CONNECTION);
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp)); MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
if (tmp->mysys_var) if (tmp->mysys_var)
{ {
@ -3943,11 +3944,16 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used && thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used &&
!thd->killed && !thd->get_stmt_da()->is_set()) !thd->killed && !thd->get_stmt_da()->is_set())
{ {
char buf[1024]; /* Ensure we don't get called here again */
thd->killed= KILL_QUERY; char buf[50], *buf2;
thd->set_killed(KILL_QUERY);
my_snprintf(buf, sizeof(buf), "--max-thread-mem-used=%llu", my_snprintf(buf, sizeof(buf), "--max-thread-mem-used=%llu",
thd->variables.max_mem_used); thd->variables.max_mem_used);
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf); if ((buf2= (char*) thd->alloc(256)))
{
my_snprintf(buf2, 256, ER_THD(thd, ER_OPTION_PREVENTS_STATEMENT), buf);
thd->set_killed(KILL_QUERY, ER_OPTION_PREVENTS_STATEMENT, buf2);
}
} }
DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0); DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0);
} }
@ -6318,7 +6324,7 @@ void create_thread_to_handle_connection(THD *thd)
DBUG_PRINT("error", DBUG_PRINT("error",
("Can't create thread to handle request (error %d)", ("Can't create thread to handle request (error %d)",
error)); error));
thd->killed= KILL_CONNECTION; // Safety thd->set_killed(KILL_CONNECTION); // Safety
mysql_mutex_unlock(&LOCK_thread_count); mysql_mutex_unlock(&LOCK_thread_count);
mysql_mutex_lock(&LOCK_connection_count); mysql_mutex_lock(&LOCK_connection_count);

View File

@ -290,7 +290,7 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_LOCK_prepared_stmt_count, key_LOCK_prepared_stmt_count,
key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_rpl_status, key_LOCK_server_started,
key_LOCK_status, key_LOCK_show_status, key_LOCK_status, key_LOCK_show_status,
key_LOCK_thd_data, key_LOCK_thd_data, key_LOCK_thd_kill,
key_LOCK_user_conn, key_LOG_LOCK_log, key_LOCK_user_conn, key_LOG_LOCK_log,
key_master_info_data_lock, key_master_info_run_lock, key_master_info_data_lock, key_master_info_run_lock,
key_master_info_sleep_lock, key_master_info_start_stop_lock, key_master_info_sleep_lock, key_master_info_start_stop_lock,

View File

@ -714,9 +714,7 @@ do_retry:
DBUG_EXECUTE_IF("inject_mdev8031", { DBUG_EXECUTE_IF("inject_mdev8031", {
/* Simulate that we get deadlock killed at this exact point. */ /* Simulate that we get deadlock killed at this exact point. */
rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED; rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED;
mysql_mutex_lock(&thd->LOCK_thd_data); thd->set_killed(KILL_CONNECTION);
thd->killed= KILL_CONNECTION;
mysql_mutex_unlock(&thd->LOCK_thd_data);
}); });
rgi->cleanup_context(thd, 1); rgi->cleanup_context(thd, 1);
wait_for_pending_deadlock_kill(thd, rgi); wait_for_pending_deadlock_kill(thd, rgi);
@ -862,9 +860,7 @@ do_retry:
/* Simulate that we get deadlock killed during open_binlog(). */ /* Simulate that we get deadlock killed during open_binlog(). */
thd->reset_for_next_command(); thd->reset_for_next_command();
rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED; rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED;
mysql_mutex_lock(&thd->LOCK_thd_data); thd->set_killed(KILL_CONNECTION);
thd->killed= KILL_CONNECTION;
mysql_mutex_unlock(&thd->LOCK_thd_data);
thd->send_kill_message(); thd->send_kill_message();
fd= (File)-1; fd= (File)-1;
err= 1; err= 1;

View File

@ -331,8 +331,7 @@ bool sp_rcontext::handle_sql_condition(THD *thd,
/* Reset error state. */ /* Reset error state. */
thd->clear_error(); thd->clear_error();
thd->killed= NOT_KILLED; // Some errors set thd->killed thd->reset_killed(); // Some errors set thd->killed, (e.g. "bad data").
// (e.g. "bad data").
/* Add a frame to handler-call-stack. */ /* Add a frame to handler-call-stack. */
Sql_condition_info *cond_info= Sql_condition_info *cond_info=

View File

@ -400,7 +400,7 @@ void kill_delayed_threads_for_table(TDC_element *element)
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) && if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
! in_use->killed) ! in_use->killed)
{ {
in_use->killed= KILL_SYSTEM_THREAD; in_use->set_killed(KILL_SYSTEM_THREAD);
mysql_mutex_lock(&in_use->mysys_var->mutex); mysql_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond) if (in_use->mysys_var->current_cond)
{ {
@ -9136,7 +9136,7 @@ bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use,
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) && if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
!in_use->killed) !in_use->killed)
{ {
in_use->killed= KILL_SYSTEM_THREAD; in_use->set_killed(KILL_SYSTEM_THREAD);
mysql_mutex_lock(&in_use->mysys_var->mutex); mysql_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond) if (in_use->mysys_var->current_cond)
{ {

View File

@ -2160,8 +2160,7 @@ lookup:
response, we can't handle it anyway. response, we can't handle it anyway.
*/ */
(void) trans_commit_stmt(thd); (void) trans_commit_stmt(thd);
if (!thd->get_stmt_da()->is_set()) thd->get_stmt_da()->disable_status();
thd->get_stmt_da()->disable_status();
BLOCK_UNLOCK_RD(query_block); BLOCK_UNLOCK_RD(query_block);
MYSQL_QUERY_CACHE_HIT(thd->query(), (ulong) thd->limit_found_rows); MYSQL_QUERY_CACHE_HIT(thd->query(), (ulong) thd->limit_found_rows);
@ -4615,7 +4614,7 @@ void Query_cache::wreck(uint line, const char *message)
DBUG_PRINT("warning", ("%5d QUERY CACHE WRECK => DISABLED",line)); DBUG_PRINT("warning", ("%5d QUERY CACHE WRECK => DISABLED",line));
DBUG_PRINT("warning", ("==================================")); DBUG_PRINT("warning", ("=================================="));
if (thd) if (thd)
thd->killed= KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
cache_dump(); cache_dump();
/* check_integrity(0); */ /* Can't call it here because of locks */ /* check_integrity(0); */ /* Can't call it here because of locks */
bins_dump(); bins_dump();

View File

@ -333,7 +333,7 @@ void thd_set_psi(THD *thd, PSI_thread *psi)
*/ */
void thd_set_killed(THD *thd) void thd_set_killed(THD *thd)
{ {
thd->killed= KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
} }
/** /**
@ -935,6 +935,7 @@ THD::THD(bool is_wsrep_applier)
query_start_used= query_start_sec_part_used= 0; query_start_used= query_start_sec_part_used= 0;
count_cuted_fields= CHECK_FIELD_IGNORE; count_cuted_fields= CHECK_FIELD_IGNORE;
killed= NOT_KILLED; killed= NOT_KILLED;
killed_err= 0;
col_access=0; col_access=0;
is_slave_error= thread_specific_used= FALSE; is_slave_error= thread_specific_used= FALSE;
my_hash_clear(&handler_tables_hash); my_hash_clear(&handler_tables_hash);
@ -992,6 +993,7 @@ THD::THD(bool is_wsrep_applier)
#endif #endif
mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_wakeup_ready, &LOCK_wakeup_ready, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_wakeup_ready, &LOCK_wakeup_ready, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_thd_kill, &LOCK_thd_kill, MY_MUTEX_INIT_FAST);
mysql_cond_init(key_COND_wakeup_ready, &COND_wakeup_ready, 0); mysql_cond_init(key_COND_wakeup_ready, &COND_wakeup_ready, 0);
/* /*
LOCK_thread_count goes before LOCK_thd_data - the former is called around LOCK_thread_count goes before LOCK_thd_data - the former is called around
@ -1256,7 +1258,7 @@ Sql_condition* THD::raise_condition(uint sql_errno,
push_warning and strict SQL_MODE case. push_warning and strict SQL_MODE case.
*/ */
level= Sql_condition::WARN_LEVEL_ERROR; level= Sql_condition::WARN_LEVEL_ERROR;
killed= KILL_BAD_DATA; set_killed(KILL_BAD_DATA);
} }
switch (level) switch (level)
@ -1564,7 +1566,7 @@ void THD::cleanup(void)
DBUG_ENTER("THD::cleanup"); DBUG_ENTER("THD::cleanup");
DBUG_ASSERT(cleanup_done == 0); DBUG_ASSERT(cleanup_done == 0);
killed= KILL_CONNECTION; set_killed(KILL_CONNECTION);
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE #ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
if (transaction.xid_state.xa_state == XA_PREPARED) if (transaction.xid_state.xa_state == XA_PREPARED)
{ {
@ -1667,6 +1669,7 @@ THD::~THD()
mysql_cond_destroy(&COND_wakeup_ready); mysql_cond_destroy(&COND_wakeup_ready);
mysql_mutex_destroy(&LOCK_wakeup_ready); mysql_mutex_destroy(&LOCK_wakeup_ready);
mysql_mutex_destroy(&LOCK_thd_data); mysql_mutex_destroy(&LOCK_thd_data);
mysql_mutex_destroy(&LOCK_thd_kill);
#ifndef DBUG_OFF #ifndef DBUG_OFF
dbug_sentry= THD_SENTRY_GONE; dbug_sentry= THD_SENTRY_GONE;
#endif #endif
@ -1839,7 +1842,8 @@ void THD::awake(killed_state state_to_set)
state_to_set= killed; state_to_set= killed;
/* Set the 'killed' flag of 'this', which is the target THD object. */ /* Set the 'killed' flag of 'this', which is the target THD object. */
killed= state_to_set; mysql_mutex_lock(&LOCK_thd_kill);
set_killed_no_mutex(state_to_set);
if (state_to_set >= KILL_CONNECTION || state_to_set == NOT_KILLED) if (state_to_set >= KILL_CONNECTION || state_to_set == NOT_KILLED)
{ {
@ -1925,6 +1929,7 @@ void THD::awake(killed_state state_to_set)
} }
mysql_mutex_unlock(&mysys_var->mutex); mysql_mutex_unlock(&mysys_var->mutex);
} }
mysql_mutex_unlock(&LOCK_thd_kill);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -1942,7 +1947,7 @@ void THD::disconnect()
mysql_mutex_lock(&LOCK_thd_data); mysql_mutex_lock(&LOCK_thd_data);
killed= KILL_CONNECTION; set_killed(KILL_CONNECTION);
#ifdef SIGNAL_WITH_VIO_CLOSE #ifdef SIGNAL_WITH_VIO_CLOSE
/* /*
@ -1978,7 +1983,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
DBUG_PRINT("info", ("kill delayed thread")); DBUG_PRINT("info", ("kill delayed thread"));
mysql_mutex_lock(&in_use->LOCK_thd_data); mysql_mutex_lock(&in_use->LOCK_thd_data);
if (in_use->killed < KILL_CONNECTION) if (in_use->killed < KILL_CONNECTION)
in_use->killed= KILL_CONNECTION; in_use->set_killed(KILL_CONNECTION);
if (in_use->mysys_var) if (in_use->mysys_var)
{ {
mysql_mutex_lock(&in_use->mysys_var->mutex); mysql_mutex_lock(&in_use->mysys_var->mutex);
@ -2031,13 +2036,21 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
/* /*
Get error number for killed state Get error number for killed state
Note that the error message can't have any parameters. Note that the error message can't have any parameters.
If one needs parameters, one should use THD::killed_err_msg
See thd::kill_message() See thd::kill_message()
*/ */
int killed_errno(killed_state killed) int THD::killed_errno()
{ {
DBUG_ENTER("killed_errno"); DBUG_ENTER("killed_errno");
DBUG_PRINT("enter", ("killed: %d", killed)); DBUG_PRINT("enter", ("killed: %d killed_errno: %d",
killed, killed_err ? killed_err->no: 0));
/* Ensure that killed_err is not set if we are not killed */
DBUG_ASSERT(!killed_err || killed != NOT_KILLED);
if (killed_err)
DBUG_RETURN(killed_err->no);
switch (killed) { switch (killed) {
case NOT_KILLED: case NOT_KILLED:
@ -2478,7 +2491,7 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
{ {
my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_FATALERROR), my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_FATALERROR),
ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1); ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
killed= KILL_CONNECTION; set_killed(KILL_CONNECTION);
return 0; return 0;
} }

View File

@ -482,7 +482,6 @@ enum killed_state
KILL_SERVER_HARD= 15 KILL_SERVER_HARD= 15
}; };
extern int killed_errno(killed_state killed);
#define killed_mask_hard(killed) ((killed_state) ((killed) & ~KILL_HARD_BIT)) #define killed_mask_hard(killed) ((killed_state) ((killed) & ~KILL_HARD_BIT))
enum killed_type enum killed_type
@ -1924,7 +1923,7 @@ public:
rpl_sql_thread_info *rpl_sql_info; rpl_sql_thread_info *rpl_sql_info;
} system_thread_info; } system_thread_info;
void reset_for_next_command(); void reset_for_next_command(bool do_clear_errors= 1);
/* /*
Constant for THD::where initialization in the beginning of every query. Constant for THD::where initialization in the beginning of every query.
@ -1980,6 +1979,8 @@ public:
Is locked when THD is deleted. Is locked when THD is deleted.
*/ */
mysql_mutex_t LOCK_thd_data; mysql_mutex_t LOCK_thd_data;
/* Protect kill information */
mysql_mutex_t LOCK_thd_kill;
/* all prepared statements and cursors of this connection */ /* all prepared statements and cursors of this connection */
Statement_map stmt_map; Statement_map stmt_map;
@ -2615,7 +2616,7 @@ public:
void check_limit_rows_examined() void check_limit_rows_examined()
{ {
if (++accessed_rows_and_keys > lex->limit_rows_examined_cnt) if (++accessed_rows_and_keys > lex->limit_rows_examined_cnt)
killed= ABORT_QUERY; set_killed(ABORT_QUERY);
} }
USER_CONN *user_connect; USER_CONN *user_connect;
@ -2716,6 +2717,16 @@ public:
*/ */
killed_state volatile killed; killed_state volatile killed;
/*
The following is used if one wants to have a specific error number and
text for the kill
*/
struct err_info
{
int no;
const char msg[256];
} *killed_err;
/* See also thd_killed() */ /* See also thd_killed() */
inline bool check_killed() inline bool check_killed()
{ {
@ -3280,18 +3291,18 @@ public:
@todo: To silence an error, one should use Internal_error_handler @todo: To silence an error, one should use Internal_error_handler
mechanism. Issuing an error that can be possibly later "cleared" is not mechanism. Issuing an error that can be possibly later "cleared" is not
compatible with other installed error handlers and audit plugins. compatible with other installed error handlers and audit plugins.
In future this function will be removed.
*/ */
inline void clear_error() inline void clear_error(bool clear_diagnostics= 0)
{ {
DBUG_ENTER("clear_error"); DBUG_ENTER("clear_error");
if (get_stmt_da()->is_error()) if (get_stmt_da()->is_error() || clear_diagnostics)
get_stmt_da()->reset_diagnostics_area(); get_stmt_da()->reset_diagnostics_area();
is_slave_error= 0; is_slave_error= 0;
if (killed == KILL_BAD_DATA) if (killed == KILL_BAD_DATA)
killed= NOT_KILLED; // KILL_BAD_DATA can be reset w/o a mutex reset_killed();
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
inline bool vio_ok() const { return net.vio != 0; } inline bool vio_ok() const { return net.vio != 0; }
/** Return FALSE if connection to client is broken. */ /** Return FALSE if connection to client is broken. */
@ -3401,10 +3412,54 @@ public:
state after execution of a non-prepared SQL statement. state after execution of a non-prepared SQL statement.
*/ */
void end_statement(); void end_statement();
inline int killed_errno() const
/*
Mark thread to be killed, with optional error number and string.
string is not released, so it has to be allocted on thd mem_root
or be a global string
Ensure that we don't replace a kill with a lesser one. For example
if user has done 'kill_connection' we shouldn't replace it with
KILL_QUERY.
*/
inline void set_killed(killed_state killed_arg,
int killed_errno_arg= 0,
const char *killed_err_msg_arg= 0)
{ {
return ::killed_errno(killed); mysql_mutex_lock(&LOCK_thd_kill);
set_killed_no_mutex(killed_arg, killed_errno_arg, killed_err_msg_arg);
mysql_mutex_unlock(&LOCK_thd_kill);
} }
/*
This is only used by THD::awake where we need to keep the lock mutex
locked over some time.
It's ok to have this inline, as in most cases killed_errno_arg will
be a constant 0 and most of the function will disappear.
*/
inline void set_killed_no_mutex(killed_state killed_arg,
int killed_errno_arg= 0,
const char *killed_err_msg_arg= 0)
{
if (killed <= killed_arg)
{
killed= killed_arg;
if (killed_errno_arg)
{
/*
If alloc fails, we only remember the killed flag.
The worst things that can happen is that we get
a suboptimal error message.
*/
if ((killed_err= (err_info*) alloc(sizeof(*killed_err))))
{
killed_err->no= killed_errno_arg;
::strmake((char*) killed_err->msg, killed_err_msg_arg,
sizeof(killed_err->msg)-1);
}
}
}
}
int killed_errno();
inline void reset_killed() inline void reset_killed()
{ {
/* /*
@ -3413,9 +3468,10 @@ public:
*/ */
if (killed != NOT_KILLED) if (killed != NOT_KILLED)
{ {
mysql_mutex_lock(&LOCK_thd_data); mysql_mutex_lock(&LOCK_thd_kill);
killed= NOT_KILLED; killed= NOT_KILLED;
mysql_mutex_unlock(&LOCK_thd_data); killed_err= 0;
mysql_mutex_unlock(&LOCK_thd_kill);
} }
} }
inline void reset_kill_query() inline void reset_kill_query()
@ -3426,11 +3482,14 @@ public:
mysys_var->abort= 0; mysys_var->abort= 0;
} }
} }
inline void send_kill_message() const inline void send_kill_message()
{ {
mysql_mutex_lock(&LOCK_thd_kill);
int err= killed_errno(); int err= killed_errno();
if (err) if (err)
my_message(err, ER_THD(this, err), MYF(0)); my_message(err, killed_err ? killed_err->msg : ER_THD(this, err),
MYF(0));
mysql_mutex_unlock(&LOCK_thd_kill);
} }
/* return TRUE if we will abort query if we make a warning now */ /* return TRUE if we will abort query if we make a warning now */
inline bool really_abort_on_warning() inline bool really_abort_on_warning()

View File

@ -1196,7 +1196,7 @@ void prepare_new_connection_state(THD* thd)
if (thd->is_error()) if (thd->is_error())
{ {
Host_errors errors; Host_errors errors;
thd->killed= KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
thd->print_aborted_warning(0, "init_connect command failed"); thd->print_aborted_warning(0, "init_connect command failed");
sql_print_warning("%s", thd->get_stmt_da()->message()); sql_print_warning("%s", thd->get_stmt_da()->message());

View File

@ -2681,7 +2681,7 @@ void kill_delayed_threads(void)
{ {
mysql_mutex_lock(&di->thd.LOCK_thd_data); mysql_mutex_lock(&di->thd.LOCK_thd_data);
if (di->thd.killed < KILL_CONNECTION) if (di->thd.killed < KILL_CONNECTION)
di->thd.killed= KILL_CONNECTION; di->thd.set_killed(KILL_CONNECTION);
if (di->thd.mysys_var) if (di->thd.mysys_var)
{ {
mysql_mutex_lock(&di->thd.mysys_var->mutex); mysql_mutex_lock(&di->thd.mysys_var->mutex);
@ -2827,7 +2827,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
thd->set_current_time(); thd->set_current_time();
threads.append(thd); threads.append(thd);
if (abort_loop) if (abort_loop)
thd->killed= KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
else else
thd->reset_killed(); thd->reset_killed();
mysql_mutex_unlock(&LOCK_thread_count); mysql_mutex_unlock(&LOCK_thread_count);
@ -2972,7 +2972,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
} }
#endif #endif
if (error == ETIMEDOUT || error == ETIME) if (error == ETIMEDOUT || error == ETIME)
thd->killed= KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
} }
/* We can't lock di->mutex and mysys_var->mutex at the same time */ /* We can't lock di->mutex and mysys_var->mutex at the same time */
mysql_mutex_unlock(&di->mutex); mysql_mutex_unlock(&di->mutex);
@ -3001,7 +3001,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
if (! (thd->lock= mysql_lock_tables(thd, &di->table, 1, 0))) if (! (thd->lock= mysql_lock_tables(thd, &di->table, 1, 0)))
{ {
/* Fatal error */ /* Fatal error */
thd->killed= KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
} }
mysql_cond_broadcast(&di->cond_client); mysql_cond_broadcast(&di->cond_client);
} }
@ -3010,7 +3010,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
if (di->handle_inserts()) if (di->handle_inserts())
{ {
/* Some fatal error */ /* Some fatal error */
thd->killed= KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
} }
} }
di->status=0; di->status=0;
@ -3054,7 +3054,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
this. this.
*/ */
mysql_mutex_lock(&thd->LOCK_thd_data); mysql_mutex_lock(&thd->LOCK_thd_data);
thd->killed= KILL_CONNECTION_HARD; // If error thd->set_killed(KILL_CONNECTION_HARD); // If error
thd->mdl_context.set_needs_thr_lock_abort(0); thd->mdl_context.set_needs_thr_lock_abort(0);
mysql_mutex_unlock(&thd->LOCK_thd_data); mysql_mutex_unlock(&thd->LOCK_thd_data);
@ -3143,7 +3143,7 @@ bool Delayed_insert::handle_inserts(void)
max_rows= delayed_insert_limit; max_rows= delayed_insert_limit;
if (thd.killed || table->s->tdc->flushed) if (thd.killed || table->s->tdc->flushed)
{ {
thd.killed= KILL_SYSTEM_THREAD; thd.set_killed(KILL_SYSTEM_THREAD);
max_rows= ULONG_MAX; // Do as much as possible max_rows= ULONG_MAX; // Do as much as possible
} }

View File

@ -613,7 +613,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
DBUG_EXECUTE_IF("simulate_kill_bug27571", DBUG_EXECUTE_IF("simulate_kill_bug27571",
{ {
error=1; error=1;
thd->killed= KILL_QUERY; thd->set_killed(KILL_QUERY);
};); };);
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY

View File

@ -669,6 +669,7 @@ void execute_init_command(THD *thd, LEX_STRING *init_command,
*/ */
save_vio= thd->net.vio; save_vio= thd->net.vio;
thd->net.vio= 0; thd->net.vio= 0;
thd->clear_error(1);
dispatch_command(COM_QUERY, thd, buf, len); dispatch_command(COM_QUERY, thd, buf, len);
thd->client_capabilities= save_client_capabilities; thd->client_capabilities= save_client_capabilities;
thd->net.vio= save_vio; thd->net.vio= save_vio;
@ -800,6 +801,7 @@ static void handle_bootstrap_impl(THD *thd)
if (bootstrap_error) if (bootstrap_error)
break; break;
thd->reset_kill_query(); /* Ensure that killed_errmsg is released */
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC)); free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
thd->lex->restore_set_statement_var(); thd->lex->restore_set_statement_var();
@ -954,13 +956,8 @@ bool do_command(THD *thd)
if(!thd->skip_wait_timeout) if(!thd->skip_wait_timeout)
my_net_set_read_timeout(net, thd->variables.net_wait_timeout); my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
/* Errors and diagnostics are cleared once here before query */
/* thd->clear_error(1);
XXX: this code is here only to clear possible errors of init_connect.
Consider moving to init_connect() instead.
*/
thd->clear_error(); // Clear error message
thd->get_stmt_da()->reset_diagnostics_area();
net_new_transaction(net); net_new_transaction(net);
@ -1123,6 +1120,7 @@ bool do_command(THD *thd)
WSREP_WARN("For retry temporally setting character set to : %s", WSREP_WARN("For retry temporally setting character set to : %s",
my_charset_latin1.csname); my_charset_latin1.csname);
} }
thd->clear_error();
return_value= dispatch_command(command, thd, thd->wsrep_retry_query, return_value= dispatch_command(command, thd, thd->wsrep_retry_query,
thd->wsrep_retry_query_len); thd->wsrep_retry_query_len);
thd->variables.character_set_client = current_charset; thd->variables.character_set_client = current_charset;
@ -1272,7 +1270,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
my_error(ER_LOCK_DEADLOCK, MYF(0), "wsrep aborted transaction"); my_error(ER_LOCK_DEADLOCK, MYF(0), "wsrep aborted transaction");
WSREP_DEBUG("Deadlock error for: %s", thd->query()); WSREP_DEBUG("Deadlock error for: %s", thd->query());
mysql_mutex_unlock(&thd->LOCK_wsrep_thd); mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
thd->killed = NOT_KILLED; thd->reset_killed();
thd->mysys_var->abort = 0; thd->mysys_var->abort = 0;
thd->wsrep_conflict_state = NO_CONFLICT; thd->wsrep_conflict_state = NO_CONFLICT;
thd->wsrep_retry_counter = 0; thd->wsrep_retry_counter = 0;
@ -1625,7 +1623,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break; break;
} }
packet= arg_end + 1; packet= arg_end + 1;
thd->reset_for_next_command(); thd->reset_for_next_command(0); // Don't clear errors
lex_start(thd); lex_start(thd);
/* Must be before we init the table list. */ /* Must be before we init the table list. */
if (lower_case_table_names) if (lower_case_table_names)
@ -1694,7 +1692,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
} }
#endif #endif
case COM_QUIT: case COM_QUIT:
/* We don't calculate statistics for this command */ /* Note: We don't calculate statistics for this command */
/* Ensure that quit works even if max_mem_used is set */
thd->variables.max_mem_used= LONGLONG_MAX;
general_log_print(thd, command, NullS); general_log_print(thd, command, NullS);
net->error=0; // Don't give 'abort' message net->error=0; // Don't give 'abort' message
thd->get_stmt_da()->disable_status(); // Don't send anything back thd->get_stmt_da()->disable_status(); // Don't send anything back
@ -1974,6 +1975,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
dec_thread_running(); dec_thread_running();
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
thd->reset_kill_query(); /* Ensure that killed_errmsg is released */
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
#if defined(ENABLED_PROFILING) #if defined(ENABLED_PROFILING)
@ -5047,7 +5049,7 @@ end_with_restore_list:
/* Disconnect the current client connection. */ /* Disconnect the current client connection. */
if (tx_release) if (tx_release)
{ {
thd->killed= KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
thd->print_aborted_warning(3, "RELEASE"); thd->print_aborted_warning(3, "RELEASE");
} }
#ifdef WITH_WSREP #ifdef WITH_WSREP
@ -5093,7 +5095,7 @@ end_with_restore_list:
} }
/* Disconnect the current client connection. */ /* Disconnect the current client connection. */
if (tx_release) if (tx_release)
thd->killed= KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (WSREP(thd) && thd->wsrep_conflict_state != NO_CONFLICT) if (WSREP(thd) && thd->wsrep_conflict_state != NO_CONFLICT)
{ {
@ -6879,6 +6881,8 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
Reset the part of THD responsible for the state of command Reset the part of THD responsible for the state of command
processing. processing.
@param do_clear_error Set if we should clear errors
This needs to be called before execution of every statement This needs to be called before execution of every statement
(prepared or conventional). It is not called by substatements of (prepared or conventional). It is not called by substatements of
routines. routines.
@ -6886,12 +6890,16 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
@todo Call it after we use THD for queries, not before. @todo Call it after we use THD for queries, not before.
*/ */
void THD::reset_for_next_command() void THD::reset_for_next_command(bool do_clear_error)
{ {
THD *thd= this; THD *thd= this;
DBUG_ENTER("THD::reset_for_next_command"); DBUG_ENTER("THD::reset_for_next_command");
DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */ DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
DBUG_ASSERT(! thd->in_sub_stmt); DBUG_ASSERT(! thd->in_sub_stmt);
if (do_clear_error)
clear_error(1);
thd->free_list= 0; thd->free_list= 0;
thd->select_number= 1; thd->select_number= 1;
/* /*
@ -6947,8 +6955,6 @@ void THD::reset_for_next_command()
reset_dynamic(&thd->user_var_events); reset_dynamic(&thd->user_var_events);
thd->user_var_events_alloc= thd->mem_root; thd->user_var_events_alloc= thd->mem_root;
} }
thd->clear_error();
thd->get_stmt_da()->reset_diagnostics_area();
thd->get_stmt_da()->reset_for_next_command(); thd->get_stmt_da()->reset_for_next_command();
thd->rand_used= 0; thd->rand_used= 0;
thd->m_sent_row_count= thd->m_examined_row_count= 0; thd->m_sent_row_count= thd->m_examined_row_count= 0;
@ -7180,7 +7186,7 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
thd->wsrep_conflict_state == CERT_FAILURE) thd->wsrep_conflict_state == CERT_FAILURE)
{ {
thd->reset_for_next_command(); thd->reset_for_next_command();
thd->killed= NOT_KILLED; thd->reset_killed();
if (is_autocommit && if (is_autocommit &&
thd->lex->sql_command != SQLCOM_SELECT && thd->lex->sql_command != SQLCOM_SELECT &&
(thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit)) (thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit))
@ -7208,7 +7214,7 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
thd->thread_id, is_autocommit, thd->wsrep_retry_counter, thd->thread_id, is_autocommit, thd->wsrep_retry_counter,
thd->variables.wsrep_retry_autocommit, thd->query()); thd->variables.wsrep_retry_autocommit, thd->query());
my_error(ER_LOCK_DEADLOCK, MYF(0), "wsrep aborted transaction"); my_error(ER_LOCK_DEADLOCK, MYF(0), "wsrep aborted transaction");
thd->killed= NOT_KILLED; thd->reset_killed();
thd->wsrep_conflict_state= NO_CONFLICT; thd->wsrep_conflict_state= NO_CONFLICT;
if (thd->wsrep_conflict_state != REPLAYING) if (thd->wsrep_conflict_state != REPLAYING)
thd->wsrep_retry_counter= 0; // reset thd->wsrep_retry_counter= 0; // reset
@ -8282,10 +8288,10 @@ void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
uint error; uint error;
if (!(error= kill_one_thread(thd, id, state, type))) if (!(error= kill_one_thread(thd, id, state, type)))
{ {
if ((!thd->killed)) if (!thd->killed)
my_ok(thd); my_ok(thd);
else else
my_error(killed_errno(thd->killed), MYF(0), id); thd->send_kill_message();
} }
else else
my_error(error, MYF(0), id); my_error(error, MYF(0), id);

View File

@ -3592,7 +3592,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
#endif #endif
DBUG_EXECUTE_IF("bug11747970_raise_error", DBUG_EXECUTE_IF("bug11747970_raise_error",
{ join->thd->killed= KILL_QUERY_HARD; }); { join->thd->set_killed(KILL_QUERY_HARD); });
if (error) if (error)
{ {
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));

View File

@ -4783,7 +4783,7 @@ int create_table_impl(THD *thd,
thd->variables.option_bits|= OPTION_KEEP_LOG; thd->variables.option_bits|= OPTION_KEEP_LOG;
thd->log_current_statement= 1; thd->log_current_statement= 1;
create_info->table_was_deleted= 1; create_info->table_was_deleted= 1;
DBUG_EXECUTE_IF("send_kill_after_delete", thd->killed= KILL_QUERY; ); DBUG_EXECUTE_IF("send_kill_after_delete", thd->set_killed(KILL_QUERY); );
/* /*
Restart statement transactions for the case of CREATE ... SELECT. Restart statement transactions for the case of CREATE ... SELECT.

View File

@ -940,7 +940,7 @@ int mysql_update(THD *thd,
// simulated killing after the loop must be ineffective for binlogging // simulated killing after the loop must be ineffective for binlogging
DBUG_EXECUTE_IF("simulate_kill_bug27571", DBUG_EXECUTE_IF("simulate_kill_bug27571",
{ {
thd->killed= KILL_QUERY; thd->set_killed(KILL_QUERY);
};); };);
error= (killed_status == NOT_KILLED)? error : 1; error= (killed_status == NOT_KILLED)? error : 1;

View File

@ -463,7 +463,7 @@ static void timeout_check(pool_timer_t *timer)
{ {
/* Wait timeout exceeded, kill connection. */ /* Wait timeout exceeded, kill connection. */
mysql_mutex_lock(&thd->LOCK_thd_data); mysql_mutex_lock(&thd->LOCK_thd_data);
thd->killed = KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
post_kill_notification(thd); post_kill_notification(thd);
mysql_mutex_unlock(&thd->LOCK_thd_data); mysql_mutex_unlock(&thd->LOCK_thd_data);
} }

View File

@ -613,7 +613,7 @@ static VOID CALLBACK timer_callback(PTP_CALLBACK_INSTANCE instance,
if (timeout <= now()) if (timeout <= now())
{ {
con->thd->killed = KILL_CONNECTION; con->thd->set_killed(KILL_CONNECTION);
if(con->thd->net.vio) if(con->thd->net.vio)
vio_shutdown(con->thd->net.vio, SD_BOTH); vio_shutdown(con->thd->net.vio, SD_BOTH);
} }

View File

@ -1965,7 +1965,7 @@ static bool have_client_connections()
static void wsrep_close_thread(THD *thd) static void wsrep_close_thread(THD *thd)
{ {
thd->killed= KILL_CONNECTION; thd->set_killed(KILL_CONNECTION);
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (thd)); MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (thd));
if (thd->mysys_var) if (thd->mysys_var)
{ {
@ -2045,7 +2045,7 @@ void wsrep_close_client_connections(my_bool wait_to_end)
if (is_replaying_connection(tmp)) if (is_replaying_connection(tmp))
{ {
tmp->killed= KILL_CONNECTION; tmp->set_killed(KILL_CONNECTION);
continue; continue;
} }

View File

@ -232,7 +232,7 @@ void wsrep_replay_transaction(THD *thd)
mysql_mutex_unlock(&thd->LOCK_wsrep_thd); mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
thd->reset_for_next_command(); thd->reset_for_next_command();
thd->killed= NOT_KILLED; thd->reset_killed();
close_thread_tables(thd); close_thread_tables(thd);
if (thd->locked_tables_mode && thd->lock) if (thd->locked_tables_mode && thd->lock)
{ {