Mysql 不同版本online DDL的处理策略

关于DDL的ONLINE和OFFLINE,通俗的讲:

  • ONLINE:在执行DDL时允许DML操作

  • OFFLINE:在执行DDL时不允许DML操作

在生产上的场景就是业务正在运行,DBA需要在表中添加新的字段同时不能影响该表的写操作就是ONLINE DDL。也就是说,所谓的ONLINE和OFFLINE更准确是针对 ALTER TABLE 语句。

在 MySQL 5.6 版本之后,引入了 ALGORITHM 参数来控制并发时 ALTER TABLE 语句的算法,官方不建议指定该参数的值,MySQL 自己会选择最优的算法。语法如下:

ALTER TABLE TABLE_NAME ADD COLUMN COLUMN_NAME COLUMN_TYPE ALGORITHM=[ COPY | INPLACE |INSTANT ];

MySQL DDL 在操作时会经历三个阶段:准备阶段、执行阶段、提交阶段,不同算法在不同阶段分别做了不同的处理。

下面介绍一下这三种算法的区别:

COPY算法:

会在 SERVER 层加锁,生成临时表,将原表的数据逐行 copy 到临时表中,此时会阻塞 DML 操作,因此 COPY 算法产生的时OFFLINE DDL。COPY 算法的三个阶段分别做了如下操作:

准备阶段:

  1. 对表的元数据加共享锁,从 *.frm 文件读取表的元数据,此时其它并发的 DDL 不能执行,DML可以执行。

  2. 共享锁升级为排他锁,此时 DDL 和 DML 都不能执行。

  3. 在 SERVER 层通过 CREATE TABLE … LIKE … 语句创建临时表,在存储引擎层也生成对应的 *.ibd 和 *.frm 文件。

执行阶段、提交阶段:

  1. 修改临时表元数据。

  2. copy 原表数据到临时表。

  3. 重命名临时表及文件。

  4. 删除原表及文件。

  5. 提交事务,释放锁。

INPLACE算法:

不会创建临时表,部分情况需要 IN-PLACE 的方式 rebild 表。会在准备阶段和提交阶段加元数据锁,执行阶段不会阻塞DML。INPLACE 算法的三个阶段分别做了如下操作:

准备阶段:

  1. 对表加元数据锁,从共享锁升级为排他锁,此时并发 DML 不能操作。

  2. 根据语句不同判断 rebuild 表或者 no-rebuild 表。如果是 no-rebuild 会在原表路径下创建 *.frm 和 *.ibd 的临时中转文件。no-rebuild 除创建二级索引外只创建 *.frm 文件;在创建二级索引时,不会生成 *.ibd 文件,但会在原 *.ibd 文件中进行修改,该操作会在参数 tmpdir 指定的路径下生成临时文件,用于存储索引排序结果,然后再合并到原 *.ibd 文件中。

  3. 如果是 rebuild 则会申请 row log 空间,用于存放 DDL 执行阶段并发执行的 DML 操作,若是 no-rebuild 则不会进行此操作。

执行阶段:

  1. 释放排他锁,保留元数据共享锁,此时并发 DML 可以执行。

  2. 扫描元表主键以及二级索引的所有数据页,生成 B+TREE 存储到临时文件中。

  3. 如果是 rebuild 则将所有对原表的 DML 操作记录在 row log 文件中。

提交阶段:

  1. 升级元数据锁从共享锁升级成排他锁,此时 DML 不能执行。

  2. 若是 rebuild 重做 row log 文件中的内容,no-rebuild 则无此操作。

  3. 重命名原表文件,将临时表名改为原表名,删除原表文件。

  4. 提交事务,完成变更。

INSTANT算法:

该算法是在 MySQL 8.0.12 版本的新特性,该算法在操作时只修改数据字典中的元数据,不会 copy 数据也不会 rebuild 表,不会加元数据排他锁,原表数据不受影响,不会阻塞 DML ,整个过程瞬间完成。只有在后期触发时才会操作原表。当前版本的 InnoDB 存储引擎支持的 INSTANT 算法的操作有:

  1. ADD COLUMN

  2. ALTER TABLE TABLE_NAME ADD/DROP INDEX INDEX_NAME(COLUMN)

  3. ALTER TABLE TABLE_NAME RENAME NEW_TABLE_NAME

  4. 设置/删除默认值

  5. 添加/删除虚拟列

补充:rebuild 是指在 SERVER 层使用 CREATE TABLE LIKE 创建表的行为,no-rebuild 表示不在 SERVER 层通过 CREATE TABLE LIKE 创建表,但是有可能在存储引擎层创建转储的 *.ibd 文件和 *.frm 文件。

【MySQL】Online DDL详解

猜你喜欢

转载自blog.csdn.net/qq_33709508/article/details/131675306