MySQL5.7 传统复制和GTID复制间的在线互相切换
一、传统复制切换为GTID复制
主/从库执行
1.SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;
持续观察MySQL错误日志一段时间,看是否有违反gtid 一致性的报错,像create table ... select 的语句是不支持的。这个时候只能做业务上的调整来满足gtid 一致性的要求,只有语句都满足了,才能继续进行一下步。
主/从库执行
2.SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;
主/从库执行
3.SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
新产生是匿名事务,slave可以识别匿名事务和gtid事务
主/从库执行
4.SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
新产生是gtid事务,slave可以识别匿名事务和gtid事务,到这一步要确保没有匿名事务产生了再进行下一步的操作,查看方法为:
SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
当值为0就表示可以进行一下操作了。
主/从库执行
5.SET @@GLOBAL.GTID_MODE = ON;
新产生是gtid事务,slave只识别gtid事务,这一步执行完主/从就都开启了gtid了。要想配置重启继续生效,将两个参数写入MySQL的配置文件中:
enforce_gtid_consistency=on
gtid_mode=on
从库执行
STOP SLAVE [FOR CHANNEL 'channel'];
CHANGE MASTER TO MASTER_AUTO_POSITION = 1 [FOR CHANNEL 'channel'];
START SLAVE [FOR CHANNEL 'channel'];
二、GTID复制切换为传统复制
从库执行
1. STOP SLAVE [FOR CHANNEL 'channel'];
等待完这步后,需要查看当前slave读取的文件及位置,传统复制需要基于这两个值继续同步。查看方法就是查看show slave status\G中的两个参数:
Relay_Master_Log_File:file #表示 sql_thread已经应用到了哪个文件
Exec_Master_Log_Pos:position #表示 sql_thread已经执行到了文件的哪个位置
2.CHANGE MASTER TO MASTER_AUTO_POSITION = 0, MASTER_LOG_FILE = file, \
MASTER_LOG_POS = position [FOR CHANNEL 'channel'];
3.START SLAVE [FOR CHANNEL 'channel'];
主从库执行
4.SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;.
主从库执行
5.SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
执行完这步后需要确认没有新gtid事务产生
官方文档上的方法:SELECT @@GLOBAL.GTID_OWNED;只要确保主从上有一个值为空就行。
另外也可以根据从上的两个参数是否不再更新来判断:
Retrieved_Gtid_Set: #已经获取到的gtid集合
Executed_Gtid_Set: #已经执行了的gtid集合
主从库执行
6.SET @@GLOBAL.GTID_MODE = OFF;
主从库执行
7.将配置写入配置文件
enforce_gtid_consistency=off
gtid_mode=off
三、基于GTID复制怎么跳过一个事务
基于GTID的复制无法使用sql_slave_skip_counter跳过错误,可以利用替换空事务的方法来处理。
从库执行:
1.停止slave,并注入空事务
STOP SLAVE [FOR CHANNEL 'channel'];
SET GTID_NEXT='aaa-bbb-ccc-ddd:N'; #需要跳过的事务的gtid
BEGIN;
COMMIT;
SET GTID_NEXT='AUTOMATIC';
START SLAVE [FOR CHANNEL 'channel'];
从库执行
2.刷新并清理binlog文件
FLUSH LOGS; #会生成一个新的binlog文件
PURGE BINARY LOGS TO 'master-bin.00000N'; #N表是最新的binlog文件
这么做的用意在于防止将来slave提升为master的时候这个问题事务继续传播。
四、基于GTID复制,将slave切换为Master
1.确保主上不再有数据更新
flush table with read lock; #会话级的,断开会话就失效了。
或
set global read_only=1; #重启失效
set global super_read_only=1
2.检查主从是否完全同步了
Master:show master status\G;
Slave:show slave status\G;
3.从库(新的主库)
STOP SLAVE;
RESET SLAVE ALL;
4.主库(新的从库)
CHANGE MASTER TO MASTER_AUTO_POSITION = 0, MASTER_LOG_FILE = file, \
MASTER_LOG_POS = position [FOR CHANNEL 'channel'];
写在最后:
本文只是基于官方文档及自己在用的过程的一些总结,英文好的可以直接去看官方文档。如果写的有错的地方也欢迎吐槽。基于Gtid的复制维护起来还是很方便的,不再需要关心binlog file及position了。slave会向Master上报它已经执行的gtid,Master会将剩余的gtid发给Slave去执行。为了防止在从上误操作导致主从的数据不一致,从最好还是设置为只读,在Slave的配置文件中加入两个参数:
super_read_only=1
read_only=1
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341