db mysql / mysql cluster 5.7.19 / my.cnf / thread_pool_stall_limit
s
MYSQL Thread Pool简介
在MySQL5.5中,MySQL为每一个数据库连接创建一个线程,并分配其所需要的所有内存,当数据库连接数较大,或者有多个并发同时请求数据库连接时,服务器需要消耗大量的资源用于线程的创建与销毁,这将直接影响数据库的整体性能。为了解决此问题,MySQL5.6后的版本引入了Thread Pool,为数据库创建一定数量的thread分组(thread_pool_size),数据库中的连接根据id与thread分组数量取模的结果分配到对应的thread分组中依次执行,这样MySQL只需要按照thread分组数量创建相应的线程数即可,避免了为每一个连接创建线程而导致的资源消耗。
根据MySQL Thread Pool的工作原理,优化建议如下:
优化执行时间较长的SQL语句,避免堵塞同一个thread分组中其它连接的SQL
结合业务压测,调整参数thread_pool_stall_limit定义的新建worker的时间阀值,当分组中worker处于忙碌状态时,能够更快的为其它连接创建新的worker,同时调整每一个分组中可创建的worker数量(由参数thread_pool_oversubscribe控制)
适当调整参数thread_pool_size的值,降低多个连接分配到同一个thread分组的概率。
案例一
SQL执行响应时间随机性超长问题
http://wiki.cns*****.com/pages/viewpage.action?pageId=31938322
http://wiki.cns*****.com/download/attachments/31938322/%E9%87%91%E8%9E%8DSQL%E5%93%8D%E5%BA%94%E6%97%B6%E9%97%B4%E9%9A%8F%E6%9C%BA%E6%80%A7%E8%B6%85%E9%95%BF%E5%8E%9F%E7%90%86%E8%AF%B4%E6%98%8E.pptx?version=1&modificationDate=1534215914000&api=v2
http://wiki.cns*****.com/download/attachments/31938322/mysql%E5%BB%B6%E8%BF%9F%E6%8A%93%E5%8C%85%E5%88%86%E6%9E%90.docx?version=1&modificationDate=1534215914000&api=v2
现象
1)耗时峰值较为频繁出现,且无明显规律
2)因较多系统使用mycat访问MySQL,难以评估为mycat耗时,MySQL耗时,或网络耗时
分析
1)应用系统接入mycat耗时分析,排查mycat耗时,和db耗时
2)网络分析mycat与db间网络耗时
3)金融mysql集群抓包分析,发现延迟出现在mysql虚拟机内部
解决方法
调整MySQL参数
thread_pool_oversubscribe 由3 调整为10 (标准配置值)
thread_pool_stall_limit 由500(标准值)调整为了 100
对正在ACTIVE或WAITING状态的线程启用一个计数器,超过计数器后将该thread标记为stalled,然后thread group创建新的thread或唤醒sleep的thread处理新的sokcet,这样将是一个很好的权衡。超时时间该参数thread_pool_stall_limit来决定,默认是500ms。
验证效果
1)会员资金渠道,账户通等MySQL5.7系统调整参数后,发现耗时毛刺明显减少
缩短thread_pool_stall_limit 的潜在影响
1)缩短thread_pool_stall_limit ,会增加MySQL创建新的线程的频率,对CPU有一定影响
2)可能会增加数据库的内部资源争抢(例如锁)
3)需要有多个需要同时执行的连接分配到同一个线程组中才会发生
4)建议有同样问题的系统先优化调整SQL,如果问题得不到解决,再考虑调整数据库参数
(mysql5.5版本使用的是每次链接创建一个线程,5.7里面使用了thread pool,减少线程的等待时间,高并发,连接数增加情况下性能减低会好于5.5)
案例二
https://blog.csdn.net/z69183787/article/details/53389909
问题分析:
基本原理:
没有引入thread pool前,MySQL使用的是one thread per connection,一旦connection增加到一定程度,MySQL的性能将急剧下降甚至被压跨。引入thread pool后将会解决上述问题,同时会减少MySQL内部的线程数(节省内存)及频繁创建线程的开销(节省cpu)。
thread pool是如何工作的呢?
在MySQL内部有一个专用的thread用来监听数据库连接请求,当一个新的请求过来,如果采用以前的模型(one-thread-per-connection),main listener(这是主线程中的listener,为了避免与thread group 中的listener混淆,我们称之为“Main listener”)将从thread cache中取出1个thread或创建1个新的thead立即处理该连接请求,由该thread完成该连接的整个生命周期;而如果采用thread pool模型,这个连接请求将会被随机放到一个thread group(thread pool由多个thread group 组成)的队列中,之后该thread group中worker thread从队列中取出并建立连接,一旦连接建立,该连接对应的socket句柄将与该thread group中的listener关联起来,之后该连接将在该thread group中完成它的生命周期。
接下来我们来说一下thread group 。thread group是thread pool的核心组件,所有的操作都是发生在thread group。thread pool由多个(数量由参数thread_pool_size来决定,默认等于cpu个数)thrad group组成。一个连接请求被随机地绑定到一个thread group,每个thread group独立工作,并且占用一个核的cpu,所以thread group都会最大限度地保持一个thread处于ACTIVE状态,并且最好只有一个。
thread group中的thread一般有4个状态:
TP_STATE_LISTENER
TP_STATE_IDLE
TP_STATE_ACTIVE
TP_STATE_WAITING
当一个线程作为listener运行时就处于“TP_STATE_LISTENER”,它通过epoll的方式监听联接到该thread group的所有连接,当一个socket就绪后,listener将决定是否唤醒一个thread或自己处理该socket。此时如果thread group的队列为空,它将自己处理该socket并将状态更改为“ACTIVE”,之后该thread 在MySQL Server内部处理“工作”,当该线程遇到锁或异步IO(比如将数据页读入到buffer pool)这些wait时,该thread将通过回调函数的方式告诉thread pool,让其把自己标记为“WAITING”状态。
此时,假设队列中有了新的socket准备就绪,是立即创建新的线程还是等待刚才的线程执行结束呢?
由于thread pool最初设计的目标是保持一定数量的线程处于“ACTIVE”状态,具体的实现方式就是控制thread group的数量和thread group内部处于"ACTIVE"状态的thread的数量。控制thread group内部的ACTIVE状态的数量,方法就是最大限度地保证处于ACTIVE状态的线程个数是1。很显然当前thread group中有一个处于WAITING状态的thread了,如果再启用一个新的线程并且处于ACTIVE状态,刚才的线程由WAITING变为ACTIVE状态时,此时将会有2个“ACTIVE”状态的线程,和最初的目标似乎相背,但显然也不能让后续就绪的socket一直等待下去,那应该怎么处理?
那么此时需要一个权衡了,提供了这样的一个方法:对正在ACTIVE或WAITING状态的线程启用一个计数器,超过计数器后将该thread标记为stalled,然后thread group创建新的thread或唤醒sleep的thread处理新的sokcet,这样将是一个很好的权衡。超时时间该参数thread_pool_stall_limit来决定,默认是500ms。
如果一个线程无事可做,它将保持空闲状态(TP_STATE_WAITING)一定时间(thread_pool_idle_timeout参数决定,默认是60秒)后“自杀”。
和我们遇到的具体问题相关的点:
假设上文提到的由“ACTIVE”转化为“WAITING”状态的线程(标记为“线程A”)所执行的“SQL"是可能是一个标准的慢sql(命名为SQLA,需要锁等待或从IO读数据),那么后续需要执行的SQL(命名SQLB)要么等待线程A结束(有可能没有超过500ms,该查询就结束了),要么需要创建新的线程(超过500ms),不管哪种情况,SQLB都会在线程等待上花费很多时间,此时SQLB就是我cat监控系统上看到的慢SQL。又因为SQLA不一定都是慢SQL,所以SQLB也不是每次在线程等待上花费较多的时间,这就吻合我们看到的现象“一定比例的慢SQL”。
解决方法:
调整thread_pool_stall_limit=10,这样就强迫被SQLA更快被标记为stalled,然后创建新的线程来处理SQLB。
理论上讲:
1.绝大部分oltp的应用,10ms内是能够查出数据的,所以这类sql不会导致work thread(thread running)数增加。
2.对于一部分超过10ms的sql,会导致work thread增加,但不会超过 thread_pool_oversubscribe这个参数值,所以总体work thread线程仍然可控
3.该参数已经在线上所有服务器运行2月多,目前没有发现与其相关的问题,在一定程度上说明该参数值是安全的。
4.据称阿里的数据库的thread_pool_stall_limit参数值也10ms,另外MySQL5.7 默认值是6ms,比10ms更激进,但可能还会基于其它优化配合才需要调整到6ms(此2因素可忽略,仅作参考)。
end
db mysql / mysql cluster 5.7.19 / my.cnf / thread_pool_stall_limit的更多相关文章
- db mysql / mysql cluster 5.7.19 / my.cnf / max_binlog_cache_size / binlog
s mysql修改binlog保存的天数 https://blog.csdn.net/Hu_wen/article/details/80582013 查看binlog过期时间,设置的时间为90天,这个 ...
- Online Schema Upgrade in MySQL Galera Cluster using TOI Method
http://severalnines.com/blog/online-schema-upgrade-mysql-galera-cluster-using-toi-method As a fo ...
- MySQL高可用方案-MySQL InnoDB Cluster
MySQL InnoDB Cluster简介 MySQL InnoDB Cluster 是最新GA的MySQL高可用方案,利用MySQL Group Replication和MySQL Shell.M ...
- 关于Oracle的rac集群和mysql Galera Cluster的想法
到了新公司,公司用的是rac,我比较熟悉mysql第三方的集群方案Galera Cluster这类多主集群, 下面是我参考了他人对rac的介绍,然后和mysql方案进行的臆测级别的分析对比. rac和 ...
- Ubuntu16.04环境下搭建基于三台主机的mysql galera cluster集群(实测有效)
(注意: (1)文中红色字体部分不一定需要操作 (2)由于word文档编辑的原因,实际操作时部分命令需要手动输入!!直接复制粘贴会提示错误!! ) 一 搭建环境: 1 Ubuntu16.04版本(系 ...
- MYSQL InnoDB Cluster
https://dev.mysql.com/doc/refman/5.7/en/group-replication.html GroupReplication的原理 https://dev.mysql ...
- laravel DB 执行 mysql函数或者字段
使用laravel框架中的DB查询mysql数据库的时候,综合遇到执行mysql函数或者,自定义字段,一般情况下DB会把传入的函数当做字段处理 方法如下: DB:raw('函数或者字段'); DB:w ...
- debian 8 解压安装mysql(版本5.7.19)
debian 8 解压安装mysql(版本5.7.19)一.下载 根据目标主机的型号官网下载mysql安装包如: mysql-server_5.7.19-1debian8_amd64.deb-bund ...
- CentOS7系统安装 Maria Db(MYSQL)教程
一.背景Maria Db是流行的跨平台MySQL数据库管理系统的分支,被认为是MySQL 的完全替代品.Maria Db是由Sun在Sun Micro systems合并期间被Oracle收购后,于2 ...
随机推荐
- webpack 打包编译-webkit-box-orient: vertical 后消失
/* autoprefixer: off */ -webkit-box-orient: vertical; // 参考 https://github.com/postcss/autoprefixer/ ...
- Codeforces Round #542 Div. 1
A:显然对于起点相同的糖果,应该按终点距离从大到小运.排个序对每个起点取max即可.读题花了一年还wa一发,自闭了. #include<iostream> #include<cstd ...
- Windows服务一直“正在启动”怎么杀
转载:https://blog.csdn.net/huanglong8/article/details/71156848 PS:cmd 记得使用 管理员身份运行 这里需要通过控制台 命令行来查询PID ...
- robotframework基本语法一
*** Settings *** Library OperatingSystem #Settings:导入测试库,资源文件,变量文件,为创建测试套件和test cases定义元数据 *** Varia ...
- ConnectionAbortedError: [WinError 10053] 您的主机中的软件中止了一个已建立的连接
socket服务端在接收socket客户端时抛出异常 ConnectionAbortedError: [WinError 10053] 您的主机中的软件中止了一个已建立的连接. socket服务端代码 ...
- CodeForces 97 E. Leaders(点双连通分量 + 倍增)
题意 给你一个有 \(n\) 个点 \(m\) 条边的无向图,有 \(q\) 次询问,每次询问两个点 \(u, v\) 之间是否存在长度为奇数的简单路径. \(1 \le n, m, q \le 10 ...
- 【UOJ#311】【UNR #2】积劳成疾(动态规划)
[UOJ#311][UNR #2]积劳成疾(动态规划) UOJ Solution 考虑最大值分治解决问题.每次枚举最大值所在的位置,强制不能跨过最大值,左右此时不会影响,可以分开考虑. 那么设\(f[ ...
- bzoj3514(LCT+主席树)
题目描述 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解 对于一个截止时间来说,越晚的变越好. 所以我们可以维护一颗以边的序号为关键字的最大生成树,然后用主席树维 ...
- Mybatis 缓存失效的几种情况
1 不在同一个sqlSession对象中 下面比较下载同一个sqlSession和不在同一sqlSession下面的两种情况: 同一sqlSession: @Test public final voi ...
- js jquery数组去重
数组去重建议直接使用jquery的 $.unique(arr);方法,此外比较好的方法是本文中的unique3方法比较快用了一个hash表,就是所谓的空间换时间.本文还提供了很多其他写法,都是大同小异 ...