mirror of
https://github.com/MariaDB/server.git
synced 2025-03-29 18:35:35 +01:00
Speed up connection time:
-Change my_rnd() slightly to make it safer if two threads use it at the same time. -Avoid some sprintf and strmov in vio. -Changed thread_count to be automically incremented (instead of under LOCK_thread_count). -Thread cache now uses LOCK_thread_cache instead of LOCK_thread_count. -Moved delete thd out from LOCK_thread_count. -Save some mysql_cond_broadcast(&COND_thread_count) calls. -Removed call to getsockname() during connect. -Initialize random generator without locks. Other things: -Added thread_safe_decrement32() and thread_safe_increment32() -Removed sql_rnd_with_mutex() and get_thread_running() Thanks to Yoshinori Matsunobu for the benchmark of connection speed and to Domas Mituzas for the inspiration for many of the fixes. include/violite.h: Change desc to a string pointer mysql-test/suite/perfschema/r/all_instances.result: Added new mutex mysys/my_rnd.c: Change my_rnd() slightly to make it safer if two threads use it at the same time. sql/event_scheduler.cc: Changed thread_count to be automically incremented Moved some safe things out from LOCK_thread_count. Simplify deleting of THD for running thread. sql/mysqld.cc: Changed thread_count to be automically incremented Thread cache now uses LOCK_thread_cache instead of LOCK_thread_count Added delete_running_thd() Moved delete thd out from LOCK_thread_count More DBUG_ENTER Only call mysql_cond_broadcast(&COND_thread_count) if thread_count is 0 Removed call to getsockname() (old not anymore needed check) sql/mysqld.h: Removed sql_rnd_with_mutex() (not needed anymore) Removed not used function get_thread_running() Added thread_safe_decrement32() and thread_safe_increment32() Simplified dec_thread_running() and inc_thread_running() sql/sql_class.cc: Removed thd_lock_thread_count() and thd_unlock_thread_count() Initialize random generator without locks sql/sql_insert.cc: Changed thread_count to be automically incremented sql/sql_parse.cc: Changed thread_count to be automically incremented vio/vio.c: Don't generate 'desc' with sprintf/strmov. Assign a pointer instead. (Good enough as this is just for debugging)
This commit is contained in:
parent
8b047ac5c4
commit
615d51b650
10 changed files with 178 additions and 176 deletions
include
mysql-test/suite/perfschema/r
mysys
sql
vio
|
@ -216,7 +216,7 @@ struct st_vio
|
|||
struct sockaddr_storage remote; /* Remote internet address */
|
||||
int addrLen; /* Length of remote address */
|
||||
enum enum_vio_type type; /* Type of connection */
|
||||
char desc[30]; /* String description */
|
||||
const char *desc; /* String description */
|
||||
char *read_buffer; /* buffer for vio_read_buff */
|
||||
char *read_pos; /* start of unfetched data in the
|
||||
read buffer */
|
||||
|
|
|
@ -64,6 +64,7 @@ wait/synch/mutex/sql/LOCK_server_started
|
|||
wait/synch/mutex/sql/LOCK_slave_list
|
||||
wait/synch/mutex/sql/LOCK_stats
|
||||
wait/synch/mutex/sql/LOCK_status
|
||||
wait/synch/mutex/sql/LOCK_thread_cache
|
||||
wait/synch/mutex/sql/LOCK_thread_count
|
||||
wait/synch/mutex/sql/LOCK_user_conn
|
||||
wait/synch/mutex/sql/LOCK_user_locks
|
||||
|
|
|
@ -45,11 +45,20 @@ void my_rnd_init(struct my_rnd_struct *rand_st, ulong seed1, ulong seed2)
|
|||
|
||||
RETURN VALUE
|
||||
generated pseudo random number
|
||||
|
||||
NOTE:
|
||||
This is codes so that it can be called by two threads at the same time
|
||||
with minimum impact.
|
||||
(As the number is supposed to be random, it doesn't matter much if
|
||||
rand->seed1 or rand->seed2 are updated with slightly wrong numbers or
|
||||
if two threads gets the same number.
|
||||
*/
|
||||
|
||||
double my_rnd(struct my_rnd_struct *rand_st)
|
||||
{
|
||||
rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
|
||||
rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
|
||||
return (((double) rand_st->seed1)/rand_st->max_value_dbl);
|
||||
unsigned long seed1;
|
||||
seed1= (rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
|
||||
rand_st->seed2=(seed1+rand_st->seed2+33) % rand_st->max_value;
|
||||
rand_st->seed1= seed1;
|
||||
return (((double) seed1)/rand_st->max_value_dbl);
|
||||
}
|
||||
|
|
|
@ -132,11 +132,11 @@ post_init_event_thread(THD *thd)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
thread_safe_increment32(&thread_count, &thread_count_lock);
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
threads.append(thd);
|
||||
thread_count++;
|
||||
inc_thread_running();
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
inc_thread_running();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -154,12 +154,8 @@ deinit_event_thread(THD *thd)
|
|||
{
|
||||
thd->proc_info= "Clearing";
|
||||
DBUG_PRINT("exit", ("Event thread finishing"));
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thread_count--;
|
||||
dec_thread_running();
|
||||
delete thd;
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
delete_running_thd(thd);
|
||||
}
|
||||
|
||||
|
||||
|
@ -436,12 +432,7 @@ Event_scheduler::start()
|
|||
ret= TRUE;
|
||||
|
||||
new_thd->proc_info= "Clearing";
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thread_count--;
|
||||
dec_thread_running();
|
||||
delete new_thd;
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
delete_running_thd(new_thd);
|
||||
}
|
||||
end:
|
||||
UNLOCK_DATA();
|
||||
|
@ -570,12 +561,7 @@ error:
|
|||
if (new_thd)
|
||||
{
|
||||
new_thd->proc_info= "Clearing";
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thread_count--;
|
||||
dec_thread_running();
|
||||
delete new_thd;
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
delete_running_thd(new_thd);
|
||||
}
|
||||
delete event_name;
|
||||
DBUG_RETURN(TRUE);
|
||||
|
|
210
sql/mysqld.cc
210
sql/mysqld.cc
|
@ -465,7 +465,7 @@ ulong delay_key_write_options;
|
|||
uint protocol_version;
|
||||
uint lower_case_table_names;
|
||||
ulong tc_heuristic_recover= 0;
|
||||
uint volatile thread_count;
|
||||
int32 thread_count;
|
||||
int32 thread_running;
|
||||
ulong thread_created;
|
||||
ulong back_log, connect_timeout, concurrency, server_id;
|
||||
|
@ -489,6 +489,7 @@ ulong executed_events=0;
|
|||
query_id_t global_query_id;
|
||||
my_atomic_rwlock_t global_query_id_lock;
|
||||
my_atomic_rwlock_t thread_running_lock;
|
||||
my_atomic_rwlock_t thread_count_lock;
|
||||
my_atomic_rwlock_t statistics_lock;
|
||||
ulong aborted_threads, aborted_connects;
|
||||
ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
|
||||
|
@ -663,7 +664,7 @@ SHOW_COMP_OPTION have_openssl;
|
|||
|
||||
pthread_key(MEM_ROOT**,THR_MALLOC);
|
||||
pthread_key(THD*, THR_THD);
|
||||
mysql_mutex_t LOCK_thread_count;
|
||||
mysql_mutex_t LOCK_thread_count, LOCK_thread_cache;
|
||||
mysql_mutex_t
|
||||
LOCK_status, LOCK_error_log, LOCK_short_uuid_generator,
|
||||
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
|
||||
|
@ -761,7 +762,8 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
|
|||
key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
|
||||
key_relay_log_info_sleep_lock,
|
||||
key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
|
||||
key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count,
|
||||
key_LOCK_error_messages, key_LOG_INFO_lock,
|
||||
key_LOCK_thread_count, key_LOCK_thread_cache,
|
||||
key_PARTITION_LOCK_auto_inc;
|
||||
PSI_mutex_key key_RELAYLOG_LOCK_index;
|
||||
|
||||
|
@ -832,6 +834,7 @@ static PSI_mutex_info all_server_mutexes[]=
|
|||
{ &key_LOCK_commit_ordered, "LOCK_commit_ordered", PSI_FLAG_GLOBAL},
|
||||
{ &key_LOG_INFO_lock, "LOG_INFO::lock", 0},
|
||||
{ &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL},
|
||||
{ &key_LOCK_thread_cache, "LOCK_thread_cache", PSI_FLAG_GLOBAL},
|
||||
{ &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0}
|
||||
};
|
||||
|
||||
|
@ -1472,7 +1475,7 @@ static void close_connections(void)
|
|||
end_slave();
|
||||
|
||||
/* Give threads time to die. */
|
||||
for (int i= 0; thread_count && i < 100; i++)
|
||||
for (int i= 0; *(volatile int32*) &thread_count && i < 100; i++)
|
||||
my_sleep(20000);
|
||||
|
||||
/*
|
||||
|
@ -1886,6 +1889,7 @@ void clean_up(bool print_message)
|
|||
sys_var_end();
|
||||
my_atomic_rwlock_destroy(&global_query_id_lock);
|
||||
my_atomic_rwlock_destroy(&thread_running_lock);
|
||||
my_atomic_rwlock_destroy(&thread_count_lock);
|
||||
my_atomic_rwlock_destroy(&statistics_lock);
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
DBUG_PRINT("quit", ("got thread count lock"));
|
||||
|
@ -1929,6 +1933,7 @@ static void clean_up_mutexes()
|
|||
DBUG_ENTER("clean_up_mutexes");
|
||||
mysql_rwlock_destroy(&LOCK_grant);
|
||||
mysql_mutex_destroy(&LOCK_thread_count);
|
||||
mysql_mutex_destroy(&LOCK_thread_cache);
|
||||
mysql_mutex_destroy(&LOCK_status);
|
||||
mysql_mutex_destroy(&LOCK_delayed_insert);
|
||||
mysql_mutex_destroy(&LOCK_delayed_status);
|
||||
|
@ -2455,6 +2460,28 @@ void dec_connection_count(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Delete THD and decrement thread counters, including thread_running
|
||||
*/
|
||||
|
||||
void delete_running_thd(THD *thd)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->unlink();
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
delete thd;
|
||||
dec_thread_running();
|
||||
thread_safe_decrement32(&thread_count, &thread_count_lock);
|
||||
if (!thread_count)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Unlink thd from global list of available connections and free thd
|
||||
|
||||
|
@ -2479,7 +2506,6 @@ void unlink_thd(THD *thd)
|
|||
mysql_mutex_unlock(&LOCK_status);
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thread_count--;
|
||||
thd->unlink();
|
||||
/*
|
||||
Used by binlog_reset_master. It would be cleaner to use
|
||||
|
@ -2487,13 +2513,11 @@ void unlink_thd(THD *thd)
|
|||
sync feature has been shut down at this point.
|
||||
*/
|
||||
DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5););
|
||||
/*
|
||||
We must delete thd inside the lock to ensure that we don't start cleanup
|
||||
before THD is deleted
|
||||
*/
|
||||
delete thd;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
delete thd;
|
||||
thread_safe_decrement32(&thread_count, &thread_count_lock);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -2505,7 +2529,7 @@ void unlink_thd(THD *thd)
|
|||
cache_thread()
|
||||
|
||||
NOTES
|
||||
LOCK_thread_count has to be locked
|
||||
LOCK_thread_cache has to be locked
|
||||
|
||||
RETURN
|
||||
0 Thread was not put in cache
|
||||
|
@ -2516,7 +2540,9 @@ void unlink_thd(THD *thd)
|
|||
|
||||
static bool cache_thread()
|
||||
{
|
||||
mysql_mutex_assert_owner(&LOCK_thread_count);
|
||||
DBUG_ENTER("cache_thread");
|
||||
|
||||
mysql_mutex_assert_owner(&LOCK_thread_cache);
|
||||
if (cached_thread_count < thread_cache_size &&
|
||||
! abort_loop && !kill_cached_threads)
|
||||
{
|
||||
|
@ -2534,7 +2560,7 @@ static bool cache_thread()
|
|||
#endif
|
||||
|
||||
while (!abort_loop && ! wake_thread && ! kill_cached_threads)
|
||||
mysql_cond_wait(&COND_thread_cache, &LOCK_thread_count);
|
||||
mysql_cond_wait(&COND_thread_cache, &LOCK_thread_cache);
|
||||
cached_thread_count--;
|
||||
if (kill_cached_threads)
|
||||
mysql_cond_signal(&COND_flush_thread_cache);
|
||||
|
@ -2569,10 +2595,10 @@ static bool cache_thread()
|
|||
thd->thr_create_utime= microsecond_interval_timer();
|
||||
thd->start_utime= thd->thr_create_utime;
|
||||
threads.append(thd);
|
||||
return(1);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2603,17 +2629,26 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
|
|||
set_current_thd(0);
|
||||
if (put_in_cache)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
mysql_mutex_lock(&LOCK_thread_cache);
|
||||
put_in_cache= cache_thread();
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_cache);
|
||||
if (put_in_cache)
|
||||
DBUG_RETURN(0); // Thread is reused
|
||||
}
|
||||
|
||||
/* It's safe to broadcast outside a lock (COND... is not deleted here) */
|
||||
DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
|
||||
/*
|
||||
It's safe to check for thread_count outside of the mutex
|
||||
as we are only interested to see if it was counted to 0 by the
|
||||
above unlink_thd() call. We should only signal COND_thread_count if
|
||||
thread_count is likely to be 0. (false positives are ok)
|
||||
*/
|
||||
if (!thread_count)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
DBUG_LEAVE; // Must match DBUG_ENTER()
|
||||
my_thread_end();
|
||||
|
||||
|
@ -2624,15 +2659,17 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
|
|||
|
||||
void flush_thread_cache()
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
DBUG_ENTER("flush_thread_cache");
|
||||
mysql_mutex_lock(&LOCK_thread_cache);
|
||||
kill_cached_threads++;
|
||||
while (cached_thread_count)
|
||||
{
|
||||
mysql_cond_broadcast(&COND_thread_cache);
|
||||
mysql_cond_wait(&COND_flush_thread_cache, &LOCK_thread_count);
|
||||
mysql_cond_wait(&COND_flush_thread_cache, &LOCK_thread_cache);
|
||||
}
|
||||
kill_cached_threads--;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_cache);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3973,6 +4010,7 @@ static int init_thread_environment()
|
|||
{
|
||||
DBUG_ENTER("init_thread_environment");
|
||||
mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST);
|
||||
mysql_mutex_init(key_LOCK_thread_cache, &LOCK_thread_cache, MY_MUTEX_INIT_FAST);
|
||||
mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST);
|
||||
mysql_mutex_init(key_LOCK_delayed_insert,
|
||||
&LOCK_delayed_insert, MY_MUTEX_INIT_FAST);
|
||||
|
@ -5363,7 +5401,7 @@ static void bootstrap(MYSQL_FILE *file)
|
|||
thd->max_client_packet_length= thd->net.max_packet;
|
||||
thd->security_ctx->master_access= ~(ulong)0;
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
||||
thread_count++;
|
||||
thread_count++; // Safe as only one thread running
|
||||
in_bootstrap= TRUE;
|
||||
|
||||
bootstrap_file=file;
|
||||
|
@ -5444,54 +5482,69 @@ void handle_connection_in_main_thread(THD *thd)
|
|||
|
||||
void create_thread_to_handle_connection(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("create_thread_to_handle_connection");
|
||||
mysql_mutex_assert_owner(&LOCK_thread_count);
|
||||
|
||||
/* Check if we can get thread from the cache */
|
||||
if (cached_thread_count > wake_thread)
|
||||
{
|
||||
/* Get thread from cache */
|
||||
thread_cache.push_back(thd);
|
||||
wake_thread++;
|
||||
mysql_cond_signal(&COND_thread_cache);
|
||||
}
|
||||
else
|
||||
{
|
||||
char error_message_buff[MYSQL_ERRMSG_SIZE];
|
||||
/* Create new thread to handle connection */
|
||||
int error;
|
||||
thread_created++;
|
||||
threads.append(thd);
|
||||
DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
|
||||
thd->prior_thr_create_utime= microsecond_interval_timer();
|
||||
if ((error= mysql_thread_create(key_thread_one_connection,
|
||||
&thd->real_id, &connection_attrib,
|
||||
handle_one_connection,
|
||||
(void*) thd)))
|
||||
mysql_mutex_lock(&LOCK_thread_cache);
|
||||
/* Recheck condition when we have the lock */
|
||||
if (cached_thread_count > wake_thread)
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
DBUG_PRINT("error",
|
||||
("Can't create thread to handle request (error %d)",
|
||||
error));
|
||||
thread_count--;
|
||||
thd->killed= KILL_CONNECTION; // Safety
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
mysql_mutex_lock(&LOCK_connection_count);
|
||||
(*thd->scheduler->connection_count)--;
|
||||
mysql_mutex_unlock(&LOCK_connection_count);
|
||||
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
/* Can't use my_error() since store_globals has not been called. */
|
||||
my_snprintf(error_message_buff, sizeof(error_message_buff),
|
||||
ER_THD(thd, ER_CANT_CREATE_THREAD), error);
|
||||
net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL);
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES);
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
delete thd;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
return;
|
||||
/* purecov: end */
|
||||
/* Get thread from cache */
|
||||
thread_cache.push_back(thd);
|
||||
wake_thread++;
|
||||
mysql_cond_signal(&COND_thread_cache);
|
||||
mysql_mutex_unlock(&LOCK_thread_cache);
|
||||
DBUG_PRINT("info",("Thread created"));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_cache);
|
||||
}
|
||||
|
||||
char error_message_buff[MYSQL_ERRMSG_SIZE];
|
||||
/* Create new thread to handle connection */
|
||||
int error;
|
||||
thread_created++;
|
||||
threads.append(thd);
|
||||
DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
|
||||
thd->prior_thr_create_utime= microsecond_interval_timer();
|
||||
if ((error= mysql_thread_create(key_thread_one_connection,
|
||||
&thd->real_id, &connection_attrib,
|
||||
handle_one_connection,
|
||||
(void*) thd)))
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
DBUG_PRINT("error",
|
||||
("Can't create thread to handle request (error %d)",
|
||||
error));
|
||||
thd->killed= KILL_CONNECTION; // Safety
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
mysql_mutex_lock(&LOCK_connection_count);
|
||||
(*thd->scheduler->connection_count)--;
|
||||
mysql_mutex_unlock(&LOCK_connection_count);
|
||||
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
/* Can't use my_error() since store_globals has not been called. */
|
||||
my_snprintf(error_message_buff, sizeof(error_message_buff),
|
||||
ER_THD(thd, ER_CANT_CREATE_THREAD), error);
|
||||
net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL);
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES);
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->unlink();
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
delete thd;
|
||||
thread_safe_decrement32(&thread_count, &thread_count_lock);
|
||||
return;
|
||||
/* purecov: end */
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
DBUG_PRINT("info",("Thread created"));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5538,10 +5591,10 @@ static void create_new_thread(THD *thd)
|
|||
|
||||
mysql_mutex_unlock(&LOCK_connection_count);
|
||||
|
||||
thread_safe_increment32(&thread_count, &thread_count_lock);
|
||||
|
||||
/* Start a new thread to handle connection. */
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
|
||||
/*
|
||||
The initialization of thread_id is done in create_embedded_thd() for
|
||||
the embedded library.
|
||||
|
@ -5549,8 +5602,6 @@ static void create_new_thread(THD *thd)
|
|||
*/
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
||||
|
||||
thread_count++;
|
||||
|
||||
MYSQL_CALLBACK(thd->scheduler, add_connection, (thd));
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -5758,20 +5809,6 @@ void handle_connections_sockets()
|
|||
}
|
||||
#endif /* HAVE_LIBWRAP */
|
||||
|
||||
{
|
||||
size_socket dummyLen;
|
||||
struct sockaddr_storage dummy;
|
||||
dummyLen = sizeof(dummy);
|
||||
if ( getsockname(new_sock,(struct sockaddr *)&dummy,
|
||||
(SOCKET_SIZE_TYPE *)&dummyLen) < 0 )
|
||||
{
|
||||
sql_perror("Error on new connection socket");
|
||||
(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
|
||||
(void) closesocket(new_sock);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Don't allow too many connections
|
||||
*/
|
||||
|
@ -7402,6 +7439,7 @@ static int mysql_init_variables(void)
|
|||
global_query_id= thread_id= 1L;
|
||||
my_atomic_rwlock_init(&global_query_id_lock);
|
||||
my_atomic_rwlock_init(&thread_running_lock);
|
||||
my_atomic_rwlock_init(&thread_count_lock);
|
||||
my_atomic_rwlock_init(&statistics_lock);
|
||||
strmov(server_version, MYSQL_SERVER_VERSION);
|
||||
threads.empty();
|
||||
|
@ -8461,12 +8499,8 @@ void refresh_status(THD *thd)
|
|||
|
||||
/*
|
||||
Set max_used_connections to the number of currently open
|
||||
connections. Lock LOCK_thread_count out of LOCK_status to avoid
|
||||
deadlocks. Status reset becomes not atomic, but status data is
|
||||
not exact anyway.
|
||||
connections. This is not perfect, but status data is not exact anyway.
|
||||
*/
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
max_used_connections= thread_count-delayed_insert_threads;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
|
||||
|
|
47
sql/mysqld.h
47
sql/mysqld.h
|
@ -56,6 +56,7 @@ void kill_mysql(void);
|
|||
void close_connection(THD *thd, uint sql_errno= 0);
|
||||
void handle_connection_in_main_thread(THD *thd);
|
||||
void create_thread_to_handle_connection(THD *thd);
|
||||
void delete_running_thd(THD *thd);
|
||||
void unlink_thd(THD *thd);
|
||||
bool one_thread_per_connection_end(THD *thd, bool put_in_cache);
|
||||
void flush_thread_cache();
|
||||
|
@ -89,7 +90,6 @@ extern bool opt_ignore_builtin_innodb;
|
|||
extern my_bool opt_character_set_client_handshake;
|
||||
extern bool volatile abort_loop;
|
||||
extern bool in_bootstrap;
|
||||
extern uint volatile thread_count;
|
||||
extern uint connection_count;
|
||||
extern my_bool opt_safe_user_create;
|
||||
extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
|
||||
|
@ -352,7 +352,8 @@ extern mysql_rwlock_t LOCK_system_variables_hash;
|
|||
extern mysql_cond_t COND_thread_count;
|
||||
extern mysql_cond_t COND_manager;
|
||||
extern int32 thread_running;
|
||||
extern my_atomic_rwlock_t thread_running_lock;
|
||||
extern int32 thread_count;
|
||||
extern my_atomic_rwlock_t thread_running_lock, thread_count_lock;
|
||||
|
||||
extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
|
||||
*opt_ssl_key;
|
||||
|
@ -479,42 +480,30 @@ inline void table_case_convert(char * name, uint length)
|
|||
name, length, name, length);
|
||||
}
|
||||
|
||||
inline ulong sql_rnd_with_mutex()
|
||||
inline void thread_safe_increment32(int32 *value, my_atomic_rwlock_t *lock)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
ulong tmp=(ulong) (my_rnd(&sql_rand) * 0xffffffff); /* make all bits random */
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
return tmp;
|
||||
my_atomic_rwlock_wrlock(lock);
|
||||
(void) my_atomic_add32(value, 1);
|
||||
my_atomic_rwlock_wrunlock(lock);
|
||||
}
|
||||
|
||||
inline int32
|
||||
inline void thread_safe_decrement32(int32 *value, my_atomic_rwlock_t *lock)
|
||||
{
|
||||
my_atomic_rwlock_wrlock(lock);
|
||||
(void) my_atomic_add32(value, -1);
|
||||
my_atomic_rwlock_wrunlock(lock);
|
||||
}
|
||||
|
||||
inline void
|
||||
inc_thread_running()
|
||||
{
|
||||
int32 num_thread_running;
|
||||
my_atomic_rwlock_wrlock(&thread_running_lock);
|
||||
num_thread_running= my_atomic_add32(&thread_running, 1);
|
||||
my_atomic_rwlock_wrunlock(&thread_running_lock);
|
||||
return (num_thread_running+1);
|
||||
thread_safe_increment32(&thread_running, &thread_running_lock);
|
||||
}
|
||||
|
||||
inline int32
|
||||
inline void
|
||||
dec_thread_running()
|
||||
{
|
||||
int32 num_thread_running;
|
||||
my_atomic_rwlock_wrlock(&thread_running_lock);
|
||||
num_thread_running= my_atomic_add32(&thread_running, -1);
|
||||
my_atomic_rwlock_wrunlock(&thread_running_lock);
|
||||
return (num_thread_running-1);
|
||||
}
|
||||
|
||||
inline int32
|
||||
get_thread_running()
|
||||
{
|
||||
int32 num_thread_running;
|
||||
my_atomic_rwlock_wrlock(&thread_running_lock);
|
||||
num_thread_running= my_atomic_load32(&thread_running);
|
||||
my_atomic_rwlock_wrunlock(&thread_running_lock);
|
||||
return num_thread_running;
|
||||
thread_safe_decrement32(&thread_running, &thread_running_lock);
|
||||
}
|
||||
|
||||
void set_server_version(void);
|
||||
|
|
|
@ -349,29 +349,6 @@ void thd_set_thread_stack(THD *thd, char *stack_start)
|
|||
thd->thread_stack= stack_start;
|
||||
}
|
||||
|
||||
/**
|
||||
Lock connection data for the set of connections this connection
|
||||
belongs to
|
||||
|
||||
@param thd THD object
|
||||
*/
|
||||
void thd_lock_thread_count(THD *)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
}
|
||||
|
||||
/**
|
||||
Lock connection data for the set of connections this connection
|
||||
belongs to
|
||||
|
||||
@param thd THD object
|
||||
*/
|
||||
void thd_unlock_thread_count(THD *)
|
||||
{
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
|
||||
/**
|
||||
Close the socket used by this connection
|
||||
|
||||
|
@ -947,7 +924,14 @@ THD::THD()
|
|||
protocol_binary.init(this);
|
||||
|
||||
tablespace_op=FALSE;
|
||||
tmp= sql_rnd_with_mutex();
|
||||
|
||||
/*
|
||||
Initialize the random generator. We call my_rnd() without a lock as
|
||||
it's not really critical if two threads modifies the structure at the
|
||||
same time. We ensure that we have an unique number foreach thread
|
||||
by adding the address of the stack.
|
||||
*/
|
||||
tmp= (ulong) (my_rnd(&sql_rand) * 0xffffffff);
|
||||
my_rnd_init(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
|
||||
substitute_null_with_insert_id = FALSE;
|
||||
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
||||
|
|
|
@ -2038,9 +2038,9 @@ public:
|
|||
thd.unlink(); // Must be unlinked under lock
|
||||
my_free(thd.query());
|
||||
thd.security_ctx->user= thd.security_ctx->host=0;
|
||||
thread_count--;
|
||||
delayed_insert_threads--;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thread_safe_decrement32(&thread_count, &thread_count_lock);
|
||||
mysql_cond_broadcast(&COND_thread_count); /* Tell main we are ready */
|
||||
}
|
||||
|
||||
|
@ -2175,9 +2175,9 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
|
|||
{
|
||||
if (!(di= new Delayed_insert()))
|
||||
goto end_create;
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thread_count++;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
thread_safe_increment32(&thread_count, &thread_count_lock);
|
||||
|
||||
/*
|
||||
Annotating delayed inserts is not supported.
|
||||
*/
|
||||
|
|
|
@ -645,9 +645,10 @@ end:
|
|||
delete thd;
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thread_count--;
|
||||
thread_safe_decrement32(&thread_count, &thread_count_lock);
|
||||
in_bootstrap= FALSE;
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
my_thread_end();
|
||||
|
|
|
@ -213,9 +213,7 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, uint flags)
|
|||
if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
|
||||
{
|
||||
vio_init(vio, type, sd, 0, flags);
|
||||
sprintf(vio->desc,
|
||||
(vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
|
||||
vio->sd);
|
||||
vio->desc= (vio->type == VIO_TYPE_SOCKET ? "socket" : "TCP/IP");
|
||||
#if !defined(__WIN__)
|
||||
#if !defined(NO_FCNTL_NONBLOCK)
|
||||
/*
|
||||
|
@ -257,7 +255,7 @@ Vio *vio_new_win32pipe(HANDLE hPipe)
|
|||
if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
|
||||
{
|
||||
vio_init(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, VIO_LOCALHOST);
|
||||
strmov(vio->desc, "named pipe");
|
||||
vio->desc= "named pipe";
|
||||
}
|
||||
DBUG_RETURN(vio);
|
||||
}
|
||||
|
@ -282,7 +280,7 @@ Vio *vio_new_win32shared_memory(HANDLE handle_file_map, HANDLE handle_map,
|
|||
vio->event_conn_closed= event_conn_closed;
|
||||
vio->shared_memory_remain= 0;
|
||||
vio->shared_memory_pos= handle_map;
|
||||
strmov(vio->desc, "shared memory");
|
||||
vio->desc= "shared memory";
|
||||
}
|
||||
DBUG_RETURN(vio);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue