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. [Codeforces261D]Maxim and Increasing Subsequence——树状数组+DP

    题目链接: Codeforces261D 题目大意:$k$次询问,每次给出一个长度为$n$的序列$b$及$b$中的最大值$maxb$,构造出序列$a$为$t$个序列$b$连接而成,求$a$的最长上升子 ...

  2. 一个服务器创建两个MySQL

    转载:http://www.2cto.com/database/201412/357863.html 将已安装的数据库文件夹复制到另一个目录下 打开复制目录下的my.ini文件修改 [client] ...

  3. Android 根据版本号更新

    1 读取android 版本号 具体文件位置: app下 build.gradle文件 versionCode和 versionName defaultConfig { versionCode 1 v ...

  4. LOJ2250 [ZJOI2017] 仙人掌【树形DP】【DFS树】

    题目分析: 不难注意到仙人掌边可以删掉.在森林中考虑树形DP. 题目中说边不能重复,但我们可以在结束后没覆盖的边覆盖一个重复边,不改变方案数. 接着将所有的边接到当前点,然后每两个方案可以任意拼接.然 ...

  5. 【XSY2767】朋友 广义后缀自动机 网络流

    题目描述 懒得写了...直接贴题面 $\sum n\leq5000,1\leq S_{i,j}\leq k\leq 1000 $ 题解 先建出广义sam. 可以发现朋友的出现位置的定义符合后缀自动机的 ...

  6. 【XSY2669】归并排序 树状数组 简单组合数学

    题目描述 有一个长度为\(n\)的排列\(n=2^k\),你要把这个数组归并排序.但是在长度为\(2\)的时候有\(\frac{1}{2}\)的概率会把两个数交换(就是有\(\frac{1}{2}\) ...

  7. power designer 一般常用快捷键(转)

    一般快捷键 快捷键 说明 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部图内容 ...

  8. 普通Splay详解

    预备知识: 二叉搜索树(BST) 至于BST,随便看一下就可以, 我们知道二叉搜索树是O(logN)的,那我们为什么要用平衡树呢? 之前我们了解到,BST的插入是小的往左子树走,大的往右子树走,如果凉 ...

  9. 洛谷P3222 [HNOI2012]射箭(计算几何,半平面交,双端队列)

    洛谷题目传送门 设抛物线方程为\(y=ax^2+bx(a<0,b>0)\),我们想要求出一组\(a,b\)使得它尽可能满足更多的要求.这个显然可以二分答案. 如何check当前的\(mid ...

  10. 使用Coverage进行代码覆盖率的测试

    软件测试实验报告 一.实验目的: 使用软件测试代码覆盖率. 二.实验工具: Windows10.Python3.6.3.Coverage. 三.实验内容: 1.编写准备测试的代码main.py和测试代 ...