A和A' 互为主备,从库B、C、D指向A,当A出问题后,B、C、D也需要重新指向A',切换复杂性也随之增加。
将节点B设置为A'的从库时,需要执行chang master 命令:
CHANGE MASTER TO
MASTER_HOST=$host_name #A'的IP
MASTER_PORT=$port #A'的端口
MASTER_USER=$user_name #A'的用户名
MASTER_PASSWORD=$password #A'的密码
MASTER_LOG_FILE=$master_log_name #A'的对应日志文件
MASTER_LOG_POS=$master_log_pos # A'的日志同步开始的位置(即同步位点,也就是日志偏移量)
那么就需要:
mysqlbinlog File --stop-datetime=T --start-datetime=T
set global sql_slave_skip_counter=1;
start slave;
slave_skip_error = "1032,1062"
上面方法虽然可以解决问题,但是操作复杂,易出错。 GTID:Global Transaction Identifier,事务提交的时候生成,是事务唯一标识。
一个 current_id 只能分配给一个事务,执行下一个事务时,需要使用 set 命令,设置 gtid_next 为另一个 gtid 或 automatic。
将 B 设置为 A` 的从库语法如下:
CHANGE MASTER TO
MASTER_HOST=$host_name
MASTER_PORT=$port
MASTER_USER=$user_name
MASTER_PASSWORD=$password
master_auto_position=1
master_auto_position=1 表示 主备关系使用的是 GTID 协议。
1. B 指定 A',基于主备协议建立连接
2. 实例B把 set_b 发给 A'(set_b 为 B 的 GTID 集合)
3. A' 算出 set_a 与 set_b 的差集,也就是存在于 set_a 但不存在于 set_b 的 GTID 的集合。判断 A' 本地是否包含了这个差集需要的所有 binlog 事务。
a. 如果不包含,表示 A' 已经把 B 需要的 binlog 给删掉了,直接返回错误;
b. 如果确认全部包含,A' 从自己的 binlog 文件里面,找出第一份不在 set_b 的事务,发给B;
4. 从该事务开始往后读文件,按顺序取 binlog 发给 B 去执行。
问题:业务高峰期,在线增加索引,双 M 结构中,备库Y执行的 DDL 语句也会传给主库X,需要通过 set sql_log_bin = off 关掉binlog,避免对主库X造成影响。但是,这时 binlog 没有记录下这个更新,会导致数据和日志不一致。使用 GTID 则可以避免这种尴尬。
X、Y都打开了 GTID 模式,主备切换流程:
set GTID_NEXT="server_uuid_Y:gno"
begin;
commit;
set gtid_next=automatic;
start slave;
这样,既可以让实例 Y 的更新有 binlog 记录,同时也可以确保不会在实例 X 执行这条更新。
你在 GTID 模式下设置主从关系的时候,从库执行 start slave 命令后,主库发现需要的 binlog 已经被删除掉了,导致主备创建不成功。这种情况下,你觉得可以怎么处理呢?
show global variables like 'gtid_purged'
,set global gtid_purged =''
,指定从库开始同步的 gtid 位置,binlog 缺失的那部分数据,在从库上就会丢失,造成主从不一致。如果数据库已经完成了很多事物,GTID 集合是不是会很大?GTID 是如何从 binlog 解析出所有事务的?
本文为Larwas原创文章,转载无需和我联系,但请注明来自larwas博客 https://larwas.com
最新评论