MYSQL threadPool 线程池

 

概述

  • mysql企业版安装插件使用
  • 限制最大并发
  • 减少服务器CPU调度
  • mysql默认线程调度one-thread-per-connection(每连接一个线程)
  • 线程池适合大量短连接或高并发情况

 

 

相关参数

Plain Text

#查看线程池参数

show global variables like '%thread_pool%';

thread_pool_high_prio_mode

有三个取值:transactions / statements / none

transactions(default): 使用优先队列和普通队列,对于事务已经开启的statement,放到优先队列中,否则放到普通队列中

statements:只使用优先队列

none: 只是用普通队列,本质上和statements相同,都是只是用一个队列

thread_pool_high_prio_tickets

取值0~4294967295,当开启了优先队列模式后(thread_pool_high_prio_mode=transactions),每个连接最多允许thread_pool_high_prio_tickets次被放到优先队列中,之后放到普通队列中,默认为4294967295

thread_pool_idle_timeout

worker线程最大空闲时间,单位为秒,超过限制后会退出,默认60

thread_pool_max_threads

threadpool中最大线程数目,所有group中worker线程总数超过该限制后不能继续创建更多线程,默认100000

thread_pool_oversubscribe

一个group中线程数过载限制,当一个group中线程数超过次限制后,继续创建worker线程会被延迟,默认3

thread_pool_size

threadpool中group数量,默认为cpu核心数,server启动时自动计算

thread_pool_stall_limit

timer线程检测间隔,单位为毫秒,默认500

 

 

架构组成

MYSQL threadPool 线程池

 

threadpool组成

 

threadGroup

一个threadgroup 为一个线程池 其中有 两个队列 和多个work线程

 

队列

  • 两个队列 高级队列和低级队列
  • 高级队列的任务会优先处理
  • 开启事务的任务 会放到高级队列中
  • 低级队列停留时间太久 也会移到高级队列

 

liistener线程

  • 监听线程池任务
  • 确定是自己变成work线程立即执行任务 还是放到队列中
  • 如果队列中待执行的语句数量为0,而listener线程转换成worker线程,并立即执行对应的语句
  • 如果队列中待执行的语句数量不为0,则认为任务比较多,将语句放入队列中
  • 为了减少线程的创建

 

worker线程

真正执行SQL的线程

 

timer线程

  • 周期检查group是否阻塞
  • 出现阻塞 通过唤醒线程或新建线程解决

Plain Text

Timer线程是用来周期性检查group是否处于处于阻塞状态,当出现阻塞的时候,会通过唤醒线程或者新建线程来解决。具体的检测方法为,通过queue_event_count的值和IO任务队列是否为空来判断线程组是否为阻塞状态。每次worker线程检查队列中任务的时候,queue_event_count会+1,每次Timer检查完group是否阻塞的时候会将queue_event_count清0,如果检查的时候任务队列不为空,而queue_event_count为0,则说明任务队列没有被正常处理,此时该group出现了阻塞,Timer线程会唤醒worker线程或者新建一个wokrer线程来处理队列中的任务,防止group长时间被阻塞。

 

 

ThreadPool 如何运行

  • 请求连接到mysql 通过线程id % group_size 确定group
  • listenner确定执行线程
  • group中的thread线程检查队列的请求,如果队列中有请求,则进行处理,如果没有请求,则休眠,一直没有被唤醒,超过thread_pool_idle_timeout后就自动退出。线程结束。当然,获取请求之前会先检查group中的running线程数是否超过thread_pool_oversubscribe+1,如果超过也会休眠。