mysql主从复制延迟问题记录

时间:2022-07-22
本文章向大家介绍mysql主从复制延迟问题记录,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1、主从复制延迟解决思路

先来看下什么是DDL和DML?

DML(data manipulation language):数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性,常用的语句有select、update、insert、delete

DDL(data definition language):是数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象的定义,常用的语句有create、alter、drop等

两者区别:

DDL是数据定义语言,就是数据库内部的对象进行创建、删除、修改的操作语言

DML只对表内部数据进行操作,而不涉及到表的定义、结构的修改

再来看下主从复制的原理

1)slave服务器上执行start slave,开启主从复制开关 2)此时,slave服务器上的IO线程会通过master服务器上授权的有复制权限的用户,去请求连接master服务器,并请求从binlog日志文件的指定位置之后发送binlog日志内容,日志文件名和位置是在确定主从关系时设置 3)master服务器接收到来自slave服务器的IO线程的请求后,master服务器上的IO线程根据slave服务器的IO线程的请求信息,读取指定binlog日志文件指定位置之后的binlog日志信息,然后返回给slave端的IO线程,返回的信息中除了binlog日志内容外,还有本次返回日志内容后在master服务端的新的binlog文件名以及在binlog中的下一个指定的更新位置 4)当slave服务器的IO线程获取来自master服务器上IO线程发送的日志内容即日志文件和位置点后,将binlog日志内容依次写入到slave端自身的relay log文件(mysql-relay-bin.xxxxxxx)的最末端,并将新的binlog文件名和位置记录到master-info文件中,以便下一次读取master端新binlog日志时,能告诉master服务器需要从新binlog日志的哪个文件哪个位置开始请求新的binlog日志内容 5)slave服务器端的SQL线程会实时监测本地relay log中新增加的日志内容,然后及时的把relay log文件中的内容解析成在master端曾经执行的SQL语句的内容,并在自身slave服务器上按语句的顺序执行应用这些SQL语句,应用完毕后清理应用过的日志 6)经过了上面的过程,就可以确保在master端和slave端执行了同样的SQL语句,当复制状态正常的情况下,master端和slave端的数据是完全一样的

主从不同步的原理

在MySQL5.6版本之前,MySQL的主从复制都是单线程的,主库对所有DDL和DML产生的binlog文件都是顺序写,所以效率很高,slave的Slave_IO_Running线程会到主库读取binlog文件,效率也还可以,而slave的Slave_SQL_Running线程将主库的DDL和DML操作又在slave执行一遍,DML和DDL的IO操作都是随机的,不是顺序的,且sql线程是单线程的,所以成本会很高,另外如果slave上其他查询操作产生的lock争用,或者一个DML语句(大事务、大查询)执行了几分钟,那么所有的DML就会等待这个DML执行完才能继续执行,所以便会导致延迟。

而我们知道master服务器开放多个连接给前端,在大并发的情况下,主库产生的DDL数量超过slave一个sql线程所能承受的范围,或者slave进行了大型的查询操作,这时便会产生延迟。

产生原因

1)主从网络延迟

2)主从机器的硬件配置不同,或从配置低于主

3)主库上有大量写操作,导致从库无法实时重放主库上的binlog日志

4)主库上存在大事务操作或者慢SQL,导致从库在应用主库binlog的过程缓慢,形成延迟

5)数据库实例的参数配置问题,从库开启了binlog,配置了每次事务都去做刷盘操作

如何判断产生延迟

从库上执行 show slave statusG,然后关注几个指标的值做简单的判断

1)查看 Seconds_Behind_Master

该值表示从库上的IO线程和SQL线程相差的时间,然后根据该数值做判断

  • 0:表示无延迟
  • NULL:表示从库上的IO线程和SQL线程中有一个出现问题
  • 大于0:表示主从出现延迟,值越大,延迟越高(可以对该值做监控,设置一个阈值)
  • 小于0:出现bug

2)主库和从库分别执行 show master statusG 和 show slave statusG

先去比较从库上的Master_Log_File 和 Relay_Master_Log_File 文件的差异

  • 有差异,说明主从延迟严重
  • 没差异,则需要进一步对比Read_Master_Log_Pos(表示从库当前读取到的主库的二进制日志文件位置点) 和 Exec_Master_Log_Pos(从库当前已经执行到的位置点) 的差异
  • 如果上面两条都没差异,则对比主库的show master status中的File文件和从库执行show slave status中的Master_Log_File,以及主库上的Position和从库上的Read_Master_Log_Pos

解决思路

1)从配置文件入手

master修改配置文件:  sync_binlog = 1    innodb_flush_log_at_trx_commit = 1

slave修改配置文件:   sync_binlog = 0    innodb_flush_log_at_trx_commit = 0

另外slave的binlog可以关闭,主从两台机器在设计之初尽量选择配置一样的。或者从的配置高一些的

2)从架构入手

增加从服务器,可以设置一主多从的架构,且取其中一台从库只做备份,不进行其他的任何操作

3)升级MySQL版本

MySQL5.7已经做到了并行复制,所以此后的版本,复制延迟问题永不存在。

mysql5.7 配置并行复制的方法

首先主库需要修改两个值,如下

mysql> show global variables like '%group_commit%';
+-----------------------------------------+-------+
| Variable_name                           | Value |
+-----------------------------------------+-------+
| binlog_group_commit_sync_delay          | 0     |
| binlog_group_commit_sync_no_delay_count | 0     |
+-----------------------------------------+-------+
2 rows in set (0.00 sec)
mysql> show global variables like '%group_commit%';
+-----------------------------------------+-------+
| Variable_name                           | Value |
+-----------------------------------------+-------+
| binlog_group_commit_sync_delay          | 0     |
| binlog_group_commit_sync_no_delay_count | 0     |
+-----------------------------------------+-------+
2 rows in set (0.00 sec)
mysql> show global variables like '%group_commit%';
+-----------------------------------------+-------+
| Variable_name                           | Value |
+-----------------------------------------+-------+
| binlog_group_commit_sync_delay          | 0     |
| binlog_group_commit_sync_no_delay_count | 0     |
+-----------------------------------------+-------+
2 rows in set (0.00 sec)
master-info-repository = table
relay-log-info-repository = table
relay-log-recovery = ON