记一次MYSQL IO优化经历
转自:http://www.runingman.net/index.php/2016/07/27/ji_yi_ci_mysql_io_you_hua_jing_li/
问题出现在渠道方给我的服务器均是自建机房的服务器,以前所有线上的服务器均为阿里云服务器(都经过io优化的),拿到服务器整个流程走下来,系统联调所有的功能均正常,因为系统所有的依赖服务都做成了docker镜像(防止部署环境因人为因素出现事故)所以整套系统部署下来系统性能理论上只跟物理机的配置有关(cpu,内存,磁盘io,网络带宽等),功能验证完成之后上线前压测,压测流量跑到正常压测流量的一半时发现系统出现性能抖动,请求超时,通过使用top命令查看cpu,内存,带宽占用均属于正常范围,渠道方给的机器配置上几乎是线上服务器的两倍,怎么着也不会一半的压测流量都杠不住,带着疑惑仔细分析除了这些影响性能的因素就只剩下磁盘io了,于是乎我上网搜了一个查看系统io占用的神器iotop,安装命令如下:
yum install iotop(需要注意的是iotop是用python写的,不支持python2.7+)
通过命令输出发现系统压测过程中磁盘io占用一直都是99%左右居高不下,难怪系统会出现请求超时,可疑进程包括mysql和jbd2,通过google这两个关键字发现了一个mysql优化相关的配置选项innodb_flush_log_at_trx_commit,遂继续google innodb_flush_log_at_trx_commit描述如下:
innodb_flush_log_at_trx_commit的设置的内容,下面是详细介绍。
0:日志缓冲每秒一次地被写到日志文件,并且对日志文件做到磁盘操作的刷新,
但是在一个事务提交不做任何操作。
1:在每个事务提交时,日志缓冲被写到日志文件,对日志文件做到磁盘操作的
刷新。
2:在每个提交,日志缓冲被写到文件,但不对日志文件做到磁盘操作的刷新。
对日志文件每秒刷新一次。网易技术部 67
默认值是 1,也是最安全的设置,即每个事务提交的时候都会从 log buffer 写
到日志文件,而且会实际刷新磁盘,但是这样性能有一定的损失。如果可以容忍在数
据库崩溃的时候损失一部分数据,那么设置成 0 或者 2 都会有所改善。设置成 0,则
在数据库崩溃的时候会丢失那些没有被写入日志文件的事务,最多丢失 1 秒钟的事
务,这种方式是最不安全的,也是效率最高的。设置成 2 的时候,因为只是没有刷新
到磁盘,但是已经写入日志文件,所以只要操作系统没有崩溃,那么并没有丢失数据 ,
比设置成 0 更安全一些。
在 mysql 的手册中,为了确保事务的持久性和复制设置的耐受性、一致性,都是
建议将这个参数设置为 1 的。
而且
1:普通硬盘情况下,innodb_flush_log_at_trx_commit参数分别是1和2的情况,两者差别巨大,差异几乎到了9倍。
2:在做了raid的情况下,innodb_flush_log_at_trx_commit参数分别是1和2的情况,两者有10%左右的差异。
3:硬盘的IO性能对性能的影响是巨大的。
后来我到网上找到两条测试磁盘读写性能的命令发现,渠道方给我的机器磁盘确实是普通磁盘,读取速度还行,写入速度简直龟速,命令如下:
1 磁盘连续写入测试(268MB)
dd if=/dev/zero of=kwxgd bs=64k count=4k oflag=dsync
2 磁盘连续读取测试(268MB)
dd if=kwxgd of=/dev/zero bs=64k count=4k iflag=direct