1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

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

@ -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
}