问题背景
线上MySQL经常遇到threads_running飙高的情况,往往在这种情况下,MySQL server会表现出hang住的假象,其实threads_running是一种结果,表示问题已经发生了,如果此时不找出问题原因采取措施,会影响到线上应用,为此我们开发了MySQL threads running control特性,监测threads_running,当发现其超过一个阈值时,server暂时拒绝服务,避免引起雪崩,待threads_running下降后正常服务。
什么是threads_running
threads_running是MySQL一个重要的实时运行状态参数,通过
SHOW STATUS LIKE ‘threads_running’;
可以查到,它代表的意义:当前并发执行的statement/command的数目,每个statement/command开始执行之前将其增加1,执行结束后减1,代码中的逻辑:
do_command
|-->dispatch_command
...
inc_thread_running
...
mysql_execute_command or execute_some_command
...
dec_thread_running
...
threads_running飙高表示server目前压力较大,一般是客户端压力突增/IO问题/CPU问题/异常SQL等原因引起,需要定位问题源头并马上解决,否则上层应用受到更大影响,为了避免hang住,这时最好的选择是让server暂时“拒载”
threads running control
我们为此开发了这样一个特性:
1. 设置两个阈值,low_watermark和high_watermark和另外一个threads_running_ctl_mode
2. 我们监测系统threads_running状态,在执行query之前,比较一下当前threads_running是否超过high_watermark阈值,如超过直拒绝执行sql,返回客户端:MySQL Server is too busy,若当前threads_running位于high_watermark和low_watermark之间,sleep一段时间(5ms)后重新进入判断逻辑,若query没有被拒绝执行并且累计sleep达到100ms后,server将接受并执行
3. threads_running_ctl_mode控制收到影响的query类型,有2个取值:SELECTS/ALL,默认为SELECTS,表示只影响SELECT语句
4. 对于已经开启的事务和SUPER权限用户,不做限制
threads running control效果
1000个并发,threads_running飙到1000

1000个并发,设置threads_running_high_watermark=500,threads_running维持在500

如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!