Mysql复制延迟解决方案

        自从软件开源火爆互联网之后,一些开源数据库也越来越受到大家关注和重视,自从阿里去IOE之后,更是全面推广开源数据库Mysql,替换商业数据库Oracle,经过经过双11的洗礼,已证明Mysql的稳定性和可靠性,这也引发了大批互联网公司使用Mysql,例如小米科技,360,美团,58同城等,下面一张图是2016年数据库使用排名,可以看出Mysql已经成为排名第二,距离第一已经是一步之遥



            Mysql复制延迟解决方案_第1张图片


        当然在使用Mysql数据库时,也会碰到一些问题,复制延迟就是最常见的。例如在市场搞促销,双11,双12等等,导致业务数据剧增,Mysql复制处理超载,就会出现延迟,而一旦出现延迟,在有些场景就会导致用户体验下降,例如:用户订单已付款,由于读写分离和mysql复制延迟,导致用户订单状态显示未付款。

        要想解决复制延迟,就得先了解复制原理,Mysql的复制其实是有2个进程在处理,一个是IO线程,一个是sql线程,IO线程主要负责拉取binlog日志,这个进程不会出现瓶颈,sql线程则需要读取日志,并解析成sql去执行,复制延迟一般出现在sql线程执行上,这就好比有上千人在家乐福同时购物,最后收银台确实只有一个,这样肯定需要排队,一段排队,就会产生延迟。

         那怎么解决复制的问题呢?

下面有3个方案,可以参考一下

方案一:修改以下2个参数

sync_binlog=0

innodb_flush_log_at_trx_commit=2

在调整上述参数之前,先解释一下mysql中这2个参数作用

     sync_binlog=0,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘。

     sync_binlog=n,当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。

     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(刷到磁盘)操作。

       上述2个参数是通过调整mysql事物提交速度,去提升复制效率的,当然这个方法是牺牲数据安全为代价的,这种方式也是在被逼无奈的情况下使用。

        

方案二:开发一套预热工具

sql线程解析出来的日志,基本都是update,insert,delete语句,insert语句自不说,update和delete语句怎么提升执行效率呢?

      那得先看看update在数据库中执行的过程,首先数据库得先去缓冲区看看涉及的数据块存不存在,如果不存在,则会去磁盘上读取,加载到缓冲区,这样就会产生一个物理IO,如果数据块在缓冲区存在,则直接从缓冲区读取,只会有一个逻辑IO,物理IO和逻辑IO的区别就在于,一个从磁盘读取,一个从内从读取,速度相差10倍以上

      按照这个思路,就是开发一套程序,去解析binlog日志,并将update,delete转换成select语句,预热要使用的数据块,加快sql线程执行sql语句的效率,提升复制效率,降低复制延迟


方案三:使用mysql5.7

     官方发布的mysql5.7版本已经支持并行复制,原来的sql线程串行执行的方式,变成并行执行,不过此版本还得经过业界验证


下面是我的公众号二维码,欢迎添加


你可能感兴趣的:(mysql)