From 74543698a76c02d1a81e17e5918ecbf6b795607b Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 5 Aug 2017 19:26:10 +0300 Subject: 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) --- sql/sql_insert.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'sql/sql_insert.cc') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 092b2154c61..721fff389e0 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2681,7 +2681,7 @@ void kill_delayed_threads(void) { mysql_mutex_lock(&di->thd.LOCK_thd_data); if (di->thd.killed < KILL_CONNECTION) - di->thd.killed= KILL_CONNECTION; + di->thd.set_killed(KILL_CONNECTION); if (di->thd.mysys_var) { mysql_mutex_lock(&di->thd.mysys_var->mutex); @@ -2827,7 +2827,7 @@ pthread_handler_t handle_delayed_insert(void *arg) thd->set_current_time(); threads.append(thd); if (abort_loop) - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); else thd->reset_killed(); mysql_mutex_unlock(&LOCK_thread_count); @@ -2972,7 +2972,7 @@ pthread_handler_t handle_delayed_insert(void *arg) } #endif 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 */ 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))) { /* Fatal error */ - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); } mysql_cond_broadcast(&di->cond_client); } @@ -3010,7 +3010,7 @@ pthread_handler_t handle_delayed_insert(void *arg) if (di->handle_inserts()) { /* Some fatal error */ - thd->killed= KILL_CONNECTION; + thd->set_killed(KILL_CONNECTION); } } di->status=0; @@ -3054,7 +3054,7 @@ pthread_handler_t handle_delayed_insert(void *arg) this. */ 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); mysql_mutex_unlock(&thd->LOCK_thd_data); @@ -3143,7 +3143,7 @@ bool Delayed_insert::handle_inserts(void) max_rows= delayed_insert_limit; 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 } -- cgit v1.2.1