MySQL thread_stack连接线程的优化
MySQL连接不仅能通过网络方式,还可以通过命名管道的方式,不论是哪种方式连接MySQL,在MySQL中都是通过线程的方式管理所有客户端请求的。每一个客户端连接都会有一个与之对应的连接线程。在MySQL中实现了一个ThreadCache池,将空闲的连接线程存放其中,而不是完成请求后就销毁。这样,当有新的连接请求时,MySQL首先会检查ThreadCache中是否存在空闲连接线程,如果存在则取出来直接使用,如果没有空闲连接线程,才创建新的连接线程。具体参数:
Thread_cache_size:ThreadCache池中应该存放的连接线程数。
Thread_stack:每个连接线程被创建时,MySQL给它分配的内存大小。当MySQL创建一个新的连接线程时,需要给它分配一定大小的内存堆栈空间,以便存放客户端的请求的Query及自身的各种状态和处理信息。
查看连接线程相关的系统变量的设置值:showvariableslike'thread%';
mysql>showvariableslike'thread%';
+-------------------+--------+
|Variable_name|Value|
+-------------------+--------+
|thread_cache_size|32|
|thread_stack|196608|
+-------------------+--------+
2rowsinset(0.00sec)
如图,系统设置了ThreadCache池最多将缓存25个连接线程,每个连接线程创建之初,系统分配192KB的内存堆栈给它。
查看系统被连接的次数及当前系统中连接线程的状态值
mysql>showstatuslike'connections';
+---------------+-------+
|Variable_name|Value|
+---------------+-------+
|Connections|620|
+---------------+-------+
1rowinset(0.00sec)
mysql>showstatuslike'%thread%';
+------------------------+-------+
|Variable_name|Value|
+------------------------+-------+
|Delayed_insert_threads|0|
|Slow_launch_threads|0|
|Threads_cached|3|
|Threads_connected|4|
|Threads_created|7|
|Threads_running|1|
+------------------------+-------+
6rowsinset(0.00sec)
系统启动到现在共接受到客户端的连接620次,共创建了7个连接线程,当前有1个连接线程处于和客户端连接的状态,而3个连接状态的线程中只有一个处于active状态,即只有一个正在处理客户端提交的请求,。而在ThreadCache池中共缓存了3个连接线程。
ThreadCache命中率:
Thread_Cache_Hit=(Connections-Threads_created)/Connections*100%;
一般在系统稳定运行一段时间后,ThreadCache命中率应该保持在90%左右才算正常。
实际应用:
针对16G/32G的机器,一般设置512K
当然如果遇到下面的错误提示就应该考虑增加这个值了。
mysql-debug:Threadstackoverrun
buginfo
报错信息:
java.sql.SQLException:Threadstackoverrun:5456bytesusedofa131072bytestack,and128000bytesneeded.Use'mysqld--thread_stack=#'tospecifyabiggerstack.
官方相应信息:
Thedefault(192KB)islargeenoughfornormaloperation.Ifthethreadstacksizeistoosmall,itlimitsthecomplexityoftheSQLstatementsthattheservercanhandle,therecursiondepthofstoredprocedures,andothermemory-consumingactions
可以使用
showvariableswhere`variable_name`='thread_stack';
查询当前数据库的默认线程栈的大小,一般情况下都能正常使用,但是当查询语句或者存储过程复杂时会报Threadstackoverrun错误,此时只要修改默认配置就可以。
解决
windows:修改mysql安装目录下的my-small.ini或者my.ini设置为256k,或者更大,然后重启服务
[mysqld]
thread_stack=256k
linux:同样要修改配置文件,但是!!!,不是安装目录下的配置文件,是/etc/my.cnf,只有这个文件才能生效,然后重启服务servicemysqlrestart
[mysqld]
thread_stack=256k