Mysql复制延迟解决方案

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



            


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

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

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

下面有3个方案,能够参考一下工具

方案一:修改如下2个参数spa

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线程串行执行的方式,变成并行执行,不过此版本还得通过业界验证


下面是个人公众号二维码,欢迎添加