主备切换
基于位点的主备切换
当我们把节点B设置成节点A’的从库的时候,需要执行一条change master命令:
CHANGE MASTER TO
MASTER_HOST=$host_name
MASTER_PORT=$port
MASTER_USER=$user_name
MASTER_PASSWORD=$password
MASTER_LOG_FILE=$master_log_name
MASTER_LOG_POS=$master_log_pos
最后两个参数MASTER_LOG_FILE和MASTER_LOG_POS表示,要从主库的master_log_name文件的master_log_pos这个位置的日志继续同步。而这个位置就是我们所说的同步位点,也就是主库对应的文件名和日志偏移量。
取位点的方法
1.等待新主库A’把中转日志(relay log)全部同步完成;
2. 在新主库上执行show master status 命令得到新主库上的file 和position;
- 获取原主库上的故障时刻T;
- 用mysqlbinlog工具分析新主库的file,得到T时刻的位点
位点的执行情况不一定是没有正确执行过的,所以通常情况下做切换任务的,需要跳过可能出现错误的情况(出现错误同步会停止)。可以通过以下方法避免:
- 一种做法是,主动跳过一个事务。每次碰到这些错误就停下来,执行一次跳过命令,直到不再出现停下来的情况,以此来跳过可能涉及的所有事务。
# 跳过命令的写法:
set global sql_slave_skip_counter=1;
start slave;
-
通过设置slave_skip_errors参数,直接设置跳过指定的错误。
- 在执行主备切换时,有这么两类错误,是经常会遇到的:
- 1062错误是插入数据时唯一键冲突;
- 1032错误是删除数据时找不到行。
- 因此,我们可以把slave_skip_errors 设置为 “1032,1062”,这样中间碰到这两个错误时就直接跳过。执行一段时间之后,我们还需要把这个参数设置为空,以免之后真的出现了主从数据不一致,也跳过了。
- 在执行主备切换时,有这么两类错误,是经常会遇到的:
GTID
概念
GTID的全称是Global Transaction Identifier,也就是全局事务ID,是一个事务在提交的时候生成的,是这个事务的唯一标识。每个MySQL实例都维护了一个GTID集合,用来对应“这个实例执行过的所有事务”。
gtid_executed,已经执行的gtid集合(gtid-sets)。gtid_purged,已经清除的gtid集合。
组成
它由两部分组成,GTID=server_uuid:gno
- server_uuid是一个实例第一次启动时自动生成的,是一个全局唯一的值;
- gno是一个整数,初始值是1,每次提交事务的时候分配给这个事务,并加1。
使用
GTID模式的启动也很简单,我们只需要在启动一个MySQL实例的时候,加上参数gtid_mode=on和enforce_gtid_consistency=on就可以了。
在GTID模式下,每个事务都会跟一个GTID一一对应。这个GTID有两种生成方式,而使用哪种方式取决于session变量gtid_next的值。
- gtid_next=automatic,代表使用默认值。MySQL就会把server_uuid:gno分配给这个事务。mysql在记录binlog的时候,先记录一行 SET @@SESSION.GTID_NEXT=‘server_uuid:gno’; 然后把这个GTID加入本实例的GTID集合
- gtid_next是一个指定的GTID的值,指定GTID已经存在于实例的GTID集合中,接下来执行的这个事务会直接被系统忽略; 没有存在于实例的GTID集合中,就将这个current_gtid分配给接下来要执行的事务,也就是说系统不需要给这个事务生成新的GTID,因此gno也不用加1。
基于GTID的主备切换
在GTID模式下,备库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协议。