mysql同步(复制)延迟的缘由及解决方案

同步延迟的本质

当从库跟不上主库的更新进度时就会出现同步(复制)延迟,这时在从库里,未同步的修改在relay_log里出现堆积,数据的版本也会渐渐跟主库差异愈来愈大。mysql

同步延迟的缘由

为了肯定延迟的缘由,咱们须要肯定是哪一个复制线程出现问题了。在mysql中,一对主从同步的链接依赖三个不一样的线程,其中两个由从库建立,一个由主库建立。sql

  • 从库的I/o线程:当你在从库经过Start Slave命令配置了主库同步信息后,这个线程就会被从库建立。用来请求主库binlog日志的备份
  • 主库的Bin log Dump线程: 当从库连上主库后,这个线程就会被建立,而后会将其binlog发送给从库。
  • 从库Slave SQL 线程: 从库建立这个线程,而后从获取的binlog里读取内容并应用。

同步延迟的解决方案

当I/O线程或SQL线程没法处理对其提出的要求时,会致使复制延迟。网络

I/O线程可能出现的问题

  1. 网络较慢
  2. 传输数据量较大
  3. 一个主从对中,binlog的读是串行的,而写是并行的

I/O线程可能出现的问题解决方案

  1. 针对1.2.开启slave_compressed_protocol选项进行数据压缩
  2. 针对3.库级别并行读

SQL线程可能出现的问题

  1. 语句没有优化或者不合适形成从库同步很慢,若有不少长时事务或太多IO活动
  2. 使用Row/Mixed格式时,从库的表没有primary key也会有问题。

SQL线程可能出现的问题解决方案

  1. 减小长时事务或IO
  2. 检查主、从库是否都有primary key

如何查看哪一个线程出现了问题

binlog文件名和位置的同步方式

此种同步方式下使用Show master statusshow slave statue命令能够查看你须要的信息,好比: Show master status命令看到的:oracle

  • 经过postion-Read_Master_Log_Pos得到你的IO线程落后主库日志的字节数
  • 经过postion-Exec_Master_Log_Pos得到你的SQL线程落后主库日志的字节数
  • 经过Read_Master_Log_Pos-Exec_Master_Log_Pos得到你的SQL线程落后IO的字节数 Show slave status命令看到的:
  • seconds_behind_master能够参考落后主库的秒数,不过不要过分依赖它,由于它的统计方式不是很准确

GTIDs同步方式

诊断所用指标(show slave status)

  • Executed GTIDs: 主从库上都能看到,返回执行的事务的id。也能够经过查询全局变量gtid_executed来获取最近执行的事务id
  • Retrieved GTIDs:只有从库上能够看到,用来返回IO线程获取的事务id
  • Purged GTIDs:显示从binlog清除了哪些已经执行完的事务。通常你只会对从库中的这个日志感兴趣

得到GTID后,你能够使用GTID_SUBTRACT()函数计算从库与主库的差别。例如,如下对从库查询显示从二进制日志中读取的还没有应用的GTID(SQL线程延迟):ide

slave> SELECT GTID_SUBTRACT('96985d6f-2ebc-11e7-84df-08002715584a:5-133', 
        '96985d6f-2ebc-11e7-84df-08002715584a:26-132') AS MissingGTIDs;
+-----------------------------------------------+
| MissingGTIDs                                  |
+-----------------------------------------------+
| 96985d6f-2ebc-11e7-84df-08002715584a:5-25:133 |
+-----------------------------------------------+
1 row in set (0.00 sec)
复制代码

GIIDs方式简介

经过GTIDs【global transaction identifiers】,能够标识每个事务,而且能够在其一旦提交追踪并应用于任何一个Slave上;这样 就不须要像BinaryLog复制依赖Log file 和位置。GTIDs彻底基于事务,只要在Master提交的全部事务都在Slave上进行了Commit,那么就能保证Master和Slave之间的数据 一致性。你能够使用基于SBR或RBR的GTIDs来实现。推荐使用RBR【Row-based replication】.函数

参考

What Causes Replication Lag?post