MDEV-18400 - Move shutdown handling to main thread
Signal handler is now respoinsible for setting abort_loop and breaking poll() in main thread. The rest is handled by main thread itself. Removed redundant LOCK_error_log init/destroy wrappers. Removed redundant unireg_end(): it is trivial and it has only one caller. Removed unused ready_to_exit from PFS. Removed kill_in_progress: duplicates abort_loop. Removed shutdown_in_progress: duplicates abort_loop. Removed ready_to_exit: was used to make sure main thread waits for cleanups, which are now done by main thread itself. Removed SIGNALS_DONT_BREAK_READ, MAYBE_BROKEN_SYSCALL, kill_broken_server: never defined/used. Make clean_up() static.
This commit is contained in:
parent
c2318291be
commit
8553525931
@ -137,7 +137,7 @@ static int prepare_for_fill(TABLE_LIST *tables)
|
|||||||
*/
|
*/
|
||||||
static bool going_down()
|
static bool going_down()
|
||||||
{
|
{
|
||||||
return shutdown_plugin || shutdown_in_progress || (thd && thd->killed);
|
return shutdown_plugin || abort_loop || (thd && thd->killed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,6 +17,5 @@
|
|||||||
#define INIT_INCLUDED
|
#define INIT_INCLUDED
|
||||||
|
|
||||||
void unireg_init(ulong options);
|
void unireg_init(ulong options);
|
||||||
void unireg_end(void);
|
|
||||||
|
|
||||||
#endif /* INIT_INCLUDED */
|
#endif /* INIT_INCLUDED */
|
||||||
|
373
sql/mysqld.cc
373
sql/mysqld.cc
@ -129,7 +129,7 @@
|
|||||||
|
|
||||||
/* We have HAVE_valgrind below as this speeds up the shutdown of MySQL */
|
/* We have HAVE_valgrind below as this speeds up the shutdown of MySQL */
|
||||||
|
|
||||||
#if defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_valgrind) && defined(__linux__)
|
#if defined(HAVE_valgrind) && defined(__linux__)
|
||||||
#define HAVE_CLOSE_SERVER_SOCK 1
|
#define HAVE_CLOSE_SERVER_SOCK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -345,7 +345,6 @@ PSI_statement_info stmt_info_rpl;
|
|||||||
static bool lower_case_table_names_used= 0;
|
static bool lower_case_table_names_used= 0;
|
||||||
static bool max_long_data_size_used= false;
|
static bool max_long_data_size_used= false;
|
||||||
static bool volatile select_thread_in_use, signal_thread_in_use;
|
static bool volatile select_thread_in_use, signal_thread_in_use;
|
||||||
static volatile bool ready_to_exit;
|
|
||||||
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
|
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
|
||||||
static my_bool opt_short_log_format= 0, opt_silent_startup= 0;
|
static my_bool opt_short_log_format= 0, opt_silent_startup= 0;
|
||||||
bool my_disable_leak_check= false;
|
bool my_disable_leak_check= false;
|
||||||
@ -395,7 +394,6 @@ bool opt_endinfo, using_udf_functions;
|
|||||||
my_bool locked_in_memory;
|
my_bool locked_in_memory;
|
||||||
bool opt_using_transactions;
|
bool opt_using_transactions;
|
||||||
bool volatile abort_loop;
|
bool volatile abort_loop;
|
||||||
bool volatile shutdown_in_progress;
|
|
||||||
uint volatile global_disable_checkpoint;
|
uint volatile global_disable_checkpoint;
|
||||||
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
|
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
|
||||||
ulong slow_start_timeout;
|
ulong slow_start_timeout;
|
||||||
@ -685,6 +683,8 @@ SHOW_COMP_OPTION have_crypt, have_compress;
|
|||||||
SHOW_COMP_OPTION have_profiling;
|
SHOW_COMP_OPTION have_profiling;
|
||||||
SHOW_COMP_OPTION have_openssl;
|
SHOW_COMP_OPTION have_openssl;
|
||||||
|
|
||||||
|
static std::atomic<char*> shutdown_user;
|
||||||
|
|
||||||
/* Thread specific variables */
|
/* Thread specific variables */
|
||||||
|
|
||||||
pthread_key(THD*, THR_THD);
|
pthread_key(THD*, THR_THD);
|
||||||
@ -692,7 +692,6 @@ pthread_key(THD*, THR_THD);
|
|||||||
/*
|
/*
|
||||||
LOCK_thread_count protects the following variables:
|
LOCK_thread_count protects the following variables:
|
||||||
thread_count Number of threads with THD that servers queries.
|
thread_count Number of threads with THD that servers queries.
|
||||||
ready_to_exit
|
|
||||||
*/
|
*/
|
||||||
mysql_mutex_t LOCK_thread_count;
|
mysql_mutex_t LOCK_thread_count;
|
||||||
|
|
||||||
@ -759,7 +758,6 @@ char *opt_binlog_index_name=0;
|
|||||||
|
|
||||||
/* Static variables */
|
/* Static variables */
|
||||||
|
|
||||||
static volatile sig_atomic_t kill_in_progress;
|
|
||||||
my_bool opt_stack_trace;
|
my_bool opt_stack_trace;
|
||||||
my_bool opt_expect_abort= 0, opt_bootstrap= 0;
|
my_bool opt_expect_abort= 0, opt_bootstrap= 0;
|
||||||
static my_bool opt_myisam_log;
|
static my_bool opt_myisam_log;
|
||||||
@ -1507,7 +1505,6 @@ static int fix_paths(void);
|
|||||||
void handle_connections_sockets();
|
void handle_connections_sockets();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pthread_handler_t kill_server_thread(void *arg);
|
|
||||||
static bool read_init_file(char *file_name);
|
static bool read_init_file(char *file_name);
|
||||||
pthread_handler_t handle_slave(void *arg);
|
pthread_handler_t handle_slave(void *arg);
|
||||||
static void clean_up(bool print_message);
|
static void clean_up(bool print_message);
|
||||||
@ -1632,20 +1629,29 @@ static my_bool kill_all_threads_once_again(THD *thd, void *)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void close_connections(void)
|
/**
|
||||||
|
Kills main thread.
|
||||||
|
|
||||||
|
@note this function is responsible for setting abort_loop and breaking
|
||||||
|
poll() in main thread. Shutdown as such is supposed to be performed by main
|
||||||
|
thread itself.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void break_connect_loop()
|
||||||
{
|
{
|
||||||
#ifdef EXTRA_DEBUG
|
#ifdef EXTRA_DEBUG
|
||||||
int count=0;
|
int count=0;
|
||||||
#endif
|
#endif
|
||||||
DBUG_ENTER("close_connections");
|
|
||||||
|
|
||||||
/* Clear thread cache */
|
abort_loop= 1;
|
||||||
kill_cached_threads++;
|
|
||||||
flush_thread_cache();
|
|
||||||
|
|
||||||
|
#if defined(__WIN__)
|
||||||
/* kill connection thread */
|
if (!SetEvent(hEventShutdown))
|
||||||
#if !defined(__WIN__)
|
DBUG_PRINT("error", ("Got error: %ld from SetEvent", GetLastError()));
|
||||||
|
#else
|
||||||
|
/* Avoid waiting for ourselves when thread-handling=no-threads. */
|
||||||
|
if (pthread_equal(pthread_self(), select_thread))
|
||||||
|
return;
|
||||||
DBUG_PRINT("quit", ("waiting for select thread: %lu",
|
DBUG_PRINT("quit", ("waiting for select thread: %lu",
|
||||||
(ulong)select_thread));
|
(ulong)select_thread));
|
||||||
|
|
||||||
@ -1676,8 +1682,44 @@ static void close_connections(void)
|
|||||||
}
|
}
|
||||||
mysql_mutex_unlock(&LOCK_start_thread);
|
mysql_mutex_unlock(&LOCK_start_thread);
|
||||||
#endif /* __WIN__ */
|
#endif /* __WIN__ */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A wrapper around kill_main_thrad().
|
||||||
|
|
||||||
|
Sets shutdown user. This function may be called by multiple threads
|
||||||
|
concurrently, thus it performs safe update of shutdown_user
|
||||||
|
(first thread wins).
|
||||||
|
*/
|
||||||
|
|
||||||
|
void kill_mysql(THD *thd)
|
||||||
|
{
|
||||||
|
char user_host_buff[MAX_USER_HOST_SIZE + 1];
|
||||||
|
char *user, *expected_shutdown_user= 0;
|
||||||
|
|
||||||
|
make_user_name(thd, user_host_buff);
|
||||||
|
|
||||||
|
if ((user= my_strdup(user_host_buff, MYF(0))) &&
|
||||||
|
!shutdown_user.compare_exchange_strong(expected_shutdown_user,
|
||||||
|
user,
|
||||||
|
std::memory_order_relaxed,
|
||||||
|
std::memory_order_relaxed))
|
||||||
|
{
|
||||||
|
my_free(user);
|
||||||
|
}
|
||||||
|
break_connect_loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void close_connections(void)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("close_connections");
|
||||||
|
|
||||||
|
/* Clear thread cache */
|
||||||
|
kill_cached_threads++;
|
||||||
|
flush_thread_cache();
|
||||||
|
|
||||||
/* Abort listening to new connections */
|
/* Abort listening to new connections */
|
||||||
DBUG_PRINT("quit",("Closing sockets"));
|
DBUG_PRINT("quit",("Closing sockets"));
|
||||||
if (!opt_disable_networking )
|
if (!opt_disable_networking )
|
||||||
@ -1800,144 +1842,6 @@ static void close_server_sock()
|
|||||||
#endif /*EMBEDDED_LIBRARY*/
|
#endif /*EMBEDDED_LIBRARY*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Set shutdown user
|
|
||||||
|
|
||||||
@note this function may be called by multiple threads concurrently, thus
|
|
||||||
it performs safe update of shutdown_user (first thread wins).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static volatile char *shutdown_user;
|
|
||||||
static void set_shutdown_user(THD *thd)
|
|
||||||
{
|
|
||||||
char user_host_buff[MAX_USER_HOST_SIZE + 1];
|
|
||||||
char *user, *expected_shutdown_user= 0;
|
|
||||||
|
|
||||||
make_user_name(thd, user_host_buff);
|
|
||||||
|
|
||||||
if ((user= my_strdup(user_host_buff, MYF(0))) &&
|
|
||||||
!my_atomic_casptr((void **) &shutdown_user,
|
|
||||||
(void **) &expected_shutdown_user, user))
|
|
||||||
my_free(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void kill_mysql(THD *thd)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("kill_mysql");
|
|
||||||
|
|
||||||
if (thd)
|
|
||||||
set_shutdown_user(thd);
|
|
||||||
|
|
||||||
#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY)
|
|
||||||
abort_loop=1; // Break connection loops
|
|
||||||
close_server_sock(); // Force accept to wake up
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__WIN__)
|
|
||||||
#if !defined(EMBEDDED_LIBRARY)
|
|
||||||
{
|
|
||||||
if (!SetEvent(hEventShutdown))
|
|
||||||
{
|
|
||||||
DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#elif defined(HAVE_PTHREAD_KILL)
|
|
||||||
if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
|
|
||||||
{
|
|
||||||
DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
|
|
||||||
}
|
|
||||||
#elif !defined(SIGNALS_DONT_BREAK_READ)
|
|
||||||
kill(current_pid, MYSQL_KILL_SIGNAL);
|
|
||||||
#endif
|
|
||||||
DBUG_PRINT("quit",("After pthread_kill"));
|
|
||||||
shutdown_in_progress=1; // Safety if kill didn't work
|
|
||||||
#ifdef SIGNALS_DONT_BREAK_READ
|
|
||||||
if (!kill_in_progress)
|
|
||||||
{
|
|
||||||
pthread_t tmp;
|
|
||||||
int error;
|
|
||||||
abort_loop=1;
|
|
||||||
if (unlikely((error= mysql_thread_create(0, /* Not instrumented */
|
|
||||||
&tmp, &connection_attrib,
|
|
||||||
kill_server_thread, (void*) 0))))
|
|
||||||
sql_print_error("Can't create thread to kill server (errno= %d).",
|
|
||||||
error);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Force server down. Kill all connections and threads and exit.
|
|
||||||
|
|
||||||
@param sig Signal number that caused kill_server to be called.
|
|
||||||
|
|
||||||
@note
|
|
||||||
A signal number of 0 mean that the function was not called
|
|
||||||
from a signal handler and there is thus no signal to block
|
|
||||||
or stop, we just want to kill the server.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void kill_server(int sig)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("kill_server");
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
|
||||||
// if there is a signal during the kill in progress, ignore the other
|
|
||||||
if (kill_in_progress) // Safety
|
|
||||||
{
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
kill_in_progress=TRUE;
|
|
||||||
abort_loop=1; // This should be set
|
|
||||||
if (sig != 0) // 0 is not a valid signal number
|
|
||||||
my_sigset(sig, SIG_IGN); /* purify inspected */
|
|
||||||
if (sig == MYSQL_KILL_SIGNAL || sig == 0)
|
|
||||||
{
|
|
||||||
char *user= (char *) my_atomic_loadptr((void**) &shutdown_user);
|
|
||||||
sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN), my_progname,
|
|
||||||
user ? user : "unknown");
|
|
||||||
if (user)
|
|
||||||
my_free(user);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sql_print_error(ER_DEFAULT(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
|
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
|
||||||
/* Stop wsrep threads in case they are running. */
|
|
||||||
if (wsrep_running_threads > 0)
|
|
||||||
{
|
|
||||||
wsrep_shutdown_replication();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
close_connections();
|
|
||||||
|
|
||||||
if (sig != MYSQL_KILL_SIGNAL &&
|
|
||||||
sig != 0)
|
|
||||||
unireg_abort(1); /* purecov: inspected */
|
|
||||||
else
|
|
||||||
unireg_end();
|
|
||||||
|
|
||||||
#endif /* EMBEDDED_LIBRARY*/
|
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(USE_ONE_SIGNAL_HAND)
|
|
||||||
pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
|
|
||||||
{
|
|
||||||
my_thread_init(); // Initialize new thread
|
|
||||||
kill_server(0);
|
|
||||||
my_thread_end();
|
|
||||||
pthread_exit(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" sig_handler print_signal_warning(int sig)
|
extern "C" sig_handler print_signal_warning(int sig)
|
||||||
{
|
{
|
||||||
if (global_system_variables.log_warnings)
|
if (global_system_variables.log_warnings)
|
||||||
@ -1953,36 +1857,6 @@ extern "C" sig_handler print_signal_warning(int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
|
||||||
static void init_error_log_mutex()
|
|
||||||
{
|
|
||||||
mysql_mutex_init(key_LOCK_error_log, &LOCK_error_log, MY_MUTEX_INIT_FAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void clean_up_error_log_mutex()
|
|
||||||
{
|
|
||||||
mysql_mutex_destroy(&LOCK_error_log);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
cleanup all memory and end program nicely.
|
|
||||||
|
|
||||||
If SIGNALS_DONT_BREAK_READ is defined, this function is called
|
|
||||||
by the main thread. To get MySQL to shut down nicely in this case
|
|
||||||
(Mac OS X) we have to call exit() instead if pthread_exit().
|
|
||||||
|
|
||||||
@note
|
|
||||||
This function never returns.
|
|
||||||
*/
|
|
||||||
void unireg_end(void)
|
|
||||||
{
|
|
||||||
clean_up(1);
|
|
||||||
sd_notify(0, "STATUS=MariaDB server is down");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" void unireg_abort(int exit_code)
|
extern "C" void unireg_abort(int exit_code)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("unireg_abort");
|
DBUG_ENTER("unireg_abort");
|
||||||
@ -2003,7 +1877,6 @@ extern "C" void unireg_abort(int exit_code)
|
|||||||
wsrep threads here, we can only diconnect from service
|
wsrep threads here, we can only diconnect from service
|
||||||
*/
|
*/
|
||||||
wsrep_close_client_connections(FALSE);
|
wsrep_close_client_connections(FALSE);
|
||||||
shutdown_in_progress= 1;
|
|
||||||
Wsrep_server_state::instance().disconnect();
|
Wsrep_server_state::instance().disconnect();
|
||||||
WSREP_INFO("Service disconnected.");
|
WSREP_INFO("Service disconnected.");
|
||||||
wsrep_close_threads(NULL); /* this won't close all threads */
|
wsrep_close_threads(NULL); /* this won't close all threads */
|
||||||
@ -2049,7 +1922,6 @@ static void mysqld_exit(int exit_code)
|
|||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
mysql_audit_finalize();
|
mysql_audit_finalize();
|
||||||
clean_up_mutexes();
|
clean_up_mutexes();
|
||||||
clean_up_error_log_mutex();
|
|
||||||
my_end((opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0));
|
my_end((opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0));
|
||||||
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
|
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
|
||||||
shutdown_performance_schema(); // we do it as late as possible
|
shutdown_performance_schema(); // we do it as late as possible
|
||||||
@ -2074,7 +1946,7 @@ static void mysqld_exit(int exit_code)
|
|||||||
|
|
||||||
#endif /* !EMBEDDED_LIBRARY */
|
#endif /* !EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
void clean_up(bool print_message)
|
static void clean_up(bool print_message)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("exit",("clean_up"));
|
DBUG_PRINT("exit",("clean_up"));
|
||||||
if (cleanup_done++)
|
if (cleanup_done++)
|
||||||
@ -2173,16 +2045,6 @@ void clean_up(bool print_message)
|
|||||||
sys_var_end();
|
sys_var_end();
|
||||||
free_charsets();
|
free_charsets();
|
||||||
|
|
||||||
/*
|
|
||||||
Signal mysqld_main() that it can exit
|
|
||||||
do the broadcast inside the lock to ensure that my_end() is not called
|
|
||||||
during broadcast()
|
|
||||||
*/
|
|
||||||
mysql_mutex_lock(&LOCK_thread_count);
|
|
||||||
ready_to_exit=1;
|
|
||||||
mysql_cond_broadcast(&COND_thread_count);
|
|
||||||
mysql_mutex_unlock(&LOCK_thread_count);
|
|
||||||
|
|
||||||
my_free(const_cast<char*>(log_bin_basename));
|
my_free(const_cast<char*>(log_bin_basename));
|
||||||
my_free(const_cast<char*>(log_bin_index));
|
my_free(const_cast<char*>(log_bin_index));
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
@ -2275,6 +2137,9 @@ static void clean_up_mutexes()
|
|||||||
mysql_mutex_destroy(&LOCK_commit_ordered);
|
mysql_mutex_destroy(&LOCK_commit_ordered);
|
||||||
mysql_mutex_destroy(&LOCK_slave_background);
|
mysql_mutex_destroy(&LOCK_slave_background);
|
||||||
mysql_cond_destroy(&COND_slave_background);
|
mysql_cond_destroy(&COND_slave_background);
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
mysql_mutex_destroy(&LOCK_error_log);
|
||||||
|
#endif
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2707,7 +2572,6 @@ void close_connection(THD *thd, uint sql_errno)
|
|||||||
mysql_audit_notify_connection_disconnect(thd, sql_errno);
|
mysql_audit_notify_connection_disconnect(thd, sql_errno);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
|
||||||
|
|
||||||
|
|
||||||
/** Called when mysqld is aborted with ^C */
|
/** Called when mysqld is aborted with ^C */
|
||||||
@ -2715,11 +2579,12 @@ void close_connection(THD *thd, uint sql_errno)
|
|||||||
extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused)))
|
extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused)))
|
||||||
{
|
{
|
||||||
DBUG_ENTER("end_mysqld_signal");
|
DBUG_ENTER("end_mysqld_signal");
|
||||||
/* Don't call kill_mysql() if signal thread is not running */
|
/* Don't kill if signal thread is not running */
|
||||||
if (signal_thread_in_use)
|
if (signal_thread_in_use)
|
||||||
kill_mysql(); // Take down mysqld nicely
|
break_connect_loop(); // Take down mysqld nicely
|
||||||
DBUG_VOID_RETURN; /* purecov: deadcode */
|
DBUG_VOID_RETURN; /* purecov: deadcode */
|
||||||
}
|
}
|
||||||
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Decrease number of connections
|
Decrease number of connections
|
||||||
@ -2965,7 +2830,7 @@ static BOOL WINAPI console_event_handler( DWORD type )
|
|||||||
*/
|
*/
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
if(hEventShutdown)
|
if(hEventShutdown)
|
||||||
kill_mysql();
|
break_connect_loop();
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
sql_print_warning("CTRL-C ignored during startup");
|
sql_print_warning("CTRL-C ignored during startup");
|
||||||
@ -3304,6 +3169,18 @@ static void start_signal_handler(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(USE_ONE_SIGNAL_HAND)
|
||||||
|
pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
|
||||||
|
{
|
||||||
|
my_thread_init(); // Initialize new thread
|
||||||
|
break_connect_loop();
|
||||||
|
my_thread_end();
|
||||||
|
pthread_exit(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** This threads handles all signals and alarms. */
|
/** This threads handles all signals and alarms. */
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
||||||
@ -3359,13 +3236,8 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
int origin;
|
int origin;
|
||||||
if (shutdown_in_progress && !abort_loop)
|
|
||||||
{
|
while ((error= my_sigwait(&set, &sig, &origin)) == EINTR) /* no-op */;
|
||||||
sig= SIGTERM;
|
|
||||||
error=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
while ((error= my_sigwait(&set, &sig, &origin)) == EINTR) /* no-op */;
|
|
||||||
if (cleanup_done)
|
if (cleanup_done)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
|
DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
|
||||||
@ -3388,7 +3260,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
|||||||
DBUG_PRINT("info",("Got signal: %d abort_loop: %d",sig,abort_loop));
|
DBUG_PRINT("info",("Got signal: %d abort_loop: %d",sig,abort_loop));
|
||||||
if (!abort_loop)
|
if (!abort_loop)
|
||||||
{
|
{
|
||||||
abort_loop=1; // mark abort for threads
|
|
||||||
/* Delete the instrumentation for the signal thread */
|
/* Delete the instrumentation for the signal thread */
|
||||||
PSI_CALL_delete_current_thread();
|
PSI_CALL_delete_current_thread();
|
||||||
#ifdef USE_ONE_SIGNAL_HAND
|
#ifdef USE_ONE_SIGNAL_HAND
|
||||||
@ -3400,7 +3271,8 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
|||||||
sql_print_error("Can't create thread to kill server (errno= %d)",
|
sql_print_error("Can't create thread to kill server (errno= %d)",
|
||||||
error);
|
error);
|
||||||
#else
|
#else
|
||||||
kill_server(sig); // MIT THREAD has a alarm thread
|
my_sigset(sig, SIG_IGN);
|
||||||
|
break_connect_loop(); // MIT THREAD has a alarm thread
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -5716,7 +5588,7 @@ int mysqld_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_PSI_INTERFACE */
|
#endif /* HAVE_PSI_INTERFACE */
|
||||||
|
|
||||||
init_error_log_mutex();
|
mysql_mutex_init(key_LOCK_error_log, &LOCK_error_log, MY_MUTEX_INIT_FAST);
|
||||||
|
|
||||||
/* Initialize audit interface globals. Audit plugins are inited later. */
|
/* Initialize audit interface globals. Audit plugins are inited later. */
|
||||||
mysql_audit_initialize();
|
mysql_audit_initialize();
|
||||||
@ -5853,18 +5725,7 @@ int mysqld_main(int argc, char **argv)
|
|||||||
|
|
||||||
if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
|
if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
|
||||||
my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
|
my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
|
||||||
{
|
unireg_abort(1);
|
||||||
abort_loop=1;
|
|
||||||
select_thread_in_use=0;
|
|
||||||
|
|
||||||
(void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
|
|
||||||
|
|
||||||
delete_pid_file(MYF(MY_WME));
|
|
||||||
|
|
||||||
if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
|
|
||||||
unlink(mysqld_unix_port);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!opt_noacl)
|
if (!opt_noacl)
|
||||||
(void) grant_init();
|
(void) grant_init();
|
||||||
@ -5916,7 +5777,7 @@ int mysqld_main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
select_thread_in_use= 0; // Allow 'kill' to work
|
select_thread_in_use= 0; // Allow 'kill' to work
|
||||||
bootstrap(mysql_stdin);
|
bootstrap(mysql_stdin);
|
||||||
if (!kill_in_progress)
|
if (!abort_loop)
|
||||||
unireg_abort(bootstrap_error ? 1 : 0);
|
unireg_abort(bootstrap_error ? 1 : 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5996,34 +5857,45 @@ int mysqld_main(int argc, char **argv)
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
handle_connections_win();
|
handle_connections_win();
|
||||||
kill_server(0);
|
|
||||||
#else
|
#else
|
||||||
handle_connections_sockets();
|
handle_connections_sockets();
|
||||||
|
|
||||||
|
mysql_mutex_lock(&LOCK_start_thread);
|
||||||
|
select_thread_in_use=0;
|
||||||
|
mysql_cond_broadcast(&COND_start_thread);
|
||||||
|
mysql_mutex_unlock(&LOCK_start_thread);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
/* Shutdown requested */
|
||||||
|
char *user= shutdown_user.load(std::memory_order_relaxed);
|
||||||
|
sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN), my_progname,
|
||||||
|
user ? user : "unknown");
|
||||||
|
if (user)
|
||||||
|
my_free(user);
|
||||||
|
|
||||||
|
#ifdef WITH_WSREP
|
||||||
|
/* Stop wsrep threads in case they are running. */
|
||||||
|
if (wsrep_running_threads > 0)
|
||||||
|
{
|
||||||
|
wsrep_shutdown_replication();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
close_connections();
|
||||||
|
|
||||||
|
clean_up(1);
|
||||||
|
sd_notify(0, "STATUS=MariaDB server is down");
|
||||||
|
|
||||||
/* (void) pthread_attr_destroy(&connection_attrib); */
|
/* (void) pthread_attr_destroy(&connection_attrib); */
|
||||||
|
|
||||||
DBUG_PRINT("quit",("Exiting main thread"));
|
DBUG_PRINT("quit",("Exiting main thread"));
|
||||||
|
|
||||||
#ifndef __WIN__
|
|
||||||
mysql_mutex_lock(&LOCK_start_thread);
|
|
||||||
select_thread_in_use=0; // For close_connections
|
|
||||||
mysql_cond_broadcast(&COND_start_thread);
|
|
||||||
mysql_mutex_unlock(&LOCK_start_thread);
|
|
||||||
#endif /* __WIN__ */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Disable the main thread instrumentation,
|
Disable the main thread instrumentation,
|
||||||
to avoid recording events during the shutdown.
|
to avoid recording events during the shutdown.
|
||||||
*/
|
*/
|
||||||
PSI_CALL_delete_current_thread();
|
PSI_CALL_delete_current_thread();
|
||||||
|
|
||||||
/* Wait until cleanup is done */
|
|
||||||
mysql_mutex_lock(&LOCK_thread_count);
|
|
||||||
while (!ready_to_exit)
|
|
||||||
mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
|
|
||||||
mysql_mutex_unlock(&LOCK_thread_count);
|
|
||||||
|
|
||||||
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
|
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
|
||||||
if (start_mode)
|
if (start_mode)
|
||||||
Service.Stop();
|
Service.Stop();
|
||||||
@ -6405,25 +6277,6 @@ void create_new_thread(CONNECT *connect)
|
|||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
|
|
||||||
#ifdef SIGNALS_DONT_BREAK_READ
|
|
||||||
inline void kill_broken_server()
|
|
||||||
{
|
|
||||||
/* hack to get around signals ignored in syscalls for problem OS's */
|
|
||||||
if (mysql_socket_getfd(unix_sock) == INVALID_SOCKET ||
|
|
||||||
(!opt_disable_networking &&
|
|
||||||
mysql_socket_getfd(base_ip_sock) == INVALID_SOCKET))
|
|
||||||
{
|
|
||||||
select_thread_in_use = 0;
|
|
||||||
/* The following call will never return */
|
|
||||||
DBUG_PRINT("general", ("killing server because socket is closed"));
|
|
||||||
kill_server((void*) MYSQL_KILL_SIGNAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#define MAYBE_BROKEN_SYSCALL kill_broken_server();
|
|
||||||
#else
|
|
||||||
#define MAYBE_BROKEN_SYSCALL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Handle new connections and spawn new process to handle them */
|
/* Handle new connections and spawn new process to handle them */
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
@ -6566,7 +6419,6 @@ void handle_connections_sockets()
|
|||||||
"STATUS=Taking your SQL requests now...\n");
|
"STATUS=Taking your SQL requests now...\n");
|
||||||
|
|
||||||
DBUG_PRINT("general",("Waiting for connections."));
|
DBUG_PRINT("general",("Waiting for connections."));
|
||||||
MAYBE_BROKEN_SYSCALL;
|
|
||||||
while (!abort_loop)
|
while (!abort_loop)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
@ -6589,15 +6441,11 @@ void handle_connections_sockets()
|
|||||||
if (!select_errors++ && !abort_loop) /* purecov: inspected */
|
if (!select_errors++ && !abort_loop) /* purecov: inspected */
|
||||||
sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
|
sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
MAYBE_BROKEN_SYSCALL
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abort_loop)
|
if (abort_loop)
|
||||||
{
|
|
||||||
MAYBE_BROKEN_SYSCALL;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
/* Is this a new connection request ? */
|
/* Is this a new connection request ? */
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
@ -6648,7 +6496,6 @@ void handle_connections_sockets()
|
|||||||
if (mysql_socket_getfd(new_sock) != INVALID_SOCKET ||
|
if (mysql_socket_getfd(new_sock) != INVALID_SOCKET ||
|
||||||
(socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
|
(socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
|
||||||
break;
|
break;
|
||||||
MAYBE_BROKEN_SYSCALL;
|
|
||||||
#if !defined(NO_FCNTL_NONBLOCK)
|
#if !defined(NO_FCNTL_NONBLOCK)
|
||||||
if (!(test_flags & TEST_BLOCKING))
|
if (!(test_flags & TEST_BLOCKING))
|
||||||
{
|
{
|
||||||
@ -6671,7 +6518,6 @@ void handle_connections_sockets()
|
|||||||
statistic_increment(connection_errors_accept, &LOCK_status);
|
statistic_increment(connection_errors_accept, &LOCK_status);
|
||||||
if ((error_count++ & 255) == 0) // This can happen often
|
if ((error_count++ & 255) == 0) // This can happen often
|
||||||
sql_perror("Error in accept");
|
sql_perror("Error in accept");
|
||||||
MAYBE_BROKEN_SYSCALL;
|
|
||||||
if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
|
if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
|
||||||
sleep(1); // Give other threads some time
|
sleep(1); // Give other threads some time
|
||||||
continue;
|
continue;
|
||||||
@ -8167,7 +8013,6 @@ static int mysql_init_variables(void)
|
|||||||
opt_bootstrap= opt_myisam_log= 0;
|
opt_bootstrap= opt_myisam_log= 0;
|
||||||
disable_log_notes= 0;
|
disable_log_notes= 0;
|
||||||
mqh_used= 0;
|
mqh_used= 0;
|
||||||
kill_in_progress= 0;
|
|
||||||
cleanup_done= 0;
|
cleanup_done= 0;
|
||||||
test_flags= select_errors= dropping_tables= ha_open_options=0;
|
test_flags= select_errors= dropping_tables= ha_open_options=0;
|
||||||
thread_count= kill_cached_threads= wake_thread= 0;
|
thread_count= kill_cached_threads= wake_thread= 0;
|
||||||
@ -8176,7 +8021,7 @@ static int mysql_init_variables(void)
|
|||||||
opt_endinfo= using_udf_functions= 0;
|
opt_endinfo= using_udf_functions= 0;
|
||||||
opt_using_transactions= 0;
|
opt_using_transactions= 0;
|
||||||
abort_loop= select_thread_in_use= signal_thread_in_use= 0;
|
abort_loop= select_thread_in_use= signal_thread_in_use= 0;
|
||||||
ready_to_exit= shutdown_in_progress= grant_option= 0;
|
grant_option= 0;
|
||||||
aborted_threads= aborted_connects= 0;
|
aborted_threads= aborted_connects= 0;
|
||||||
subquery_cache_miss= subquery_cache_hit= 0;
|
subquery_cache_miss= subquery_cache_hit= 0;
|
||||||
delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
|
delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
|
||||||
|
@ -82,7 +82,7 @@ enum enum_slave_parallel_mode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
void kill_mysql(THD *thd= 0);
|
void kill_mysql(THD *thd);
|
||||||
void close_connection(THD *thd, uint sql_errno= 0);
|
void close_connection(THD *thd, uint sql_errno= 0);
|
||||||
void handle_connection_in_main_thread(CONNECT *thd);
|
void handle_connection_in_main_thread(CONNECT *thd);
|
||||||
void create_thread_to_handle_connection(CONNECT *connect);
|
void create_thread_to_handle_connection(CONNECT *connect);
|
||||||
@ -770,8 +770,6 @@ enum enum_query_type
|
|||||||
/* query_id */
|
/* query_id */
|
||||||
extern query_id_t global_query_id;
|
extern query_id_t global_query_id;
|
||||||
|
|
||||||
void unireg_end(void);
|
|
||||||
|
|
||||||
/* increment query_id and return it. */
|
/* increment query_id and return it. */
|
||||||
inline __attribute__((warn_unused_result)) query_id_t next_query_id()
|
inline __attribute__((warn_unused_result)) query_id_t next_query_id()
|
||||||
{
|
{
|
||||||
|
@ -1436,7 +1436,7 @@ bool Master_info_index::add_master_info(Master_info *mi, bool write_to_file)
|
|||||||
We have to protect against shutdown to ensure we are not calling
|
We have to protect against shutdown to ensure we are not calling
|
||||||
my_hash_insert() while my_hash_free() is in progress
|
my_hash_insert() while my_hash_free() is in progress
|
||||||
*/
|
*/
|
||||||
if (unlikely(shutdown_in_progress) ||
|
if (unlikely(abort_loop) ||
|
||||||
!my_hash_insert(&master_info_hash, (uchar*) mi))
|
!my_hash_insert(&master_info_hash, (uchar*) mi))
|
||||||
{
|
{
|
||||||
if (global_system_variables.log_warnings > 1)
|
if (global_system_variables.log_warnings > 1)
|
||||||
@ -1579,7 +1579,7 @@ uint any_slave_sql_running(bool already_locked)
|
|||||||
|
|
||||||
if (!already_locked)
|
if (!already_locked)
|
||||||
mysql_mutex_lock(&LOCK_active_mi);
|
mysql_mutex_lock(&LOCK_active_mi);
|
||||||
if (unlikely(shutdown_in_progress || !master_info_index))
|
if (unlikely(abort_loop || !master_info_index))
|
||||||
count= 1;
|
count= 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -184,8 +184,6 @@ extern char internal_table_name[2];
|
|||||||
extern char empty_c_string[1];
|
extern char empty_c_string[1];
|
||||||
extern MYSQL_PLUGIN_IMPORT const char **errmesg;
|
extern MYSQL_PLUGIN_IMPORT const char **errmesg;
|
||||||
|
|
||||||
extern bool volatile shutdown_in_progress;
|
|
||||||
|
|
||||||
extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd);
|
extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd);
|
||||||
extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen);
|
extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen);
|
||||||
|
|
||||||
|
@ -2403,10 +2403,10 @@ void wsrep_kill_mysql(THD *thd)
|
|||||||
{
|
{
|
||||||
if (mysqld_server_started)
|
if (mysqld_server_started)
|
||||||
{
|
{
|
||||||
if (!shutdown_in_progress)
|
if (!abort_loop)
|
||||||
{
|
{
|
||||||
WSREP_INFO("starting shutdown");
|
WSREP_INFO("starting shutdown");
|
||||||
kill_mysql();
|
kill_mysql(thd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -24,8 +24,6 @@
|
|||||||
|
|
||||||
struct sql_digest_storage;
|
struct sql_digest_storage;
|
||||||
|
|
||||||
volatile bool ready_to_exit= false;
|
|
||||||
|
|
||||||
uint lower_case_table_names= 0;
|
uint lower_case_table_names= 0;
|
||||||
CHARSET_INFO *files_charset_info= NULL;
|
CHARSET_INFO *files_charset_info= NULL;
|
||||||
CHARSET_INFO *system_charset_info= NULL;
|
CHARSET_INFO *system_charset_info= NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user