MDEV-6150 Speed up connection speed by moving creation of THD to new thread
Creating a CONNECT object on client connect and pass this to the working thread which creates the THD. Split LOCK_thread_count to different mutexes Added LOCK_thread_start to syncronize threads Moved most usage of LOCK_thread_count to dedicated functions Use next_thread_id() instead of thread_id++ Other things: - Thread id now starts from 1 instead of 2 - Added cast for thread_id as thread id is now of type my_thread_id - Made THD->host const (To ensure it's not changed) - Removed some DBUG_PRINT() about entering/exiting mutex as these was already logged by mutex code - Fixed that aborted_connects and connection_errors_internal are counted in all cases - Don't take locks for current_linfo when we set it (not needed as it was 0 before)
This commit is contained in:
parent
076aa182c2
commit
3d4a7390c1
@ -280,6 +280,12 @@ make_atomic_store(32)
|
||||
make_atomic_store(64)
|
||||
make_atomic_store(ptr)
|
||||
|
||||
#if SIZEOF_LONG == 4
|
||||
#define my_atomic_addlong(A,B) my_atomic_add32((int32*) (A), (B))
|
||||
#else
|
||||
#define my_atomic_addlong(A,B) my_atomic_add64((int64*) (A), (B))
|
||||
#endif
|
||||
|
||||
#ifdef _atomic_h_cleanup_
|
||||
#include _atomic_h_cleanup_
|
||||
#undef _atomic_h_cleanup_
|
||||
|
@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
#ifndef MYSQL_SOCKET_H
|
||||
#define MYSQL_SOCKET_H
|
||||
|
||||
/* For strlen() */
|
||||
#include <string.h>
|
||||
/* For MY_STAT */
|
||||
#include <my_dir.h>
|
||||
/* For my_chsize */
|
||||
|
@ -100,8 +100,6 @@ bool thd_is_connection_alive(THD *thd);
|
||||
void close_connection(THD *thd, uint errcode);
|
||||
/* End the connection before closing it */
|
||||
void end_connection(THD *thd);
|
||||
/* Cleanup the THD object */
|
||||
void thd_cleanup(THD *thd);
|
||||
/* Decrement connection counter */
|
||||
void dec_connection_count();
|
||||
/* Destroy THD object */
|
||||
|
@ -664,7 +664,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag)
|
||||
void *create_embedded_thd(int client_flag)
|
||||
{
|
||||
THD * thd= new THD;
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id();
|
||||
|
||||
thd->thread_stack= (char*) &thd;
|
||||
if (thd->store_globals())
|
||||
|
45
mysql-test/r/connect2.result
Normal file
45
mysql-test/r/connect2.result
Normal file
@ -0,0 +1,45 @@
|
||||
SET @old_debug= @@session.debug;
|
||||
set @old_thread_cache_size=@@global.thread_cache_size;
|
||||
select 1;
|
||||
1
|
||||
1
|
||||
set global debug_dbug='+d,simulate_failed_connection_1';
|
||||
connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR HY000: Lost connection to MySQL server at 'reading initial communication packet', system error: 95 "Operation not supported"
|
||||
set global debug_dbug=@old_debug;
|
||||
set global debug_dbug='+d,simulate_failed_connection_2';
|
||||
connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR HY000: Lost connection to MySQL server at 'reading initial communication packet', system error: 95 "Operation not supported"
|
||||
set global debug_dbug=@old_debug;
|
||||
select 1;
|
||||
1
|
||||
1
|
||||
select 1;
|
||||
1
|
||||
1
|
||||
set global debug_dbug='+d,simulate_failed_connection_1';
|
||||
connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR HY000: Lost connection to MySQL server at 'reading initial communication packet', system error: 95 "Operation not supported"
|
||||
set global debug_dbug=@old_debug;
|
||||
set global debug_dbug='+d,simulate_failed_connection_2';
|
||||
connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR HY000: Lost connection to MySQL server at 'reading initial communication packet', system error: 95 "Operation not supported"
|
||||
set global debug_dbug=@old_debug;
|
||||
select 1;
|
||||
1
|
||||
1
|
||||
set @@global.thread_cache_size=2;
|
||||
select 1;
|
||||
1
|
||||
1
|
||||
select 1;
|
||||
1
|
||||
1
|
||||
set global debug_dbug='+d,simulate_failed_connection_2';
|
||||
connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR HY000: Lost connection to MySQL server at 'reading initial communication packet', system error: 95 "Operation not supported"
|
||||
show status like "Threads_connected";
|
||||
Variable_name Value
|
||||
Threads_connected 1
|
||||
set global debug_dbug=@old_debug;
|
||||
set global thread_cache_size=@old_thread_cache_size;
|
@ -436,9 +436,9 @@ My own slow query sleep(2)
|
||||
My own slow query 0
|
||||
SELECT * FROM mysql.slow_log WHERE seq >= 2 LIMIT 3;
|
||||
start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text thread_id rows_affected seq
|
||||
START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 3 0 2
|
||||
START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 3 0 3
|
||||
START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 3 0 4
|
||||
START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 2 0 2
|
||||
START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 2 0 3
|
||||
START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 2 0 4
|
||||
SET GLOBAL slow_query_log = 0;
|
||||
SET SESSION long_query_time =@saved_long_query_time;
|
||||
FLUSH LOGS;
|
||||
|
@ -10,5 +10,8 @@ ERROR HY000: Too many connections
|
||||
SELECT 0;
|
||||
0
|
||||
0
|
||||
show status like "Threads_connected";
|
||||
Variable_name Value
|
||||
Threads_connected 3
|
||||
SET GLOBAL log_warnings=default;
|
||||
SET GLOBAL max_connections=default;
|
||||
|
@ -27,10 +27,10 @@ ROLLBACK/*!*/;
|
||||
/*!100001 SET @@session.server_id=1*//*!*/;
|
||||
/*!100001 SET @@session.gtid_seq_no=1*//*!*/;
|
||||
# at 352
|
||||
#<date> server id 1 end_log_pos 532 Query thread_id=4 exec_time=x error_code=0
|
||||
#<date> server id 1 end_log_pos 532 Query thread_id=3 exec_time=x error_code=0
|
||||
use `test`/*!*/;
|
||||
SET TIMESTAMP=X/*!*/;
|
||||
SET @@session.pseudo_thread_id=4/*!*/;
|
||||
SET @@session.pseudo_thread_id=3/*!*/;
|
||||
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
|
||||
SET @@session.sql_mode=1342177280/*!*/;
|
||||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
@ -44,7 +44,7 @@ CREATE TABLE t1 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 TINYINT, f4 MEDIUMINT, f
|
||||
#<date> server id 1 end_log_pos 570 GTID 0-1-2 ddl
|
||||
/*!100001 SET @@session.gtid_seq_no=2*//*!*/;
|
||||
# at 570
|
||||
#<date> server id 1 end_log_pos 743 Query thread_id=4 exec_time=x error_code=0
|
||||
#<date> server id 1 end_log_pos 743 Query thread_id=3 exec_time=x error_code=0
|
||||
SET TIMESTAMP=X/*!*/;
|
||||
CREATE TABLE t2 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 INT, f4 INT, f5 MEDIUMINT, f6 INT, f7 INT, f8 char(1))
|
||||
/*!*/;
|
||||
@ -69,7 +69,7 @@ BEGIN
|
||||
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
|
||||
### @9='' /* STRING(1) meta=65025 nullable=1 is_null=0 */
|
||||
# at 898
|
||||
#<date> server id 1 end_log_pos 967 Query thread_id=4 exec_time=x error_code=0
|
||||
#<date> server id 1 end_log_pos 967 Query thread_id=3 exec_time=x error_code=0
|
||||
SET TIMESTAMP=X/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
@ -94,7 +94,7 @@ BEGIN
|
||||
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
|
||||
### @9=NULL /* STRING(1) meta=65025 nullable=1 is_null=1 */
|
||||
# at 1121
|
||||
#<date> server id 1 end_log_pos 1190 Query thread_id=4 exec_time=x error_code=0
|
||||
#<date> server id 1 end_log_pos 1190 Query thread_id=3 exec_time=x error_code=0
|
||||
SET TIMESTAMP=X/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
@ -119,7 +119,7 @@ BEGIN
|
||||
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
|
||||
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
|
||||
# at 1343
|
||||
#<date> server id 1 end_log_pos 1412 Query thread_id=4 exec_time=x error_code=0
|
||||
#<date> server id 1 end_log_pos 1412 Query thread_id=3 exec_time=x error_code=0
|
||||
SET TIMESTAMP=X/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
@ -144,7 +144,7 @@ BEGIN
|
||||
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
|
||||
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
|
||||
# at 1568
|
||||
#<date> server id 1 end_log_pos 1637 Query thread_id=4 exec_time=x error_code=0
|
||||
#<date> server id 1 end_log_pos 1637 Query thread_id=3 exec_time=x error_code=0
|
||||
SET TIMESTAMP=X/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
@ -202,7 +202,7 @@ BEGIN
|
||||
### @8=7 /* INT meta=0 nullable=1 is_null=0 */
|
||||
### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */
|
||||
# at 1890
|
||||
#<date> server id 1 end_log_pos 1959 Query thread_id=4 exec_time=x error_code=0
|
||||
#<date> server id 1 end_log_pos 1959 Query thread_id=3 exec_time=x error_code=0
|
||||
SET TIMESTAMP=X/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
@ -234,7 +234,7 @@ BEGIN
|
||||
### SET
|
||||
### @5=5 /* INT meta=0 nullable=1 is_null=0 */
|
||||
# at 2119
|
||||
#<date> server id 1 end_log_pos 2188 Query thread_id=4 exec_time=x error_code=0
|
||||
#<date> server id 1 end_log_pos 2188 Query thread_id=3 exec_time=x error_code=0
|
||||
SET TIMESTAMP=X/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
@ -260,7 +260,7 @@ BEGIN
|
||||
### WHERE
|
||||
### @1=13 /* INT meta=0 nullable=0 is_null=0 */
|
||||
# at 2328
|
||||
#<date> server id 1 end_log_pos 2397 Query thread_id=4 exec_time=x error_code=0
|
||||
#<date> server id 1 end_log_pos 2397 Query thread_id=3 exec_time=x error_code=0
|
||||
SET TIMESTAMP=X/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
@ -286,7 +286,7 @@ BEGIN
|
||||
### WHERE
|
||||
### @1=13 /* INT meta=0 nullable=0 is_null=0 */
|
||||
# at 2537
|
||||
#<date> server id 1 end_log_pos 2606 Query thread_id=4 exec_time=x error_code=0
|
||||
#<date> server id 1 end_log_pos 2606 Query thread_id=3 exec_time=x error_code=0
|
||||
SET TIMESTAMP=X/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
|
@ -1 +0,0 @@
|
||||
RESET MASTER;
|
@ -1,26 +0,0 @@
|
||||
# ==== Purpose ====
|
||||
#
|
||||
# Test bugs in RESET MASTER.
|
||||
|
||||
--source include/have_debug.inc
|
||||
--source include/have_log_bin.inc
|
||||
|
||||
#######################################################################
|
||||
# BUG#12574820: binlog.binlog_tmp_table timing out in daily and weekly trunk run
|
||||
# Problem: MYSQL_BIN_LOG::reset_logs acquired LOCK_thread_count and
|
||||
# LOCK_log in the wrong order. This could cause a deadlock when
|
||||
# RESET MASTER was run concurrently with a disconnecting thread.
|
||||
#######################################################################
|
||||
|
||||
# We use sleep, not debug_sync, because the sync point needs to be in
|
||||
# the thread shut down code after the debug sync facility has been
|
||||
# shut down.
|
||||
--let $write_var= SET debug_dbug="+d,sleep_after_lock_thread_count_before_delete_thd"; CREATE TEMPORARY TABLE test.t1 (a INT);
|
||||
--let $write_to_file= GENERATE
|
||||
--disable_query_log
|
||||
--source include/write_var_to_file.inc
|
||||
--enable_query_log
|
||||
|
||||
--exec $MYSQL < $write_to_file
|
||||
RESET MASTER;
|
||||
--remove_file $write_to_file
|
9
mysql-test/t/connect2.cnf
Normal file
9
mysql-test/t/connect2.cnf
Normal file
@ -0,0 +1,9 @@
|
||||
!include include/default_my.cnf
|
||||
|
||||
[mysqld.1]
|
||||
extra-port= @ENV.MASTER_EXTRA_PORT
|
||||
extra-max-connections=2
|
||||
thread_handling=pool-of-threads
|
||||
|
||||
[ENV]
|
||||
MASTER_EXTRA_PORT= @OPT.port
|
81
mysql-test/t/connect2.test
Normal file
81
mysql-test/t/connect2.test
Normal file
@ -0,0 +1,81 @@
|
||||
# This test is to check various cases of connections, some which require
|
||||
# DBUG
|
||||
|
||||
# This test makes no sense with the embedded server
|
||||
--source include/not_embedded.inc
|
||||
--source include/have_debug.inc
|
||||
|
||||
SET @old_debug= @@session.debug;
|
||||
set @old_thread_cache_size=@@global.thread_cache_size;
|
||||
|
||||
# Test connections to the
|
||||
|
||||
connect(con1,localhost,root,,test,,);
|
||||
select 1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
set global debug_dbug='+d,simulate_failed_connection_1';
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 2013
|
||||
connect(con1,localhost,root,,test,,);
|
||||
connection default;
|
||||
set global debug_dbug=@old_debug;
|
||||
set global debug_dbug='+d,simulate_failed_connection_2';
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 2013
|
||||
connect(con1,localhost,root,,test,,);
|
||||
connection default;
|
||||
set global debug_dbug=@old_debug;
|
||||
connect(con1,localhost,root,,test,,);
|
||||
select 1;
|
||||
disconnect con1;
|
||||
|
||||
# Test connections to the extra port.
|
||||
|
||||
connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,);
|
||||
select 1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
set global debug_dbug='+d,simulate_failed_connection_1';
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_EXTRA_PORT MASTER_PORT
|
||||
--error 2013
|
||||
connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,);
|
||||
connection default;
|
||||
set global debug_dbug=@old_debug;
|
||||
set global debug_dbug='+d,simulate_failed_connection_2';
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_EXTRA_PORT MASTER_PORT
|
||||
--error 2013
|
||||
connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,);
|
||||
connection default;
|
||||
set global debug_dbug=@old_debug;
|
||||
connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,);
|
||||
select 1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
|
||||
#
|
||||
# Test thread cache
|
||||
#
|
||||
set @@global.thread_cache_size=2;
|
||||
connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,);
|
||||
select 1;
|
||||
connect(con2,localhost,root,,test,$MASTER_EXTRA_PORT,);
|
||||
select 1;
|
||||
disconnect con1;
|
||||
disconnect con2;
|
||||
connection default;
|
||||
set global debug_dbug='+d,simulate_failed_connection_2';
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_EXTRA_PORT MASTER_PORT
|
||||
--error 2013
|
||||
connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,);
|
||||
connection default;
|
||||
|
||||
# Check that threads_connected didn't count aborted connections
|
||||
show status like "Threads_connected";
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
|
||||
set global debug_dbug=@old_debug;
|
||||
set global thread_cache_size=@old_thread_cache_size;
|
@ -17,6 +17,7 @@ SELECT 2;
|
||||
|
||||
--connection default
|
||||
SELECT 0;
|
||||
show status like "Threads_connected";
|
||||
|
||||
SET GLOBAL log_warnings=default;
|
||||
SET GLOBAL max_connections=default;
|
||||
|
@ -1068,7 +1068,7 @@ static void link_into_queue(KEYCACHE_WQUEUE *wqueue,
|
||||
static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue,
|
||||
struct st_my_thread_var *thread)
|
||||
{
|
||||
KEYCACHE_DBUG_PRINT("unlink_from_queue", ("thread %ld", thread->id));
|
||||
KEYCACHE_DBUG_PRINT("unlink_from_queue", ("thread %ld", (ulong) thread->id));
|
||||
DBUG_ASSERT(thread->next && thread->prev);
|
||||
|
||||
if (thread->next == thread)
|
||||
@ -1145,7 +1145,7 @@ static void wait_on_queue(KEYCACHE_WQUEUE *wqueue,
|
||||
*/
|
||||
do
|
||||
{
|
||||
KEYCACHE_DBUG_PRINT("wait", ("suspend thread %ld", thread->id));
|
||||
KEYCACHE_DBUG_PRINT("wait", ("suspend thread %ld", (ulong) thread->id));
|
||||
keycache_pthread_cond_wait(&thread->suspend, mutex);
|
||||
}
|
||||
while (thread->next);
|
||||
@ -1184,7 +1184,7 @@ static void release_whole_queue(KEYCACHE_WQUEUE *wqueue)
|
||||
thread=next;
|
||||
DBUG_ASSERT(thread && thread->init == 1);
|
||||
KEYCACHE_DBUG_PRINT("release_whole_queue: signal",
|
||||
("thread %ld", thread->id));
|
||||
("thread %ld", (ulong) thread->id));
|
||||
/* Take thread from queue. */
|
||||
next= thread->next;
|
||||
thread->next= NULL;
|
||||
@ -1388,7 +1388,8 @@ static void link_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block,
|
||||
*/
|
||||
if ((HASH_LINK *) thread->keycache_link == hash_link)
|
||||
{
|
||||
KEYCACHE_DBUG_PRINT("link_block: signal", ("thread %ld", thread->id));
|
||||
KEYCACHE_DBUG_PRINT("link_block: signal",
|
||||
("thread %ld", (ulong) thread->id));
|
||||
keycache_pthread_cond_signal(&thread->suspend);
|
||||
unlink_from_queue(&keycache->waiting_for_block, thread);
|
||||
block->requests++;
|
||||
@ -1677,7 +1678,7 @@ static void wait_for_readers(SIMPLE_KEY_CACHE_CB *keycache,
|
||||
{
|
||||
KEYCACHE_DBUG_PRINT("wait_for_readers: wait",
|
||||
("suspend thread %ld block %u",
|
||||
thread->id, BLOCK_NUMBER(block)));
|
||||
(ulong) thread->id, BLOCK_NUMBER(block)));
|
||||
/* There must be no other waiter. We have no queue here. */
|
||||
DBUG_ASSERT(!block->condvar);
|
||||
block->condvar= &thread->suspend;
|
||||
@ -1737,7 +1738,8 @@ static void unlink_hash(SIMPLE_KEY_CACHE_CB *keycache, HASH_LINK *hash_link)
|
||||
*/
|
||||
if (page->file == hash_link->file && page->filepos == hash_link->diskpos)
|
||||
{
|
||||
KEYCACHE_DBUG_PRINT("unlink_hash: signal", ("thread %ld", thread->id));
|
||||
KEYCACHE_DBUG_PRINT("unlink_hash: signal",
|
||||
("thread %ld", (ulong) thread->id));
|
||||
keycache_pthread_cond_signal(&thread->suspend);
|
||||
unlink_from_queue(&keycache->waiting_for_hash_link, thread);
|
||||
}
|
||||
@ -1821,7 +1823,7 @@ restart:
|
||||
thread->keycache_link= (void *) &page;
|
||||
link_into_queue(&keycache->waiting_for_hash_link, thread);
|
||||
KEYCACHE_DBUG_PRINT("get_hash_link: wait",
|
||||
("suspend thread %ld", thread->id));
|
||||
("suspend thread %ld", (ulong) thread->id));
|
||||
keycache_pthread_cond_wait(&thread->suspend,
|
||||
&keycache->cache_lock);
|
||||
thread->keycache_link= NULL;
|
||||
@ -1987,7 +1989,7 @@ restart:
|
||||
do
|
||||
{
|
||||
KEYCACHE_DBUG_PRINT("find_key_block: wait",
|
||||
("suspend thread %ld", thread->id));
|
||||
("suspend thread %ld", (ulong) thread->id));
|
||||
keycache_pthread_cond_wait(&thread->suspend,
|
||||
&keycache->cache_lock);
|
||||
} while (thread->next);
|
||||
@ -2334,7 +2336,7 @@ restart:
|
||||
do
|
||||
{
|
||||
KEYCACHE_DBUG_PRINT("find_key_block: wait",
|
||||
("suspend thread %ld", thread->id));
|
||||
("suspend thread %ld", (ulong) thread->id));
|
||||
keycache_pthread_cond_wait(&thread->suspend,
|
||||
&keycache->cache_lock);
|
||||
}
|
||||
@ -4585,7 +4587,7 @@ static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache)
|
||||
KEYCACHE_PAGE *page;
|
||||
uint i;
|
||||
|
||||
fprintf(keycache_dump_file, "thread:%u\n", thread->id);
|
||||
fprintf(keycache_dump_file, "thread:%lu\n", (ulong) thread->id);
|
||||
|
||||
i=0;
|
||||
thread=last=waiting_for_hash_link.last_thread;
|
||||
@ -4596,8 +4598,8 @@ static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache)
|
||||
thread=thread->next;
|
||||
page= (KEYCACHE_PAGE *) thread->keycache_link;
|
||||
fprintf(keycache_dump_file,
|
||||
"thread:%u, (file,filepos)=(%u,%lu)\n",
|
||||
thread->id,(uint) page->file,(ulong) page->filepos);
|
||||
"thread:%lu, (file,filepos)=(%u,%lu)\n",
|
||||
(ulong) thread->id,(uint) page->file,(ulong) page->filepos);
|
||||
if (++i == MAX_QUEUE_LEN)
|
||||
break;
|
||||
}
|
||||
@ -4612,8 +4614,8 @@ static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache)
|
||||
thread=thread->next;
|
||||
hash_link= (HASH_LINK *) thread->keycache_link;
|
||||
fprintf(keycache_dump_file,
|
||||
"thread:%u hash_link:%u (file,filepos)=(%u,%lu)\n",
|
||||
thread->id, (uint) HASH_LINK_NUMBER(hash_link),
|
||||
"thread:%lu hash_link:%u (file,filepos)=(%u,%lu)\n",
|
||||
(ulong) thread->id, (uint) HASH_LINK_NUMBER(hash_link),
|
||||
(uint) hash_link->file,(ulong) hash_link->diskpos);
|
||||
if (++i == MAX_QUEUE_LEN)
|
||||
break;
|
||||
@ -4640,7 +4642,7 @@ static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache)
|
||||
{
|
||||
thread=thread->next;
|
||||
fprintf(keycache_dump_file,
|
||||
"thread:%u\n", thread->id);
|
||||
"thread:%lu\n", (ulong) thread->id);
|
||||
if (++i == MAX_QUEUE_LEN)
|
||||
break;
|
||||
}
|
||||
|
@ -772,7 +772,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
|
||||
|
||||
mysql_mutex_lock(&lock->mutex);
|
||||
DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx type: %d",
|
||||
(long) data, data->owner->thread_id,
|
||||
(long) data, (ulong) data->owner->thread_id,
|
||||
(long) lock, (int) lock_type));
|
||||
check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ?
|
||||
"enter read_lock" : "enter write_lock", lock_type, 0);
|
||||
@ -809,7 +809,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
|
||||
*/
|
||||
|
||||
DBUG_PRINT("lock",("write locked 1 by thread: 0x%lx",
|
||||
lock->write.data->owner->thread_id));
|
||||
(ulong) lock->write.data->owner->thread_id));
|
||||
if (thr_lock_owner_equal(data->owner, lock->write.data->owner) ||
|
||||
(lock->write.data->type <= TL_WRITE_DELAYED &&
|
||||
(((int) lock_type <= (int) TL_READ_HIGH_PRIORITY) ||
|
||||
@ -968,7 +968,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
|
||||
goto end;
|
||||
}
|
||||
DBUG_PRINT("lock",("write locked 2 by thread: 0x%lx",
|
||||
lock->write.data->owner->thread_id));
|
||||
(ulong) lock->write.data->owner->thread_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1004,7 +1004,8 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
|
||||
}
|
||||
}
|
||||
DBUG_PRINT("lock",("write locked 3 by thread: 0x%lx type: %d",
|
||||
lock->read.data->owner->thread_id, data->type));
|
||||
(ulong) lock->read.data->owner->thread_id,
|
||||
data->type));
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_break_lock(data, &lock->write, &lock->write_wait))
|
||||
@ -1069,7 +1070,7 @@ static inline void free_all_read_locks(THR_LOCK *lock,
|
||||
}
|
||||
/* purecov: begin inspected */
|
||||
DBUG_PRINT("lock",("giving read lock to thread: 0x%lx",
|
||||
data->owner->thread_id));
|
||||
(ulong) data->owner->thread_id));
|
||||
/* purecov: end */
|
||||
data->cond=0; /* Mark thread free */
|
||||
mysql_cond_signal(cond);
|
||||
@ -1087,8 +1088,9 @@ void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags)
|
||||
THR_LOCK *lock=data->lock;
|
||||
enum thr_lock_type lock_type=data->type;
|
||||
DBUG_ENTER("thr_unlock");
|
||||
DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx",
|
||||
(long) data, data->owner->thread_id, (long) lock));
|
||||
DBUG_PRINT("lock",("data: %p thread: 0x%lx lock: %p",
|
||||
data, (ulong) data->owner->thread_id,
|
||||
lock));
|
||||
mysql_mutex_lock(&lock->mutex);
|
||||
check_locks(lock,"start of release lock", lock_type, 0);
|
||||
|
||||
@ -1181,7 +1183,7 @@ static void wake_up_waiters(THR_LOCK *lock)
|
||||
data->type=TL_WRITE; /* Upgrade lock */
|
||||
/* purecov: begin inspected */
|
||||
DBUG_PRINT("lock",("giving write lock of type %d to thread: 0x%lx",
|
||||
data->type, data->owner->thread_id));
|
||||
data->type, (ulong) data->owner->thread_id));
|
||||
/* purecov: end */
|
||||
{
|
||||
mysql_cond_t *cond= data->cond;
|
||||
@ -1423,9 +1425,9 @@ void thr_multi_unlock(THR_LOCK_DATA **data,uint count, uint unlock_flags)
|
||||
thr_unlock(*pos, unlock_flags);
|
||||
else
|
||||
{
|
||||
DBUG_PRINT("lock",("Free lock: data: 0x%lx thread: 0x%lx lock: 0x%lx",
|
||||
(long) *pos, (*pos)->owner->thread_id,
|
||||
(long) (*pos)->lock));
|
||||
DBUG_PRINT("lock",("Free lock: data: %p thread: 0x%lx lock: %p",
|
||||
*pos, (ulong) (*pos)->owner->thread_id,
|
||||
(*pos)->lock));
|
||||
}
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
@ -1673,7 +1675,7 @@ static void thr_print_lock(const char* name,struct st_lock_list *list)
|
||||
prev= &list->data;
|
||||
for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
|
||||
{
|
||||
printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->thread_id,
|
||||
printf("%p (%lu:%d); ", data, (ulong) data->owner->thread_id,
|
||||
(int) data->type);
|
||||
if (data->prev != prev)
|
||||
printf("\nWarning: prev didn't point at previous lock\n");
|
||||
|
@ -510,7 +510,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
|
||||
fprintf(stderr,
|
||||
"safe_mutex: Count was %d in thread 0x%lx when locking mutex %s "
|
||||
"at %s, line %d\n",
|
||||
mp->count-1, my_thread_dbug_id(), mp->name, file, line);
|
||||
mp->count-1, (ulong) my_thread_dbug_id(), mp->name, file, line);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
@ -564,7 +564,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
|
||||
fprintf(stderr,
|
||||
"safe_mutex: Count was %d in thread 0x%lx when locking mutex "
|
||||
"%s at %s, line %d (error: %d (%d))\n",
|
||||
mp->count-1, my_thread_dbug_id(), mp->name, file, line,
|
||||
mp->count-1, (ulong) my_thread_dbug_id(), mp->name, file, line,
|
||||
error, error);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
|
@ -280,9 +280,7 @@ pthread_handler_t background_thread(void *arg __attribute__((unused)))
|
||||
if (my_thread_init())
|
||||
return 0;
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd_thread_id= thread_id++;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd_thread_id= next_thread_id();
|
||||
|
||||
if (slept_ok(startup_interval))
|
||||
{
|
||||
|
@ -308,11 +308,9 @@ dbcontext::init_thread(const void *stack_bottom, volatile int& shutdown_flag)
|
||||
DBG_THR(fprintf(stderr, "HNDSOCK x0 %p\n", thd));
|
||||
}
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id = thread_id++;
|
||||
threads.append(thd);
|
||||
++thread_count;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->thread_id = next_thread_id();
|
||||
thread_safe_increment32(&thread_count);
|
||||
add_to_active_threads(thd);
|
||||
}
|
||||
|
||||
DBG_THR(fprintf(stderr, "HNDSOCK init thread wsts\n"));
|
||||
|
@ -135,9 +135,7 @@ post_init_event_thread(THD *thd)
|
||||
}
|
||||
|
||||
thread_safe_increment32(&thread_count);
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
threads.append(thd);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
add_to_active_threads(thd);
|
||||
inc_thread_running();
|
||||
return FALSE;
|
||||
}
|
||||
@ -191,9 +189,7 @@ pre_init_event_thread(THD* thd)
|
||||
thd->net.read_timeout= slave_net_timeout;
|
||||
thd->variables.option_bits|= OPTION_AUTO_IS_NULL;
|
||||
thd->client_capabilities|= CLIENT_MULTI_RESULTS;
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id();
|
||||
|
||||
/*
|
||||
Guarantees that we will see the thread in SHOW PROCESSLIST though its
|
||||
@ -479,7 +475,7 @@ Event_scheduler::run(THD *thd)
|
||||
DBUG_ENTER("Event_scheduler::run");
|
||||
|
||||
sql_print_information("Event Scheduler: scheduler thread started with id %lu",
|
||||
thd->thread_id);
|
||||
(ulong) thd->thread_id);
|
||||
/*
|
||||
Recalculate the values in the queue because there could have been stops
|
||||
in executions of the scheduler and some times could have passed by.
|
||||
@ -669,13 +665,13 @@ Event_scheduler::stop()
|
||||
|
||||
state= STOPPING;
|
||||
DBUG_PRINT("info", ("Scheduler thread has id %lu",
|
||||
scheduler_thd->thread_id));
|
||||
(ulong) scheduler_thd->thread_id));
|
||||
/* Lock from delete */
|
||||
mysql_mutex_lock(&scheduler_thd->LOCK_thd_data);
|
||||
/* This will wake up the thread if it waits on Queue's conditional */
|
||||
sql_print_information("Event Scheduler: Killing the scheduler thread, "
|
||||
"thread id %lu",
|
||||
scheduler_thd->thread_id);
|
||||
(ulong) scheduler_thd->thread_id);
|
||||
scheduler_thd->awake(KILL_CONNECTION);
|
||||
mysql_mutex_unlock(&scheduler_thd->LOCK_thd_data);
|
||||
|
||||
@ -832,7 +828,8 @@ Event_scheduler::dump_internal_status()
|
||||
puts("");
|
||||
puts("Event scheduler status:");
|
||||
printf("State : %s\n", scheduler_states_names[state].str);
|
||||
printf("Thread id : %lu\n", scheduler_thd? scheduler_thd->thread_id : 0);
|
||||
printf("Thread id : %lu\n", scheduler_thd ?
|
||||
(ulong) scheduler_thd->thread_id : (ulong) 0);
|
||||
printf("LLA : %s:%u\n", mutex_last_locked_in_func,
|
||||
mutex_last_locked_at_line);
|
||||
printf("LUA : %s:%u\n", mutex_last_unlocked_in_func,
|
||||
|
@ -412,7 +412,7 @@ static inline bool is_hostname_valid(const char *hostname)
|
||||
|
||||
int ip_to_hostname(struct sockaddr_storage *ip_storage,
|
||||
const char *ip_string,
|
||||
char **hostname,
|
||||
const char **hostname,
|
||||
uint *connect_errors)
|
||||
{
|
||||
const struct sockaddr *ip= (const sockaddr *) ip_storage;
|
||||
@ -436,7 +436,7 @@ int ip_to_hostname(struct sockaddr_storage *ip_storage,
|
||||
DBUG_PRINT("info", ("Loopback address detected."));
|
||||
|
||||
/* Do not count connect errors from localhost. */
|
||||
*hostname= (char *) my_localhost;
|
||||
*hostname= my_localhost;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ extern ulong host_cache_size;
|
||||
#define RC_BLOCKED_HOST 1
|
||||
int ip_to_hostname(struct sockaddr_storage *ip_storage,
|
||||
const char *ip_string,
|
||||
char **hostname, uint *connect_errors);
|
||||
const char **hostname, uint *connect_errors);
|
||||
|
||||
void inc_host_errors(const char *ip_string, Host_errors *errors);
|
||||
void reset_host_connect_errors(const char *ip_string);
|
||||
|
@ -6582,7 +6582,6 @@ int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate)
|
||||
DBUG_ENTER("MYSQL_BIN_LOG::rotate_and_purge");
|
||||
bool check_purge= false;
|
||||
|
||||
//todo: fix the macro def and restore safe_mutex_assert_not_owner(&LOCK_log);
|
||||
mysql_mutex_lock(&LOCK_log);
|
||||
prev_binlog_id= current_binlog_id;
|
||||
if ((error= rotate(force_rotate, &check_purge)))
|
||||
@ -9508,9 +9507,7 @@ binlog_background_thread(void *arg __attribute__((unused)))
|
||||
thd= new THD;
|
||||
thd->system_thread= SYSTEM_THREAD_BINLOG_BACKGROUND;
|
||||
thd->thread_stack= (char*) &thd; /* Set approximate stack start */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id= thread_id++;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd->thread_id= next_thread_id();
|
||||
thd->store_globals();
|
||||
thd->security_ctx->skip_grants();
|
||||
thd->set_command(COM_DAEMON);
|
||||
@ -9597,9 +9594,8 @@ binlog_background_thread(void *arg __attribute__((unused)))
|
||||
|
||||
THD_STAGE_INFO(thd, stage_binlog_stopping_background_thread);
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
/* No need to use mutex as thd is not linked into other threads */
|
||||
delete thd;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
my_thread_end();
|
||||
|
||||
|
449
sql/mysqld.cc
449
sql/mysqld.cc
@ -377,7 +377,7 @@ static char *default_collation_name;
|
||||
char *default_storage_engine, *default_tmp_storage_engine;
|
||||
char *enforced_storage_engine=NULL;
|
||||
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
|
||||
static I_List<THD> thread_cache;
|
||||
static I_List<CONNECT> thread_cache;
|
||||
static bool binlog_format_used= false;
|
||||
LEX_STRING opt_init_connect, opt_init_slave;
|
||||
mysql_cond_t COND_thread_cache;
|
||||
@ -409,8 +409,7 @@ uint volatile global_disable_checkpoint;
|
||||
ulong slow_start_timeout;
|
||||
#endif
|
||||
/*
|
||||
True if the bootstrap thread is running. Protected by LOCK_thread_count,
|
||||
just like thread_count.
|
||||
True if the bootstrap thread is running. Protected by LOCK_start_thread.
|
||||
Used in bootstrap() function to determine if the bootstrap thread
|
||||
has completed. Note, that we can't use 'thread_count' instead,
|
||||
since in 5.1, in presence of the Event Scheduler, there may be
|
||||
@ -422,7 +421,7 @@ ulong slow_start_timeout;
|
||||
bootstrap either, since we want to be able to process event-related
|
||||
SQL commands in the init file and in --bootstrap mode.
|
||||
*/
|
||||
bool in_bootstrap= FALSE;
|
||||
bool volatile in_bootstrap= FALSE;
|
||||
/**
|
||||
@brief 'grant_option' is used to indicate if privileges needs
|
||||
to be checked, in which case the lock, LOCK_grant, is used
|
||||
@ -556,7 +555,8 @@ ulong max_prepared_stmt_count;
|
||||
statements.
|
||||
*/
|
||||
ulong prepared_stmt_count=0;
|
||||
ulong thread_id=1L,current_pid;
|
||||
my_thread_id global_thread_id= 0;
|
||||
ulong current_pid;
|
||||
ulong slow_launch_threads = 0;
|
||||
uint sync_binlog_period= 0, sync_relaylog_period= 0,
|
||||
sync_relayloginfo_period= 0, sync_masterinfo_period= 0;
|
||||
@ -712,7 +712,33 @@ SHOW_COMP_OPTION have_openssl;
|
||||
/* Thread specific variables */
|
||||
|
||||
pthread_key(THD*, THR_THD);
|
||||
mysql_mutex_t LOCK_thread_count, LOCK_thread_cache;
|
||||
|
||||
/*
|
||||
LOCK_thread_count protects the following variables:
|
||||
thread_count Number of threads with THD that servers queries.
|
||||
threads Linked list of active THD's.
|
||||
The effect of this is that one can't unlink and
|
||||
delete a THD as long as one has locked
|
||||
LOCK_thread_count.
|
||||
ready_to_exit
|
||||
delayed_insert_threads
|
||||
*/
|
||||
mysql_mutex_t LOCK_thread_count;
|
||||
|
||||
/*
|
||||
LOCK_start_thread is used to syncronize thread start and stop with
|
||||
other threads.
|
||||
|
||||
It also protects these variables:
|
||||
handler_count
|
||||
in_bootstrap
|
||||
select_thread_in_use
|
||||
slave_init_thread_running
|
||||
check_temp_dir() call
|
||||
*/
|
||||
mysql_mutex_t LOCK_start_thread;
|
||||
|
||||
mysql_mutex_t LOCK_thread_cache;
|
||||
mysql_mutex_t
|
||||
LOCK_status, LOCK_show_status, LOCK_error_log, LOCK_short_uuid_generator,
|
||||
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
|
||||
@ -737,7 +763,7 @@ mysql_mutex_t LOCK_des_key_file;
|
||||
#endif
|
||||
mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
|
||||
mysql_rwlock_t LOCK_system_variables_hash;
|
||||
mysql_cond_t COND_thread_count;
|
||||
mysql_cond_t COND_thread_count, COND_start_thread;
|
||||
pthread_t signal_thread;
|
||||
pthread_attr_t connection_attrib;
|
||||
mysql_mutex_t LOCK_server_started;
|
||||
@ -887,6 +913,7 @@ 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_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
|
||||
key_LOCK_error_messages, key_LOG_INFO_lock,
|
||||
key_LOCK_start_thread,
|
||||
key_LOCK_thread_count, key_LOCK_thread_cache,
|
||||
key_PARTITION_LOCK_auto_inc;
|
||||
PSI_mutex_key key_RELAYLOG_LOCK_index;
|
||||
@ -973,6 +1000,7 @@ static PSI_mutex_info all_server_mutexes[]=
|
||||
{ &key_LOCK_thread_cache, "LOCK_thread_cache", PSI_FLAG_GLOBAL},
|
||||
{ &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0},
|
||||
{ &key_LOCK_slave_state, "LOCK_slave_state", 0},
|
||||
{ &key_LOCK_start_thread, "LOCK_start_thread", PSI_FLAG_GLOBAL},
|
||||
{ &key_LOCK_binlog_state, "LOCK_binlog_state", 0},
|
||||
{ &key_LOCK_rpl_thread, "LOCK_rpl_thread", 0},
|
||||
{ &key_LOCK_rpl_thread_pool, "LOCK_rpl_thread_pool", 0},
|
||||
@ -1014,6 +1042,7 @@ PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
|
||||
key_rpl_group_info_sleep_cond,
|
||||
key_TABLE_SHARE_cond, key_user_level_lock_cond,
|
||||
key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache,
|
||||
key_COND_start_thread,
|
||||
key_BINLOG_COND_queue_busy;
|
||||
PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready,
|
||||
key_COND_wait_commit;
|
||||
@ -1073,6 +1102,7 @@ static PSI_cond_info all_server_conds[]=
|
||||
{ &key_COND_group_commit_orderer, "COND_group_commit_orderer", 0},
|
||||
{ &key_COND_prepare_ordered, "COND_prepare_ordered", 0},
|
||||
{ &key_COND_slave_init, "COND_slave_init", 0},
|
||||
{ &key_COND_start_thread, "COND_start_thread", PSI_FLAG_GLOBAL},
|
||||
{ &key_COND_wait_gtid, "COND_wait_gtid", 0},
|
||||
{ &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0}
|
||||
};
|
||||
@ -1199,8 +1229,13 @@ void init_net_server_extension(THD *thd)
|
||||
/* Activate this private extension for the mysqld server. */
|
||||
thd->net.extension= & thd->m_net_server_extension;
|
||||
}
|
||||
#else
|
||||
void init_net_server_extension(THD *thd)
|
||||
{
|
||||
}
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
|
||||
/**
|
||||
A log message for the error log, buffered in memory.
|
||||
Log messages are temporarily buffered when generated before the error log
|
||||
@ -1545,8 +1580,8 @@ static void close_connections(void)
|
||||
#if !defined(__WIN__)
|
||||
DBUG_PRINT("quit", ("waiting for select thread: 0x%lx",
|
||||
(ulong) select_thread));
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
|
||||
mysql_mutex_lock(&LOCK_start_thread);
|
||||
while (select_thread_in_use)
|
||||
{
|
||||
struct timespec abstime;
|
||||
@ -1560,7 +1595,7 @@ static void close_connections(void)
|
||||
set_timespec(abstime, 2);
|
||||
for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
|
||||
{
|
||||
error= mysql_cond_timedwait(&COND_thread_count, &LOCK_thread_count,
|
||||
error= mysql_cond_timedwait(&COND_start_thread, &LOCK_start_thread,
|
||||
&abstime);
|
||||
if (error != EINTR)
|
||||
break;
|
||||
@ -1571,7 +1606,7 @@ static void close_connections(void)
|
||||
#endif
|
||||
close_server_sock();
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_start_thread);
|
||||
#endif /* __WIN__ */
|
||||
|
||||
|
||||
@ -1640,7 +1675,7 @@ static void close_connections(void)
|
||||
while ((tmp=it++))
|
||||
{
|
||||
DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
|
||||
tmp->thread_id));
|
||||
(ulong) tmp->thread_id));
|
||||
/* We skip slave threads & scheduler on this first loop through. */
|
||||
if (tmp->slave_thread)
|
||||
continue;
|
||||
@ -1696,6 +1731,8 @@ static void close_connections(void)
|
||||
much smaller than even 2 seconds, this is only a safety fallback against
|
||||
stuck threads so server shutdown is not held up forever.
|
||||
*/
|
||||
DBUG_PRINT("info", ("thread_count: %d", thread_count));
|
||||
|
||||
for (int i= 0; *(volatile int32*) &thread_count && i < 1000; i++)
|
||||
my_sleep(20000);
|
||||
|
||||
@ -1707,11 +1744,9 @@ static void close_connections(void)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
DBUG_PRINT("quit",("Locking LOCK_thread_count"));
|
||||
mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
||||
if (!(tmp=threads.get()))
|
||||
{
|
||||
DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
break;
|
||||
}
|
||||
@ -1720,12 +1755,13 @@ static void close_connections(void)
|
||||
{
|
||||
if (global_system_variables.log_warnings)
|
||||
sql_print_warning(ER_DEFAULT(ER_FORCING_CLOSE),my_progname,
|
||||
tmp->thread_id,
|
||||
(ulong) tmp->thread_id,
|
||||
(tmp->main_security_ctx.user ?
|
||||
tmp->main_security_ctx.user : ""));
|
||||
close_connection(tmp,ER_SERVER_SHUTDOWN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/*
|
||||
* WSREP_TODO:
|
||||
@ -1992,7 +2028,8 @@ pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
|
||||
extern "C" sig_handler print_signal_warning(int sig)
|
||||
{
|
||||
if (global_system_variables.log_warnings)
|
||||
sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id());
|
||||
sql_print_warning("Got signal %d from thread %ld", sig,
|
||||
(ulong) my_thread_id());
|
||||
#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
|
||||
my_sigset(sig,print_signal_warning); /* int. thread system calls */
|
||||
#endif
|
||||
@ -2207,10 +2244,14 @@ void clean_up(bool print_message)
|
||||
logger.cleanup_end();
|
||||
sys_var_end();
|
||||
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);
|
||||
DBUG_PRINT("quit", ("got thread count lock"));
|
||||
ready_to_exit=1;
|
||||
/* do the broadcast inside the lock to ensure that my_end() is not called */
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
@ -2258,6 +2299,7 @@ static void clean_up_mutexes()
|
||||
mysql_rwlock_destroy(&LOCK_grant);
|
||||
mysql_mutex_destroy(&LOCK_thread_count);
|
||||
mysql_mutex_destroy(&LOCK_thread_cache);
|
||||
mysql_mutex_destroy(&LOCK_start_thread);
|
||||
mysql_mutex_destroy(&LOCK_status);
|
||||
mysql_mutex_destroy(&LOCK_show_status);
|
||||
mysql_mutex_destroy(&LOCK_delayed_insert);
|
||||
@ -2291,6 +2333,7 @@ static void clean_up_mutexes()
|
||||
mysql_mutex_destroy(&LOCK_error_messages);
|
||||
mysql_cond_destroy(&COND_thread_count);
|
||||
mysql_cond_destroy(&COND_thread_cache);
|
||||
mysql_cond_destroy(&COND_start_thread);
|
||||
mysql_cond_destroy(&COND_flush_thread_cache);
|
||||
mysql_mutex_destroy(&LOCK_server_started);
|
||||
mysql_cond_destroy(&COND_server_started);
|
||||
@ -2312,7 +2355,9 @@ static void clean_up_mutexes()
|
||||
static void set_ports()
|
||||
{
|
||||
}
|
||||
|
||||
void close_connection(THD *thd, uint sql_errno)
|
||||
{
|
||||
}
|
||||
#else
|
||||
static void set_ports()
|
||||
{
|
||||
@ -2794,6 +2839,7 @@ static void network_init(void)
|
||||
@note
|
||||
For the connection that is doing shutdown, this is called twice
|
||||
*/
|
||||
|
||||
void close_connection(THD *thd, uint sql_errno)
|
||||
{
|
||||
DBUG_ENTER("close_connection");
|
||||
@ -2829,20 +2875,6 @@ extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused)))
|
||||
DBUG_VOID_RETURN; /* purecov: deadcode */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cleanup THD object
|
||||
|
||||
SYNOPSIS
|
||||
thd_cleanup()
|
||||
thd Thread handler
|
||||
*/
|
||||
|
||||
void thd_cleanup(THD *thd)
|
||||
{
|
||||
thd->cleanup();
|
||||
}
|
||||
|
||||
/*
|
||||
Decrease number of connections
|
||||
|
||||
@ -2850,43 +2882,49 @@ void thd_cleanup(THD *thd)
|
||||
dec_connection_count()
|
||||
*/
|
||||
|
||||
void dec_connection_count(THD *thd)
|
||||
void dec_connection_count(scheduler_functions *scheduler)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
/*
|
||||
Do not decrement when its wsrep system thread. wsrep_applier is set for
|
||||
applier as well as rollbacker threads.
|
||||
*/
|
||||
if (thd->wsrep_applier)
|
||||
return;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
DBUG_ASSERT(*thd->scheduler->connection_count > 0);
|
||||
mysql_mutex_lock(&LOCK_connection_count);
|
||||
(*thd->scheduler->connection_count)--;
|
||||
(*scheduler->connection_count)--;
|
||||
mysql_mutex_unlock(&LOCK_connection_count);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Delete THD and decrement thread counters, including thread_running
|
||||
|
||||
This is mainly used to delete event threads which are not increasing
|
||||
global counters.
|
||||
*/
|
||||
|
||||
void delete_running_thd(THD *thd)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->unlink();
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd->add_status_to_global();
|
||||
unlink_not_visible_thd(thd);
|
||||
|
||||
delete thd;
|
||||
dec_thread_running();
|
||||
dec_thread_count();
|
||||
}
|
||||
|
||||
/*
|
||||
Decrease number of threads. Signal when it reaches 0
|
||||
|
||||
SYNOPSIS
|
||||
dec_thread_count()
|
||||
*/
|
||||
|
||||
void dec_thread_count(void)
|
||||
{
|
||||
DBUG_ASSERT(thread_count > 0);
|
||||
thread_safe_decrement32(&thread_count);
|
||||
signal_thd_deleted();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Send a signal to unblock close_conneciton() if there is no more
|
||||
threads running with a THD attached
|
||||
Send a signal to unblock close_conneciton() / rpl_slave_init_thread()
|
||||
if there is no more threads running with a THD attached
|
||||
|
||||
It's safe to check for thread_count and service_thread_count outside
|
||||
of a mutex as we are only interested to see if they where decremented
|
||||
@ -2898,7 +2936,7 @@ void delete_running_thd(THD *thd)
|
||||
|
||||
void signal_thd_deleted()
|
||||
{
|
||||
if (!thread_count && ! service_thread_count)
|
||||
if (!thread_count && !service_thread_count)
|
||||
{
|
||||
/* Signal close_connections() that all THD's are freed */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
@ -2914,9 +2952,6 @@ void signal_thd_deleted()
|
||||
SYNOPSIS
|
||||
unlink_thd()
|
||||
thd Thread handler
|
||||
|
||||
NOTES
|
||||
LOCK_thread_count is locked and left locked
|
||||
*/
|
||||
|
||||
void unlink_thd(THD *thd)
|
||||
@ -2924,23 +2959,18 @@ void unlink_thd(THD *thd)
|
||||
DBUG_ENTER("unlink_thd");
|
||||
DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
|
||||
|
||||
thd_cleanup(thd);
|
||||
dec_connection_count(thd);
|
||||
|
||||
/*
|
||||
Do not decrement when its wsrep system thread. wsrep_applier is set for
|
||||
applier as well as rollbacker threads.
|
||||
*/
|
||||
if (IF_WSREP(!thd->wsrep_applier, 1))
|
||||
dec_connection_count(thd->scheduler);
|
||||
thd->cleanup();
|
||||
thd->add_status_to_global();
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->unlink();
|
||||
/*
|
||||
Used by binlog_reset_master. It would be cleaner to use
|
||||
DEBUG_SYNC here, but that's not possible because the THD's debug
|
||||
sync feature has been shut down at this point.
|
||||
*/
|
||||
DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5););
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
unlink_not_visible_thd(thd);
|
||||
delete thd;
|
||||
thread_safe_decrement32(&thread_count);
|
||||
dec_thread_count();
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -2989,11 +3019,21 @@ static bool cache_thread()
|
||||
mysql_cond_signal(&COND_flush_thread_cache);
|
||||
if (wake_thread)
|
||||
{
|
||||
CONNECT *connect;
|
||||
THD *thd;
|
||||
|
||||
wake_thread--;
|
||||
thd= thread_cache.get();
|
||||
connect= thread_cache.get();
|
||||
mysql_mutex_unlock(&LOCK_thread_cache);
|
||||
|
||||
if (!(thd= connect->create_thd()))
|
||||
{
|
||||
/* Out of resources. Free thread to get more resources */
|
||||
connect->close_and_delete();
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
delete connect;
|
||||
|
||||
thd->thread_stack= (char*) &thd; // For store_globals
|
||||
(void) thd->store_globals();
|
||||
|
||||
@ -3016,10 +3056,7 @@ static bool cache_thread()
|
||||
thd->thr_create_utime= microsecond_interval_timer();
|
||||
thd->start_utime= thd->thr_create_utime;
|
||||
|
||||
/* Link thd into list of all active threads (THD's) */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
threads.append(thd);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
add_to_active_threads(thd);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
@ -3033,7 +3070,7 @@ static bool cache_thread()
|
||||
|
||||
SYNOPSIS
|
||||
one_thread_per_connection_end()
|
||||
thd Thread handler
|
||||
thd Thread handler. This may be null if we run out of resources.
|
||||
put_in_cache Store thread in cache, if there is room in it
|
||||
Normally this is true in all cases except when we got
|
||||
out of resources initializing the current thread
|
||||
@ -3052,12 +3089,13 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
|
||||
DBUG_ENTER("one_thread_per_connection_end");
|
||||
const bool wsrep_applier= IF_WSREP(thd->wsrep_applier, false);
|
||||
|
||||
unlink_thd(thd);
|
||||
if (thd)
|
||||
unlink_thd(thd);
|
||||
|
||||
if (!wsrep_applier && put_in_cache && cache_thread())
|
||||
DBUG_RETURN(0); // Thread is reused
|
||||
|
||||
signal_thd_deleted();
|
||||
DBUG_PRINT("info", ("killing thread"));
|
||||
DBUG_LEAVE; // Must match DBUG_ENTER()
|
||||
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
|
||||
ERR_remove_state(0);
|
||||
@ -3425,7 +3463,7 @@ static void start_signal_handler(void)
|
||||
(void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
|
||||
(void) my_setstacksize(&thr_attr,my_thread_stack_size);
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
mysql_mutex_lock(&LOCK_start_thread);
|
||||
if ((error= mysql_thread_create(key_thread_signal_hand,
|
||||
&signal_thread, &thr_attr, signal_hand, 0)))
|
||||
{
|
||||
@ -3433,8 +3471,8 @@ static void start_signal_handler(void)
|
||||
error,errno);
|
||||
exit(1);
|
||||
}
|
||||
mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_cond_wait(&COND_start_thread, &LOCK_start_thread);
|
||||
mysql_mutex_unlock(&LOCK_start_thread);
|
||||
|
||||
(void) pthread_attr_destroy(&thr_attr);
|
||||
DBUG_VOID_RETURN;
|
||||
@ -3484,12 +3522,12 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
||||
signal to start_signal_handler that we are ready
|
||||
This works by waiting for start_signal_handler to free mutex,
|
||||
after which we signal it that we are ready.
|
||||
At this pointer there is no other threads running, so there
|
||||
At this point there is no other threads running, so there
|
||||
should not be any other mysql_cond_signal() calls.
|
||||
*/
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_lock(&LOCK_start_thread);
|
||||
mysql_cond_broadcast(&COND_start_thread);
|
||||
mysql_mutex_unlock(&LOCK_start_thread);
|
||||
|
||||
(void) pthread_sigmask(SIG_BLOCK,&set,NULL);
|
||||
for (;;)
|
||||
@ -4124,7 +4162,7 @@ static int init_common_variables()
|
||||
sf_malloc_dbug_id= mariadb_dbug_id;
|
||||
#endif
|
||||
|
||||
max_system_variables.pseudo_thread_id= (ulong)~0;
|
||||
max_system_variables.pseudo_thread_id= ~(my_thread_id) 0;
|
||||
server_start_time= flush_status_time= my_time(0);
|
||||
|
||||
global_rpl_filter= new Rpl_filter;
|
||||
@ -4637,6 +4675,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_start_thread, &LOCK_start_thread, MY_MUTEX_INIT_FAST);
|
||||
mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST);
|
||||
mysql_mutex_init(key_LOCK_show_status, &LOCK_show_status, MY_MUTEX_INIT_SLOW);
|
||||
mysql_mutex_init(key_LOCK_delayed_insert,
|
||||
@ -4699,6 +4738,7 @@ static int init_thread_environment()
|
||||
mysql_rwlock_init(key_rwlock_LOCK_grant, &LOCK_grant);
|
||||
mysql_cond_init(key_COND_thread_count, &COND_thread_count, NULL);
|
||||
mysql_cond_init(key_COND_thread_cache, &COND_thread_cache, NULL);
|
||||
mysql_cond_init(key_COND_start_thread, &COND_start_thread, NULL);
|
||||
mysql_cond_init(key_COND_flush_thread_cache, &COND_flush_thread_cache, NULL);
|
||||
#ifdef HAVE_REPLICATION
|
||||
mysql_mutex_init(key_LOCK_rpl_status, &LOCK_rpl_status, MY_MUTEX_INIT_FAST);
|
||||
@ -5465,7 +5505,7 @@ static void handle_connections_methods()
|
||||
unireg_abort(1); // Will not return
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
mysql_mutex_lock(&LOCK_thread_start);
|
||||
mysql_cond_init(key_COND_handler_count, &COND_handler_count, NULL);
|
||||
handler_count=0;
|
||||
if (hPipe != INVALID_HANDLE_VALUE)
|
||||
@ -5508,17 +5548,17 @@ static void handle_connections_methods()
|
||||
#endif
|
||||
|
||||
while (handler_count > 0)
|
||||
mysql_cond_wait(&COND_handler_count, &LOCK_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_cond_wait(&COND_handler_count, &LOCK_thread_start);
|
||||
mysql_mutex_unlock(&LOCK_thread_start);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void decrement_handler_count()
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
handler_count--;
|
||||
mysql_cond_signal(&COND_handler_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_mutex_lock(&LOCK_thread_start);
|
||||
if (--handler_count == 0)
|
||||
mysql_cond_signal(&COND_handler_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_start);
|
||||
my_thread_end();
|
||||
}
|
||||
#else
|
||||
@ -5985,18 +6025,10 @@ int mysqld_main(int argc, char **argv)
|
||||
DBUG_PRINT("quit",("Exiting main thread"));
|
||||
|
||||
#ifndef __WIN__
|
||||
#ifdef EXTRA_DEBUG2
|
||||
sql_print_error("Before Lock_thread_count");
|
||||
#endif
|
||||
WSREP_DEBUG("Before Lock_thread_count");
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
DBUG_PRINT("quit", ("Got thread_count mutex"));
|
||||
mysql_mutex_lock(&LOCK_start_thread);
|
||||
select_thread_in_use=0; // For close_connections
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
#ifdef EXTRA_DEBUG2
|
||||
sql_print_error("After lock_thread_count");
|
||||
#endif
|
||||
mysql_cond_broadcast(&COND_start_thread);
|
||||
mysql_mutex_unlock(&LOCK_start_thread);
|
||||
#endif /* __WIN__ */
|
||||
|
||||
#ifdef HAVE_PSI_THREAD_INTERFACE
|
||||
@ -6261,7 +6293,7 @@ static void bootstrap(MYSQL_FILE *file)
|
||||
my_net_init(&thd->net,(st_vio*) 0, (void*) 0, MYF(0));
|
||||
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++;
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id();
|
||||
thread_count++; // Safe as only one thread running
|
||||
in_bootstrap= TRUE;
|
||||
|
||||
@ -6281,10 +6313,7 @@ static void bootstrap(MYSQL_FILE *file)
|
||||
/* Wait for thread to die */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
while (in_bootstrap)
|
||||
{
|
||||
mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
|
||||
DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
#else
|
||||
thd->mysql= 0;
|
||||
@ -6314,7 +6343,7 @@ static bool read_init_file(char *file_name)
|
||||
*/
|
||||
void inc_thread_created(void)
|
||||
{
|
||||
thread_created++;
|
||||
statistic_increment(thread_created, &LOCK_status);
|
||||
}
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@ -6325,18 +6354,12 @@ void inc_thread_created(void)
|
||||
NOTES
|
||||
This is only used for debugging, when starting mysqld with
|
||||
--thread-handling=no-threads or --one-thread
|
||||
|
||||
When we enter this function, LOCK_thread_count is hold!
|
||||
*/
|
||||
|
||||
void handle_connection_in_main_thread(THD *thd)
|
||||
void handle_connection_in_main_thread(CONNECT *connect)
|
||||
{
|
||||
mysql_mutex_assert_owner(&LOCK_thread_count);
|
||||
thread_cache_size=0; // Safety
|
||||
threads.append(thd);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd->start_utime= microsecond_interval_timer();
|
||||
do_handle_one_connection(thd);
|
||||
thread_cache_size= 0; // Safety
|
||||
do_handle_one_connection(connect);
|
||||
}
|
||||
|
||||
|
||||
@ -6344,10 +6367,11 @@ void handle_connection_in_main_thread(THD *thd)
|
||||
Scheduler that uses one thread per connection
|
||||
*/
|
||||
|
||||
void create_thread_to_handle_connection(THD *thd)
|
||||
void create_thread_to_handle_connection(CONNECT *connect)
|
||||
{
|
||||
char error_message_buff[MYSQL_ERRMSG_SIZE];
|
||||
int error;
|
||||
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)
|
||||
@ -6356,9 +6380,8 @@ void create_thread_to_handle_connection(THD *thd)
|
||||
/* Recheck condition when we have the lock */
|
||||
if (cached_thread_count > wake_thread)
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
/* Get thread from cache */
|
||||
thread_cache.push_back(thd);
|
||||
thread_cache.push_back(connect);
|
||||
wake_thread++;
|
||||
mysql_cond_signal(&COND_thread_cache);
|
||||
mysql_mutex_unlock(&LOCK_thread_cache);
|
||||
@ -6368,46 +6391,33 @@ void create_thread_to_handle_connection(THD *thd)
|
||||
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();
|
||||
inc_thread_created();
|
||||
DBUG_PRINT("info",(("creating thread %lu"), (ulong) connect->thread_id));
|
||||
connect->prior_thr_create_utime= microsecond_interval_timer();
|
||||
|
||||
if ((error= mysql_thread_create(key_thread_one_connection,
|
||||
&thd->real_id, &connection_attrib,
|
||||
&connect->real_id, &connection_attrib,
|
||||
handle_one_connection,
|
||||
(void*) thd)))
|
||||
(void*) connect)))
|
||||
{
|
||||
/* 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);
|
||||
|
||||
dec_connection_count(connect->scheduler);
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
statistic_increment(connection_errors_internal, &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);
|
||||
return;
|
||||
ER_DEFAULT(ER_CANT_CREATE_THREAD), error);
|
||||
connect->close_with_error(ER_CANT_CREATE_THREAD,
|
||||
error_message_buff,
|
||||
ER_OUT_OF_RESOURCES);
|
||||
/* thread_count was incremented in create_new_thread() */
|
||||
dec_thread_count();
|
||||
DBUG_VOID_RETURN;
|
||||
/* purecov: end */
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
DBUG_PRINT("info",("Thread created"));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -6426,7 +6436,7 @@ void create_thread_to_handle_connection(THD *thd)
|
||||
@param[in,out] thd Thread handle of future thread.
|
||||
*/
|
||||
|
||||
static void create_new_thread(THD *thd)
|
||||
static void create_new_thread(CONNECT *connect)
|
||||
{
|
||||
DBUG_ENTER("create_new_thread");
|
||||
|
||||
@ -6437,20 +6447,19 @@ static void create_new_thread(THD *thd)
|
||||
|
||||
mysql_mutex_lock(&LOCK_connection_count);
|
||||
|
||||
if (*thd->scheduler->connection_count >=
|
||||
*thd->scheduler->max_connections + 1|| abort_loop)
|
||||
if (*connect->scheduler->connection_count >=
|
||||
*connect->scheduler->max_connections + 1|| abort_loop)
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_connection_count);
|
||||
|
||||
DBUG_PRINT("error",("Too many connections"));
|
||||
close_connection(thd, ER_CON_COUNT_ERROR);
|
||||
|
||||
mysql_mutex_unlock(&LOCK_connection_count);
|
||||
statistic_increment(denied_connections, &LOCK_status);
|
||||
delete thd;
|
||||
statistic_increment(connection_errors_max_connection, &LOCK_status);
|
||||
connect->close_with_error(0, NullS, ER_CON_COUNT_ERROR);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
++*thd->scheduler->connection_count;
|
||||
++*connect->scheduler->connection_count;
|
||||
|
||||
if (connection_count + extra_connection_count > max_used_connections)
|
||||
max_used_connections= connection_count + extra_connection_count;
|
||||
@ -6458,17 +6467,15 @@ static void create_new_thread(THD *thd)
|
||||
mysql_mutex_unlock(&LOCK_connection_count);
|
||||
|
||||
thread_safe_increment32(&thread_count);
|
||||
connect->thread_count_incremented= 1;
|
||||
|
||||
/* 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.
|
||||
TODO: refactor this to avoid code duplication there
|
||||
*/
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
||||
|
||||
MYSQL_CALLBACK(thd->scheduler, add_connection, (thd));
|
||||
connect->thread_id= next_thread_id();
|
||||
connect->scheduler->add_connection(connect);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -6503,13 +6510,12 @@ void handle_connections_sockets()
|
||||
MYSQL_SOCKET sock= mysql_socket_invalid();
|
||||
MYSQL_SOCKET new_sock= mysql_socket_invalid();
|
||||
uint error_count=0;
|
||||
THD *thd;
|
||||
CONNECT *connect;
|
||||
struct sockaddr_storage cAddr;
|
||||
int ip_flags __attribute__((unused))=0;
|
||||
int socket_flags __attribute__((unused))= 0;
|
||||
int extra_ip_flags __attribute__((unused))=0;
|
||||
int flags=0,retval;
|
||||
st_vio *vio_tmp;
|
||||
bool is_unix_sock;
|
||||
#ifdef HAVE_POLL
|
||||
int socket_count= 0;
|
||||
@ -6708,58 +6714,43 @@ void handle_connections_sockets()
|
||||
}
|
||||
#endif /* HAVE_LIBWRAP */
|
||||
|
||||
/*
|
||||
** Don't allow too many connections
|
||||
*/
|
||||
DBUG_PRINT("info", ("Creating CONNECT for new connection"));
|
||||
|
||||
DBUG_PRINT("info", ("Creating THD for new connection"));
|
||||
if (!(thd= new THD))
|
||||
if ((connect= new CONNECT()))
|
||||
{
|
||||
is_unix_sock= (mysql_socket_getfd(sock) ==
|
||||
mysql_socket_getfd(unix_sock));
|
||||
|
||||
if (!(connect->vio=
|
||||
mysql_socket_vio_new(new_sock,
|
||||
is_unix_sock ? VIO_TYPE_SOCKET :
|
||||
VIO_TYPE_TCPIP,
|
||||
is_unix_sock ? VIO_LOCALHOST: 0)))
|
||||
{
|
||||
delete connect;
|
||||
connect= 0; // Error handling below
|
||||
}
|
||||
}
|
||||
|
||||
if (!connect)
|
||||
{
|
||||
/* Connect failure */
|
||||
(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
|
||||
(void) mysql_socket_close(new_sock);
|
||||
statistic_increment(connection_errors_internal, &LOCK_status);
|
||||
continue;
|
||||
}
|
||||
/* Set to get io buffers to be part of THD */
|
||||
set_current_thd(thd);
|
||||
|
||||
is_unix_sock= (mysql_socket_getfd(sock) ==
|
||||
mysql_socket_getfd(unix_sock));
|
||||
|
||||
if (!(vio_tmp=
|
||||
mysql_socket_vio_new(new_sock,
|
||||
is_unix_sock ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
|
||||
is_unix_sock ? VIO_LOCALHOST: 0)) ||
|
||||
my_net_init(&thd->net, vio_tmp, thd, MYF(MY_THREAD_SPECIFIC)))
|
||||
{
|
||||
/*
|
||||
Only delete the temporary vio if we didn't already attach it to the
|
||||
NET object. The destructor in THD will delete any initialized net
|
||||
structure.
|
||||
*/
|
||||
if (vio_tmp && thd->net.vio != vio_tmp)
|
||||
vio_delete(vio_tmp);
|
||||
else
|
||||
{
|
||||
(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
|
||||
(void) mysql_socket_close(new_sock);
|
||||
}
|
||||
delete thd;
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
statistic_increment(connection_errors_internal, &LOCK_status);
|
||||
continue;
|
||||
}
|
||||
|
||||
init_net_server_extension(thd);
|
||||
if (is_unix_sock)
|
||||
thd->security_ctx->host=(char*) my_localhost;
|
||||
connect->host= my_localhost;
|
||||
|
||||
if (mysql_socket_getfd(sock) == mysql_socket_getfd(extra_ip_sock))
|
||||
{
|
||||
thd->extra_port= 1;
|
||||
thd->scheduler= extra_thread_scheduler;
|
||||
connect->extra_port= 1;
|
||||
connect->scheduler= extra_thread_scheduler;
|
||||
}
|
||||
create_new_thread(thd);
|
||||
set_current_thd(0);
|
||||
create_new_thread(connect);
|
||||
}
|
||||
sd_notify(0, "STOPPING=1\n"
|
||||
"STATUS=Shutdown in progress");
|
||||
@ -6780,7 +6771,6 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
|
||||
{
|
||||
HANDLE hConnectedPipe;
|
||||
OVERLAPPED connectOverlapped= {0};
|
||||
THD *thd;
|
||||
my_thread_init();
|
||||
DBUG_ENTER("handle_connections_namedpipes");
|
||||
connectOverlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
@ -6849,24 +6839,18 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
|
||||
continue; // We have to try again
|
||||
}
|
||||
|
||||
if (!(thd = new THD))
|
||||
if (!(connect= new CONNECT) ||
|
||||
!(connect->vio= vio_new_win32pipe(hConnectedPipe)))
|
||||
{
|
||||
DisconnectNamedPipe(hConnectedPipe);
|
||||
CloseHandle(hConnectedPipe);
|
||||
delete connect;
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
statistic_increment(connection_errors_internal, &LOCK_status);
|
||||
continue;
|
||||
}
|
||||
set_current_thd(thd);
|
||||
if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
|
||||
my_net_init(&thd->net, thd->net.vio, thd, MYF(MY_THREAD_SPECIFIC)))
|
||||
{
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES);
|
||||
delete thd;
|
||||
continue;
|
||||
}
|
||||
/* Host is unknown */
|
||||
thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
|
||||
create_new_thread(thd);
|
||||
set_current_thd(0);
|
||||
connect->host= my_localhost;
|
||||
create_new_thread(connect);
|
||||
}
|
||||
CloseHandle(connectOverlapped.hEvent);
|
||||
DBUG_LEAVE;
|
||||
@ -6903,7 +6887,8 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
|
||||
/*
|
||||
get enough space base-name + '_' + longest suffix we might ever send
|
||||
*/
|
||||
if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
|
||||
if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L,
|
||||
MYF(MY_FAE))))
|
||||
goto error;
|
||||
|
||||
if (my_security_attr_create(&sa_event, &errmsg,
|
||||
@ -6969,7 +6954,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
|
||||
HANDLE event_server_wrote= 0;
|
||||
HANDLE event_server_read= 0;
|
||||
HANDLE event_conn_closed= 0;
|
||||
THD *thd= 0;
|
||||
CONNECT *connect= 0;
|
||||
|
||||
p= int10_to_str(connect_number, connect_number_char, 10);
|
||||
/*
|
||||
@ -7031,8 +7016,13 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
|
||||
}
|
||||
if (abort_loop)
|
||||
goto errorconn;
|
||||
if (!(thd= new THD))
|
||||
|
||||
if (!(connect= new CONNECT))
|
||||
{
|
||||
errmsg= "Could not create CONNECT object";
|
||||
goto errorconn;
|
||||
}
|
||||
|
||||
/* Send number of connection to client */
|
||||
int4store(handle_connect_map, connect_number);
|
||||
if (!SetEvent(event_connect_answer))
|
||||
@ -7046,24 +7036,20 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
|
||||
errmsg= "Could not set client to read mode";
|
||||
goto errorconn;
|
||||
}
|
||||
set_current_thd(thd);
|
||||
if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
|
||||
if (!(connect->vio= vio_new_win32shared_memory(handle_client_file_map,
|
||||
handle_client_map,
|
||||
event_client_wrote,
|
||||
event_client_read,
|
||||
event_server_wrote,
|
||||
event_server_read,
|
||||
event_conn_closed)) ||
|
||||
my_net_init(&thd->net, thd->net.vio, thd, MYF(MY_THREAD_SPECIFIC)))
|
||||
event_conn_closed)))
|
||||
{
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES);
|
||||
errmsg= 0;
|
||||
errmsg= "Could not create VIO object";
|
||||
goto errorconn;
|
||||
}
|
||||
thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */
|
||||
create_new_thread(thd);
|
||||
connect->host= my_localhost; /* Host is unknown */
|
||||
create_new_thread(connect);
|
||||
connect_number++;
|
||||
set_current_thd(thd);
|
||||
continue;
|
||||
|
||||
errorconn:
|
||||
@ -7089,9 +7075,11 @@ errorconn:
|
||||
CloseHandle(event_client_read);
|
||||
if (event_conn_closed)
|
||||
CloseHandle(event_conn_closed);
|
||||
delete thd;
|
||||
|
||||
delete connect;
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
statistic_increment(connection_errors_internal, &LOCK_status);
|
||||
}
|
||||
set_current_thd(0);
|
||||
|
||||
/* End shared memory handling */
|
||||
error:
|
||||
@ -8383,7 +8371,7 @@ SHOW_VAR status_vars[]= {
|
||||
{"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
|
||||
{"Com", (char*) com_status_vars, SHOW_ARRAY},
|
||||
{"Compression", (char*) &show_net_compression, SHOW_SIMPLE_FUNC},
|
||||
{"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH},
|
||||
{"Connections", (char*) &global_thread_id, SHOW_LONG_NOFLUSH},
|
||||
{"Connection_errors_accept", (char*) &connection_errors_accept, SHOW_LONG},
|
||||
{"Connection_errors_internal", (char*) &connection_errors_internal, SHOW_LONG},
|
||||
{"Connection_errors_max_connections", (char*) &connection_errors_max_connection, SHOW_LONG},
|
||||
@ -8763,7 +8751,8 @@ static int mysql_init_variables(void)
|
||||
what_to_log= ~ (1L << (uint) COM_TIME);
|
||||
denied_connections= 0;
|
||||
executed_events= 0;
|
||||
global_query_id= thread_id= 1L;
|
||||
global_query_id= 1;
|
||||
global_thread_id= 0;
|
||||
strmov(server_version, MYSQL_SERVER_VERSION);
|
||||
threads.empty();
|
||||
thread_cache.empty();
|
||||
|
30
sql/mysqld.h
30
sql/mysqld.h
@ -30,6 +30,7 @@
|
||||
#include "my_rdtsc.h"
|
||||
|
||||
class THD;
|
||||
class CONNECT;
|
||||
struct handlerton;
|
||||
class Time_zone;
|
||||
|
||||
@ -81,8 +82,8 @@ enum enum_slave_parallel_mode {
|
||||
/* Function prototypes */
|
||||
void kill_mysql(THD *thd= 0);
|
||||
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 handle_connection_in_main_thread(CONNECT *thd);
|
||||
void create_thread_to_handle_connection(CONNECT *connect);
|
||||
void delete_running_thd(THD *thd);
|
||||
void signal_thd_deleted();
|
||||
void unlink_thd(THD *thd);
|
||||
@ -90,6 +91,8 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache);
|
||||
void flush_thread_cache();
|
||||
void refresh_status(THD *thd);
|
||||
bool is_secure_file_path(char *path);
|
||||
void dec_connection_count(scheduler_functions *scheduler);
|
||||
extern void init_net_server_extension(THD *thd);
|
||||
|
||||
extern "C" MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info;
|
||||
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *files_charset_info ;
|
||||
@ -117,7 +120,7 @@ extern bool opt_skip_name_resolve;
|
||||
extern bool opt_ignore_builtin_innodb;
|
||||
extern my_bool opt_character_set_client_handshake;
|
||||
extern bool volatile abort_loop;
|
||||
extern bool in_bootstrap;
|
||||
extern bool volatile in_bootstrap;
|
||||
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;
|
||||
@ -177,7 +180,7 @@ extern char log_error_file[FN_REFLEN], *opt_tc_log_file;
|
||||
extern const double log_10[309];
|
||||
extern ulonglong keybuff_size;
|
||||
extern ulonglong thd_startup_options;
|
||||
extern ulong thread_id;
|
||||
extern my_thread_id global_thread_id;
|
||||
extern ulong binlog_cache_use, binlog_cache_disk_use;
|
||||
extern ulong binlog_stmt_cache_use, binlog_stmt_cache_disk_use;
|
||||
extern ulong aborted_threads,aborted_connects;
|
||||
@ -292,6 +295,7 @@ extern 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_rpl_group_info_sleep_lock,
|
||||
key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
|
||||
key_LOCK_start_thread,
|
||||
key_LOCK_error_messages, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc;
|
||||
extern PSI_mutex_key key_RELAYLOG_LOCK_index;
|
||||
extern PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state,
|
||||
@ -323,6 +327,7 @@ extern PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
|
||||
key_relay_log_info_start_cond, key_relay_log_info_stop_cond,
|
||||
key_rpl_group_info_sleep_cond,
|
||||
key_TABLE_SHARE_cond, key_user_level_lock_cond,
|
||||
key_COND_start_thread,
|
||||
key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache;
|
||||
extern PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready,
|
||||
key_COND_wait_commit;
|
||||
@ -558,6 +563,7 @@ extern mysql_mutex_t
|
||||
LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count,
|
||||
LOCK_slave_init;
|
||||
extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count;
|
||||
extern mysql_mutex_t LOCK_start_thread;
|
||||
#ifdef HAVE_OPENSSL
|
||||
extern char* des_key_file;
|
||||
extern mysql_mutex_t LOCK_des_key_file;
|
||||
@ -566,7 +572,7 @@ extern mysql_mutex_t LOCK_server_started;
|
||||
extern mysql_cond_t COND_server_started;
|
||||
extern mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
|
||||
extern mysql_rwlock_t LOCK_system_variables_hash;
|
||||
extern mysql_cond_t COND_thread_count;
|
||||
extern mysql_cond_t COND_thread_count, COND_start_thread;
|
||||
extern mysql_cond_t COND_manager;
|
||||
extern mysql_cond_t COND_slave_init;
|
||||
extern int32 thread_running;
|
||||
@ -698,6 +704,16 @@ inline query_id_t get_query_id()
|
||||
return my_atomic_load64_explicit(&global_query_id, MY_MEMORY_ORDER_RELAXED);
|
||||
}
|
||||
|
||||
/* increment global_thread_id and return it. */
|
||||
inline __attribute__((warn_unused_result)) my_thread_id next_thread_id()
|
||||
{
|
||||
return my_atomic_add32_explicit(&global_thread_id, 1, MY_MEMORY_ORDER_RELAXED);
|
||||
}
|
||||
|
||||
#if defined(MYSQL_DYNAMIC_PLUGIN) && defined(_WIN32)
|
||||
extern my_thread_id next_thread_id_noinline();
|
||||
#define next_thread_id() next_thread_id_noinline()
|
||||
#endif
|
||||
|
||||
/*
|
||||
TODO: Replace this with an inline function.
|
||||
@ -746,7 +762,8 @@ inline void dec_thread_running()
|
||||
thread_safe_decrement32(&thread_running);
|
||||
}
|
||||
|
||||
void set_server_version(void);
|
||||
extern void set_server_version(void);
|
||||
extern void dec_thread_count(void);
|
||||
|
||||
#if defined(MYSQL_DYNAMIC_PLUGIN) && defined(_WIN32)
|
||||
extern "C" THD *_current_thd_noinline();
|
||||
@ -768,6 +785,7 @@ inline int set_current_thd(THD *thd)
|
||||
return my_pthread_setspecific_ptr(THR_THD, thd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@todo remove, make it static in ha_maria.cc
|
||||
currently it's needed for sql_select.cc
|
||||
|
@ -3944,7 +3944,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
|
||||
{
|
||||
/* if we run out of slots or we are not using tempool */
|
||||
sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
|
||||
thd->thread_id, thd->tmp_table++);
|
||||
(ulong) thd->thread_id, thd->tmp_table++);
|
||||
}
|
||||
fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
|
||||
|
||||
|
@ -969,10 +969,8 @@ handle_rpl_parallel_thread(void *arg)
|
||||
my_thread_init();
|
||||
thd = new THD;
|
||||
thd->thread_stack = (char*)&thd;
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
||||
threads.append(thd);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id();
|
||||
add_to_active_threads(thd);
|
||||
set_current_thd(thd);
|
||||
pthread_detach_this_thread();
|
||||
thd->init_for_queries();
|
||||
@ -1372,10 +1370,10 @@ handle_rpl_parallel_thread(void *arg)
|
||||
thd->reset_db(NULL, 0);
|
||||
thd_proc_info(thd, "Slave worker thread exiting");
|
||||
thd->temporary_tables= 0;
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
|
||||
THD_CHECK_SENTRY(thd);
|
||||
unlink_not_visible_thd(thd);
|
||||
delete thd;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
mysql_mutex_lock(&rpt->LOCK_rpl_thread);
|
||||
rpt->running= false;
|
||||
|
@ -22,9 +22,9 @@
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "mysqld.h"
|
||||
#include "sql_connect.h" // init_new_connection_handler_thread
|
||||
#include "scheduler.h"
|
||||
#include "mysqld.h"
|
||||
#include "sql_class.h"
|
||||
#include "sql_callback.h"
|
||||
#include <violite.h>
|
||||
@ -35,7 +35,8 @@
|
||||
|
||||
static bool no_threads_end(THD *thd, bool put_in_cache)
|
||||
{
|
||||
unlink_thd(thd);
|
||||
if (thd)
|
||||
unlink_thd(thd);
|
||||
return 1; // Abort handle_one_connection
|
||||
}
|
||||
|
||||
@ -81,7 +82,9 @@ static void scheduler_wait_net_end(void) {
|
||||
one_thread_scheduler() or one_thread_per_connection_scheduler() in
|
||||
mysqld.cc, so this init function will always be called.
|
||||
*/
|
||||
void scheduler_init() {
|
||||
|
||||
void scheduler_init()
|
||||
{
|
||||
thr_set_lock_wait_callback(scheduler_wait_lock_begin,
|
||||
scheduler_wait_lock_end);
|
||||
thr_set_sync_wait_callback(scheduler_wait_sync_begin,
|
||||
@ -118,7 +121,6 @@ void post_kill_notification(THD *thd)
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
||||
|
||||
void one_thread_per_connection_scheduler(scheduler_functions *func,
|
||||
ulong *arg_max_connections,
|
||||
uint *arg_connection_count)
|
||||
@ -132,6 +134,14 @@ void one_thread_per_connection_scheduler(scheduler_functions *func,
|
||||
func->end_thread= one_thread_per_connection_end;
|
||||
func->post_kill_notification= post_kill_notification;
|
||||
}
|
||||
#else
|
||||
bool init_new_connection_handler_thread()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void handle_connection_in_main_thread(CONNECT *connect)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -144,10 +154,7 @@ void one_thread_scheduler(scheduler_functions *func)
|
||||
func->max_threads= 1;
|
||||
func->max_connections= &max_connections;
|
||||
func->connection_count= &connection_count;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
func->init_new_connection_thread= init_new_connection_handler_thread;
|
||||
func->add_connection= handle_connection_in_main_thread;
|
||||
#endif
|
||||
func->end_thread= no_threads_end;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ struct scheduler_functions
|
||||
ulong *max_connections;
|
||||
bool (*init)(void);
|
||||
bool (*init_new_connection_thread)(void);
|
||||
void (*add_connection)(THD *thd);
|
||||
void (*add_connection)(CONNECT *connect);
|
||||
void (*thd_wait_begin)(THD *thd, int wait_type);
|
||||
void (*thd_wait_end)(THD *thd);
|
||||
void (*post_kill_notification)(THD *thd);
|
||||
|
64
sql/slave.cc
64
sql/slave.cc
@ -294,9 +294,7 @@ handle_slave_init(void *arg __attribute__((unused)))
|
||||
my_thread_init();
|
||||
thd= new THD;
|
||||
thd->thread_stack= (char*) &thd; /* Set approximate stack start */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id= thread_id++;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd->thread_id= next_thread_id();
|
||||
thd->system_thread = SYSTEM_THREAD_SLAVE_INIT;
|
||||
thread_safe_increment32(&service_thread_count);
|
||||
thd->store_globals();
|
||||
@ -310,19 +308,17 @@ handle_slave_init(void *arg __attribute__((unused)))
|
||||
rpl_gtid_slave_state_table_name.str,
|
||||
thd->get_stmt_da()->sql_errno(),
|
||||
thd->get_stmt_da()->message());
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
delete thd;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thread_safe_decrement32(&service_thread_count);
|
||||
signal_thd_deleted();
|
||||
my_thread_end();
|
||||
|
||||
mysql_mutex_lock(&LOCK_slave_init);
|
||||
/* Signal run_slave_init_thread() that we are done */
|
||||
|
||||
mysql_mutex_lock(&LOCK_start_thread);
|
||||
slave_init_thread_running= false;
|
||||
mysql_cond_broadcast(&COND_slave_init);
|
||||
mysql_mutex_unlock(&LOCK_slave_init);
|
||||
mysql_cond_broadcast(&COND_start_thread);
|
||||
mysql_mutex_unlock(&LOCK_start_thread);
|
||||
|
||||
my_thread_end();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -347,11 +343,10 @@ run_slave_init_thread()
|
||||
return 1;
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&LOCK_slave_init);
|
||||
mysql_mutex_lock(&LOCK_start_thread);
|
||||
while (slave_init_thread_running)
|
||||
mysql_cond_wait(&COND_slave_init, &LOCK_slave_init);
|
||||
mysql_mutex_unlock(&LOCK_slave_init);
|
||||
|
||||
mysql_cond_wait(&COND_start_thread, &LOCK_start_thread);
|
||||
mysql_mutex_unlock(&LOCK_start_thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3076,9 +3071,7 @@ static int init_slave_thread(THD* thd, Master_info *mi,
|
||||
thd->variables.log_slow_filter= global_system_variables.log_slow_filter;
|
||||
set_slave_thread_options(thd);
|
||||
thd->client_capabilities = CLIENT_LOCAL_FILES;
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id();
|
||||
|
||||
if (thd_type == SLAVE_THD_SQL)
|
||||
THD_STAGE_INFO(thd, stage_waiting_for_the_next_event_in_relay_log);
|
||||
@ -3970,9 +3963,7 @@ pthread_handler_t handle_slave_io(void *arg)
|
||||
goto err_during_init;
|
||||
}
|
||||
thd->system_thread_info.rpl_io_info= &io_info;
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
threads.append(thd);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
add_to_active_threads(thd);
|
||||
mi->slave_running = MYSQL_SLAVE_RUN_NOT_CONNECT;
|
||||
mi->abort_slave = 0;
|
||||
mysql_mutex_unlock(&mi->run_lock);
|
||||
@ -4295,6 +4286,7 @@ err:
|
||||
flush_master_info(mi, TRUE, TRUE);
|
||||
THD_STAGE_INFO(thd, stage_waiting_for_slave_mutex_on_exit);
|
||||
thd->add_status_to_global();
|
||||
unlink_not_visible_thd(thd);
|
||||
mysql_mutex_lock(&mi->run_lock);
|
||||
|
||||
err_during_init:
|
||||
@ -4354,7 +4346,8 @@ int check_temp_dir(char* tmp_file)
|
||||
size_t tmp_dir_size;
|
||||
DBUG_ENTER("check_temp_dir");
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
/* This look is safe to use as this function is only called once */
|
||||
mysql_mutex_lock(&LOCK_start_thread);
|
||||
if (check_temp_dir_run)
|
||||
{
|
||||
result= check_temp_dir_result;
|
||||
@ -4393,7 +4386,7 @@ int check_temp_dir(char* tmp_file)
|
||||
|
||||
end:
|
||||
check_temp_dir_result= result;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_start_thread);
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
@ -4571,9 +4564,7 @@ pthread_handler_t handle_slave_sql(void *arg)
|
||||
applied. In all other cases it must be FALSE.
|
||||
*/
|
||||
thd->variables.binlog_annotate_row_events= 0;
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
threads.append(thd);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
add_to_active_threads(thd);
|
||||
/*
|
||||
We are going to set slave_running to 1. Assuming slave I/O thread is
|
||||
alive and connected, this is going to make Seconds_Behind_Master be 0
|
||||
@ -4882,7 +4873,9 @@ pthread_handler_t handle_slave_sql(void *arg)
|
||||
}
|
||||
THD_STAGE_INFO(thd, stage_waiting_for_slave_mutex_on_exit);
|
||||
thd->add_status_to_global();
|
||||
unlink_not_visible_thd(thd);
|
||||
mysql_mutex_lock(&rli->run_lock);
|
||||
|
||||
err_during_init:
|
||||
/* We need data_lock, at least to wake up any waiting master_pos_wait() */
|
||||
mysql_mutex_lock(&rli->data_lock);
|
||||
@ -4906,12 +4899,8 @@ err_during_init:
|
||||
to avoid unneeded position re-init
|
||||
*/
|
||||
thd->temporary_tables = 0; // remove tempation from destructor to close them
|
||||
THD_CHECK_SENTRY(thd);
|
||||
rli->sql_driver_thd= 0;
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->rgi_fake= thd->rgi_slave= NULL;
|
||||
delete serial_rgi;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/*
|
||||
@ -4940,10 +4929,11 @@ err_during_init:
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/*
|
||||
Note: the order of the broadcast and unlock calls below (first broadcast, then unlock)
|
||||
is important. Otherwise a killer_thread can execute between the calls and
|
||||
delete the mi structure leading to a crash! (see BUG#25306 for details)
|
||||
*/
|
||||
Note: the order of the broadcast and unlock calls below (first
|
||||
broadcast, then unlock) is important. Otherwise a killer_thread can
|
||||
execute between the calls and delete the mi structure leading to a
|
||||
crash! (see BUG#25306 for details)
|
||||
*/
|
||||
mysql_cond_broadcast(&rli->stop_cond);
|
||||
DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
|
||||
mysql_mutex_unlock(&rli->run_lock); // tell the world we are done
|
||||
@ -4959,9 +4949,13 @@ err_during_init:
|
||||
rpl_parallel_inactivate_pool(&global_rpl_thread_pool);
|
||||
mysql_mutex_unlock(&LOCK_active_mi);
|
||||
|
||||
/* TODO: Check if this lock is needed */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
delete thd;
|
||||
delete serial_rgi;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
THD_CHECK_SENTRY(thd);
|
||||
delete thd;
|
||||
thread_safe_decrement32(&service_thread_count);
|
||||
signal_thd_deleted();
|
||||
|
||||
|
@ -1233,7 +1233,8 @@ bool close_temporary_tables(THD *thd)
|
||||
*/
|
||||
for (;
|
||||
table && is_user_table(table) &&
|
||||
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id &&
|
||||
(ulong) tmpkeyval(thd, table) ==
|
||||
(ulong) thd->variables.pseudo_thread_id &&
|
||||
table->s->db.length == db.length() &&
|
||||
memcmp(table->s->db.str, db.ptr(), db.length()) == 0;
|
||||
table= next)
|
||||
|
@ -702,12 +702,6 @@ extern "C"
|
||||
@param length length of buffer
|
||||
@param max_query_len how many chars of query to copy (0 for all)
|
||||
|
||||
@req LOCK_thread_count
|
||||
|
||||
@note LOCK_thread_count mutex is not necessary when the function is invoked on
|
||||
the currently running thread (current_thd) or if the caller in some other
|
||||
way guarantees that access to thd->query is serialized.
|
||||
|
||||
@return Pointer to string
|
||||
*/
|
||||
|
||||
@ -953,7 +947,7 @@ THD::THD(bool is_wsrep_applier)
|
||||
// Must be reset to handle error with THD's created for init of mysqld
|
||||
lex->current_select= 0;
|
||||
user_time.val= start_time= start_time_sec_part= 0;
|
||||
start_utime= utime_after_query= prior_thr_create_utime= 0L;
|
||||
start_utime= utime_after_query= 0;
|
||||
utime_after_lock= 0L;
|
||||
progress.arena= 0;
|
||||
progress.report_to_client= 0;
|
||||
@ -1378,6 +1372,12 @@ extern "C" THD *_current_thd_noinline(void)
|
||||
{
|
||||
return my_pthread_getspecific_ptr(THD*,THR_THD);
|
||||
}
|
||||
|
||||
extern "C" my_thread_id next_thread_id_noinline()
|
||||
{
|
||||
#undef next_thread_id
|
||||
return next_thread_id();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1628,6 +1628,10 @@ THD::~THD()
|
||||
THD *orig_thd= current_thd;
|
||||
THD_CHECK_SENTRY(this);
|
||||
DBUG_ENTER("~THD()");
|
||||
/* Check that we have already called thd->unlink() */
|
||||
DBUG_ASSERT(prev == 0 && next == 0);
|
||||
/* This takes a long time so we should not do this under LOCK_thread_count */
|
||||
mysql_mutex_assert_not_owner(&LOCK_thread_count);
|
||||
|
||||
/*
|
||||
In error cases, thd may not be current thd. We have to fix this so
|
||||
@ -4073,7 +4077,7 @@ void Security_context::destroy()
|
||||
// If not pointer to constant
|
||||
if (host != my_localhost)
|
||||
{
|
||||
my_free(host);
|
||||
my_free((char*) host);
|
||||
host= NULL;
|
||||
}
|
||||
if (user != delayed_user)
|
||||
|
@ -1185,7 +1185,8 @@ public:
|
||||
priv_user - The user privilege we are using. May be "" for anonymous user.
|
||||
ip - client IP
|
||||
*/
|
||||
char *host, *user, *ip;
|
||||
const char *host;
|
||||
char *user, *ip;
|
||||
char priv_user[USERNAME_LENGTH];
|
||||
char proxy_user[USERNAME_LENGTH + MAX_HOSTNAME + 5];
|
||||
/* The host privilege we are using */
|
||||
@ -4027,8 +4028,41 @@ public:
|
||||
{
|
||||
main_lex.restore_set_statement_var();
|
||||
}
|
||||
|
||||
/*
|
||||
Reset current_linfo
|
||||
Setting current_linfo to 0 needs to be done with LOCK_thread_count to
|
||||
ensure that adjust_linfo_offsets doesn't use a structure that may
|
||||
be deleted.
|
||||
*/
|
||||
inline void reset_current_linfo()
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
current_linfo= 0;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
};
|
||||
|
||||
inline void add_to_active_threads(THD *thd)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
threads.append(thd);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
|
||||
/*
|
||||
This should be called when you want to delete a thd that was not
|
||||
running any queries.
|
||||
This function will assert if the THD was not linked.
|
||||
*/
|
||||
|
||||
inline void unlink_not_visible_thd(THD *thd)
|
||||
{
|
||||
thd->assert_if_linked();
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->unlink();
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
|
||||
/** A short cut for thd->get_stmt_da()->set_ok_status(). */
|
||||
|
||||
|
@ -827,14 +827,17 @@ bool thd_init_client_charset(THD *thd, uint cs_number)
|
||||
Initialize connection threads
|
||||
*/
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
bool init_new_connection_handler_thread()
|
||||
{
|
||||
pthread_detach_this_thread();
|
||||
if (my_thread_init())
|
||||
{
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
statistic_increment(connection_errors_internal, &LOCK_status);
|
||||
return 1;
|
||||
}
|
||||
DBUG_EXECUTE_IF("simulate_failed_connection_1", return(1); );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -850,7 +853,6 @@ bool init_new_connection_handler_thread()
|
||||
1 error
|
||||
*/
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
static int check_connection(THD *thd)
|
||||
{
|
||||
uint connect_errors= 0;
|
||||
@ -951,6 +953,7 @@ static int check_connection(THD *thd)
|
||||
this is treated as a global server OOM error.
|
||||
TODO: remove the need for my_strdup.
|
||||
*/
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
statistic_increment(connection_errors_internal, &LOCK_status);
|
||||
return 1; /* The error is set by my_strdup(). */
|
||||
}
|
||||
@ -968,7 +971,7 @@ static int check_connection(THD *thd)
|
||||
if (thd->main_security_ctx.host)
|
||||
{
|
||||
if (thd->main_security_ctx.host != my_localhost)
|
||||
thd->main_security_ctx.host[MY_MIN(strlen(thd->main_security_ctx.host),
|
||||
((char*) thd->main_security_ctx.host)[MY_MIN(strlen(thd->main_security_ctx.host),
|
||||
HOSTNAME_LENGTH)]= 0;
|
||||
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
|
||||
}
|
||||
@ -1016,6 +1019,7 @@ static int check_connection(THD *thd)
|
||||
Hence, there is no reason to account on OOM conditions per client IP,
|
||||
we count failures in the global server status instead.
|
||||
*/
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
statistic_increment(connection_errors_internal, &LOCK_status);
|
||||
return 1; /* The error is set by alloc(). */
|
||||
}
|
||||
@ -1054,7 +1058,8 @@ bool setup_connection_thread_globals(THD *thd)
|
||||
{
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES);
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
MYSQL_CALLBACK(thd->scheduler, end_thread, (thd, 0));
|
||||
statistic_increment(connection_errors_internal, &LOCK_status);
|
||||
thd->scheduler->end_thread(thd, 0);
|
||||
return 1; // Error
|
||||
}
|
||||
return 0;
|
||||
@ -1082,7 +1087,7 @@ bool login_connection(THD *thd)
|
||||
int error= 0;
|
||||
DBUG_ENTER("login_connection");
|
||||
DBUG_PRINT("info", ("login_connection called by thread %lu",
|
||||
thd->thread_id));
|
||||
(ulong) thd->thread_id));
|
||||
|
||||
/* Use "connect_timeout" value during connection phase */
|
||||
my_net_set_read_timeout(net, connect_timeout);
|
||||
@ -1254,11 +1259,11 @@ void prepare_new_connection_state(THD* thd)
|
||||
|
||||
pthread_handler_t handle_one_connection(void *arg)
|
||||
{
|
||||
THD *thd= (THD*) arg;
|
||||
CONNECT *connect= (CONNECT*) arg;
|
||||
|
||||
mysql_thread_set_psi_id(thd->thread_id);
|
||||
mysql_thread_set_psi_id(connect->thread_id);
|
||||
|
||||
do_handle_one_connection(thd);
|
||||
do_handle_one_connection(connect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1290,19 +1295,17 @@ bool thd_is_connection_alive(THD *thd)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void do_handle_one_connection(THD *thd_arg)
|
||||
|
||||
void do_handle_one_connection(CONNECT *connect)
|
||||
{
|
||||
THD *thd= thd_arg;
|
||||
|
||||
thd->thr_create_utime= microsecond_interval_timer();
|
||||
/* We need to set this because of time_out_user_resource_limits */
|
||||
thd->start_utime= thd->thr_create_utime;
|
||||
|
||||
if (MYSQL_CALLBACK_ELSE(thd->scheduler, init_new_connection_thread, (), 0))
|
||||
ulonglong thr_create_utime= microsecond_interval_timer();
|
||||
THD *thd;
|
||||
if (connect->scheduler->init_new_connection_thread() ||
|
||||
!(thd= connect->create_thd()))
|
||||
{
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES);
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
MYSQL_CALLBACK(thd->scheduler, end_thread, (thd, 0));
|
||||
scheduler_functions *scheduler= connect->scheduler;
|
||||
connect->close_with_error(0, 0, ER_OUT_OF_RESOURCES);
|
||||
scheduler->end_thread(0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1311,14 +1314,22 @@ void do_handle_one_connection(THD *thd_arg)
|
||||
increment slow_launch_threads counter if it took more than
|
||||
slow_launch_time seconds to create the thread.
|
||||
*/
|
||||
if (thd->prior_thr_create_utime)
|
||||
|
||||
if (connect->prior_thr_create_utime)
|
||||
{
|
||||
ulong launch_time= (ulong) (thd->thr_create_utime -
|
||||
thd->prior_thr_create_utime);
|
||||
ulong launch_time= (ulong) (thr_create_utime -
|
||||
connect->prior_thr_create_utime);
|
||||
if (launch_time >= slow_launch_time*1000000L)
|
||||
statistic_increment(slow_launch_threads, &LOCK_status);
|
||||
thd->prior_thr_create_utime= 0;
|
||||
}
|
||||
delete connect;
|
||||
|
||||
/* Make THD visible in show processlist */
|
||||
add_to_active_threads(thd);
|
||||
|
||||
thd->thr_create_utime= thr_create_utime;
|
||||
/* We need to set this because of time_out_user_resource_limits */
|
||||
thd->start_utime= thr_create_utime;
|
||||
|
||||
/*
|
||||
handle_one_connection() is normally the only way a thread would
|
||||
@ -1365,7 +1376,7 @@ end_thread:
|
||||
if (thd->userstat_running)
|
||||
update_global_user_stats(thd, create_user, time(NULL));
|
||||
|
||||
if (MYSQL_CALLBACK_ELSE(thd->scheduler, end_thread, (thd, 1), 0))
|
||||
if (thd->scheduler->end_thread(thd, 1))
|
||||
return; // Probably no-threads
|
||||
|
||||
/*
|
||||
@ -1377,3 +1388,110 @@ end_thread:
|
||||
}
|
||||
}
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
|
||||
/* Handling of CONNECT objects */
|
||||
|
||||
/*
|
||||
Close connection without error and delete the connect object
|
||||
This and close_with_error are only called if we didn't manage to
|
||||
create a new thd object.
|
||||
*/
|
||||
|
||||
void CONNECT::close_and_delete()
|
||||
{
|
||||
DBUG_ENTER("close_and_delete");
|
||||
|
||||
if (vio)
|
||||
vio_close(vio);
|
||||
if (thread_count_incremented)
|
||||
{
|
||||
/*
|
||||
Normally this is handled by THD::unlink. As we haven't yet created
|
||||
a THD and put it in the thread list, we have to manage counting here.
|
||||
*/
|
||||
dec_thread_count();
|
||||
dec_connection_count(scheduler);
|
||||
}
|
||||
statistic_increment(connection_errors_internal, &LOCK_status);
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
|
||||
delete this;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Close a connection with a possible error to the end user
|
||||
Alse deletes the connection object, like close_and_delete()
|
||||
*/
|
||||
|
||||
void CONNECT::close_with_error(uint sql_errno,
|
||||
const char *message, uint close_error)
|
||||
{
|
||||
THD *thd= create_thd();
|
||||
if (thd)
|
||||
{
|
||||
if (sql_errno)
|
||||
net_send_error(thd, sql_errno, message, NULL);
|
||||
close_connection(thd, close_error);
|
||||
delete thd;
|
||||
set_current_thd(0);
|
||||
if (thread_count_incremented)
|
||||
{
|
||||
dec_thread_count();
|
||||
dec_connection_count(scheduler);
|
||||
}
|
||||
delete this;
|
||||
statistic_increment(connection_errors_internal, &LOCK_status);
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Out of memory; We can't generate an error, just close the connection
|
||||
close_and_delete() will increment statistics.
|
||||
*/
|
||||
close_and_delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CONNECT::~CONNECT()
|
||||
{
|
||||
if (vio)
|
||||
vio_delete(vio);
|
||||
}
|
||||
|
||||
/* Create a THD based on a CONNECT object */
|
||||
|
||||
THD *CONNECT::create_thd()
|
||||
{
|
||||
my_bool res;
|
||||
THD *thd;
|
||||
DBUG_ENTER("create_thd");
|
||||
|
||||
DBUG_EXECUTE_IF("simulate_failed_connection_2", DBUG_RETURN(0); );
|
||||
|
||||
if (!(thd= new THD))
|
||||
DBUG_RETURN(0);
|
||||
|
||||
set_current_thd(thd);
|
||||
res= my_net_init(&thd->net, vio, thd, MYF(MY_THREAD_SPECIFIC));
|
||||
vio= 0; // Vio now handled by thd
|
||||
|
||||
if (res)
|
||||
{
|
||||
delete thd;
|
||||
set_current_thd(0);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
init_net_server_extension(thd);
|
||||
|
||||
thd->security_ctx->host= host;
|
||||
thd->extra_port= extra_port;
|
||||
thd->scheduler= scheduler;
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id;
|
||||
thd->real_id= real_id;
|
||||
DBUG_RETURN(thd);
|
||||
}
|
||||
|
@ -19,8 +19,43 @@
|
||||
#include "my_sys.h" /* pthread_handler_t */
|
||||
#include "mysql_com.h" /* enum_server_command */
|
||||
#include "structs.h"
|
||||
#include <mysql/psi/mysql_socket.h>
|
||||
#include <hash.h>
|
||||
|
||||
/*
|
||||
Object to hold connect information to be given to the newly created thread
|
||||
*/
|
||||
|
||||
class scheduler_functions;
|
||||
|
||||
class CONNECT : public ilink {
|
||||
public:
|
||||
/* To be copied to THD */
|
||||
Vio *vio; /* Copied to THD with my_net_init() */
|
||||
const char *host;
|
||||
scheduler_functions *scheduler;
|
||||
my_thread_id thread_id;
|
||||
pthread_t real_id;
|
||||
bool extra_port;
|
||||
|
||||
/* Own variables */
|
||||
bool thread_count_incremented;
|
||||
ulonglong prior_thr_create_utime;
|
||||
|
||||
CONNECT()
|
||||
:vio(0), host(0), scheduler(thread_scheduler), thread_id(0), real_id(0),
|
||||
extra_port(0),
|
||||
thread_count_incremented(0), prior_thr_create_utime(0)
|
||||
{
|
||||
};
|
||||
~CONNECT();
|
||||
void close_and_delete();
|
||||
void close_with_error(uint sql_errno,
|
||||
const char *message, uint close_error);
|
||||
THD *create_thd();
|
||||
};
|
||||
|
||||
|
||||
class THD;
|
||||
typedef struct st_lex_user LEX_USER;
|
||||
typedef struct user_conn USER_CONN;
|
||||
@ -37,7 +72,7 @@ void free_global_index_stats(void);
|
||||
void free_global_client_stats(void);
|
||||
|
||||
pthread_handler_t handle_one_connection(void *arg);
|
||||
void do_handle_one_connection(THD *thd_arg);
|
||||
void do_handle_one_connection(CONNECT *connect);
|
||||
bool init_new_connection_handler_thread();
|
||||
void reset_mqh(LEX_USER *lu, bool get_them);
|
||||
bool check_mqh(THD *thd, uint check_command);
|
||||
|
@ -2068,6 +2068,7 @@ public:
|
||||
delayed_lock= global_system_variables.low_priority_updates ?
|
||||
TL_WRITE_LOW_PRIORITY : TL_WRITE;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thread_safe_increment32(&thread_count);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
~Delayed_insert()
|
||||
@ -2081,17 +2082,24 @@ public:
|
||||
close_thread_tables(&thd);
|
||||
thd.mdl_context.release_transactional_locks();
|
||||
}
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
mysql_mutex_destroy(&mutex);
|
||||
mysql_cond_destroy(&cond);
|
||||
mysql_cond_destroy(&cond_client);
|
||||
|
||||
/*
|
||||
We could use unlink_not_visible_threads() here, but as
|
||||
delayed_insert_threads also needs to be protected by
|
||||
the LOCK_thread_count mutex, we open code this.
|
||||
*/
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd.unlink(); // Must be unlinked under lock
|
||||
my_free(thd.query());
|
||||
thd.security_ctx->user= thd.security_ctx->host=0;
|
||||
delayed_insert_threads--;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thread_safe_decrement32(&thread_count);
|
||||
mysql_cond_broadcast(&COND_thread_count); /* Tell main we are ready */
|
||||
|
||||
my_free(thd.query());
|
||||
thd.security_ctx->user= 0;
|
||||
thd.security_ctx->host= 0;
|
||||
dec_thread_count();
|
||||
}
|
||||
|
||||
/* The following is for checking when we can delete ourselves */
|
||||
@ -2226,8 +2234,6 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
|
||||
if (!(di= new Delayed_insert(thd->lex->current_select)))
|
||||
goto end_create;
|
||||
|
||||
thread_safe_increment32(&thread_count);
|
||||
|
||||
/*
|
||||
Annotating delayed inserts is not supported.
|
||||
*/
|
||||
@ -2803,15 +2809,13 @@ pthread_handler_t handle_delayed_insert(void *arg)
|
||||
|
||||
pthread_detach_this_thread();
|
||||
/* Add thread to THD list so that's it's visible in 'show processlist' */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id();
|
||||
thd->set_current_time();
|
||||
threads.append(thd);
|
||||
add_to_active_threads(thd);
|
||||
if (abort_loop)
|
||||
thd->killed= KILL_CONNECTION;
|
||||
else
|
||||
thd->reset_killed();
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
mysql_thread_set_psi_id(thd->thread_id);
|
||||
|
||||
|
@ -650,6 +650,10 @@ struct ilink
|
||||
if (next) next->prev=prev;
|
||||
prev=0 ; next=0;
|
||||
}
|
||||
inline void assert_if_linked()
|
||||
{
|
||||
DBUG_ASSERT(prev != 0 && next != 0);
|
||||
}
|
||||
virtual ~ilink() { unlink(); } /*lint -e1740 */
|
||||
};
|
||||
|
||||
|
@ -844,12 +844,13 @@ end:
|
||||
delete thd;
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
thread_safe_decrement32(&thread_count);
|
||||
DBUG_ASSERT(thread_count == 1);
|
||||
in_bootstrap= FALSE;
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
/*
|
||||
dec_thread_count will signal bootstrap() function that we have ended as
|
||||
thread_count will become 0.
|
||||
*/
|
||||
dec_thread_count();
|
||||
my_thread_end();
|
||||
pthread_exit(0);
|
||||
#endif
|
||||
@ -954,7 +955,6 @@ bool do_command(THD *thd)
|
||||
if(!thd->skip_wait_timeout)
|
||||
my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
|
||||
|
||||
|
||||
/*
|
||||
XXX: this code is here only to clear possible errors of init_connect.
|
||||
Consider moving to init_connect() instead.
|
||||
@ -7279,7 +7279,6 @@ void mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
and Query_log_event::print() would give ';;' output).
|
||||
This also helps display only the current query in SHOW
|
||||
PROCESSLIST.
|
||||
Note that we don't need LOCK_thread_count to modify query_length.
|
||||
*/
|
||||
if (found_semicolon && (ulong) (found_semicolon - thd->query()))
|
||||
thd->set_query_inner(thd->query(),
|
||||
|
@ -2181,9 +2181,7 @@ static int init_binlog_sender(binlog_send_info *info,
|
||||
linfo->pos= *pos;
|
||||
|
||||
// note: publish that we use file, before we open it
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->current_linfo= linfo;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
if (check_start_offset(info, linfo->log_file_name, *pos))
|
||||
return 1;
|
||||
@ -2922,9 +2920,7 @@ err:
|
||||
mysql_file_close(file, MYF(MY_WME));
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->current_linfo = 0;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd->reset_current_linfo();
|
||||
thd->variables.max_allowed_packet= old_max_allowed_packet;
|
||||
delete info->fdev;
|
||||
|
||||
@ -3379,10 +3375,8 @@ err:
|
||||
SYNOPSIS
|
||||
kill_zombie_dump_threads()
|
||||
slave_server_id the slave's server id
|
||||
|
||||
*/
|
||||
|
||||
|
||||
void kill_zombie_dump_threads(uint32 slave_server_id)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
@ -3946,9 +3940,7 @@ bool mysql_show_binlog_events(THD* thd)
|
||||
goto err;
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->current_linfo = &linfo;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd->current_linfo= &linfo;
|
||||
|
||||
if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0)
|
||||
goto err;
|
||||
@ -4080,9 +4072,7 @@ err:
|
||||
else
|
||||
my_eof(thd);
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->current_linfo = 0;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
thd->reset_current_linfo();
|
||||
thd->variables.max_allowed_packet= old_max_allowed_packet;
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
@ -16137,7 +16137,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
|
||||
{
|
||||
/* if we run out of slots or we are not using tempool */
|
||||
sprintf(path, "%s%lx_%lx_%x", tmp_file_prefix,current_pid,
|
||||
thd->thread_id, thd->tmp_table++);
|
||||
(ulong) thd->thread_id, thd->tmp_table++);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -88,7 +88,7 @@ static my_bool print_cached_tables_callback(TDC_element *element,
|
||||
THD *in_use= entry->in_use;
|
||||
printf("%-14.14s %-32s%6ld%8ld%6d %s\n",
|
||||
entry->s->db.str, entry->s->table_name.str, element->version,
|
||||
in_use ? in_use->thread_id : 0,
|
||||
in_use ? (long) in_use->thread_id : (long) 0,
|
||||
entry->db_stat ? 1 : 0,
|
||||
in_use ? lock_descriptions[(int)entry->reginfo.lock_type] :
|
||||
"Not in use");
|
||||
|
@ -38,10 +38,12 @@ extern int threadpool_add_connection(THD *thd);
|
||||
threadpool_unix.cc or threadpool_win.cc
|
||||
*/
|
||||
extern bool tp_init();
|
||||
extern void tp_add_connection(THD*);
|
||||
extern bool tp_init_new_connection_thread();
|
||||
extern void tp_add_connection(CONNECT *);
|
||||
extern void tp_wait_begin(THD *, int);
|
||||
extern void tp_wait_end(THD*);
|
||||
extern void tp_post_kill_notification(THD *thd);
|
||||
extern bool tp_end_thread(THD *thd, bool cache_thread);
|
||||
extern void tp_end(void);
|
||||
|
||||
/* Used in SHOW for threadpool_idle_thread_count */
|
||||
|
@ -221,7 +221,8 @@ int threadpool_process_request(THD *thd)
|
||||
|
||||
|
||||
/*
|
||||
In the loop below, the flow is essentially the copy of thead-per-connections
|
||||
In the loop below, the flow is essentially the copy of
|
||||
thead-per-connections
|
||||
logic, see do_handle_one_connection() in sql_connect.c
|
||||
|
||||
The goal is to execute a single query, thus the loop is normally executed
|
||||
@ -266,12 +267,12 @@ static scheduler_functions tp_scheduler_functions=
|
||||
NULL,
|
||||
NULL,
|
||||
tp_init, // init
|
||||
NULL, // init_new_connection_thread
|
||||
tp_init_new_connection_thread, // init_new_connection_thread
|
||||
tp_add_connection, // add_connection
|
||||
tp_wait_begin, // thd_wait_begin
|
||||
tp_wait_end, // thd_wait_end
|
||||
post_kill_notification, // post_kill_notification
|
||||
NULL, // end_thread
|
||||
tp_end_thread, // Dummy function
|
||||
tp_end // end
|
||||
};
|
||||
|
||||
|
@ -809,7 +809,7 @@ static int create_worker(thread_group_t *thread_group)
|
||||
if (!err)
|
||||
{
|
||||
thread_group->last_thread_creation_time=microsecond_interval_timer();
|
||||
thread_created++;
|
||||
statistic_increment(thread_created,&LOCK_status);
|
||||
add_thread_count(thread_group, 1);
|
||||
}
|
||||
else
|
||||
@ -1203,14 +1203,14 @@ void wait_end(thread_group_t *thread_group)
|
||||
Allocate/initialize a new connection structure.
|
||||
*/
|
||||
|
||||
connection_t *alloc_connection(THD *thd)
|
||||
connection_t *alloc_connection()
|
||||
{
|
||||
connection_t* connection;
|
||||
DBUG_ENTER("alloc_connection");
|
||||
DBUG_EXECUTE_IF("simulate_failed_connection_1", DBUG_RETURN(0); );
|
||||
|
||||
connection_t* connection = (connection_t *)my_malloc(sizeof(connection_t),0);
|
||||
if (connection)
|
||||
if ((connection = (connection_t *)my_malloc(sizeof(connection_t),0)))
|
||||
{
|
||||
connection->thd = thd;
|
||||
connection->waiting= false;
|
||||
connection->logged_in= false;
|
||||
connection->bound_to_poll_descriptor= false;
|
||||
@ -1225,38 +1225,40 @@ connection_t *alloc_connection(THD *thd)
|
||||
Add a new connection to thread pool..
|
||||
*/
|
||||
|
||||
void tp_add_connection(THD *thd)
|
||||
void tp_add_connection(CONNECT *connect)
|
||||
{
|
||||
connection_t *connection;
|
||||
THD *thd;
|
||||
DBUG_ENTER("tp_add_connection");
|
||||
|
||||
threads.append(thd);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
connection_t *connection= alloc_connection(thd);
|
||||
if (connection)
|
||||
|
||||
if (!(connection= alloc_connection()) || !(thd= connect->create_thd()))
|
||||
{
|
||||
thd->event_scheduler.data= connection;
|
||||
|
||||
/* Assign connection to a group. */
|
||||
thread_group_t *group=
|
||||
&all_groups[thd->thread_id%group_count];
|
||||
|
||||
connection->thread_group=group;
|
||||
|
||||
mysql_mutex_lock(&group->mutex);
|
||||
group->connection_count++;
|
||||
mysql_mutex_unlock(&group->mutex);
|
||||
|
||||
/*
|
||||
Add connection to the work queue.Actual logon
|
||||
will be done by a worker thread.
|
||||
*/
|
||||
queue_put(group, connection);
|
||||
my_free(connection);
|
||||
connect->close_and_delete();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocation failed */
|
||||
threadpool_cleanup_connection(thd);
|
||||
}
|
||||
connection->thd= thd;
|
||||
delete connect;
|
||||
|
||||
add_to_active_threads(thd);
|
||||
|
||||
thd->event_scheduler.data= connection;
|
||||
|
||||
/* Assign connection to a group. */
|
||||
thread_group_t *group=
|
||||
&all_groups[thd->thread_id%group_count];
|
||||
|
||||
connection->thread_group=group;
|
||||
|
||||
mysql_mutex_lock(&group->mutex);
|
||||
group->connection_count++;
|
||||
mysql_mutex_unlock(&group->mutex);
|
||||
|
||||
/*
|
||||
Add connection to the work queue.Actual logon
|
||||
will be done by a worker thread.
|
||||
*/
|
||||
queue_put(group, connection);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -1549,6 +1551,18 @@ bool tp_init()
|
||||
}
|
||||
|
||||
|
||||
/* Dummy functions, do nothing */
|
||||
|
||||
bool tp_init_new_connection_thread()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool tp_end_thread(THD *thd, bool cache_thread)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tp_end()
|
||||
{
|
||||
DBUG_ENTER("tp_end");
|
||||
|
@ -230,7 +230,7 @@ struct connection_t
|
||||
};
|
||||
|
||||
|
||||
void init_connection(connection_t *connection)
|
||||
void init_connection(connection_t *connection, THD *thd)
|
||||
{
|
||||
connection->logged_in = false;
|
||||
connection->handle= 0;
|
||||
@ -243,7 +243,8 @@ void init_connection(connection_t *connection)
|
||||
memset(&connection->overlapped, 0, sizeof(OVERLAPPED));
|
||||
InitializeThreadpoolEnvironment(&connection->callback_environ);
|
||||
SetThreadpoolCallbackPool(&connection->callback_environ, pool);
|
||||
connection->thd = 0;
|
||||
connection->thd = thd;
|
||||
thd->event_scheduler.data= connection;
|
||||
}
|
||||
|
||||
|
||||
@ -465,7 +466,7 @@ static void check_thread_init()
|
||||
if (FlsGetValue(fls) == NULL)
|
||||
{
|
||||
FlsSetValue(fls, (void *)1);
|
||||
thread_created++;
|
||||
statistic_increment(thread_created, &LOCK_status);
|
||||
InterlockedIncrement((volatile long *)&tp_stats.num_worker_threads);
|
||||
}
|
||||
}
|
||||
@ -532,6 +533,16 @@ bool tp_init(void)
|
||||
}
|
||||
|
||||
|
||||
/* Dummy functions, do nothing */
|
||||
|
||||
bool tp_init_new_connection_thread()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool tp_end_thread(THD *thd, bool cache_thread)
|
||||
{}
|
||||
|
||||
/**
|
||||
Scheduler callback : Destroy the scheduler.
|
||||
*/
|
||||
@ -544,7 +555,6 @@ void tp_end(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Handle read completion/notification.
|
||||
*/
|
||||
@ -656,24 +666,26 @@ static void CALLBACK shm_read_callback(PTP_CALLBACK_INSTANCE instance,
|
||||
|
||||
/*
|
||||
Notify the thread pool about a new connection.
|
||||
NOTE: LOCK_thread_count is locked on entry. This function must unlock it.
|
||||
*/
|
||||
void tp_add_connection(THD *thd)
|
||||
{
|
||||
threads.append(thd);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
connection_t *con = (connection_t *)malloc(sizeof(connection_t));
|
||||
if(!con)
|
||||
void tp_add_connection(CONNECT *connect)
|
||||
{
|
||||
THD *thd;
|
||||
connection_t *con;
|
||||
|
||||
if (!(con = (connection_t *) malloc(sizeof(connection_t))) ||
|
||||
!(thd= connect->create_thd()))
|
||||
{
|
||||
tp_log_warning("Allocation failed", "tp_add_connection");
|
||||
threadpool_cleanup_connection(thd);
|
||||
free(con)
|
||||
connect->close_and_delete();
|
||||
return;
|
||||
}
|
||||
delete connect;
|
||||
|
||||
init_connection(con);
|
||||
con->thd= thd;
|
||||
thd->event_scheduler.data= con;
|
||||
add_to_active_threads(thd);
|
||||
|
||||
init_connection(con, thd);
|
||||
|
||||
/* Try to login asynchronously, using threads in the pool */
|
||||
PTP_WORK wrk = CreateThreadpoolWork(login_callback,con, &con->callback_environ);
|
||||
|
@ -1744,8 +1744,9 @@ pthread_handler_t start_wsrep_THD(void *arg)
|
||||
goto error;
|
||||
}
|
||||
|
||||
thd->thread_id= next_thread_id();
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id=thread_id++;
|
||||
|
||||
if (wsrep_gtid_mode)
|
||||
{
|
||||
|
@ -1077,7 +1077,7 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache)
|
||||
{
|
||||
DBUG_PRINT("signal",
|
||||
("thread %s %ld", last_thread->next->name,
|
||||
last_thread->next->id));
|
||||
(ulong) last_thread->next->id));
|
||||
pagecache_pthread_cond_signal(&last_thread->next->suspend);
|
||||
}
|
||||
}
|
||||
@ -1341,7 +1341,8 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
|
||||
*/
|
||||
if ((PAGECACHE_HASH_LINK *) thread->keycache_link == hash_link)
|
||||
{
|
||||
DBUG_PRINT("signal", ("thread: %s %ld", thread->name, thread->id));
|
||||
DBUG_PRINT("signal", ("thread: %s %ld", thread->name,
|
||||
(ulong) thread->id));
|
||||
pagecache_pthread_cond_signal(&thread->suspend);
|
||||
wqueue_unlink_from_queue(&pagecache->waiting_for_block, thread);
|
||||
block->requests++;
|
||||
@ -1579,7 +1580,7 @@ static inline void wait_for_readers(PAGECACHE *pagecache
|
||||
DBUG_ENTER("wait_for_readers");
|
||||
DBUG_PRINT("wait",
|
||||
("suspend thread: %s %ld block: %u",
|
||||
thread->name, thread->id,
|
||||
thread->name, (ulong) thread->id,
|
||||
PCBLOCK_NUMBER(pagecache, block)));
|
||||
block->condvar= &thread->suspend;
|
||||
pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock);
|
||||
@ -1604,7 +1605,7 @@ static void wait_for_flush(PAGECACHE *pagecache
|
||||
do
|
||||
{
|
||||
DBUG_PRINT("wait",
|
||||
("suspend thread %s %ld", thread->name, thread->id));
|
||||
("suspend thread %s %ld", thread->name, (ulong) thread->id));
|
||||
pagecache_pthread_cond_wait(&thread->suspend,
|
||||
&pagecache->cache_lock);
|
||||
}
|
||||
@ -1671,7 +1672,8 @@ static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link)
|
||||
if (page->file.file == hash_link->file.file &&
|
||||
page->pageno == hash_link->pageno)
|
||||
{
|
||||
DBUG_PRINT("signal", ("thread %s %ld", thread->name, thread->id));
|
||||
DBUG_PRINT("signal", ("thread %s %ld", thread->name,
|
||||
(ulong) thread->id));
|
||||
pagecache_pthread_cond_signal(&thread->suspend);
|
||||
wqueue_unlink_from_queue(&pagecache->waiting_for_hash_link, thread);
|
||||
}
|
||||
@ -1811,7 +1813,7 @@ restart:
|
||||
thread->keycache_link= (void *) &page;
|
||||
wqueue_link_into_queue(&pagecache->waiting_for_hash_link, thread);
|
||||
DBUG_PRINT("wait",
|
||||
("suspend thread %s %ld", thread->name, thread->id));
|
||||
("suspend thread %s %ld", thread->name, (ulong) thread->id));
|
||||
pagecache_pthread_cond_wait(&thread->suspend,
|
||||
&pagecache->cache_lock);
|
||||
thread->keycache_link= NULL;
|
||||
@ -1991,7 +1993,8 @@ restart:
|
||||
do
|
||||
{
|
||||
DBUG_PRINT("wait",
|
||||
("suspend thread %s %ld", thread->name, thread->id));
|
||||
("suspend thread %s %ld", thread->name,
|
||||
(ulong) thread->id));
|
||||
pagecache_pthread_cond_wait(&thread->suspend,
|
||||
&pagecache->cache_lock);
|
||||
}
|
||||
@ -2082,7 +2085,8 @@ restart:
|
||||
do
|
||||
{
|
||||
DBUG_PRINT("wait",
|
||||
("suspend thread %s %ld", thread->name, thread->id));
|
||||
("suspend thread %s %ld", thread->name,
|
||||
(ulong) thread->id));
|
||||
pagecache_pthread_cond_wait(&thread->suspend,
|
||||
&pagecache->cache_lock);
|
||||
}
|
||||
@ -2355,7 +2359,7 @@ static my_bool pagecache_wait_lock(PAGECACHE *pagecache,
|
||||
do
|
||||
{
|
||||
DBUG_PRINT("wait",
|
||||
("suspend thread %s %ld", thread->name, thread->id));
|
||||
("suspend thread %s %ld", thread->name, (ulong) thread->id));
|
||||
pagecache_pthread_cond_wait(&thread->suspend,
|
||||
&pagecache->cache_lock);
|
||||
}
|
||||
@ -2755,7 +2759,8 @@ static void read_block(PAGECACHE *pagecache,
|
||||
do
|
||||
{
|
||||
DBUG_PRINT("wait",
|
||||
("suspend thread %s %ld", thread->name, thread->id));
|
||||
("suspend thread %s %ld", thread->name,
|
||||
(ulong) thread->id));
|
||||
pagecache_pthread_cond_wait(&thread->suspend,
|
||||
&pagecache->cache_lock);
|
||||
}
|
||||
@ -4549,7 +4554,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
|
||||
{
|
||||
DBUG_PRINT("wait",
|
||||
("(1) suspend thread %s %ld",
|
||||
thread->name, thread->id));
|
||||
thread->name, (ulong) thread->id));
|
||||
pagecache_pthread_cond_wait(&thread->suspend,
|
||||
&pagecache->cache_lock);
|
||||
}
|
||||
@ -4710,7 +4715,7 @@ restart:
|
||||
{
|
||||
DBUG_PRINT("wait",
|
||||
("(2) suspend thread %s %ld",
|
||||
thread->name, thread->id));
|
||||
thread->name, (ulong) thread->id));
|
||||
pagecache_pthread_cond_wait(&thread->suspend,
|
||||
&pagecache->cache_lock);
|
||||
}
|
||||
@ -4914,7 +4919,8 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
|
||||
do
|
||||
{
|
||||
DBUG_PRINT("wait",
|
||||
("suspend thread %s %ld", thread->name, thread->id));
|
||||
("suspend thread %s %ld", thread->name,
|
||||
(ulong) thread->id));
|
||||
pagecache_pthread_cond_wait(&thread->suspend,
|
||||
&pagecache->cache_lock);
|
||||
}
|
||||
@ -5057,7 +5063,8 @@ static void pagecache_dump(PAGECACHE *pagecache)
|
||||
PAGECACHE_PAGE *page;
|
||||
uint i;
|
||||
|
||||
fprintf(pagecache_dump_file, "thread: %s %ld\n", thread->name, thread->id);
|
||||
fprintf(pagecache_dump_file, "thread: %s %ld\n", thread->name,
|
||||
(ulong) thread->id);
|
||||
|
||||
i=0;
|
||||
thread=last=waiting_for_hash_link.last_thread;
|
||||
@ -5069,7 +5076,7 @@ static void pagecache_dump(PAGECACHE *pagecache)
|
||||
page= (PAGECACHE_PAGE *) thread->keycache_link;
|
||||
fprintf(pagecache_dump_file,
|
||||
"thread: %s %ld, (file,pageno)=(%u,%lu)\n",
|
||||
thread->name, thread->id,
|
||||
thread->name, (ulong) thread->id,
|
||||
(uint) page->file.file,(ulong) page->pageno);
|
||||
if (++i == MAX_QUEUE_LEN)
|
||||
break;
|
||||
@ -5086,7 +5093,7 @@ static void pagecache_dump(PAGECACHE *pagecache)
|
||||
hash_link= (PAGECACHE_HASH_LINK *) thread->keycache_link;
|
||||
fprintf(pagecache_dump_file,
|
||||
"thread: %s %u hash_link:%u (file,pageno)=(%u,%lu)\n",
|
||||
thread->name, thread->id,
|
||||
thread->name, (ulong) thread->id,
|
||||
(uint) PAGECACHE_HASH_LINK_NUMBER(pagecache, hash_link),
|
||||
(uint) hash_link->file.file,(ulong) hash_link->pageno);
|
||||
if (++i == MAX_QUEUE_LEN)
|
||||
@ -5116,7 +5123,7 @@ static void pagecache_dump(PAGECACHE *pagecache)
|
||||
{
|
||||
thread=thread->next;
|
||||
fprintf(pagecache_dump_file,
|
||||
"thread: %s %ld\n", thread->name, thread->id);
|
||||
"thread: %s %ld\n", thread->name, (ulong) thread->id);
|
||||
if (++i == MAX_QUEUE_LEN)
|
||||
break;
|
||||
}
|
||||
|
@ -37,8 +37,6 @@
|
||||
#include "spd_ping_table.h"
|
||||
#include "spd_malloc.h"
|
||||
|
||||
extern ulong *spd_db_att_thread_id;
|
||||
|
||||
extern handlerton *spider_hton_ptr;
|
||||
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
|
||||
pthread_mutex_t spider_conn_id_mutex;
|
||||
@ -2269,9 +2267,7 @@ void *spider_bg_conn_action(
|
||||
my_thread_end();
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id = (*spd_db_att_thread_id)++;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->thread_id = next_thread_id();
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
mysql_thread_set_psi_id(thd->thread_id);
|
||||
#endif
|
||||
@ -2782,9 +2778,7 @@ void *spider_bg_sts_action(
|
||||
#endif
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id = (*spd_db_att_thread_id)++;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->thread_id = next_thread_id();
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
mysql_thread_set_psi_id(thd->thread_id);
|
||||
#endif
|
||||
@ -3164,9 +3158,7 @@ void *spider_bg_crd_action(
|
||||
#endif
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id = (*spd_db_att_thread_id)++;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->thread_id = next_thread_id();
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
mysql_thread_set_psi_id(thd->thread_id);
|
||||
#endif
|
||||
@ -3653,9 +3645,7 @@ void *spider_bg_mon_action(
|
||||
my_thread_end();
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id = (*spd_db_att_thread_id)++;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->thread_id = next_thread_id();
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
mysql_thread_set_psi_id(thd->thread_id);
|
||||
#endif
|
||||
|
@ -737,7 +737,8 @@ int spider_db_errorno(
|
||||
"to %ld: %d %s\n",
|
||||
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
|
||||
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
|
||||
current_thd->thread_id, error_num, conn->db_conn->get_error());
|
||||
(ulong) current_thd->thread_id, error_num,
|
||||
conn->db_conn->get_error());
|
||||
}
|
||||
if (!conn->mta_conn_mutex_unlock_later)
|
||||
{
|
||||
@ -757,7 +758,8 @@ int spider_db_errorno(
|
||||
"to %ld: %d %s\n",
|
||||
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
|
||||
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
|
||||
current_thd->thread_id, error_num, conn->db_conn->get_error());
|
||||
(ulong) current_thd->thread_id, error_num,
|
||||
conn->db_conn->get_error());
|
||||
}
|
||||
if (!conn->mta_conn_mutex_unlock_later)
|
||||
{
|
||||
|
@ -1717,7 +1717,7 @@ int spider_db_mysql::exec_query(
|
||||
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
|
||||
security_ctx->user ? security_ctx->user : "system user",
|
||||
security_ctx->host_or_ip,
|
||||
thd->thread_id,
|
||||
(ulong) thd->thread_id,
|
||||
tmp_query_str.c_ptr_safe());
|
||||
}
|
||||
if (log_result_error_with_sql & 1)
|
||||
@ -1731,7 +1731,7 @@ int spider_db_mysql::exec_query(
|
||||
"sql: %s\n",
|
||||
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
|
||||
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
|
||||
thd->thread_id, conn->tgt_host, db_conn->thread_id,
|
||||
(ulong) thd->thread_id, conn->tgt_host, (ulong) db_conn->thread_id,
|
||||
tmp_query_str.c_ptr_safe());
|
||||
}
|
||||
}
|
||||
@ -1745,7 +1745,7 @@ int spider_db_mysql::exec_query(
|
||||
"affected_rows: %llu id: %llu status: %u warning_count: %u\n",
|
||||
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
|
||||
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
|
||||
conn->tgt_host, db_conn->thread_id, thd->thread_id,
|
||||
conn->tgt_host, (ulong) db_conn->thread_id, (ulong) thd->thread_id,
|
||||
db_conn->affected_rows, db_conn->insert_id,
|
||||
db_conn->server_status, db_conn->warning_count);
|
||||
if (spider_param_log_result_errors() >= 3)
|
||||
@ -1760,7 +1760,7 @@ int spider_db_mysql::exec_query(
|
||||
"affected_rows: %llu id: %llu status: %u warning_count: %u\n",
|
||||
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
|
||||
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
|
||||
conn->tgt_host, db_conn->thread_id, thd->thread_id,
|
||||
conn->tgt_host, (ulong) db_conn->thread_id, (ulong) thd->thread_id,
|
||||
db_conn->affected_rows, db_conn->insert_id,
|
||||
db_conn->server_status, db_conn->warning_count);
|
||||
}
|
||||
@ -1889,8 +1889,8 @@ void spider_db_mysql::print_warnings(
|
||||
"from [%s] %ld to %ld: %s %s %s\n",
|
||||
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
|
||||
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
|
||||
conn->tgt_host, db_conn->thread_id,
|
||||
current_thd->thread_id, row[0], row[1], row[2]);
|
||||
conn->tgt_host, (ulong) db_conn->thread_id,
|
||||
(ulong) current_thd->thread_id, row[0], row[1], row[2]);
|
||||
row = mysql_fetch_row(res);
|
||||
}
|
||||
if (res)
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include "spd_direct_sql.h"
|
||||
#include "spd_malloc.h"
|
||||
|
||||
ulong *spd_db_att_thread_id;
|
||||
#ifdef SPIDER_XID_USES_xid_cache_iterate
|
||||
#else
|
||||
#ifdef XID_CACHE_IS_SPLITTED
|
||||
@ -6327,8 +6326,6 @@ int spider_db_init(
|
||||
|
||||
#ifdef _WIN32
|
||||
HMODULE current_module = GetModuleHandle(NULL);
|
||||
spd_db_att_thread_id = (ulong *)
|
||||
GetProcAddress(current_module, "?thread_id@@3KA");
|
||||
#ifdef SPIDER_XID_USES_xid_cache_iterate
|
||||
#else
|
||||
#ifdef XID_CACHE_IS_SPLITTED
|
||||
@ -6362,7 +6359,6 @@ int spider_db_init(
|
||||
spd_abort_loop = (bool volatile *)
|
||||
GetProcAddress(current_module, "?abort_loop@@3_NC");
|
||||
#else
|
||||
spd_db_att_thread_id = &thread_id;
|
||||
#ifdef SPIDER_XID_USES_xid_cache_iterate
|
||||
#else
|
||||
#ifdef XID_CACHE_IS_SPLITTED
|
||||
|
Loading…
x
Reference in New Issue
Block a user