浅谈 DDL 技术解密

首先,用过数据库的小伙伴们(本文以 MySQL InnoDB 为例)都知道,MySQL 不止有增删改数据操作(DML),还有改表结构的操作(DDL),当新增加字段等修改表结构时,就需要进行 DDL 操作。可是,如果对一个存储了上百万甚至上千上万的数据表进行 DDL 操作,数据库是怎么做到的呢?会不会有一个很大的事务锁?会不会影响数据的插入和更新?今天就会聊聊这个问题,以及 PT-OSC、GH-OST 等技术,是如何高效的解决这个问题的。

Before MySQL 5.5

在 MySQL 5.5 版本及之前版本,DDL 操作主要有 copy table 和 inplace 两种方式。

1,Copy Table 方式

Copy Table 顾名思义,就是通过临时表拷贝的方式实现的。在 MySQL 5.5 版本及之前版本,修改表结构是表级锁,所以在整个 DDL 过程中表都是锁着不可写入的。这使得在修改时容易导致数据库 CPU、IO 等性能的消耗,以及主从同步的延迟。

上述过程,MySQL 自动完成转存数据,交换表名和删除旧表等操作,时间消耗最多的是在往临时表(Server 层)插入数据的过程,整个 DDL 过程中,表是不能执行 DML 的。

2,IN-Place 方式

在 MySQL 5.5 版本中,增加了 IN-Place 方式。所谓 IN-Place 方式,就是索引创建在原表上直接进行,不会 copy 整个表,只需要在原来的 idb 文件上,新建所需要的索引页,这比 Copy Table 节约极大的 IO 资源,且减少了 DDL 执行时长。

对比 Copy Table 和 IN-Place 两种方式,我们看下官网的内容(MySQL 5.5):

(引自:https://dev.mysql.com/doc/refman/5.5/en/alter-table.html)

以上是 MySQL 5.5 版本中的说明,而 MySQL 5.6 版本,则正式提出了 COPY 和 INPLACE 两种方式。

(引自:https://dev.mysql.com/doc/refman/5.6/en/alter-table.html)

3,Fast Index Creation(FIC)

Innodb 存储引擎从 1.0.x 版本开始,对添加索引操作引入了新特性 Fast Index Creation(FIC 特性)。FIC 就是添加或删除二级索引的时候,可以不用复制原表,而是在创建或删除二级索引时会对原表加上一个 S 锁(共享锁),允许其他会话进行读操作,但禁止写操作,根据当前表数据创建索引,新索引创建完成之后,解除 S 锁,允许写操作。

FIC 在创建索引时不需要拷贝整表数据,但只对二级索引有效,对主键索引无效,对于主键索引的创建和删除同样需要重建一个临时表。

对比 IN-Place 和 FIC,在网上查了一些资料,说“INPLACE 方式也称为 InnoDB fast index creation”,那两个应该不是一回事?我们看下官网的内容(MySQL 5.5):

(引自:https://dev.mysql.com/doc/refman/5.5/en/innodb-create-index-overview.html)

在 MySQL 5.5 的官方说明中,并没有明确说明 FIC 就是 INPLACE,并且此版本中的 FIC 只支持二级索引和辅助索引的增加和删除。而在 MySQL 5.6 官方说明中,则指出 Online DDL 特性基于 InnoDB FIC 构建。

This chapter requires login to view full content. You are viewing a preview.

Login to View Full Content

Course Curriculum

3

框架与 I/O:Spring、Netty 与 Web 容器

理解 Spring Boot 自动装配、AOP 与事务原理,掌握 Netty Reactor 模型及 Tomcat 连接处理机制,构建高内聚、易扩展的应用服务层。
4

高性能中间件:消息、缓存与存储

熟练运用 MySQL 索引/事务、Redis 缓存策略、Kafka/RocketMQ 消息可靠性,以及 ZooKeeper 分布式协调,搭建稳定、解耦的分布式数据底座。
6

云原生:容器化、可观测性与工程效能

通过 Docker/K8s 实现弹性部署,集成 Metrics/Logs/Traces 构建可观测体系,推动 DevOps 与自动化,让架构在云上持续交付与进化。