MySQL之Online DDL

4天前 10.3k 0

从上面的介绍中我们得知,Copy重建表方式的DDL会阻塞DML操作。那么,不会阻塞DML操作的Online DDL又是怎么工作的,我们一起来揭晓。在MySQL 5.5版本之前,重建表都是通过Copy的方式来实现的。MySQL 5.6版本开始引入的Online DDL,对这个操作流程做了优化。具体的过程如下:

1、建立一个临时文件,扫描源表主键的所有数据页;
2、用数据页中源表的记录生成B+树,存储到临时文件中;
3、生成临时文件的过程中,将所有对源表的操作记录在一个日志文件(row log)中;
4、临时文件生成后,将日志文件中的操作应用到临时文件,得到一个逻辑数据上与源表相同的数据文件;
5、用临时文件替换源表的数据文件。

和Copy方式不同,由于日志文件记录和重放操作这个功能的存在,这个方案在重建表的过程中,允许对源表做增删改操作。这也就是Online DDL名字的来源。

还有一个问题需要注意,在MySQL 5.5版本中引入了MDL(MetaData Lock),MDL不需要显式使用,在访问一个表的时候会被自动加上。MDL的作用是,维护元数据的一致性、保证读写的正确性。MDL锁是表级锁,是Server层的锁,主要用于隔离DML和DDL操作之间的干扰。当对一个表做增删改查操作的时候,加MDL读锁;当要对表做结构变更操作的时候,加MDL写锁。根据锁兼容矩阵来看:

MySQL之Online DDL-1

读写锁之间、写锁之间是互斥的,如果互斥,那么DDL还能是Online的吗?下面就从加锁角度来描述一下整个过程:

* PREPARE阶段:
a. 创建新的临时.frm文件;
b. 持有MDL写锁(EXCLUSIVE-MDL),禁止读写;
c. 根据ALTER类型确定执行方式(copy、online-rebuild、online-norebuild);
d. 更新数据字典的内存对象;
e. 分配row_log对象用来记录增量;
f. 生成新的临时ibd文件;

* DDL阶段:
g. 降级MDL写锁(EXCLUSIVE-MDL)为MDL读锁(SHARED_UPGRADABLE-MDL);
h. 扫描old_table的聚簇索引每一条记录record,并遍历新表的索引进行处理;
i. 根据record构造对应的索引项,将构造索引项插入soft_buffer块排序;
j. 将sort_buffer块更新到新的索引上;
k. 记录DDL执行过程中产生的增量并在新表上重放;
l. 记录DDL执行过程中产生的增量(仅rebuild类型需要);
m. 重放row_log间产生DML操作append到row_log最后一个block;

* COMMIT阶段:
n. 当前block为row_log最后一个时,禁止读写,升级到MDL写锁(EXCLUSIVE-MDL);
o. 重做row_log中最后一部分增量;
p. 更新InnoDB的数据字典表;
q. 提交事务(刷事务的redo日志);
r. 修改统计信息;
s. rename临时.ibd文件、.frm文件。

整个过程中,如果申请和升级MDL写锁的步骤没有锁冲突,相对于整个DDL过程来说,锁的时间非常短。Online DDL最耗时的过程就是DDL阶段拷贝数据到临时表的过程,这个步骤的执行期间可以接受增删改操作,对业务来说,就可以认为是Online的。※ Online DDL的使用限制与问题:
1、仍然存在排他锁,有锁等待的风险;
2、增量日志大小是有限制的;

[root@localhost][(none)]> SHOW VARIABLES LIKE 'innodb_online_alter_log_max_size';
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| innodb_online_alter_log_max_size | 134217728 |
+----------------------------------+-----------+
1 row in set (0.00 sec)

innodb_online_alter_log_max_size参数的默认值是128M,如果在DDL过程中,row_log大小超过这个值,那么就会报错ERROR 1062 (23000): Duplication entry3、有可能造成主从延迟;
4、无法暂停,只能中断;
5、VARCHAR数据类型最好不要跨越255字节门槛,可能会导致Online DDL失效。

相关文章

最新发布!MySQL 9.0 的向量 (VECTOR) 类型文档更新
国产数据库中级认证HCIP-openGauss经验分享
保障数据完整性与稳定性:数据库一致性
OceanBase 里的 DDL 超时时间
OceanBase v3.1.x 将不再更新版本 | 社区月报2024.6
openGauss Developer Day 2024 | SIG组工作会议亮点回看!

发布评论