〇、前言
前面笔记中的都是一主一备的结构,但是基本上我们的服务架构都是一主多从。为什么?因为大多是都是读多写少的业务。
一、正文
1.1.一主多从基本结构图解?
虚线箭头表示的是主备关系,也就是 A 和 A’互为主备, 从库 B、C、D 指向的是主库 A。一主多从的设置,一般用于读写分离,主库负责所有的写入和一部分读,其他的读请求则由从库分担。
1.2.一主多从的主备切换有哪两种方式?
-
基于位点的主备切换
-
GTID的主备切换
1.3.什么是基于位点的主备切换?有哪核心四步?切换过程中会出现哪两种错误?解决方式是什么?这种方式的弊端是什么?
-
把节点 B 设置成节点 A’的从库的时候,需要执行一条 change master 命令,其中除了制定机器、端口、用户名和密码之外还要制定主库日志名称和同步位点。
-
1)等待A’执行完成relay log日志。2)执行 A’的show master status查看最新位点()。2)取A库的故障时刻T。3)用 mysqlbinlog 工具解析 A’的 File,得到 T 时刻的位点。4)执行change master命令
-
删除数据不存在错误和主键冲突错误
-
1)主动跳过一个事务set global sql_slave_skip_counter=1;start slave。2)设置 slave_skip_errors 参数,直接设置跳过指定的错误,等到主备间的同步关系建立完成,并稳定执行一段时间之后,我们还需要把这个参数设置为空。
-
手动出错较多。
1.4.什么是GTID?哪个版本引入了?GTID由哪几部分组成,组成部分容易引起歧义点的地方是什么?GTID的生成方式有哪两种,对应的策略是什么?
-
GTID 的全称是 Global Transaction Identifier,也就是全局事务 ID,是一个事务在提交的时候生成的,是这个事务的唯一标识。
-
5.6版本之后
-
两部分;server_id : transaction_id(独家叫法gno);在 MySQL 里面我们说 transaction_id 就是指事务 id,事务 id 是在事务执行过程中分配的,如果这个事务回滚了,事务 id 也会递增,而 gno 是在事务提交的时候才会分配。
-
1)如果 gtid_next=automatic,代表使用默认值。这时,MySQL 就会把 server_uuid:gno 分配给这个事务。a. 记录 binlog 的时候,先记录一行 SET @@SESSION.GTID_NEXT=‘server_uuid:gno’;b. 把这个 GTID 加入本实例的 GTID 集合。2)如果 gtid_next 是一个指定的 GTID 的值,比如通过 set gtid_next='current_gtid’指定为 current_gtid,那么就有两种可能:a. 如果 current_gtid 已经存在于实例的 GTID 集合中,接下来执行的这个事务会直接被系统忽略;b. 如果 current_gtid 没有存在于实例的 GTID 集合中,就将这个 current_gtid 分配给接下来要执行的事务,也就是说系统不需要给这个事务生成新的 GTID,因此 gno 也不用加 1。
1.5.每个 MySQL 实例都维护了一个 GTID 集合,用来对应“这个实例执行过的所有事务”。
1.6.GTID的主备切换命令是什么?
- master_auto_position=1,无需制定postion和file。
1.6.1.GTID的步骤是什么?
前提:实例 A’的 GTID 集合记为 set_a,实例 B 的 GTID 集合记为 set_b。
在实例 B 上执行 start slave 命令,取 binlog 的逻辑是这样的:
-
实例 B 指定主库 A’,基于主备协议建立连接。
-
实例 B 把 set_b 发给主库 A’。
-
实例 A’算出 set_a 与 set_b 的差集,也就是所有存在于 set_a,但是不存在于 set_b 的 GTID 的集合,判断 A’本地是否包含了这个差集需要的所有 binlog 事务。a. 如果不包含,表示 A’已经把实例 B 需要的 binlog 给删掉了,直接返回错误;b. 如果确认全部包含,A’从自己的 binlog 文件里面,找出第一个不在 set_b 的事务,发给 B;
-
之后就从这个事务开始,往后读文件,按顺序取 binlog 发给 B 去执行。
⭐️:在基于 GTID 的主备关系里,系统认为只要建立主备关系,就必须保证主库发给备库的日志是完整的。因此,如果实例 B 需要的日志已经不存在,A’就拒绝把日志发给 B。
1.6.2.与基于位点的不同之处是什么?
-
基于位点的协议,是由备库决定的,备库指定哪个位点,主库就发哪个位点,不做日志的完整性判断。
二、思考
在 GTID 模式下设置主从关系的时候,从库执行 start slave 命令后,主库发现需要的 binlog 已经被删除掉了,导致主备创建不成功。这种情况下,你觉得可以怎么处理呢?
答:
-
如果业务允许主从不一致的情况,那么可以在主库上先执行 show global variables like ‘gtid_purged’,得到主库已经删除的 GTID 集合,假设是 gtid_purged1;然后先在从库上执行 reset master,再执行 set global gtid_purged =‘gtid_purged1’;最后执行 start slave,就会从主库现存的 binlog 开始同步。binlog 缺失的那一部分,数据在从库上就可能会有丢失,造成主从不一致。--金融业务不可取
-
如果需要主从数据一致的话,最好还是通过重新搭建从库来做。--太慢了
-
如果有其他的从库保留有全量的 binlog 的话,可以把新的从库先接到这个保留了全量 binlog 的从库,追上日志以后,如果有需要,再接回主库。
-
如果 binlog 有备份的情况,可以先在从库上应用缺失的 binlog,然后再执行 start slave。
三、评论
3.1.GTID空洞问题会造成什么影响?--先Mark一下,随后回头来看