一 问题描述
一台Zabbix proxy收到持续IO报警信息。
xxxxx: High disk io on sdb for 5 minutes Trigger status: PROBLEM Bandwidth utilization for sdb (hk-zabbix-prod-proxy:disk.status[sdb,util]): 97.1 %
关于使用Zabbix监控磁盘IO可以参考
http://john88wang.blog.51cto.com/2165294/1545834
二 解决办法
登录这台服务器上先找出是什么程序在占用磁盘IO
使用 vmstat -S M 3
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 5 1 0 489 376 65049 0 0 0 1956 16554 13392 3 1 94 3 0 0 2 0 480 376 65057 0 0 0 4263 18374 12537 2 1 94 3 0 1 1 0 489 376 65047 0 0 0 2173 16294 13499 2 1 95 2 0 1 1 0 490 376 65046 0 0 0 4225 20427 15262 5 1 92 3 0 6 0 0 492 376 65046 0 0 0 988 15024 12345 2 3 93 2 0 0 1 0 491 376 65045 0 0 0 2068 14824 12619 3 1 94 2 0 6 1 0 483 376 65047 0 0 0 3404 17717 12316 1 1 95 3 0 0 1 0 493 376 65044 0 0 0 2084 13136 13430 1 1 95 3 0 1 1 0 480 376 65056 0 0 0 5292 14833 13194 3 1 92 3 0 3 1 0 476 376 65062 0 0 0 1484 11698 11063 2 1 95 3 0 1 0 0 493 376 65045 0 0 0 14237 11399 11245 1 1 96 2 0 1 0 0 490 376 65046 0 0 0 6484 12396 12582 2 1 95 2 0 1 0 0 469 376 65069 0 0 0 1564 13884 13044 5 1 92 2 0 0 1 0 492 376 65046 0 0 0 2589 12915 12921 2 1 95 2 0
通过vmstat看出cpu的wa大概是%3,这里还看不出磁盘IO有多大的问题
继续使用iostat -xmt 3查看磁盘IO
05/18/2016 11:05:15 PM avg-cpu: %user %nice %system %iowait %steal %idle 1.51 0.00 1.13 2.38 0.00 94.99 Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sdb 0.00 267.00 0.00 161.33 0.00 1.67 21.21 0.88 5.41 5.03 81.20 05/18/2016 11:05:18 PM avg-cpu: %user %nice %system %iowait %steal %idle 2.10 0.00 1.02 2.54 0.00 94.35 Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util sda 0.00 3.67 0.00 2.00 0.00 0.02 22.67 0.02 9.67 4.00 0.80 sdb 0.00 534.33 0.00 181.67 0.00 2.79 31.50 0.99 5.45 4.96 90.17 05/18/2016 11:05:21 PM avg-cpu: %user %nice %system %iowait %steal %idle 2.25 0.00 1.65 2.93 0.00 93.16 Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util sda 0.00 1.67 0.00 1.00 0.00 0.01 21.33 0.01 13.33 6.00 0.60 sdb 0.00 241.67 0.00 186.00 0.00 1.66 18.31 1.21 6.50 4.99 92.90 05/18/2016 11:05:24 PM avg-cpu: %user %nice %system %iowait %steal %idle 3.29 0.00 3.06 2.86 0.00 90.79 Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util sda 0.00 2.33 0.00 1.00 0.00 0.01 26.67 0.01 5.33 3.33 0.33 sdb 0.00 1593.33 0.00 186.67 0.00 6.95 76.20 2.25 12.07 4.91 91.63
可以看出连续多次输出中,磁盘sdb的利用率都是85%以上
然后使用iotop查看哪些进程在使用io
可以看出主要是MySQL在使用磁盘IO,但是怎么会有个奇怪的进程[jdb2/sdb1-8]占用那么高的磁盘IO
这里涉及到两个知识点
文件系统EXT4的journaling进程jdb2
MySQL的磁盘写入调优
最快的解决方式就是关闭这个磁盘的journaling日志
tune2fs -O "^has_journal" /dev/sdb1
但是不建议这样使用,因为关闭了EXT4的日志记录功能就存在丢失数据的风险。MySQL的InnoDB表即使关闭了EXT4的日志记录功能也能够不丢失数据,只要开启了innodb_doublewrite 参数,默认就是开启的。
innodb_doublewrite 参数开启后,InnoDB会存储所有的数据两次,先存储数据到doublewrite buffer,然后再存储数据到数据文件中。
mysql> show variables like '%double%'; +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | innodb_doublewrite | ON | +--------------------+-------+ 1 row in set (0.00 sec)
sync_binlog
sync_binlog参数也会影响到MySQL数据库服务器的磁盘IO.如果这个变量的值大于0,MySQL server synchronizes its binary log to disk(using fdatasync()) after sync_binlog commit groups are written to the binary log.
innodb_flush_log_at_trx_commit
这个参数默认值是1. 简单点说这个参数就是平衡InnoDB事务日志写入磁盘的频率和MySQL性能的一个参数。这个参数有3个取值
0 每次事务提交操作时不从log buffer中刷新日志到磁盘,InnoDB大约每秒从log buffer中刷新日志到磁盘,也就是说,如果发生MySQL崩溃,那么大约会丢失1秒的数据。
1 每次事务提交操作时都从log buffer中刷新日志到磁盘,这个是最安全的方式
2 InnoDB的log buffer中的数据在每次事务提交操作之后再刷新到磁盘,普通日志大约每秒刷新到磁盘。如果有MySQL崩溃或者断电等情况大约会丢失1秒的数据
对于Zabbix应用,丢失1秒数据的风险性不大。所以设置
innodb_flush_log_at_trx_commit = 0
再观察磁盘IO就恢复正常了
参考文档:
http://serverfault.com/questions/363355/io-wait-causing-so-much-slowdown-ext4-jdb2-at-99-io-during-mysql-commit
https://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_doublewrite
https://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html#sysvar_sync_binlog
https://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html