介绍
在默认的MySQL连接器下,MySQL服务会为每个接入的连接分配一个线程,当连接数非常大时,线程的上下文切换及线程之间热锁的竞争将无意义的占用CPU,导致服务性能下降。本特性基于Percona线程池,并加入了新的优化和bug修复,为Linux下的MySQL服务引入线程池的连接器。配置使用该连接器模块后,连接的建立与调度由线程池连接器接管。通过引入可动态伸缩的线程池,使服务器即使在有大量客户端连接的情况下,也能保持最佳性能。通过使用线程池连接器将减少MySQL的线程数量,从而减少上下文切换和热锁竞争的消耗。使用线程池对大量连接的OLTP短查询的场景将有最大帮助。
应用场景
- 对于大量连接的OLTP短查询的场景将有最大收益。
- 对于大量连接的只读短查询也有明显收益。
- 对于有较多长查询连接的场景,可配置线程池为小线程组数模式,避免长查询导致线程池性能下降问题。
特性以patch文件的方式实现,具体使用方法参考安装patch。
特性介绍
图1 总体原理框架


整个线程池分为若干个线程组和一个timer线程,线程组个数默认为服务器上CPU的核心数,也可通过配置文件或命令行启动参数调整,参见配置参数thread_pool_size。用户连接被轮询分配到对应线程组上,连接上的所有查询请求都将由其绑定的线程组处理。当客户端连接发送来SQL语句时,线程组为该连接分配worker线程进行处理。SQL执行结束后,线程组回收worker线程。通过一定策略控制worker线程的数量,从而使得实际worker线程数保持在一个高性能的数量范围内。
本特性支持的功能:
- 线程组个数可自适应也可动态修改。
- 优先队列与普通队列区分处理事务中连接、持锁连接与普通查询语句连接,优化性能,详细请见thread_pool_high_prio_mode与thread_pool_high_prio_tickets。
- 动态伸缩worker线程的个数,使运行中的线程数保持在一个高效的数量范围。
- 防线程池停滞(线程池饥饿)问题。
- 本地unix socket连接使用额外连接器。
- information_schema增加四张状态信息表,可实时监控线程池状态。
功能配置的详细说明请见配置参数。

每个线程组对应:
- 一个pollfd,epoll_create返回的poll描述符。
- 零个或一个listener线程,epoll_wait等待网络可读事件。
- 一个普通队列,存放有网络可读事件的连接对象(包含TPC连接信息与SQL执行上下文状态信息),待被worker线程处理。
- 一个优先队列,存放有网络可读事件的、正处于事务过程中等情况的连接对象,待优先被worker线程处理。
- 零个、一个或多个worker线程,获取有可读事件的连接对象,处理连接的登录验证、SQL接收执行和结果返回,当线程组中没有listener线程时,新空闲的将进入休眠的第一个worker线程会转化为listener线程。
- 一个waiting队列,当worker线程没有任务需要处理时,就会进入条件等待休眠,放入队列,被外部信号唤醒或等待超时自动唤醒后,线程状态重新标识为active状态处理任务或退出结束多余的worker线程。
- 一个mutex锁,保护线程组中的一些资源在多线程中的操作。
所有线程组共有一个timer线程,timer线程用于检测线程组中是否出现任务停滞,即一段时间内没有新的任务产生或任务队列不为空时却没有任务被消费掉的情况。
父主题: MySQL 5.7.57 线程池特性指南