今天时间有点晚了,就写一个小的知识点吧,在我们线上的环境中,大多都是采用的主从复制的架构,当我们在从库使用mysqldump进行逻辑备份的时候,如果此时主库有一个小的DDL操作,那么我们在从库上会看到什么现象?
开始分析之前,我们先了解下mysqldump这个工具,我们知道,mysqldump是官方自带的逻辑备份工具,可以将数据表中的记录备份成一个可执行的sql文件。我们在使用的过程中,都会带上--single-transaction这个参数,这个参数有这么几个功能:
1、在导出数据之前,开启一个事务,拿到一致性视图。而由于MySQL中支持MVCC多版本控制协议,可以确保你在导出数据的过程中,其他DML语句是可以正常更新进表中的。
2、该参数避免了复制过程中的锁全表操作。
但是我们需要知道,--single-transaction只支持有事务功能的存储引擎。如果是MyISAM这种不支持事务的存储引擎,那么在备份的时候只能锁全表。
下面我们回答题目中的问题,如果我们在从库进行mysqldump备份操作,实际上从库上会进行这么几个步骤,这里我们画一个mysqldump的备份步骤:
步骤1 SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
步骤2 START TRANSACTION WITH CONSISTENT SNAPSHOT;
/* other tables */
步骤3:SAVEPOINT sp;
/* 时刻 1 */
步骤4:show create table `table_1`;
/* 时刻 2 */
步骤5:SELECT * FROM `table_1`;
/* 时刻 3 */
步骤6:ROLLBACK TO SAVEPOINT sp;
/* 时刻 4 */
/* other tables */
步骤1:设置RR隔离级别
步骤2:开启事务,拿到一致性视图
步骤3:设置一个保存点
步骤4:拿到table_1的表结构
步骤5:拿到table_1的表数据
步骤6:回滚到保存点
步骤7:拿到table2的表结构...
步骤8:......
这里,假设我们主库上对table_1进行了DDL变更,新增了一个字段,那么从库可能会发生下面的情况:
1、如果主库上的DDL操作在步骤4之前到达从库,那么对mysqldump无影响
2、如果在时刻2到达,此时mysqldump会停止,并且会报错:Table definition has changed, please retry transaction
3、如果在时刻2和时刻3之间到达(也就是步骤5执行期间到达),此时正在进行select * from table_1操作,mysqldump占用着表table_1的元数据锁,也就是MDL锁,binlog会被阻塞,发生主从延迟
4、如果在步骤6之后开始,则MySQL已经释放了table_1的元数据锁,那么不会对从库产生影响,mysqldump拿到的是DDL变更前的表结构。