当备库用–single-transaction 做逻辑备份的时候,如果从主库的 binlog 传来一个 DDL 语句会怎么样?
假设这个 DDL 是针对表 t1 的, 这里我把备份过程中几个关键的语句列出来:
Q1:SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Q2:START TRANSACTION WITH CONSISTENT SNAPSHOT;
Q3:SAVEPOINT sp;
###时刻 1###
Q4:show create table `t1`;
###时刻 2###
Q5:SELECT * FROM `t1`;
###时刻 3###
Q6:ROLLBACK TO SAVEPOINT sp;
###时刻 4###
1、在备份开始的时候,为了确保 RR(可重复读)隔离级别,再设置一次 RR 隔离级别 (Q1);
2、启动事务,这里用 WITH CONSISTENT SNAPSHOT 确保这个语句执行完就可以得到一个一致性视图(Q2);
3、设置一个保存点,这个很重要(Q3);
4、show create 是为了拿到表结构 (Q4);
5、SELECT * FROM `t1`; 开始正式导出数据(Q5);
6、回滚到 SAVEPOINT sp,在这里的作用是释放 t1 的 MDL 锁 (Q6);
DDL 从主库传过来的时间按照效果不同,分为4个时刻,如下:
a、如果在 Q4 语句执行之前到达,现象:没有影响,备份拿到的是 DDL 后的表结构;
b、如果在“时刻 2”到达,则表结构被改过,Q5 执行的时候,报 Table definition has changed, please retry transaction,现象:mysqldump 终止;
c、如果在“时刻 2”和“时刻 3”之间到达,mysqldump 占着 t1 的 MDL 读锁,binlog 被阻塞,现象:主从延迟,直到 Q6 执行完成;
d、从“时刻 4”开始,mysqldump 释放了 MDL 读锁,现象:没有影响,备份拿到的是 DDL 前的表结构;