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:
Monty 2016-02-01 12:45:39 +02:00
parent 076aa182c2
commit 3d4a7390c1
50 changed files with 878 additions and 551 deletions

View File

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

View File

@ -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 */

View File

@ -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 */

View File

@ -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())

View 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;

View File

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

View File

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

View File

@ -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
/*!*/;

View File

@ -1 +0,0 @@
RESET MASTER;

View File

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

View 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

View 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;

View File

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

View File

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

View File

@ -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");

View File

@ -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();

View File

@ -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))
{

View File

@ -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"));

View File

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

View File

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

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

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

View File

@ -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);

View File

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

View File

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

View File

@ -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);

View File

@ -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();

View File

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

View File

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

View File

@ -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(). */

View File

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

View File

@ -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);

View File

@ -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);

View File

@ -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 */
};

View File

@ -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(),

View File

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

View File

@ -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++);
}
/*

View File

@ -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");

View File

@ -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 */

View File

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

View File

@ -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");

View File

@ -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);

View File

@ -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)
{

View File

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

View File

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

View File

@ -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)
{

View File

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

View File

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