MySQL压测时Linux中断异常飚高,原来是因为...

简介: MySQL压测时Linux中断异常飚高,原来是因为...

1. 系统环境

  • OS: CentOS Linux release 7.8.2003 (Core)
  • Kernel: 3.10.0-1127.19.1.el7.x86_64
  • MySQL: 用5.0、5.7均有此问题,应该和版本无关

2. 压测工具

  • benchyou[1]
  • mysql_random_load[2]

3. 问题现象

利用 mysql_random_load 工具连接MySQL写入数据时,性能非常非常低。

由于 mysql_random_load 工具不支持通过socket连接,只好放弃,改用benchyou。顺便说一下,benchyousysbench极为相似,也非常好用。

改用benchyou工具后,压测正常。看来的确不是MySQL版本的问题。

mysql_random_load 工具进行压测时,系统负载非常高,同时可观测到系统的中断也很高并且也很不均衡。

[root@yejr.run]# vmstat -S m 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0  73585      2  41051    0    0   117    91    4    2  0  0 99  0  0
 2  0      0  73585      2  41051    0    0     0 28320 55444 100207 18  2 80  0  0
 4  0      0  73584      2  41052    0    0     0  1936 52949 98607 18  2 81  0  0
 2  0      0  73583      2  41052    0    0     0  4864 56375 101262 14  2 84  0  0
 4  0      0  73583      2  41052    0    0     0 29064 55806 103715 19  2 80  0  0
 5  0      0  73583      2  41052    0    0     0  5704 55854 98386 15  2 83  0  0

可以看到 system.in 这列的值非常高,改成benchyou工具后,这列的值从5.5万降到1.6万。

[root@yejr.run]# vmstat -S m 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 4  0      0  77238      2  38371    0    0   118    88    2    3  0  0 99  0  0
 2  0      0  77234      2  38374    0    0     0 31620 16039 77988  3  2 95  0  0
 2  0      0  77231      2  38377    0    0     0 31996 16091 78926  3  2 95  0  0
 3  0      0  77229      2  38378    0    0     0 33028 16347 81006  3  2 95  0  0
 0  0      0  77226      2  38383    0    0     0 52412 15496 75715  3  2 95  0  0
 2  0      0  77224      2  38384    0    0     0 32252 16167 79352  3  2 95  0  0

再看下有问题时的系统中断表现

[root@yejr.run]# mpstat -I SUM -P ALL 1
Linux 3.10.0-1127.19.1.el7.x86_64 (yejr.run)  09/28/2020  _x86_64_ (32 CPU)
05:37:40 PM  CPU    intr/s
05:37:41 PM  all  51833.00
05:37:41 PM    0   2069.00
05:37:41 PM    1   1159.00
05:37:41 PM    2   2979.00
05:37:41 PM    3   1580.00
05:37:41 PM    4   1627.00
05:37:41 PM    5   1461.00
05:37:41 PM    6   1243.00
05:37:41 PM    7   1825.00
05:37:41 PM    8   2154.00
05:37:41 PM    9   1367.00
05:37:41 PM   10   1277.00
05:37:41 PM   11   1376.00
05:37:41 PM   12   4085.00
05:37:41 PM   13   1601.00
05:37:41 PM   14   4045.00
05:37:41 PM   15   1857.00
05:37:41 PM   16   1692.00
05:37:41 PM   17    722.00
05:37:41 PM   18    118.00
05:37:41 PM   19   1862.00
05:37:41 PM   20   1637.00
05:37:41 PM   21   1130.00
05:37:41 PM   22   1750.00
05:37:41 PM   23   1653.00
05:37:41 PM   24   1417.00
05:37:41 PM   25   1547.00
05:37:41 PM   26   1500.00
05:37:41 PM   27   1033.00
05:37:41 PM   28     20.00
05:37:41 PM   29   1683.00
05:37:41 PM   30    888.00
05:37:41 PM   31   1549.00

可以看到每秒中断总量有5.5万,但多个CPU间并不均衡。

4. 问题分析

初步认定是因为系统中断太高导致的写入性能差,并且也认定是因为多个CPU间中断不均衡导致的这个问题。

观察是都有哪些中断比较高,发现主要是 LOC 和 RES 这两个每秒的增长比较大。

[root@yejr.run]# watch -d cat /proc/interrupts
...
LOC: 2468939840 2374791518 2373834803 2373613050   Local timer interrupts
SPU:          0          0          0          0   Spurious interrupts
PMI:          0          0          0          0   Performance monitoring interrupts
IWI:   50073298   45861632   45568755   45833911   IRQ work interrupts
RTR:          0          0          0          0   APIC ICR read retries
RES: 3472920231 3022439316 2990464825 3012790828   Rescheduling interrupts
CAL:    5131479    6539715   17285454   11211131   Function call interrupts
TLB:   23094853   24045725   24230472   24271286   TLB shootdowns
TRM:          0          0          0          0   Thermal event interrupts
...

在尝试修改相关中断号绑定的CPU后(参考:SMP affinity and proper interrupt handling in Linux[3]),问题还是没有得到缓解。

后来某神秘大佬给指点了下,才发现原来是个内核的bug,涉及到参数 kernel.timer_migration,需要将其设置为 0 才行。

[root@yejr.run]# sysctl -w kernel.timer_migration=0

当然了,最好持久化写入到 /etc/sysctl.conf 文件中。

[root@yejr.run]# cat /etc/sysctl.conf
kernel.timer_migration=0
#加载配置文件使之生效
[root@yejr.run]# sysctl -p

再次用 mysql_random_load 工具进行压测就没事了。

下面是关于该bug的描述

The bug is when linux os receive too many tcp packages, 
and the tcp may add too many timer, but in
get_target_base->get_nohz_timer_target it check current 
cpu is idle, sometimes thouth the current core is very busy,
but the idle_cpu result is 1, in this time
if set kernel.timer_migration=1 ,the timer will be move to next cpu.

bug详情见:Bug 124661 - kernel.timer_migration=1 cause too many Rescheduling interrupts[4]

最后,值得一提的是,在云主机上修改该参数应该是不管用,除非修改物理机的。我在某云主机上运行 mysql_random_load 工具压测也遇到类似问题,修改内核参数后问题依旧。

文内链接

  • [1]:https://github.com/xelabs/benchyou
  • [2]:https://github.com/Percona-Lab/mysql_random_data_load
  • [3]:http://www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux
  • [4]:https://bugzilla.kernel.org/show_bug.cgi?id=124661

全文完。

Enjoy Linux & MySQL :)

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
3月前
|
存储 安全 Unix
七、Linux Shell 与脚本基础
别再一遍遍地敲重复的命令了,把它们写进Shell脚本,就能一键搞定。脚本本质上就是个存着一堆命令的文本文件,但要让它“活”起来,有几个关键点:文件开头最好用#!/usr/bin/env bash来指定解释器,并用chmod +x给它执行权限。执行时也有讲究:./script.sh是在一个新“房间”(子Shell)里跑,不影响你;而source script.sh是在当前“房间”里跑,适合用来加载环境变量和配置文件。
455 9
|
3月前
|
存储 Shell Linux
八、Linux Shell 脚本:变量与字符串
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
369 2
|
5月前
|
Web App开发 缓存 安全
Linux一键清理系统垃圾:释放30GB空间的Shell脚本实战​
这篇博客介绍了一个实用的Linux系统盘清理脚本,主要功能包括: 安全权限检查和旧内核清理,保留当前使用内核 7天以上日志文件清理和系统日志压缩 浏览器缓存(Chrome/Firefox)、APT缓存、临时文件清理 智能清理Snap旧版本和Docker无用数据 提供磁盘空间使用前后对比和大文件查找功能 脚本采用交互式设计确保安全性,适合定期维护开发环境、服务器和个人电脑。文章详细解析了脚本的关键功能代码,并给出了使用建议。完整脚本已开源,用户可根据需求自定义调整清理策略。
656 1
|
7月前
|
Linux Shell
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
228 4
|
7月前
|
Linux Shell 数据安全/隐私保护
Centos或Linux编写一键式Shell脚本创建用户、组、目录分配权限指导手册
Centos或Linux编写一键式Shell脚本创建用户、组、目录分配权限指导手册
448 3
|
8月前
|
Linux Shell
在Linux、CentOS7中设置shell脚本开机自启动服务
以上就是在CentOS 7中设置shell脚本开机自启动服务的全部步骤。希望这个指南能帮助你更好地管理你的Linux系统。
692 25
|
10月前
|
Shell Linux
【linux】Shell脚本中basename和dirname的详细用法教程
本文详细介绍了Linux Shell脚本中 `basename`和 `dirname`命令的用法,包括去除路径信息、去除后缀、批量处理文件名和路径等。同时,通过文件备份和日志文件分离的实践应用,展示了这两个命令在实际脚本中的应用场景。希望本文能帮助您更好地理解和应用 `basename`和 `dirname`命令,提高Shell脚本编写的效率和灵活性。
789 32
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
人工智能 监控 Shell
常用的 55 个 Linux Shell 脚本(包括基础案例、文件操作、实用工具、图形化、sed、gawk)
这篇文章提供了55个常用的Linux Shell脚本实例,涵盖基础案例、文件操作、实用工具、图形化界面及sed、gawk的使用。
2523 2
|
Shell Linux 开发工具
linux shell 脚本调试技巧
【9月更文挑战第3天】在Linux中调试shell脚本可采用多种技巧:使用`-x`选项显示每行命令及变量扩展情况;通过`read`或`trap`设置断点;利用`echo`检查变量值,`set`显示所有变量;检查退出状态码 `$?` 进行错误处理;使用`bashdb`等调试工具实现更复杂调试功能。
495 5