MDEV-18353 Shutdown may miss to wait for connection thread
* count CONNECT objects too * wait for all CONNECT objects to disappear (to be converted to THDs) before killing THDs away
This commit is contained in:
parent
b34cafe9d9
commit
4533e6ef65
5
mysql-test/main/shutdown_not_windows.combinations
Normal file
5
mysql-test/main/shutdown_not_windows.combinations
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[1tpc]
|
||||||
|
--thread-handling=one-thread-per-connection
|
||||||
|
|
||||||
|
[pot]
|
||||||
|
--thread-handling=pool-of-threads
|
8
mysql-test/main/shutdown_not_windows.result
Normal file
8
mysql-test/main/shutdown_not_windows.result
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
# MDEV-18353 Shutdown may miss to wait for connection thread
|
||||||
|
#
|
||||||
|
call mtr.add_suppression('Thread .* did not exit');
|
||||||
|
set @old_dbug=@@global.debug_dbug;
|
||||||
|
set global debug_dbug='+d,CONNECT_wait';
|
||||||
|
select variable_value into @cons from information_schema.global_status where variable_name='connections';
|
||||||
|
# restart
|
14
mysql-test/main/shutdown_not_windows.test
Normal file
14
mysql-test/main/shutdown_not_windows.test
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
source include/not_windows.inc;
|
||||||
|
source include/not_embedded.inc;
|
||||||
|
source include/have_debug.inc;
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-18353 Shutdown may miss to wait for connection thread
|
||||||
|
--echo #
|
||||||
|
call mtr.add_suppression('Thread .* did not exit');
|
||||||
|
set @old_dbug=@@global.debug_dbug;
|
||||||
|
set global debug_dbug='+d,CONNECT_wait';
|
||||||
|
select variable_value into @cons from information_schema.global_status where variable_name='connections';
|
||||||
|
exec $MYSQL -e 'select sleep(3600)' >/dev/null 2>&1 &;
|
||||||
|
let $wait_condition= select variable_value>@cons from information_schema.global_status where variable_name='connections';
|
||||||
|
source include/wait_condition.inc;
|
||||||
|
source include/restart_mysqld.inc;
|
@ -456,7 +456,7 @@ ulong delay_key_write_options;
|
|||||||
uint protocol_version;
|
uint protocol_version;
|
||||||
uint lower_case_table_names;
|
uint lower_case_table_names;
|
||||||
ulong tc_heuristic_recover= 0;
|
ulong tc_heuristic_recover= 0;
|
||||||
Atomic_counter<uint32_t> THD_count::count;
|
Atomic_counter<uint32_t> THD_count::count, CONNECT::count;
|
||||||
bool shutdown_wait_for_slaves;
|
bool shutdown_wait_for_slaves;
|
||||||
Atomic_counter<uint32_t> slave_open_temp_tables;
|
Atomic_counter<uint32_t> slave_open_temp_tables;
|
||||||
ulong thread_created;
|
ulong thread_created;
|
||||||
@ -1719,6 +1719,9 @@ static void close_connections(void)
|
|||||||
#endif
|
#endif
|
||||||
end_thr_alarm(0); // Abort old alarms.
|
end_thr_alarm(0); // Abort old alarms.
|
||||||
|
|
||||||
|
while (CONNECT::count)
|
||||||
|
my_sleep(100);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
First signal all threads that it's time to die
|
First signal all threads that it's time to die
|
||||||
This will give the threads some time to gracefully abort their
|
This will give the threads some time to gracefully abort their
|
||||||
@ -8036,7 +8039,7 @@ static int mysql_init_variables(void)
|
|||||||
mqh_used= 0;
|
mqh_used= 0;
|
||||||
cleanup_done= 0;
|
cleanup_done= 0;
|
||||||
select_errors= dropping_tables= ha_open_options=0;
|
select_errors= dropping_tables= ha_open_options=0;
|
||||||
THD_count::count= kill_cached_threads= wake_thread= 0;
|
THD_count::count= CONNECT::count= kill_cached_threads= wake_thread= 0;
|
||||||
slave_open_temp_tables= 0;
|
slave_open_temp_tables= 0;
|
||||||
cached_thread_count= 0;
|
cached_thread_count= 0;
|
||||||
opt_endinfo= using_udf_functions= 0;
|
opt_endinfo= using_udf_functions= 0;
|
||||||
|
@ -1360,6 +1360,14 @@ void do_handle_one_connection(CONNECT *connect)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("CONNECT_wait",
|
||||||
|
{
|
||||||
|
extern MYSQL_SOCKET unix_sock;
|
||||||
|
DBUG_ASSERT(unix_sock.fd >= 0);
|
||||||
|
while (unix_sock.fd >= 0)
|
||||||
|
my_sleep(1000);
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If a thread was created to handle this connection:
|
If a thread was created to handle this connection:
|
||||||
increment slow_launch_threads counter if it took more than
|
increment slow_launch_threads counter if it took more than
|
||||||
@ -1373,10 +1381,10 @@ void do_handle_one_connection(CONNECT *connect)
|
|||||||
if (launch_time >= slow_launch_time*1000000L)
|
if (launch_time >= slow_launch_time*1000000L)
|
||||||
statistic_increment(slow_launch_threads, &LOCK_status);
|
statistic_increment(slow_launch_threads, &LOCK_status);
|
||||||
}
|
}
|
||||||
delete connect;
|
|
||||||
|
|
||||||
/* Make THD visible in show processlist */
|
server_threads.insert(thd); // Make THD visible in show processlist
|
||||||
server_threads.insert(thd);
|
|
||||||
|
delete connect; // must be after server_threads.insert, see close_connections()
|
||||||
|
|
||||||
thd->thr_create_utime= thr_create_utime;
|
thd->thr_create_utime= thr_create_utime;
|
||||||
/* We need to set this because of time_out_user_resource_limits */
|
/* We need to set this because of time_out_user_resource_limits */
|
||||||
@ -1482,6 +1490,7 @@ CONNECT::~CONNECT()
|
|||||||
{
|
{
|
||||||
if (vio)
|
if (vio)
|
||||||
vio_delete(vio);
|
vio_delete(vio);
|
||||||
|
count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,11 +42,14 @@ public:
|
|||||||
bool thread_count_incremented;
|
bool thread_count_incremented;
|
||||||
ulonglong prior_thr_create_utime;
|
ulonglong prior_thr_create_utime;
|
||||||
|
|
||||||
|
static Atomic_counter<uint32_t> count;
|
||||||
|
|
||||||
CONNECT()
|
CONNECT()
|
||||||
:vio(0), host(0), scheduler(thread_scheduler), thread_id(0), real_id(0),
|
:vio(0), host(0), scheduler(thread_scheduler), thread_id(0), real_id(0),
|
||||||
extra_port(0),
|
extra_port(0),
|
||||||
thread_count_incremented(0), prior_thr_create_utime(0)
|
thread_count_incremented(0), prior_thr_create_utime(0)
|
||||||
{
|
{
|
||||||
|
count++;
|
||||||
};
|
};
|
||||||
~CONNECT();
|
~CONNECT();
|
||||||
void close_and_delete();
|
void close_and_delete();
|
||||||
|
@ -222,6 +222,14 @@ static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data)
|
|||||||
{
|
{
|
||||||
THD *thd= NULL;
|
THD *thd= NULL;
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("CONNECT_wait",
|
||||||
|
{
|
||||||
|
extern MYSQL_SOCKET unix_sock;
|
||||||
|
DBUG_ASSERT(unix_sock.fd >= 0);
|
||||||
|
while (unix_sock.fd >= 0)
|
||||||
|
my_sleep(1000);
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a new connection context: mysys_thread_var and PSI thread
|
Create a new connection context: mysys_thread_var and PSI thread
|
||||||
Store them in THD.
|
Store them in THD.
|
||||||
@ -247,8 +255,8 @@ static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
delete connect;
|
server_threads.insert(thd); // Make THD visible in show processlist
|
||||||
server_threads.insert(thd);
|
delete connect; // must be after server_threads.insert, see close_connections()
|
||||||
thd->set_mysys_var(mysys_var);
|
thd->set_mysys_var(mysys_var);
|
||||||
thd->event_scheduler.data= scheduler_data;
|
thd->event_scheduler.data= scheduler_data;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user