一主多从的主备切换
author:陈镇坤27
创建时间:2021年12月7日00:59:34
编辑时间:2021年12月9日11:49:11
转载请注明出处
文章目录
————————————————————————————————
问:MySQL的主备主从结构当中,备库和从库的区别是什么?
答:备库和从库都设置只读, 但从库对外接收客户端访问,而备库只对主库接收访问。备库的作用是当主库发生故障时做备用。
基于位点的主备切换
问:你知道什么是基于位点的主备切换吗?简单介绍下如何做。
答:基于位点的意思,是指为从库指定新的主库时,同步的binlog由用户手动设置的主库binlog对应位置开始同步,因此叫做基于位点的主备切换。
过程:进入从库,执行下列命令(下面是一行连贯的命令)
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分别代表要开始同步的主库的binlog文件和该文件的POS偏移量。
问:知道主库最新binlog 的位点,可以让从库通过位点同步的方式,从最新的binlog位置开始同步吗?
答:不可以,因为同样的pos位置可能对应的日志不一样,这其中的原因就包含了日志并行复制的原理。
问:怎么确定从库需要同步的对应主库binlog位点呢?
答:根据时间点来进行复制。某一时刻主库的的日志节点对应从库某一时刻的日志,若主库在事务提交完成,转储日志到从库和备库完后,立即发生故障掉电,则故障时间节点下,从库实现了日志同步。在等待备库的中转日志消费完毕后,备库的日志会比故障时间节点多N条(中转日志上刚刚同步好的),从库与该新主库日志根据故障时间节点进行同步,理论上会发生数据主键重复的错误(如果是statement格式不会,但不要用statement!),进而中止同步,此时,通过下列sql指令
set global sql_slave_skip_counter=1;
start slave;
可跳过此错误,并继续执行同步(每次都需要手动跳过错误)。
也可以通过slave_skip_errors参数,设置“指定的错误发生时,进行跳过”,这里指定的错误,大多数场景是:
1062 错误是插入数据时唯一键冲突;
1032 错误是删除数据时找不到行。
set slave_skip_errors = 1062,1032
PS:主备切换完毕后,记得将该slave_skip_errors参数设为默认值!
GTID
问:什么是GTID?
答:MySQL5.6引入GTID,全称Global Transaction Identifier,与在过去学习时了解到的事务生成时由系统分配的事务id不同的是,GTID是在事务提交那一刻生成。GTID单调递增。
格式:
GTID=source_id:transaction_id
source_id是MySQL实例,全局唯一。
GTID由session变量gtid_next决定生成的形式。
方式一:若gtid_next=automatic,则由MySQL来进行事务分配。
set @@SESSION.GTID_NEXT = ‘source_id:transaction_id’;
再将该GTID加入本MySQL实例的GTID集合中。
方式二:若gtid_next=‘指定的值’,则同步日志时,若发现该GTID已经存在本MySQL实例的GTID集合中,则自动忽略,否则,将该GTID插入到本实例的GTID集合中。此后,若要继续同步事务,需要设置gtid_next=automatic
问:GTID与事务生成时获得的事务id有什么区别?
答:前者是事务提交时生成,具有连贯性;后者回滚后,事务依旧在前者的基础上进行单调递增, 因此事务id可能非连贯。
问:怎么利用GTID的特点来解决日志同步时的重复日志数据更新报错问题?
答:将重复的日志对应的GTID加入到从库的MySQL实例的GTID集合中。
set gtid_next='aaaaaaaa-cccc-dddd-eeee-ffffffffffff:10';
begin;
commit;
set gtid_next=automatic;
start slave;
基于GTID的主备切换
问:介绍下基于GTID的主备(从库设置备库为新主库)切换方式的步骤。
答:
CHANGE MASTER TO
MASTER_HOST=$host_name
MASTER_PORT=$port
MASTER_USER=$user_name
MASTER_PASSWORD=$password
master_auto_position=1
其中,master_auto_position代表同步时,主备间采取的是GTID协议。
问:基于GTID的主备(从库设置备库为新主库)切换过程中,底层逻辑流程是什么?
答:
1)从库与新备库建立连接;
2)从库将本实例GTID集合发给新备库;
3)新备库根据本实例GTID和接收到的GTID集合,计算差集,并按差集实际顺序的第一条开始,向从库转储binlog;
4)从库同步日志,若日志对应GTID在本实例GTID集合中已存在,则跳过。
PS:从库同步后,其GTID集合为:旧主库的GTID集合+新主库的GTID集合,新主库也同样如此。
实战
问:一个MM结构的主备库,若进行大表的DDL,除了停止binlog服务之外,可以利用GTID怎么做?
答:在主库上,执行stop slave(停止接收从库的转储日志),在从库上执行DDL语句,执行完毕后,在从库上查出该DDL语句对应的GTID,在主库的GTID集合中加入该DDL语句的GTID,随后执行start slave。
之后,进行主备切换,然后重复一遍此操作。