Skip to content

inplace DDL是什么

In-place DDL(原地DDL或在线DDL)是一种在数据库中执行数据定义语言(DDL)操作(如 ALTER TABLE)的机制,其核心特点是避免对整张表进行数据的完整复制和重建。它直接在原始表的数据文件上进行结构修改,从而显著减少操作期间的资源消耗和对业务的影响。

这个概念在处理大表的结构变更时尤其重要,是现代关系型数据库(特别是MySQL的InnoDB存储引擎)提升可用性的关键特性之一。

核心思想:原地装修 vs. 拆了重建

为了更好地理解,我们可以用一个比喻:

  • 传统DDL(Copying DDL):就像你要给一个房间(数据表)增加一根柱子。传统方法是,你在旁边找块空地,按照新的图纸(新表结构)盖一个一模一样的新房间,然后把旧房间里的所有家具(数据)一件一件搬到新房间,最后拆掉旧房间,让新房间顶替它的位置。这个过程耗时耗力,而且在“搬家”期间,这个房间基本无法正常使用(表被长时间锁定)。

  • In-place DDL:则像是直接在原来的房间里施工。工人(数据库引擎)带着工具和材料进来,在不把所有家具都搬出去的情况下,直接在房间内部把柱子建好。这个过程中,房间可能短时间会有一些干扰(短暂的锁),但大部分时间里,人们还是可以进出和使用房间里的家具的(表在大部分时间内可读写)。

传统DDL(Copying方式)的工作流程

  1. 创建一个符合新表结构的临时表。
  2. 将原始表锁定,防止数据写入。
  3. 将原始表中的数据逐行复制到临时表中。
  4. 在临时表上创建新的索引。
  5. 复制完成后,将原始表删除,并将临时表重命名为原始表的名称。
  6. 释放锁。

这个过程的缺点非常明显: * 长时间锁定:在数据复制期间,表通常是只读甚至完全锁定的,对线上业务是灾难性的。 * 双倍空间:需要临时的磁盘空间来存放新表,如果原表是1TB,你就需要额外的1TB空间。 * 高I/O消耗:大量的数据读取和写入会给服务器带来巨大的I/O压力。

In-place DDL的优势

In-place DDL通过避免全表复制,带来了革命性的改进:

  1. 更高的可用性:操作期间对表的锁定时间极大地缩短,甚至可以实现完全不锁表(允许并发的读写操作)。这被称为“Online DDL”。
  2. 更少的磁盘空间:不需要额外的空间来创建临时表。
  3. 更低的I/O负载:只修改与表结构相关的元数据和少量数据页,避免了海量数据的迁移。

在MySQL中的实践

MySQL的InnoDB存储引擎是In-place DDL的典型实践者。从MySQL 5.6版本开始,Online DDL功能得到了极大的增强。在执行ALTER TABLE语句时,可以通过ALGORITHMLOCK子句来控制DDL的执行方式。

ALTER TABLE table_name [alter_specification], ALGORITHM=INPLACE, LOCK=NONE;

  • ALGORITHM子句:

    • INPLACE:告诉MySQL尽可能使用原地算法。如果该操作不支持INPLACE,则会报错。
    • COPY:强制使用传统的拷贝算法。
    • INSTANT:MySQL 8.0引入的更快的算法,只修改元数据,不涉及数据文件,速度极快(例如,添加列)。
    • DEFAULT:由MySQL自行决定使用最佳算法。
  • LOCK子句:

    • NONE:最理想的状态,允许并发的读和写(DML)。
    • SHARED:允许并发读,但禁止并发写。
    • EXCLUSIVE:完全锁定表,禁止任何读写。
    • DEFAULT:MySQL在保证数据一致性的前提下,选择侵入性最小的锁级别。

并不是所有操作都支持In-place

需要注意的是,并非所有的DDL操作都能以In-place方式完成。这取决于操作的类型和数据库的版本。

通常支持In-place的操作:

  • 添加、删除或重命名索引。
  • 添加、删除或重命名列(在现代版本中,添加列几乎是瞬间完成的)。
  • 修改列的默认值。
  • 修改ENUMSET列的定义。

通常需要Copying(重建表)的操作:

  • 修改列的数据类型(例如INT改为BIGINT)。
  • 修改表的字符集。
  • 修改主键。
  • 改变表的ROW_FORMAT
特性 In-place DDL (原地/在线) Copying DDL (拷贝/离线)
核心机制 直接修改原表数据文件,不复制数据 创建新表,复制所有数据,然后替换
可用性 高,锁时间极短,甚至无锁 低,长时间锁定表
磁盘空间 无需额外空间 需要约等于原表大小的额外空间
I/O负载 低,仅修改元数据和必要数据 高,全表数据的读写
适用场景 对可用性要求高的生产环境,尤其是大表 旧版本数据库,或某些不支持In-place的复杂操作