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
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- 文本处理三剑客之—awk
- Python办公自动化|批量提取Excel数据
- 3分钟短文 | 有挑战!PHP用1个函数实现post请求,你用哪个?
- linux 磁盘管理
- linux 安装各个版本nodejs
- python3 使用cookie模拟post实现修改活码内容
- VIM 创建程序文件自动添加头部注释
- 【简记】Linux 计划任务 Crontab
- VS Code 免密登录Linux服务器
- Linux部署私钥实现免密登录
- 搭建Jenkins+tomcat+maven+Gitlab持续部署/回滚系统
- Java--注解
- 如何在 Ubuntu 20.04 上安装 Jenkins
- 在 Linux 下如何检查内存使用率
- 3分钟短文 | MySQL存时间,到底该用timestamp还是datetime?