意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

从库的gtid set为什么会出现gap?

来源:恒创科技 编辑:恒创科技编辑部
2023-12-20 23:08:59
slave_skip_errors概述

mysql在主从复制过程中,由于各种的原因,从服务器可能会遇到执行BINLOG中的SQL出错的情况,在默认情况下,服务器会停止复制进程,不再进行同步,等到用户自行来处理。
slave-skip-errors的作用就是用来定义复制过程中从服务器可以自动跳过的错误号,当复制过程中遇到定义的错误号,就可以自动跳过,直接执行后面的SQL语句。

slave_skip_errors选项有四个可用值,分别为:
off,all,ErorCode,ddl_exist_errors
默认情况下该参数值是off,我们可以列出具体的error code,也可以选择all
一些error code代表的错误如下:

1007: 数据库已存在,创建数据库失败
1008: 数据库不存在,删除数据库失败
1050: 数据表已存在,创建数据表失败
1051: 数据表不存在,删除数据表失败
1054: 字段不存在,或程序文件跟数据库有冲突
1060: 字段重复,导致无法插入
1061: 重复键名
1068: 定义了多个主键
1094: 位置线程ID
1146: 数据表缺失,请恢复数据库
1053: 复制过程中主服务器宕机
1062: 主键冲突 Duplicate entry '%s' for key %d

my.cnf中的写法

slave_skip_errors=1062,1053
slave_skip_errors=all
slave_skip_errors=ddl_exist_errors



从库的gtid set为什么会出现gap?

该参数为全局静态参数,不能动态调整,可在my.cnf中加入该参数列表后重启mysql服务器生效。
必须注意的是,启动这个参数,如果处理不当,很可能造成主从数据库的数据不同步,在应用中需要根据实际情况,如果对数据完整性要求不是很严格,那么这个选项确实可以减轻维护的成本。


GTID SET出现GAP一个bug

这个bug存在于8.0.25最新版本(包括老版本),如果我们设置了slave-skip-errors=all参数后,遇到错误后DDL和DML对于GTID的处理不一致。可能导致slave重启失败。

​DDL :跳过操作,跳过GTID。GTID 不连续。
DML:跳过操作,但是不跳过GTID。GTID 连续。​


另一个bug

并没有设置skip-slave-error参数,那么是其他什么BUG导致的呢?实际上这个BUG是5.7.23以下的版本,

并且设置了replicate_wild_do_table等过滤规则会后对CREATE DATABASE/ALTER DATABASE/DROP DATABASE会过滤掉操作,并且从库的GTID也会被抛弃掉,这样就产生了大量的空洞。

测试验证

选择低于5.7.23的一个版本安装主从复制

从库配置表白名单

replicate_wild_do_table=test.t1                              



版本5.7.20(主库)

Server version: 5.7.20-log MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database test3;
Query OK, 1 row affected (0.00 sec)

mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 1804
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 802e82b5-1efa-11ed-9196-5254000a56df:1-9
1 row in set (0.00 sec)

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> insert into t1 values(3);
Query OK, 1 row affected (0.01 sec)

mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 2057
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 802e82b5-1efa-11ed-9196-5254000a56df:1-10
1 row in set (0.00 sec)

从上面操作可以看到,主库进行create database的操作gtid编号是9,insert到test.t1(也就是我们配置的表白名单)gtid编号是10


版本5.7.20(从库)

mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000003
Position: 600
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 802e82b5-1efa-11ed-9196-5254000a56df:1-3:7-8
1 row in set (0.00 sec)

mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000003
Position: 844
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 802e82b5-1efa-11ed-9196-5254000a56df:1-3:7-8:10
1 row in set (0.00 sec)



从库的gtid set为什么会出现gap?_服务器

主库

从库的gtid set为什么会出现gap?_数据库_02

从库


结论很明显,GTID为9的事务被抛弃了,而insert t1的事务传过来了。因此出现了gtid set的gap。


下面是官网提供的bug地址

​​https://bugs.mysql.com/bug.php?id=88891​​​​https://bugs.mysql.com/bug.php?id=91086​​


上一篇: 教你将多个文件夹复制到指定的文件夹中 下一篇: mysql自连接