今天遇到一个关于从库gtid有间隙的问题
问题1:发现从库的gtid集合存在间隙,是什么原因产生的!
一、问题现象,如下所示:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table: emp.%
Replicate_Wild_Ignore_Table:
Master_UUID: 192cb19f-1a3e-11ed-a619-005056b6e3a1
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Retrieved_Gtid_Set: 192cb19f-1a3e-11ed-a619-005056b6e3a1:1-
421996 #你设置了只同步个别库,但是也是全量拉取binlog,所以这里是连续的!
Executed_Gtid_Set:
192cb19f-1a3e-11ed-a619-005056b6e3a1:1-419859:419861-421996, #应用的时候可能有间隙!
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
mysql>
二、问题分析:
主库执行了:create database compattarn_yl; 但是从库设置Replicate_Wild_Do_Table: emp.%,选择只同步emp库,所以从库在应用relay log的时候,没有应用create database compattarn_yl,于是选择跳过,进而产生了一个间隙,原因是你没有设置库级别的过滤,如果你设置的是Replicate_Do_DB或者Replicate_Ignore_DB这类库级别的过滤,这个时候你create database的时候,就不会产生间隙了!
三、问题解决:把间隙设置一个空事务,补进slave的gtid集合中
1、停止slave进程
mysql> STOP SLAVE; 只要停止stop sql thread即可!
2、设置事务号,事务号从Retrieved_Gtid_Set获取,前面的所示间隙为:
192cb19f-1a3e-11ed-a619-005056b6e3a1:419860
在session里设置gtid_next,即跳过这个GTID,
mysql> SET @@SESSION.GTID_NEXT= '
192cb19f-1a3e-11ed-a619-005056b6e3a1:419860'
3、设置空事物
mysql> BEGIN; COMMIT;
4、恢复事物号
mysql> SET SESSION GTID_NEXT = AUTOMATIC;
5、启动slave进程
mysql> START SLAVE;
问题2,如果从库产生了gtid间隙,那么当你在从库上reset slave all,从新change的时候,就可能会有问题!
一、问题描述:
因为某个原因从库应用gtid的时候产生了间隙,那么当你需要切换master的时候,例如从change master1切换到change master2,这个时候你需要在从库执行如下操作:
1)stop slave;
2) reset slave all ;
3)change master to master2;
4)start slave;
但是发现报错:如下所示
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_Running: No
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Seconds_Behind_Master: 0
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name: master_21115
Master_TLS_Version:
1 row in set (0.00 sec)
二、问题分析:
因为当你第一次change to ,并且start slave的时候,slave会把他自己的执行过的gtid集合(也就是SET @@GLOBAL.GTID_PURGED的gtid集合 )发送给master,并和master执行过的gtid集合做对比,然后找到差异的,这时候就会把间隙也当做差异,slave会认为差异的gtid也需要从master拉取对应的binlog, 但是这个binlog已经被master purge了,不存在了,于是就报错了
the master has purged binary logs containing GTIDs that the slave requires;
注意如果你是正常的stop slave+start slave,那么这个时候slave不会尝试去找间隙的gtid,因为他relay log中已经有所有的gtid,所以不需要从新拉一次binlog了,而reset slave all会清空所有的relay log;
三、
解决办法:去掉从库间隙,不去master再要这个gtid了
方法1:直接设置一个空事务即可,推荐使用;
1、停止slave进程
mysql> STOP SLAVE; 只要停止stop sql thread即可!
2、设置事务号,事务号从Retrieved_Gtid_Set获取,前面的所示间隙为:
192cb19f-1a3e-11ed-a619-005056b6e3a1:419860
在session里设置gtid_next,即跳过这个GTID,
mysql> SET @@SESSION.GTID_NEXT= '
192cb19f-1a3e-11ed-a619-005056b6e3a1:419860'
3、设置空事物
mysql> BEGIN; COMMIT;
4、恢复事物号
mysql> SET SESSION GTID_NEXT = AUTOMATIC;
5、启动slave进程
mysql> START SLAVE;
方法2:
1)stop slave;
2)在从库查看当前gtid的集合,发现从库应用主库的gtid集合有间隙(gid=
419860),如下所示
show master status;
192cb19f-1a3e-11ed-a619-005056b6e3a1:1-419859:419861-421802,
3)reset master ;
4) 去掉间隙,改成如下所示的样子,
SET @@GLOBAL.GTID_PURGED='
192cb19f-1a3e-11ed-a619-005056b6e3a1:1-421802';
5)start slave;
题外话:
1、如果主库执行了reset master;
那么从库需要执行reset slave all,然后从新change下,否则报错找不到master的binlog, 因为主库reset master会清空binlog文件,并且binlog序号从1开始!所以slave需要reset slave all
2、如果master包含两个gtid,一个是实时用的,一个是静态的或者说是无用的,
如下所示:
MySQL [(none)]> show master status\G
*************************** 1. row ***************************
File: mysql-bin.002969
Position: 229787697
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 09029e35-2fe0-11eb-a5b5-7cd30ae00c02:1-3, #这个是由于某种原因产生的一个无用的gtid,或者说静态gtid
712270d9-9864-11eb-8f3f-7cd30ac477f4:1-2478794562 #这个是本实例实时写入的gtid,每写一个事务,该gtid就会加1
这个时候,如果你需要搭建从库,需要保证在slave上设置SET @@GLOBAL.GTID_PURGED=master的两个gtid,否则slave也会报错
the master has purged binary logs containing GTIDs that the slave requires,
除非master当前写的binlog中包含另一个静态gtid全部事务,换句话说就是只会在当前写的binlog文件中去找是否有slave需要的那个静态gtid集合,如果有就拉取,如果没有就报错;但是如果slave需要找的是实时用的gtid事务,这个事务没有在当前写的binlog文件中,这时候不会报错,他会去之前的binlog文件中找到需要的gtid;
3、relay_log_recovery参数
Enables automatic relay log recovery immediately following server startup. The recovery process creates a new relay log file, initializes the SQL thread position to this new relay log, and initializes the I/O thread to the SQL thread position. Reading of the relay log from the master then continues.
现在我们考虑一个问题,假设当从库意外宕机后,同时从库的relay log也一起损坏了,而主库的日志已经传到了从库,只是从库还没有来得及应用这些日志,那么从库该如何处理?
1) 在从库中将relay_log_recovery不设置或者设置为off,如果碰到上面的情形,从库会丢失那些没有应用的日志,主从会不一致。
2)在从库中将relay_log_recovery设置为on,假如果碰到上面的情形,从库会自动放弃所有未执行的relay log,重新生成一个relay log,并将从库的io线程的position重新指向新的relay log。并将sql线程的position退回到跟io线程的position保持一致,重新从新的postion开始拉取binlog并开始同步,(
其实就是从crash时应用的binlog点位开始从新再次拉取binlog,然后sql线程回退到这个点位)这样在从库中事务不会丢失。这个参数建议开启。
编辑推荐:
- mysql从库gtid间隙问题03-01
- 事务的概述03-01
- 数据库表设计三范式03-01
- 干货好文 | 初探MySQL迁移到ClickHouse03-01
- Centos下安装mariaDB方法03-01
- MySQL 崩溃恢复过程分析03-01
- 2017-03-25 ACMUG阳春三月深圳行纪要03-01
- 移动应用安全常用组件Soot、Flowdroid简介&基本使用03-01
下一篇:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- 干货好文 | 初探MySQL迁移到ClickHouse
干货好文 | 初探MySQL迁移到ClickHouse
26-03-01 - Centos下安装mariaDB方法
Centos下安装mariaDB方法
26-03-01 - MySQL 崩溃恢复过程分析
MySQL 崩溃恢复过程分析
26-03-01 - 移动应用安全常用组件Soot、Flowdroid简介&基本使用
移动应用安全常用组件Soot、Flowdroid简介&基本使用
26-03-01 - 一条 sql 了解 MYSQL 的架构设计
一条 sql 了解 MYSQL 的架构设计
26-03-01 - Topling 又双叒叕送福利啦!!!
Topling 又双叒叕送福利啦!!!
26-03-01 - 移动硬盘变本地硬盘怎么办,移动硬盘变本地硬盘找到办法
移动硬盘变本地硬盘怎么办,移动硬盘变本地硬盘找到办法
26-03-01 - mysql字符集
mysql字符集
26-03-01 - Docker-Compose实现Mysql主从
Docker-Compose实现Mysql主从
26-03-01 - OceanBase社区版4.0正式上线,2分钟内可完成快速部署
OceanBase社区版4.0正式上线,2分钟内可完成快速部署
26-03-01
