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的更多相关文章

  1. 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天,这个 ...

  2. 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 ...

  3. MySQL高可用方案-MySQL InnoDB Cluster

    MySQL InnoDB Cluster简介 MySQL InnoDB Cluster 是最新GA的MySQL高可用方案,利用MySQL Group Replication和MySQL Shell.M ...

  4. 关于Oracle的rac集群和mysql Galera Cluster的想法

    到了新公司,公司用的是rac,我比较熟悉mysql第三方的集群方案Galera Cluster这类多主集群, 下面是我参考了他人对rac的介绍,然后和mysql方案进行的臆测级别的分析对比. rac和 ...

  5. Ubuntu16.04环境下搭建基于三台主机的mysql galera cluster集群(实测有效)

    (注意: (1)文中红色字体部分不一定需要操作 (2)由于word文档编辑的原因,实际操作时部分命令需要手动输入!!直接复制粘贴会提示错误!! ) 一  搭建环境: 1 Ubuntu16.04版本(系 ...

  6. MYSQL InnoDB Cluster

    https://dev.mysql.com/doc/refman/5.7/en/group-replication.html GroupReplication的原理 https://dev.mysql ...

  7. laravel DB 执行 mysql函数或者字段

    使用laravel框架中的DB查询mysql数据库的时候,综合遇到执行mysql函数或者,自定义字段,一般情况下DB会把传入的函数当做字段处理 方法如下: DB:raw('函数或者字段'); DB:w ...

  8. debian 8 解压安装mysql(版本5.7.19)

    debian 8 解压安装mysql(版本5.7.19)一.下载 根据目标主机的型号官网下载mysql安装包如: mysql-server_5.7.19-1debian8_amd64.deb-bund ...

  9. CentOS7系统安装 Maria Db(MYSQL)教程

    一.背景Maria Db是流行的跨平台MySQL数据库管理系统的分支,被认为是MySQL 的完全替代品.Maria Db是由Sun在Sun Micro systems合并期间被Oracle收购后,于2 ...

随机推荐

  1. Xml文件汉化后改变代码页

    源Xml文件代码页为ansi,汉化后要转换为UTF-8,在网上搜素了以下结果,但解释的不都清楚,我找了好一阵才找到相应的操作.   为防止自己以后忘了,补充如下: 经过这样的设置,生成的汉化xml文件 ...

  2. 下载模板、Excel导入、导出

    下载模板 /// <summary> /// 下载模板 /// </summary> /// <returns></returns> public Ac ...

  3. 初步了解HTML

    超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言. 您可以使用 HTML 来建立自己的 WEB 站点,HTML 运行在浏览器上 ...

  4. Iroha and a Grid AtCoder - 1974(思维水题)

    就是一个组合数水题 偷个图 去掉阴影部分  把整个图看成上下两个矩形 对于上面的矩形求出起点到每个绿点的方案 对于下面的矩形 求出每个绿点到终点的方案 上下两个绿点的方案相乘后相加 就是了 想想为什么 ...

  5. Codeforces Round #541 (Div. 2) D(并查集+拓扑排序) F (并查集)

    D. Gourmet choice 链接:http://codeforces.com/contest/1131/problem/D 思路: =  的情况我们用并查集把他们扔到一个集合,然后根据 > ...

  6. jwt实现

    <?phpnamespace app\admin\controller;use think\Config;use think\Controller;use think\Request;use t ...

  7. ecplise properties文件 中文转码

    1.安装插件 2.重开ecplise 3.在项目的乱码文件如jeesite.properties右键 openwith propertiesEditor 就可以看到中文了 输入 proedit 安装完 ...

  8. 使用 Zabbix 监控 Jenkins

    笔者最近的工作涉及到使用 Zabbix 监控 Jenkins.在谷歌上搜索到的文章非常少,能操作的就更少了.所以决定写一篇文章介绍如何使用 Zabbix 监控 Jenkins. 下图为整体架构图: 整 ...

  9. [HNOI2015]落忆枫音 解题报告

    [HNOI2015]落忆枫音 设每个点入度是\(d_i\),如果不加边,答案是 \[ \prod_{i=2}^nd_i \] 意思是我们给每个点选一个父亲 然后我们加了一条边,最后如果还这么统计,那么 ...

  10. CANOE入门(三)

    最好的学习方式是什么?模仿.有人会问,那不是山寨么?但是我认为,那是模仿的初级阶段,当把别人最好的设计已经融化到自己的血液里,变成自己的东西,而灵活运用的时候,才是真正高级阶段.正所谓画虎画皮难画骨. ...