当前位置: 首页 > news >正文

MySQL如何管理客户端连接?线程池篇

在之前的文章里,为大家介绍了MySQL的连接管理线程的工作方式,在这一篇里为大家介绍管理连接的第二种方式,线程池。

MySQL默认的连接控制方式采用的是每个连接使用一个线程执行客户端的请求。MySQL的线程池是包含在企业版里面的服务器插件。使用线程池的目的是为了改善大量并发连接所带来的性能下降。在大量并发连接的工作负载下,使用线程池可以解决无法利用CPU缓存、上下文切换开销过大以及资源争用等问题。

线程池功能由插件库文件、服务器系统变量及Performance Schema里面的检测点组成。

线程池是由一定数量的线程组(默认为16个通过thread_pool_size
进行配置)构成,每个线程组管理一组客户端连接,最大连接数为4096。连接创建之后会以轮询的方式分配给线程组。连接池打破了每个连接与线程一一对应的关系,这一点与MySQL默认的线程控制方式不同,默认方式将一个线程与一个连接相关联,以便给定的线程从其连接执行所有的语句。

默认情况下,线程池试图确保每个组中每次最多执行一个线程,但有时为了获得最佳性能,允许临时执行多个线程。每组里面有一个监听线程,负责监听分配给该组的连接。线程会选择立即执行或稍后执行连接里面的语句,如果语句是唯一接收到的,并且当前没有排队或正在执行的语句,该语句就会立即执行。其它情况则会选择稍后执行。当该语句被判断为立即执行时,监听线程负责执行该语句,如果能够快速完成执行,该线程会返回监听状态,如果执行语句时间过长产生停滞,线程组会开启一个新的监听线程。线程池插件使用一个后台线程监控线程组状态,以确保线程组不会因为停滞的语句阻塞线程组。

可以通过thread_pool_stall_limit 配置等待值时长,短等待值允许线程更快启动,也有助于避免死锁情况。长时间等待值对于长时间运行的工作负载非常有用,可以避免在当前语句执行时启动太多新语句。

通过thread_pool_max_active_query_threads设置运行的最大线程,如果该值不为0,则该数值为允许运行的最大线程数量,设置为0使用默认最大值。

线程池侧重于限制短时间运行语句的并发数量。在执行语句达到待值时长之前,它会阻止其他语句开始执行。如果语句执行超过了待值时长,允许其继续执行,但不再阻止其他语句启动。通过这种方式,线程池尝试确保每个线程组中永远不会有超过一个的短时间运行语句,但可能有多个长时间运行的语句。

如果遇到磁盘I/O操作或用户级锁(行锁或表锁),语句就会被阻塞,将导致线程组无法使用。线程池的回调功能,可以确保线程池立即启动该组中的新线程来执行另一条语句。当一个被阻塞的线程返回时,线程池允许它立即重新启动。

线程池包含两个队列,高优先级队列和低优先级队列。当前正在执行的语句及该事务后续关联的语句将进入高优先级队列,其它语句进入低优先级队列。

此外,线程池重用活跃的线程,以更好地利用CPU缓存。这是一个对性能有很大影响的调整。

理论上,可能出现的最大线程数是 max_connectionsthread_pool_size的总和。当所有连接都处于执行模式,并且每个组都创建了一个额外的线程来监听,可能会发生这种情况。

总结一下,MySQL的线程池被设计为扩展连接、避免死锁,通过对线程进行分组、区分优先级、轮询调度,高效利用CPU缓存、减少上下文切换开销,提升MySQL服务器性能!

感谢您关注“MySQL解决方案工程师”!

QQ群号:763628645

QQ群二维码如下, 添加请注明:姓名+地区+职位,否则不予通过

相关文章:

  • TVP两周年:携手同行,让未来可见
  • 你知道全知乎阅读量最高的问题是什么吗?我全都爬下来了
  • 高并发下,如何让你的数据库再快一点?
  • 2300天,再出发
  • MySQL 实战笔记 第01期:MySQL 角色管理
  • MySQL 实战笔记 第02期:MySQL 元数据锁
  • 经常用Redis,这些坑你知道吗?
  • Redis为什么这么快?
  • 迁移至MySQL的数据流转流程优化
  • 长文:读《经济学32定律》
  • 使用Rancher搭建K8S测试环境
  • 深度学习在视觉搜索和匹配中的应用
  • MySQL 5.7和MySQL 8.0的4个细节差异
  • 开启读书模式-2021
  • 我收集了如下的一些语录
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • Docker下部署自己的LNMP工作环境
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • ES6之路之模块详解
  • Java反射-动态类加载和重新加载
  • java正则表式的使用
  • JWT究竟是什么呢?
  • Node 版本管理
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • SQLServer之创建数据库快照
  • vue学习系列(二)vue-cli
  • 记录一下第一次使用npm
  • 看域名解析域名安全对SEO的影响
  • 力扣(LeetCode)965
  • 找一份好的前端工作,起点很重要
  • 2017年360最后一道编程题
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​Linux·i2c驱动架构​
  • ​MySQL主从复制一致性检测
  • ​决定德拉瓦州地区版图的关键历史事件
  • #if和#ifdef区别
  • (二)斐波那契Fabonacci函数
  • (十)c52学习之旅-定时器实验
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (转)shell调试方法
  • .gitignore
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .NET 常见的偏门问题
  • .net 后台导出excel ,word
  • .net的socket示例
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .NET中使用Redis (二)
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • /proc/vmstat 详解
  • @EnableWebMvc介绍和使用详细demo
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [Angular] 笔记 18:Angular Router
  • [AutoSar]状态管理(五)Dcm与BswM、EcuM的复位实现