实验环境
此次实验的环境如下
MySQL 5.7.25
Redhat 6.10
操作系统账号:mysql
数据库复制账号:repl
复制格式:基于行的复制
IP地址
主从关系
复制账号
复制格式
11.12.14.29
主库
repl
Row-Based
11.12.14.30
从库(半同步)
repl
Row-Based
11.12.14.31
从库(异步)
repl
Row-Based
通过前面的介绍我们知道MySQL的复制有两种方法
基于二进制日志文件位置
基于GTID
上一节的内容为GTID的生命周期,提到了gtid_next系统变量,当备库接收到主库的GTID事务后,会将gtid_next变量设为该GTID作为下一个需要执行的事务
接下来具体说下这个系统变量
1. gtid_next
我们知道一个新的事务在提交后会被分配一个新的GTID,当该事务在从库上被应用时会保留主库上的GTID
我们可以通过设定gtid_next 的值来改变这种行为
1.1 AUTOMATIC
当设置为AUTOMATIC时(默认值)时,系统会自动分配一个GTID,如果事务回滚或者没有写入到二进制文件时则不会分配
1.2 具体的GTID值
我们可以设置该变量为一个具体的有效的GTID,这时服务器会将该GTID分配给下一个事务,就算该事务没有被写入二进制日志或者为空事务,该GTID也会被分配并加入到gtid_executed变量中
这里需要注意的是,如果该变量值不为AUTOMATIC,我们需要手动的为每个事务指定GTID,否则该事务会失败,你可以将其改为AUTOMATIC,让服务器自动分配,具体可看下面的实验
2. gtid_purged
在gtid_purged系统变量里面的GTID集合是那些已经在服务器上提交的,但已经不存在与二进制日志文件中了
gtid_purged 是gtid_executed的一个子集
存在于该变量里面的GTID主要有如下种类
从库如果禁用二进制日志功能的话,提交的事务会被记录进去
该事务所在的二进制日志文件被清理,可能是人为清理的也可能是自动清理的,自动清理由expire_logs_days参数控制
通过设置GLOBAL.gtid_purged变量手动添加进去的,gtid_purged的值,则该GTID也会被写入到gtid_executed变量里面,即不会被执行,注意只有当gtid_executed为空时才可以手动添加
2.1 mysqldump中的gtid_purged
还记得在mysqldump专题中讲到需要加上--set-gtid-purged=off参数吗,如果不加上的话会在文件中出现set gtid_purged信息
如果这时候用他来还原的话,如果需要还原的库gtid_executed有信息的话是会还原失败的
这时可以通过reset master清除掉gtid_executed信息即可
3. 关于gtid_next的实验
这个实验我们模拟手工设置gtid_next的值,注意该变量是会话级别的
首先查看现在的执行过的GTID值
之后手动设置,首先我们设置为已经执行过的GTID
SET @@SESSION.GTID_NEXT= 'e99ae99a-811d-11e9-9ca2-0050568cef02:9';
会发现执行成功了,但是并没有新增,说明相同的GTID会被忽略
这时我们讲其设为未执行过的GTID,这里我们跳过10和11两个编号
SET @@SESSION.GTID_NEXT= 'e99ae99a-811d-11e9-9ca2-0050568cef02:12;
会发现执行成功并且新增了一行
而且gtid_executed显示的GTID集为1-9:12,有GAP
接下来我们我们试试不设置gtid_next的值看能不能执行成功
会发现报错了,说明我们需要手动设置
最后我们讲值设为自动的
SET @@SESSION.GTID_NEXT='AUTOMATIC';
之后插入几行,发现GTID的GAP补回来了
4. 参考资料
本专题内容翻译自官方文档并结合自己的环境