Linux磁盘IO利用率高的场景排查解决路径

作为一个DBA难免不了会遇到性能问题(尤其是磁盘IO等的性能问题),那么我们遇到性能问题该如何进行排查?例如我们在高并发的业务下,出现业务响应慢,处理时间长,我们又该如何入手进行排查和解决,技术社群的这篇文章《故障分析 | linux 磁盘io利用率高,分析的正确姿势》将会讲解IO高的情况下如何分析及定位。

一、环境复现

环境配置:本次测试使用128C_512G_4TSSD服务器配置,MySQL版本为8.0.27。

场景模拟:使用sysbench创建5个表,每个表2亿条数据,执行产生笛卡尔积查询的sql语句,产生io,可以模拟业务压力。首先使用sysbench进行数据压测

二、系统层面底层故障排查

Shell> sysbench --test=/usr/local/share/sysbench/oltp_insert.lua --mysql-host=XXX --mysql-port=3306 --mysql-user=pcms --mysql-password=abc123 --mysql-db=sysbench --percentile=99 --table-size=2000000000 --tables=5 --threads=1000 prepare

使用sysbench进行模拟高并发,

shell> sysbench --test=/usr/local/share/sysbench/oltp_write_only.lua --mysql-host=xxx --mysql-port=3306 --mysql-user=pcms --mysql-password=abc123 --mysql-db=sysbench --percentile=99 --table-size=2000000000 --tables=5 --threads=1000 --max-time=60000 --report-interval=1 --threads=1000 --max-requests=0 --mysql-ignore-errors=all run

执行笛卡尔积sql语句,

mysql> select SQL_NO_CACHE b.id,a.k from sbtest_a a left join sbtest_b b on a.id=b.id  group by a.k order by b.c desc;

2.1 检查当前服务器状态

77c2fac47ef7cd6d9cadf2da582c7f2c.png

由上可知:目前一分钟负载为72.56,且呈上升趋势,并且存在io压力。

2.2 查看当前各个磁盘设备的io情况

e94996a4d54eb211943e5a12cba6367f.png

由上可知:目前有多块物理磁盘,sda磁盘的io压力较大。

2.3 检查sda磁盘当前的io读写情况

2a7572044475060497c331df14329345.png

由上可知:目前sda磁盘的压力比较大,每秒写入比每秒读差距较大,证明目前有大量的io写入。

2.4 检查sda磁盘中哪个应用程序占用的io比较高

f6439b993e31a27382000710c1a00037.png

由上可知:占用io高的应用程序是mysql,且pid为73739

2.5 分析应用程序中哪一个线程占用的io比较高

c40e2a93fc99703df61a4e19c1d18fd6.png

由上可知:74770这个线程占用的io比较高。

2.6 分析这个线程在干什么?

5e67301a3b98e5d71859b5dfbd54947e.png

由上可知:目前这个线程在写入多个文件,fd为文件句柄,文件句柄号有64、159。

2.7 查看这个文件句柄是什么

shell> lsof -p 73739|grep 159u
mysqld 73739 mysql  159u   REG                8,0   212143246  7046482357 /mysql/mysqldata/16320fff-5fd5-4c47-889a-a9e1a8591d0d/tmp/#7046482357 (deleted)
[root@mysql-4 ~]# lsof -p 73739|grep 64u
mysqld 73739 mysql   64u   REG                8,0   211872724  6979323031 /mysql/mysqldata/16320fff-5fd5-4c47-889a-a9e1a8591d0d/tmp/#6979323031 (deleted)

由上可知:这个线程在大量的写入临时文件。

三、分析MySQL应用程序

3.1 查看当前的会话列表

mysql> select * from information_schema.processlist where command !='sleep';
|  9 | pcms             | 172.16.76.12:57596 | sysbench | Query            |   67 | executing                                                     | select SQL_NO_CACHE b.id,a.k from sbtest_a a left join sbtest_b b on a.id=b.id  group by a.k order by b.c desc |   66477 |         0 |             0 |

由上可知:目前这个sql已经执行了67s,且此sql使用了group by和order by,必然会产生io。

3.2 通过线程号查询会话

9c20723b55a711062f17f89747a2bf5c.png

由上可知:通过查询threads表可以进行验证,该线程在频繁创建临时表的原因就来源于此sql。

3.3 查看该sql语句的执行计划,进行进一步认证

af546dd971e5fd7378242fa65e72dfe4.png

由上可知:该sql的执行计划用到了临时表及临时文件,符合。

3.4 查看全局状态进一步进行确认

df008a0914562084ec95b28ef145d6e8.png

多执行几次,可以看出tmp_files和tmp_disk_tables的值在增长,证明在大量的创建临时文件及磁盘临时表,符合该线程的行为。

四、故障处理

通过上述的一系列排查,我们已经分析出来,目前sda磁盘的io使用率最高,且mysqld程序占用的最多,通过排查有一个线程在频繁的创建临时表或临时文件且通过登录mysql排查会话及线程视图可以找到是由某一个慢sql导致的,查看此慢sql的执行计划也会创建临时表和临时文件符合我们之前排查的预期。此时我们就需要针对此慢sql进行优化,优化步骤由DBA进行处理,此处进行忽略。慢sql优化完成后可以进行io的继续观察,看io是否有下降

五、代码分析

我们可以使用pstack进行跟踪线程号,获取当前的线程堆栈信息。切记pstack会调用gdb进行debug调试。

51253070dfa11d9fa6ff58bc365c65bc.png

8ee5e411b350704ab0f2430f883ad37d.png

如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发pyq,

d4e37b2a46b00341a6af97ae754ab82b.png

近期更新的文章:

MySQL查询优化

mysqldump导出的SQL事务大小可以控制么?

MySQL远程登录提示Access denied的场景

JDBC连接参数useCursorFetch的使用场景

MySQL中索引创建错误的场景

近期的热文:

推荐一篇Oracle RAC Cache Fusion的经典论文

"红警"游戏开源代码带给我们的震撼

文章分类和索引:

公众号1300篇文章分类和索引

猜你喜欢

转载自blog.csdn.net/bisal/article/details/133326496