MySQL 多线程定时统计_mysql并发线程控制之控制thread_running数量

本文介绍了MySQL服务器在面对并发线程数过多时的控制策略,包括高水位和低水位限流。低水位限流采用了基于FIFO的cond-wait/signal策略,优化了线程等待和执行,以防止服务器出现hang住的情况。文章还详细讲解了线程控制的代码实现,并展示了通过补丁实现的低水位优化,以及测试效果,表明这种优化可以有效控制并发线程,提高系统稳定性。
摘要由CSDN通过智能技术生成

前面两篇帖子分别总结了innodb_thread_concurrency和thread pool的原理:

前者是在存储引擎层面限制并发运行的线程数,代码路径过于靠后,此时query已在server层完成解析;

后者则是在server层创建多组常驻线程,用于接收客户端连接发送的query并代为执行,而不是为每个连接单独创建一个线程。

除了这两种解决方案,还可以在server层进行running thread数量判断,如果达到阈值则直接报错或sleep。

thread_running的意义

thread_running状态变量记录了当前并发执行stmt/command的数量,执行前加1执行后减1;

代码逻辑

do_command

-->dispatch_command

...

inc_thread_running

...

mysql_execute_command or execute_some_command

...

dec_thread_running

...

Thread_running突然飙高的诱因:

1客户端连接暴增;

2系统性能瓶颈,如CPU,IO或者mem swap;

3异常sql;

往往在这种情况下,MySQL server会表现出hang住的假象。

解决方案

暂时禁止新sql执行,为此引入两个阈值low_watermark和high_watermark,以及变量threads_running_ctl_mode(selects或者all );

执行query前,检查thread_running,

1若其已达high_watermark阈值则直接拒绝执行并返回错误:mysql

server is too busy

2若其位于low和high之间,则sleep 5ms,然后继续尝试,累计等待100ms后则执行

3对于已经开启事务和super用户,不做限制

4

threads_running_ctl_mode控制query类型:SELECTS/ALL,默认为SELECTS,表示只影响SELECT语句

Patch部分源码见注1

进一步改进

将低水位限流从sleep-retry优化为基于FIFO的cond-wait/signal(实现8个FIFO);

1高水位限流(这点保持不变);

2低水位优化;其他解决方案:mariadb开发thread pool,percona在其上实现了优先队列;

本patch优势:思路与thread pool一致,但代码更简洁(不到1000行);而且增加了特定query的过滤;

Patch部分代码见注2

低水位优化细节

1新增thread_active记录并发线程数,位于mysql_execute_command(sql解析之后),高水位则在query解析之前判断;

Thread_active只统计select/DML,而commit/rollback则放过。

2采用FIFO,当thread_active >=

thread_running_low_watermark时进程进入FIFO等待,其他线程执行完sql后唤醒FIFO;

保证并发线程控制在thread_running_low_watermark内,同时引入threads_running_wait_timeout控制线程在FIFO最大等待时间,超时则直接报错返回。

3引入8个FIFO,降低了进出FIFO的锁竞争,线程采用RR分配到不同fifo,每个队列限制并发运行线程为threads_running_low_watermark/8。

已经通过高水位验证的thread,开始执行query,[解析后进行低水位判断,若通过则执行],执行当前sql完毕后,thread可能发起新query,则重复[]过程。

新增系统变量

threads_running_wait_timeout:进入FIFO排队最长时间,等待超时后sql被拒,默认100,单位为毫秒ms。

新增状态变量

threads_active:当前并发SELECT/INSERT/UPDATE/DELETE执行的线程数目;

threads_wait:当前进入到FIFO中等待的线程数目;

测试效果

./sysbench

--test=tests/db/select.lua --max-requests=0 --mysql-host=myxxxx.cm3

--mysql-user=test --mysql-table-engine=innodb --oltp-table-size=5000000

--oltp-tables-count=32

e26759f88fea47fd2d34c9cdc059f757.png

normal

mysql-0 :未打补丁版本,设置innodb_thread_concurrency=0

normal

mysql-1 :未打补丁版本,innodb_thread_concurrency=32

patched

mysql :低水位限流补丁版本(活跃线程数不超过64)

注1

+static my_bool thread_running_control(THD *thd, ulong tr)

+{

+  int slept_cnt= 0;

+  ulong tr_low, tr_high;

+  DBUG_ENTER("thread_running_control");

+

+  /*

+    Super user/slave thre

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值