赞
踩
背景:请假在外中,听平台组同事反馈了一个问题,在往生产数据库中导入部分数据时会造成客户端的访问超时,初步定位是因为服务器磁盘占用IO过高,导数据时IO会飙升到100%,因此引起了不少数据库的慢查询操作导致客户端响应超时,无奈只好暂时停止了导入数据的脚本,同时也延误了针对这部分数据的生产测试工作。于是我第二天回到公司就投入了对这个问题的跟踪定位工作。
环境描述:
首先我们数据库某最大表的数据也不过300w多条,对于MySQL来说还是能够正常处理的。而且客户端并发量也不过1K多,数据库的TPS也未过百,我先后使用了top,iostat监测到的IO利用率确实都已经达到极限了。最后使用iotop这个工具发现了一个吃IO的罪犯jbd2
Overview
The Journaling Block Device (JBD) provides a filesystem-independent interface for filesystem journaling. ext3, ext4 and OCFS2 are known to use JBD. OCFS2 starting from linux 2.6.28 and ext4 use a fork of JBD called JBD2.
可以知晓它的主要功能是向文件系统写日志。那么肯定是由于对文件系统的操作太频繁导致的IO压力过大,问题这是个系统进程,是系统问题还是?
目前我这台服务器上只有一个应用需要大量操作IO,那就是MySQL数据库,会不会由他导致的?怀着这个疑问我用google将mysql和jbd2联合作为关键字进行搜索,得到了这么一个线索sync_binlog,innodb_flush_log_at_trx_commit这两个mysql的配置项。顿时我仿佛想起了什么,于是翻到《高性能MySQL》这本书的第10章——复制的章节(从上面的环境描述中可以看到我使用了MySQL的主主复制)找到了对sync_binlog的说明
那么innodb_flush_log_at_trx_commit呢?
如果innodb_flush_log_at_trx_commit设置为0,log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行.该模式下,在事务提交的时候,不会主动触发写入磁盘的操作。
如果innodb_flush_log_at_trx_commit设置为1,每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去.
如果innodb_flush_log_at_trx_commit设置为2,每次事务提交时MySQL都会把log buffer的数据写入log file.但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。
由于我们的业务数据的特点,对数据可靠性并不如金融、订单系统那么高于是在权衡下就把sync_binlog设置为每500次刷新一次磁盘,而将innodb_flush_log_at_trx_commit设置为2,再用iotop等工具查看系统IO情况,大大降了下来。好吧,这个借刀杀IO的罪犯终于找到并被处理了。
后记:在这次处理问题的过程中有两个小插曲。
某领导找来几个人对此问题进行会诊,有猜测服务器资源不够的,有猜测脚本问题的,有猜测数据库本身效率底下的…我个人非常非常反感在没有经过性能监控和数据的分析而凭空猜测问题的做法。我希望给所有靠凭空想象定位问题的人提个醒,请不要随意对自己不了解的问题定性,因为别人不会把你看做高手,只会对你视而不见。
在找出jbd2的问题之后,看到一些论坛解决方案说是由于linux内核的bug可以选择升级系统内核或者修改内核配置项来解决,也许是对的,但是即使能解决这个问题对我来说成本也很大。我希望大家遇到问题时在利用网络资源的同时结合自己的情况进行进一步分析再选择采用什么解决方案,适合自己的才是最好的。
参考资料:
http://unix.stackexchange.com/questions/86875/determining-specific-file-responsible-for-high-i-o
http://serverfault.com/questions/363355/io-wait-causing-so-much-slowdown-ext4-jdb2-at-99-io-during-mysql-commit
http://blog.itpub.net/22664653/viewspace-1063134/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。