summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc7
-rw-r--r--sql/log.cc3
-rw-r--r--sql/mysqld.cc50
-rw-r--r--sql/opt_sum.cc2
-rw-r--r--sql/scheduler.cc11
-rw-r--r--sql/slave.cc1
-rw-r--r--sql/sp_head.cc9
-rw-r--r--sql/sql_base.cc4
-rw-r--r--sql/sql_class.cc14
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_connect.cc3
-rw-r--r--sql/sql_insert.cc17
-rw-r--r--sql/sql_parse.cc17
-rw-r--r--sql/sql_show.cc8
14 files changed, 104 insertions, 44 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 751e31fdf9f..905668114dd 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1403,9 +1403,14 @@ int ha_rollback_trans(THD *thd, bool all)
slave SQL thread, it would not stop the thread but just be printed in
the error log; but we don't want users to wonder why they have this
message in the error log, so we don't send it.
+
+ We don't have to test for thd->killed == THD::KILL_SYSTEM_THREAD as
+ it doesn't matter if a warning is pushed to a system thread or not:
+ No one will see it...
*/
if (is_real_trans && thd->transaction.all.modified_non_trans_table &&
- !thd->slave_thread && thd->killed != THD::KILL_CONNECTION)
+ !thd->slave_thread && thd->killed != THD::KILL_CONNECTION &&
+ thd->killed != THD::KILL_SERVER)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
diff --git a/sql/log.cc b/sql/log.cc
index d345d0f6102..e53c8d12770 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -5175,7 +5175,8 @@ int query_error_code(THD *thd, bool not_killed)
is not set to these errors when specified not_killed by the
caller.
*/
- if (error == ER_SERVER_SHUTDOWN || error == ER_QUERY_INTERRUPTED)
+ if (error == ER_SERVER_SHUTDOWN || error == ER_QUERY_INTERRUPTED ||
+ error == ER_NEW_ABORTING_CONNECTION)
error= 0;
}
else
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index a3417282661..97472777185 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2034,6 +2034,17 @@ void close_connection(THD *thd, uint errcode, bool lock)
if (lock)
(void) pthread_mutex_lock(&LOCK_thread_count);
thd->killed= THD::KILL_CONNECTION;
+
+ if (global_system_variables.log_warnings > 3)
+ {
+ Security_context *sctx= &thd->main_security_ctx;
+ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
+ thd->thread_id,(thd->db ? thd->db : "unconnected"),
+ sctx->user ? sctx->user : "unauthenticated",
+ sctx->host_or_ip,
+ (errcode ? ER(errcode) : "CLOSE_CONNECTION"));
+ }
+
if ((vio= thd->net.vio) != 0)
{
if (errcode)
@@ -2195,24 +2206,6 @@ void flush_thread_cache()
}
-#ifdef THREAD_SPECIFIC_SIGPIPE
-/**
- Aborts a thread nicely. Comes here on SIGPIPE.
-
- @todo
- One should have to fix that thr_alarm know about this thread too.
-*/
-extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
-{
- THD *thd=current_thd;
- DBUG_ENTER("abort_thread");
- if (thd)
- thd->killed= THD::KILL_CONNECTION;
- DBUG_VOID_RETURN;
-}
-#endif
-
-
/******************************************************************************
Setup a signal thread with handles all signals.
Because Linux doesn't support schemas use a mutex to check that
@@ -2747,6 +2740,12 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
case THD::KILL_QUERY:
kreason= "KILL_QUERY";
break;
+ case THD::KILL_SYSTEM_THREAD:
+ kreason= "KILL_SYSTEM_THREAD";
+ break;
+ case THD::KILL_SERVER:
+ kreason= "KILL_SERVER";
+ break;
case THD::KILLED_NO_VALUE:
kreason= "KILLED_NO_VALUE";
break;
@@ -6142,7 +6141,9 @@ enum options_mysqld
OPT_SECURE_FILE_PRIV,
OPT_MIN_EXAMINED_ROW_LIMIT,
OPT_LOG_SLOW_SLAVE_STATEMENTS,
- OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_DEBUG_ASSERT_IF_CRASHED_TABLE, OPT_OLD_MODE,
+ OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_DEBUG_ASSERT_IF_CRASHED_TABLE,
+ OPT_DEBUG_ASSERT_ON_ERROR,
+ OPT_OLD_MODE,
OPT_TEST_IGNORE_WRONG_OPTIONS, OPT_TEST_RESTART,
#if defined(ENABLED_DEBUG_SYNC)
OPT_DEBUG_SYNC_TIMEOUT,
@@ -6332,6 +6333,10 @@ struct my_option my_long_options[] =
"Do an assert in handler::print_error() if we get a crashed table",
&debug_assert_if_crashed_table, &debug_assert_if_crashed_table,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug-assert-on-error", OPT_DEBUG_ASSERT_ON_ERROR,
+ "Do an assert in various functions if we get a fatal error",
+ &my_assert_on_error, &my_assert_on_error,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD,
"Set the default character set (deprecated option, use --character-set-server instead).",
@@ -9580,14 +9585,17 @@ static int get_options(int *argc,char **argv)
my_crc_dbug_check= opt_my_crc_dbug_check;
/*
- Log mysys errors when we don't have a thd or thd->log_all_errors is set (recovery) to
- the log. This is mainly useful for debugging strange system errors.
+ Log mysys errors when we don't have a thd or thd->log_all_errors is set
+ (recovery) to the log. This is mainly useful for debugging strange system
+ errors.
*/
if (global_system_variables.log_warnings >= 10)
my_global_flags= MY_WME | ME_JUST_INFO;
/* Log all errors not handled by thd->handle_error() to my_message_sql() */
if (global_system_variables.log_warnings >= 11)
my_global_flags|= ME_NOREFRESH;
+ if (my_assert_on_error)
+ debug_assert_if_crashed_table= 1;
/* long_query_time is in microseconds */
global_system_variables.long_query_time= max_system_variables.long_query_time=
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 43fbe17a25b..dc93548418a 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -671,6 +671,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
case Item_func::GE_FUNC:
break;
case Item_func::BETWEEN:
+ if (((Item_func_between*) cond)->negated)
+ DBUG_RETURN(FALSE);
between= 1;
break;
case Item_func::MULT_EQUAL_FUNC:
diff --git a/sql/scheduler.cc b/sql/scheduler.cc
index 5b8f834aecc..6dd93640dc5 100644
--- a/sql/scheduler.cc
+++ b/sql/scheduler.cc
@@ -376,7 +376,9 @@ void libevent_kill_thd_callback(int Fd, short, void*)
{
THD *thd= (THD*)list->data;
list= list_rest(list);
- if (thd->killed == THD::KILL_CONNECTION)
+ if (thd->killed == THD::KILL_CONNECTION ||
+ thd->killed == THD::KILL_SYSTEM_THREAD ||
+ thd->killed == THD::KILL_SERVER)
{
/*
Delete from libevent and add to the processing queue.
@@ -531,9 +533,10 @@ static void libevent_connection_close(THD *thd)
static bool libevent_should_close_connection(THD* thd)
{
- return thd->net.error ||
- thd->net.vio == 0 ||
- thd->killed == THD::KILL_CONNECTION;
+ return (thd->net.error ||
+ thd->net.vio == 0 ||
+ thd->killed == THD::KILL_CONNECTION ||
+ thd->killed == THD::KILL_SERVER);
}
diff --git a/sql/slave.cc b/sql/slave.cc
index cfa6c9fdc56..1ab1caecfb5 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -837,6 +837,7 @@ bool is_network_error(uint errorno)
errorno == CR_SERVER_GONE_ERROR ||
errorno == CR_SERVER_LOST ||
errorno == ER_CON_COUNT_ERROR ||
+ errorno == ER_NEW_ABORTING_CONNECTION ||
errorno == ER_SERVER_SHUTDOWN)
return TRUE;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index bd2dcfd8653..6532e6c56f2 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -374,8 +374,8 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
thd->abort_on_warning=
- thd->variables.sql_mode &
- (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES);
+ test(thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
thd->transaction.stmt.modified_non_trans_table= FALSE;
/* Save the value in the field. Convert the value if needed. */
@@ -1362,7 +1362,10 @@ sp_head::execute(THD *thd)
If the DB has changed, the pointer has changed too, but the
original thd->db will then have been freed
*/
- if (cur_db_changed && thd->killed != THD::KILL_CONNECTION)
+ if (cur_db_changed &&
+ thd->killed != THD::KILL_CONNECTION &&
+ thd->killed != THD::KILL_SERVER &&
+ thd->killed != THD::KILL_SYSTEM_THREAD)
{
/*
Force switching back to the saved current database, because it may be
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 9268fe53167..bca8167f2b9 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -8896,7 +8896,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
{
if (!in_use->killed)
{
- in_use->killed= THD::KILL_CONNECTION;
+ in_use->killed= THD::KILL_SYSTEM_THREAD;
pthread_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond)
{
@@ -9230,7 +9230,7 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
! in_use->killed)
{
- in_use->killed= THD::KILL_CONNECTION;
+ in_use->killed= THD::KILL_SYSTEM_THREAD;
pthread_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond)
{
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 6344ac45574..16165cdedbb 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1273,6 +1273,15 @@ void THD::awake(THD::killed_state state_to_set)
THD_CHECK_SENTRY(this);
safe_mutex_assert_owner(&LOCK_thd_data);
+ if (global_system_variables.log_warnings > 3)
+ {
+ Security_context *sctx= security_ctx;
+ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
+ thread_id,(db ? db : "unconnected"),
+ sctx->user ? sctx->user : "unauthenticated",
+ sctx->host_or_ip,
+ "KILLED");
+ }
killed= state_to_set;
if (state_to_set != THD::KILL_QUERY)
{
@@ -3392,7 +3401,10 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
extern "C" int thd_killed(const MYSQL_THD thd)
{
- return(thd->killed);
+ if (thd->killed == THD::NOT_KILLED || thd->killed == THD::KILL_BAD_DATA ||
+ thd->killed == THD::KILL_SYSTEM_THREAD)
+ return 0;
+ return thd->killed;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 3403126a3aa..748c2a4a818 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1978,7 +1978,9 @@ public:
NOT_KILLED=0,
KILL_BAD_DATA=1,
KILL_CONNECTION=ER_SERVER_SHUTDOWN,
+ KILL_SYSTEM_THREAD=ER_NEW_ABORTING_CONNECTION, /* Kill connection nicely */
KILL_QUERY=ER_QUERY_INTERRUPTED,
+ KILL_SERVER, /* Placeholder for shortdown */
KILLED_NO_VALUE /* means neither of the states */
};
killed_state volatile killed;
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index f6bfe975d51..5b7d392d773 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -1181,7 +1181,8 @@ pthread_handler_t handle_one_connection(void *arg)
prepare_new_connection_state(thd);
while (!net->error && net->vio != 0 &&
- !(thd->killed == THD::KILL_CONNECTION))
+ thd->killed != THD::KILL_CONNECTION &&
+ thd->killed != THD::KILL_SERVER)
{
if (do_command(thd))
break;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 386650ff99c..b840eebf4cc 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2362,7 +2362,7 @@ void kill_delayed_threads(void)
Delayed_insert *di;
while ((di= it++))
{
- di->thd.killed= THD::KILL_CONNECTION;
+ di->thd.killed= THD::KILL_SYSTEM_THREAD;
pthread_mutex_lock(&di->thd.LOCK_thd_data);
if (di->thd.mysys_var)
{
@@ -2447,7 +2447,8 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
for (;;)
{
- if (thd->killed == THD::KILL_CONNECTION)
+ if (thd->killed == THD::KILL_CONNECTION ||
+ thd->killed == THD::KILL_SYSTEM_THREAD || thd->killed == THD::KILL_SERVER)
{
uint lock_count;
/*
@@ -2495,7 +2496,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
break;
if (error == ETIMEDOUT || error == ETIME)
{
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= THD::KILL_SYSTEM_THREAD;
break;
}
}
@@ -2528,7 +2529,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
{
/* Fatal error */
di->dead= 1;
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= THD::KILL_SYSTEM_THREAD;
}
pthread_cond_broadcast(&di->cond_client);
}
@@ -2538,7 +2539,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
{
/* Some fatal error */
di->dead= 1;
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= THD::KILL_SYSTEM_THREAD;
}
}
di->status=0;
@@ -2598,7 +2599,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
thd->set_current_time();
threads.append(thd);
- thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
+ thd->killed=abort_loop ? THD::KILL_SYSTEM_THREAD : THD::NOT_KILLED;
pthread_mutex_unlock(&LOCK_thread_count);
/*
@@ -2632,7 +2633,7 @@ end:
di->table=0;
di->dead= 1; // If error
- thd->killed= THD::KILL_CONNECTION; // If error
+ thd->killed= THD::KILL_SYSTEM_THREAD; // If error
pthread_mutex_unlock(&di->mutex);
close_thread_tables(thd); // Free the table
@@ -2711,7 +2712,7 @@ bool Delayed_insert::handle_inserts(void)
max_rows= delayed_insert_limit;
if (thd.killed || table->needs_reopen_or_name_lock())
{
- thd.killed= THD::KILL_CONNECTION;
+ thd.killed= THD::KILL_SYSTEM_THREAD;
max_rows= ULONG_MAX; // Do as much as possible
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f9d9536f11b..f850dc9145f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -792,7 +792,17 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
if (res < 0)
my_error(thd->killed_errno(), MYF(0));
else if ((res == 0) && do_release)
+ {
thd->killed= THD::KILL_CONNECTION;
+ if (global_system_variables.log_warnings > 3)
+ {
+ Security_context *sctx= &thd->main_security_ctx;
+ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
+ thd->thread_id,(thd->db ? thd->db : "unconnected"),
+ sctx->user ? sctx->user : "unauthenticated",
+ sctx->host_or_ip, "RELEASE");
+ }
+ }
DBUG_RETURN(res);
}
@@ -1614,6 +1624,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd_proc_info(thd, 0);
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
+
+ /* Check that some variables are reset properly */
+ DBUG_ASSERT(thd->abort_on_warning == 0);
DBUG_RETURN(error);
}
@@ -7197,6 +7210,10 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
If user of both killer and killee are non-NULL, proceed with
slayage if both are string-equal.
+
+ It's ok to also kill DELAYED threads with KILL_CONNECTION instead of
+ KILL_SYSTEM_THREAD; The difference is that KILL_CONNECTION may be
+ faster and do a harder kill than KILL_SYSTEM_THREAD;
*/
if ((thd->security_ctx->master_access & SUPER_ACL) ||
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index e4981701025..2a717ba1572 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1943,7 +1943,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
pthread_mutex_lock(&tmp->LOCK_thd_data);
if ((mysys_var= tmp->mysys_var))
pthread_mutex_lock(&mysys_var->mutex);
- thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
+ thd_info->proc_info= (char*) (tmp->killed != THD::NOT_KILLED &&
+ tmp->killed != THD::KILL_BAD_DATA ?
+ "Killed" : 0);
#ifndef EMBEDDED_LIBRARY
thd_info->state_info= (char*) (tmp->net.reading_or_writing ?
(tmp->net.reading_or_writing == 2 ?
@@ -2082,7 +2084,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
if ((mysys_var= tmp->mysys_var))
pthread_mutex_lock(&mysys_var->mutex);
/* COMMAND */
- if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
+ if ((val= (char *) ((tmp->killed != THD::NOT_KILLED &&
+ tmp->killed != THD::KILL_BAD_DATA ?
+ "Killed" : 0))))
table->field[4]->store(val, strlen(val), cs);
else
table->field[4]->store(command_name[tmp->command].str,