自建Mysql.5.7.17插入速度优化

前言

最近开发同事表示这dev环境的mysql插入怎么这么慢(表字段大概有242个),作为运维,那肯定是不能忍的。于是写了个重复插入,开始测试mysql参数。直到看到了这篇文章。于是乎,借轮子用用。于是对此进行排版。

#于是我自己写了个insert脚本,插入自定义数量的记录,进行测试。
#!/bin/bash
sum=0
switch=true
user=test
pwd=test
start=$(date +%s )

Get_date() {
datetime=$(date +%s )
end=$datetime
}

Insert() {
        sql=`mysql -u$user-$pwd  << EOF
        source /data/test/insert.sql;
        exit
        EOF`
        echo $sql
}

while $switch ;do
sum=$((sum+1))
Insert
[ $sum = 1000 ] &&  $swtich=false
done
Get_date
echo "Insert counts $sum times,expend $(($end-$start)) sec"
#Mysql默认innodb_flush_log_at_trx_commit=1
#原本插入1000条记录,花费138秒

#Counts 1000 times,expend 138 sec
#my.cnf中增加下面参数后重启mysql
innodb_flush_log_at_trx_commit=2

#现在插入1000条记录,花费了9秒钟
#Counts 1000 times,expend 9 sec
#得出结论,插入速度得到大幅度提升。

下面内容是对innodb_flush_log_at_trx_commit的参数的详解。

参数意义

innodb_flush_log_at_trx_commit和sync_binlog 两个参数是控制MySQL 磁盘写入策略以及数据安全性的关键参数。本文从参数含义,性能,安全角度阐述两个参数为不同的值时对db 性能,数据的影响.

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(刷到磁盘)操作。
注意:
	由于进程调度策略问题,这个“每秒执行一次 flush(刷到磁盘)操作”并不是保证100%的“每秒”。

sync_binlog

sync_binlog 的默认值是0,像操作系统刷其他文件的机制一样,MySQL不会同步到磁盘中去而是依赖操作系统来刷新binary log。
当sync_binlog =N (N>0) ,MySQL 在每写 N次 二进制日志binary log时,会使用fdatasync()函数将它的写二进制日志binary log同步到磁盘中去。
注意:
	如果启用了autocommit,那么每一个语句statement就会有一次写操作;否则每个事务对应一个写操作。

根据上述描述,原博做了一张图,可以方便大家查看。
在这里插入图片描述

性能

两个参数在不同值时对db的纯写入的影响表现如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200410094153493.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dheW5lX3ByaW1lcw==,size_16,color_FFFFFF,t_70)

测试场景1

innodb_flush_log_at_trx_commit=2 
sync_binlog=1000

测试场景2

innodb_flush_log_at_trx_commit=1 
sync_binlog=1000

测试场景3

innodb_flush_log_at_trx_commit=1 
sync_binlog=1

测试场景4

innodb_flush_log_at_trx_commit=1
sync_binlog=1000

测试场景5

innodb_flush_log_at_trx_commit=2 
sync_binlog=1000 
场景 TPS
场景1 41000
场景2 33000
场景3 26000
场景4 33000
由此可见,当两个参数设置为双1的时候,写入性能最差,sync_binlog=N (N>1 ) 	
innodb_flush_log_at_trx_commit=2 时,(在当前模式下)MySQL的写操作才能达到最高性能。

安全

当innodb_flush_log_at_trx_commit和sync_binlog  都为 1 时是最安全的,在mysqld 服务崩溃或者服务器主机crash的情况下,binary log 只有可能丢失最多一个语句或者一个事务。但是鱼与熊掌不可兼得,双11 会导致频繁的io操作,因此该模式也是最慢的一种方式。
当innodb_flush_log_at_trx_commit设置为0,mysqld进程的崩溃会导致上一秒钟所有事务数据的丢失。
当innodb_flush_log_at_trx_commit设置为2,只有在操作系统崩溃或者系统掉电的情况下,上一秒钟所有事务数据才可能丢失。

双1适合数据安全性要求非常高,而且磁盘IO写能力足够支持业务,比如订单,交易,充值,支付消费系统。双1模式下,当磁盘IO无法满足业务需求时 比如11.11 活动的压力。推荐的做法是 innodb_flush_log_at_trx_commit=2 ,sync_binlog=N (N为500 或1000) 且使用带蓄电池后备电源的缓存cache,防止系统断电异常。

小结

系统性能和数据安全是业务系统高可用稳定的必要因素。我们对系统的优化需要寻找一个平衡点,合适的才是最好的,根据不同的业务场景需求,可以将两个参数做组合调整,以便是db系统的性能达到最优化。

原博的参考文章

http://dev.mysql.com/doc/refman/5.1/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
http://dev.mysql.com/doc/refman/5.1/en/replication-options-binary-log.html#sysvar_sync_binlog
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章