MySQL Thread pool 操作过程

来源:互联网 发布:linux jdk下载 64位 编辑:程序博客网 时间:2024/05/20 19:17

Thread pool 操作过程:

thread pool 包含一定数量的 thread groups,每个 groups 管理一定量的 client connections,当mysql建立 connection 时,thread pool 会以循环的方式(round-robin fashion)将其分配到其中的一个 thread groups 中。


thread_pool_size 规定了 thread groups 的数量,这样也就规定了同时可以执行多少个 statement 可取值为1—64,每个thread group 的最大线程数是4096。

thread pool 将 connection 和 threads 分隔开,所以 connection 和 thread 和没有固定的联系。


算法:

每个 thread group 有一个监听线程,该线程监听那些从 connection 发送过滤的 statement,当接受到一个 statement 的时候,thread group 会有两个选择:立即执行或者放入队列稍后执行。


当接受到的只是一个语句,而且没有其他语句处于队列,或者当前没有语句正在执行,那么就会立即执行该语句,否则的话该语句就会放入到队列中。


当立即执行该语句时,那监控线程就会来执行此任务,此时意味着在该 thread group 中临时没有线程处于监听状态,如果该语句执行的很快,那么该线程还会返回来继续处于监听状态。否则的话,thread pool 就会在需要的时候创建一个新的线程来监听。thread pool 有一个后台线程来周期的监控 thread group 的状态,以免因为执行SQL时,thread group 被 block(比如遇到disk io 产生中断等)。


thread_pool_stall_limit 参数取值范围 60ms---- 6s,该值代表了该语句将要结束并且要执行下一个语句的时间间隔

(线程在超过 thread_pool_size 时,会等待 thread_pool_stall_limit ms 后创建新线程,防止线程池瞬间扩展而还来不必要的线程开销)。较小的值允许新的线程快速的启动,这样也可以防止死锁的产生。对于那些长时间执行的statement,适合较大的值,这样防止同时执行太多的 statement。


thread pool专注于并发的短时间运行的statement ?

当 statement 遇到 disk io 时,或者 row lock 或者 table lock 的时候,会造成 thread group 变的不可用,此时 thread pool 有一个回调机制来让该 group 内开启一个新的 thread 来执行其他的 statement,当 blocked thread 返回的时候,thread pool 立马使用。


对于队列:high-priority queue 和 low-priority queue

一般情况下,事务里的第一个 statement 会被放到低级别的队列中,其他的语句会被放到较高级别的队列中,thread_pool_high_priority_connection 可以将所有 statement 都放到高级别的队列中。


如果语句针对的是非事务型的存储引擎,或者存储引擎 autocommit = 1 所有的语句都会被放入到 low 级别的队列中,

当 thread group 选择队列中的语句开始执行的时候,先检查高优先级的队列,然后是低优先级的队列,对于发现的语句,它会从队列中移除并开始执行。


如果某个语句在低优先级的队列中时间太长,thread pool 会将其放入到高优先级的队列中,thread_pool_prio_kickup_timer 参数来控制这个时间。

thread pool 会选择重用最活跃的 threads 来充分利用 CPU 的缓存,这个小小的调整对性能影响很大。


下面是当 thread group 有多个 threads 活跃时举出的实例:

1、一个线程执行一个 statement,但是时间已经超过了 stalled time,thread group 会开启一个新的 thread 来执行其他的statement,设置当第一个语句还在执行过程中。


2、一个线程正在执行一个 statement,然后被 blocked 并被 thread pool 检测到,这个时候该 thread group 允许

开启一个新的线程来执行另一个 statement。


3、一个线程正在执行一个 statement,然后被 blocked,但没有被 thread pool 检测到,这个时候只有等到 stalled 时间

才能开启一个新的线程来执行新的 statement。


在某些线程被 blocked,但不被 thread pool 检测到,但也不会阻止其他语句的执行,也不会造成 thread pool 死锁,这些情况是很重要的。

1、长时间运行的 statement.

2、Binary log dump threads.

3、Statements blocked on a row lock, table lock, sleep, or any other blocking activity that has not been reported back to the thread pool by MySQL Server or a storage engine.


以上情况,为防止死锁的产生,该 statement 都会被放到 stalled 类别对待,最大的线程数是 the sum of max_connections and thread_pool_size。

0 0
原创粉丝点击