diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.cc | 7 | ||||
-rw-r--r-- | sql/log.cc | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 50 | ||||
-rw-r--r-- | sql/opt_sum.cc | 2 | ||||
-rw-r--r-- | sql/scheduler.cc | 11 | ||||
-rw-r--r-- | sql/slave.cc | 1 | ||||
-rw-r--r-- | sql/sp_head.cc | 9 | ||||
-rw-r--r-- | sql/sql_base.cc | 4 | ||||
-rw-r--r-- | sql/sql_class.cc | 14 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_connect.cc | 3 | ||||
-rw-r--r-- | sql/sql_insert.cc | 17 | ||||
-rw-r--r-- | sql/sql_parse.cc | 17 | ||||
-rw-r--r-- | sql/sql_show.cc | 8 |
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, |