当前位置: 首页 > news >正文

MySQL Online DDL:演变、原理与实践

在MySQL数据库的发展历程中,Online DDL功能的出现极大地提升了数据库表结构变更时的可用性和性能。从早期版本对表结构变更操作的诸多限制,到如今成熟的Online DDL体系,这一功能经历了显著的演进。

一、Online DDL的发展轨迹

MySQL在5.5版本中引入了INPLACE DDL方式,但由于实现上的缺陷,该方式依然会阻塞INSERT、UPDATE、DELETE等操作,给用户带来了极大的困扰。到了5.6版本,MySQL正式引入Online DDL功能,官方开始支持更多类型的ALTER TABLE操作以避免数据拷贝,并且在DDL过程中不再阻塞DML操作,真正实现了Online DDL。然而,并非所有的DDL操作都支持在线执行。

5.7版本在5.6的基础上进一步拓展,新增了重命名索引支持,同时支持数值类型长度的调整以及VARCHAR类型的在线增大。不过,其基本实现逻辑和限制条件与5.6版本相比并无根本性变化。

MySQL 8.0对DDL的实现进行了重新设计,最大的改进之一是支持DDL操作的原子特性。此外,Online DDL的ALGORITHM参数新增了INSTANT选项。该选项只需修改数据字典中的元数据,无需拷贝数据、重建表,也无需加排他MDL锁,整个DDL过程几乎瞬间完成,且不会阻塞DML操作。

二、Online DDL的算法剖析

在深入了解Online DDL之前,有必要先认识传统DDL的两种算法:copy和inplace。

Copy算法

Copy算法的执行步骤如下:首先按照原表定义创建一个新的临时表,接着对原表加写锁,禁止DML操作但允许select操作。随后在临时表上执行DDL,将原表数据拷贝到临时表,释放原表的写锁,最后删除原表,并将临时表重命名为原表。由于在操作过程中需要锁表,禁止DML,因此Copy算法不属于Online DDL。例如,删除主键、修改列类型、修改字符集等会导致行记录格式发生变化的操作,无法通过全量 + 增量实现Online,通常会采用Copy算法。

Inplace算法

Inplace算法直接在原表上进行更改,无需生成临时表和数据拷贝。根据是否变更行记录格式,Inplace算法又可分为两类:

  1. rebuild:需要重建表,重新组织聚簇索引。例如,optimize table、添加索引、添加/删除列、修改列NULL/NOT NULL属性等操作。对于这类操作,Online的实现方式是缓存DDL期间的DML,待DDL完成后,将DML应用到表上。
  2. no - rebuild:无需重建表,仅需修改表的元数据,如删除索引、修改列名、修改列默认值、修改列自增值等操作。

在Copy数据到新表期间,原表上加的是MDL读锁,允许DML操作,禁止DDL操作;在应用增量期间,对原表加MDL写锁,禁止DML和DDL操作。需要注意的是,根据表A重建出来的数据放在tmp_file里,这个临时文件由InnoDB在内部创建,整个DDL过程都在InnoDB内部完成。对于Server层来说,数据并未挪动到临时表,这就是“Inplace”名称的由来。

三、Online DDL过程中的锁机制

默认情况下,MySQL支持Online DDL操作,并且在执行过程中会尽量减少锁的使用,无需特殊操作即可启用。然而,MySQL在选择锁机制时,尽管会尽量减少限制,但仍有可能选择使用锁。为了避免因锁导致表无法读写的情况,可以在执行Online DDL语句时,使用ALGORITHM和LOCK关键字。

ALGORITHM的选项

  1. INPLACE:直接在原表上执行DDL操作。
  2. COPY:使用临时表方式,克隆临时表,在临时表上执行DDL,再导入数据并进行重命名。此过程需要额外一倍的磁盘空间,且执行期间表不允许DML操作。
  3. DEFAULT:默认方式,由MySQL自行选择,优先使用INPLACE方式。

LOCK的选项

  1. SHARE:共享锁,执行DDL的表可读取,但不可写入。
  2. NONE:无任何限制,执行DDL的表可读可写。
  3. EXCLUSIVE:排他锁,执行DDL的表不可读也不可写。
  4. DEFAULT:默认值,不指定LOCK子句时使用。不建议使用此选项,除非确定DDL语句不会锁表,否则应指定锁类型。

执行DDL操作时,ALGORITHM选项可以不指定,此时MySQL会按照INSTANT、INPLACE、COPY的顺序自动选择合适的模式。也可以指定ALGORITHM=DEFAULT,效果相同。若指定的ALGORITHM选项不被支持,会直接报错。

在执行Online DDL之前,应选择非业务高峰期,并确认待执行的表上没有未提交的事务、锁等信息。可通过特定SQL语句进行查看:

select * from information_schema.innodb_locks;
select * from information_schema.innodb_trx;
select * from information_schema.innodb_lock_waits;
select * from information_schema.processlist;

四、DDL操作的需求与挑战

DDL操作涉及数据库表结构的修改,如添加/删除列、修改列定义、添加/删除索引等。在早期版本中,执行这些操作时需要锁定整个表,严重影响数据库的可用性。因此,实现在线DDL成为提升系统灵活性和性能的关键需求。

五、MySQL 5.7在线DDL功能特点

MySQL 5.7通过InnoDB存储引擎对在线DDL功能进行了改进,主要特点如下:

  1. 支持添加辅助索引:可在运行中的表上添加辅助索引,无需锁定整个表。
  2. 支持修改列定义:能够在线修改列的数据类型、长度等定义。
  3. 支持修改字符集和排序规则:可在线修改表的字符集和排序规则设置。
  4. 支持重命名列:可在不影响读写操作的情况下,对表中的列进行重命名。

六、实现原理与优化

在线DDL功能的实现包含以下关键步骤和优化措施:

  1. 创建临时表:创建临时表存储DDL操作所需的新结构,确保旧表仍可进行读写操作。
  2. 数据复制和同步:逐步将旧表数据复制到临时表,并保持两者数据同步,保证数据完整性和一致性。
  3. 变更捕获和重放:利用日志和重做日志等机制,捕获DDL操作期间的数据变更,并重放到临时表中,确保操作完成后数据的一致性。
  4. 最终切换:DDL操作完成后,数据库引擎在适当的时机切换到临时表,使其成为新的表结构,并对新表进行后续读写操作。

七、使用限制与注意事项

尽管MySQL 5.7的在线DDL功能提供了近似在线的体验,但仍存在一些限制和注意事项:

  1. 并非所有DDL操作都支持在线执行:部分操作仍需锁定整个表。
  2. 资源占用问题:DDL操作期间可能占用大量系统资源,在高负载时应谨慎使用。
  3. 充分评估和测试:进行在线DDL操作前,需对操作进行充分评估和测试,确保数据的完整性和一致性。

八、各版本支持的详细情况

相关数据可参考MySQL官方文档:

  • https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html
  • https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html
  • https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html

九、DDL的执行模式

  1. INSTANT DDL:MySQL 8.0引入的新功能,当前支持范围较小,包括修改二级索引类型、新增列、修改列默认值、修改列ENUM值、重命名表等操作。
  2. ALGORITHM选择策略
    • 用户显式指定ALGORITHM时,使用指定选项。
    • 用户未指定时,若操作支持INPLACE,则优先选择INPLACE,否则选择COPY。当前不支持INPLACE的操作主要有删除主键、修改列数据类型、修改表字符集等。
  3. Online DDL的界定:从DML操作的角度来看,若DDL操作不阻塞DML操作,则为Online DDL。当前非Online DDL操作相对较少,主要包括新增全文索引、新增空间索引、删除主键、修改列数据类型、指定表字符集、修改表字符集等。更多详细示例可参考官方文档。

十、常见问题探讨

Q1:Online DDL会不会锁表?

要回答这个问题,首先需明确“锁表”的含义。在InnoDB表中,影响DML操作的锁包括MDL锁、表锁、行锁和GAP锁。其中,MDL锁在Server层添加,其他三种在InnoDB层添加。所有操作都需先获取Server层的MDL锁,再获取InnoDB层所需的锁。

DDL的基本过程为:开始时获取对应表的MDL X锁,进行准备工作;然后将MDL X锁降级为MDL S锁,执行真正的DDL操作;最后将MDL S锁升级为MDL X锁,完成DDL操作并释放MDL锁。因此,在真正执行DDL操作期间,不会“锁表”。但如果在第一阶段无法获取MDL X锁,就可能导致“锁表”。例如,当一个会话执行慢查询时,另一个会话尝试进行DDL操作,可能无法获取MDL X锁,从而导致后续的查询和操作无法执行,此时可认为表被“锁表”。在MySQL 5.7/8.0中,可开启performance_schema,通过查询metadata_locks表获取MDL锁的信息;阿里云RDS 5.6版本新增了I_S.MDL_INFO表,用于提供MDL的查询。

综上所述,Online DDL并非绝对安全,不能随意执行,线上操作应在业务低峰期谨慎进行。

Q2:支持INPLACE算法的DDL一定是Online的吗?

从概念上讲,INPLACE和Online是两个不同维度的概念。COPY和INPLACE描述的是DDL内部的执行逻辑,COPY是在Server层的操作,INPLACE是在InnoDB层的操作。而用户更关注的Online与否,通常只与是否允许并发DML有关。基本结论是:COPY算法执行的DDL肯定不是Online的;INPLACE算法执行的DDL不一定是Online的。

Q3:INPLACE DDL需不需要额外的数据空间?

MySQL内部对于DDL的ALGORITHM主要有INPLACE和COPY两种选择(8.0新增的INSTANT使用范围较小)。COPY算法通过创建临时表并拷贝原表数据,显然需要额外的数据空间。对于支持INPLACE算法的DDL,同样需要额外的数据空间。这是因为INPLACE描述的是表,而非数据文件。只要不创建临时表,都属于INPLACE操作。实际上,许多INPLACE DDL操作会重建表(创建临时数据文件),如增加主键、重建主键、新增列(8.0支持INSTANT DDL的情况除外)、删除列、调整列顺序、删除列默认值、增加列默认值、修改表的ROW_FORMAT、OPTIMIZE表等,这些操作都需要额外的数据空间。

相关文章:

  • RAG 文档嵌入到向量数据库FAISS
  • 前沿科技:具身智能(Embodied Intelligence)详解
  • 利用cusur+claude3.7 angent模式一句提示词生成一个前端网站
  • 阿里拟收购两氢一氧公司 陈航将出任阿里集团钉钉 CEO
  • 【CV/NLP/生成式AI】
  • 二月公开赛Web-ssrfme
  • 4月1号.
  • Redis:主从复制
  • 机器学习+EEG熵进行双相情感障碍诊断的综合评估
  • Git基本操作
  • ThreadLocal用法详解
  • 聊一聊缓存如何进行测试
  • 图片边缘采样
  • 自动化释放linux服务器内存脚本
  • 6-2 赶工中~
  • Https安全
  • ansible条件判断及循环
  • 【系统架构设计师】嵌入式操作系统的定义及特点
  • Spring实现WebScoket
  • UE5学习记录 part13
  • 案件发回重审,李在明参选韩总统之路再添波折
  • 解放日报:浦东夯实“热带雨林”式科创生态
  • 图忆|上海车展40年:中国人的梦中情车有哪些变化(上)
  • 上海国际咖啡文化节开幕,北外滩集结了超350个展位
  • 辽宁辽阳市白塔区一饭店发生火灾,当地已启动应急响应机制
  • 15世纪以来中国文化如何向欧洲传播?《东学西传文献集成初编》发布