当前位置: 代码网 > it编程>数据库>Mysql > 深入理解Mysql OnlineDDL的算法

深入理解Mysql OnlineDDL的算法

2025年09月29日 Mysql 我要评论
mysql 5.6 及以后版本(尤其是 innodb 存储引擎)引入的一项极其重要的功能,它允许数据库管理员在执行alter table操作时,最大程度地减少对表锁定和应用程序可用性的影响。核心目标:

mysql 5.6 及以后版本(尤其是 innodb 存储引擎)引入的一项极其重要的功能,它允许数据库管理员在执行 alter table 操作时,最大程度地减少对表锁定和应用程序可用性的影响

核心目标: 在 ddl 操作进行时,允许对表进行并发读取(select) 和写入(insert, update, delete) 操作。

一、online ddl 是什么?

online ddl 是 mysql 5.6 版本引入,并在后续版本中不断增强的一项功能。它允许你在执行数据定义语言(ddl)操作时(如 alter table),尽可能地减少对表的锁定时问,使得:

  • 写操作(dml):在 ddl 操作进行的同时,应用程序依然可以对表执行 insertupdatedelete 等操作,最大程度保证业务的连续性。
  • 读操作select 查询通常可以正常进行,不受影响。

这与早期的 copy table 机制形成鲜明对比,早期方式需要全程锁表,直到操作完成,对于大表来说意味着长时间的停机。

二、online ddl 的三种主要算法

mysql 在执行 ddl 时,根据操作类型的不同,底层主要采用三种算法。理解这些算法是理解 online ddl 的关键。

2.1copy(复制法)

过程:

  • 创建一个与原始表结构相同的临时表(.frm.ibd 等文件)。
  • 在新的临时表上执行 ddl 操作。
  • 将原始表的数据逐行复制到临时表中。
  • 在此期间,对原始表的写操作会被阻塞(通常只在数据拷贝的最后阶段有短暂锁表)。
  • 数据复制完成后,用新的临时表替换原始表,并删除旧的表。

特点

  • 需要两倍的存储空间。
  • 过程中大部分时间会阻塞写操作,影响业务。
  • 是 mysql 5.5 及之前版本的主要方式。

2.2 inplace (原地法)

过程

无需创建临时表文件,直接在原始表的存储文件(如 innodb 的 .ibd 文件)上进行操作。

通常分为两个阶段:

  • 准备阶段(prepare):创建新的.frm文件,准备数据字典更改。可能需要短暂的排他锁(x锁)
  • 执行阶段(execute):应用更改到存储引擎,这通常是操作中最耗时的部分。在此阶段,允许并发的dml操作

特点

  • 所需磁盘空间远少于 copy 算法(通常只需要日志文件的空间)。
  • 允许在执行阶段进行并发 dml,大大减少了锁表时间。

2.3instant (即刻法,mysql 8.0+)

过程

  • 操作只修改数据字典(元数据),而不触及表中的实际数据或索引。
  • 例如,添加一个可为 null 且有默认值的列,只需要在数据字典中记录一下“这个表有这个列,默认值是什么”,而不需要重建表或复制数据

特点

  • 速度极快,通常能在毫秒级完成。
  • 完全不阻塞任何 dml 操作,是真正的“online”。
  • 对存储空间没有额外要求。

三、online ddl 的锁机制

即使是 inplace 算法,也并非全程无锁。online ddl 涉及两种主要的锁:

  • shared锁(读锁):在 ddl 的准备阶段,可能会短暂地获取。允许其他会话读,但阻塞写。
  • exclusive锁(写锁/排他锁):在 ddl 的开始(准备阶段)和结束(提交阶段)可能会短暂地获取。此时会阻塞所有其他的读和写操作

关键点:online ddl 的“online”体现在其耗时的数据拷贝/重建阶段(execute阶段)是不锁表的,而只在元数据变更的瞬间需要短暂的排他锁。这个瞬间通常非常短,可以忽略不计。

四 关键区别

特性copyinplaceinstant
核心方式重建整个表原地修改,避免重建整个表仅修改元数据
锁表时间长 (全程锁或长写锁)短 (准备/提交锁)极短 (毫秒级元数据锁)
执行阶段不允许读写允许并发读写允许并发读写
空间占用双倍表空间额外日志/临时文件空间几乎无额外空间
速度中等 (取决于操作复杂度)极快 (毫秒级)
并发影响高 (停机)低 (短暂阻塞写)极低 (几乎无感知)
主要优势兼容性平衡性能和并发瞬时完成,零感知
典型操作部分无法 inplace 的操作 (如删除主键)添加/删除索引、修改列属性等添加/删除列 (有条件)、改默认值

4.1 生动的比喻:给飞行中的飞机换引擎

想象一下,你要给一架正在飞行的飞机更换引擎(这相当于对数据库表做 alter table)。

copy 算法:让所有乘客下飞机(阻塞 dml),把飞机拖进机库,拆下旧引擎,换上新引擎,最后再让乘客登机。在此期间,飞机完全停运

inplace 算法

  • 准备阶段 (prepare):工程师们做好所有准备工作:新引擎运到机场,所有工具就位。这需要飞机短暂地保持静止短暂的排他锁)。
  • 执行阶段 (execute)飞机保持飞行状态(允许并发 dml)。工程师们挂在机翼上,开始拆卸旧引擎,同时安装新引擎。乘客们(dml 操作)仍然可以在机舱内正常走动、点餐(insertupdatedelete)。
  • 提交阶段:新引擎安装完毕,最后进行一个极其快速的切换和检查,确保新引擎完全接管工作。这又需要飞机瞬间的静止短暂的排他锁)。

4.2 如何指定和查看算法

指定算法: 在 alter table 语句中使用 algorithm 子句。

alter table your_table add column new_col int, algorithm=instant; -- 尝试强制使用 instant
alter table your_table add index idx_name (col_name), algorithm=inplace, lock=none; -- 尝试强制 inplace 且无锁
  • algorithm=default:让 mysql 选择它认为最高效的可用算法。
  • algorithm=copy | inplace | instant:强制使用特定算法。如果该算法不支持此操作,语句会报错。

指定锁策略: 使用 lock 子句。

alter table ... lock=none; -- 尽可能允许并发读写 (最高并发)
alter table ... lock=shared; -- 允许读,阻塞写
alter table ... lock=exclusive; -- 阻塞读写 (传统方式)
alter table ... lock=default; -- 让 mysql 选择最小必要的锁策略

指定的 lock 级别必须兼容于操作本身支持的级别。例如,一个操作在 inplace 执行阶段允许 lock=none,但你强制指定 lock=exclusive 是允许的(虽然不推荐)。反之,如果操作本身在某个阶段必须短暂加 exclusive 锁,你指定 lock=none 会导致语句失败。

查看算法和锁: 执行 alter table 前,使用 alter table ... algorithm=inplace, lock=none 并加上 no_write_to_binlog 和 commit 子句通常不会真正执行,mysql 会检查并报告它将使用的算法和锁。更好的方法是查询 information_schema.innodb_tables 或使用 show create table 观察进度(对于长时间操作),或者直接执行后观察输出信息(很多客户端会显示使用的算法)。最准确的是查看官方文档对具体操作的支持矩阵。

4.3 重要注意事项

  • 并非所有 ddl 都是 online 的: 即使使用 inplace 算法,部分操作在准备或提交阶段也需要短暂的排他锁 (exclusive)。一些操作(如修改主键、修改某些列的数据类型、更改表字符集等)可能仍然需要 copy 算法或更长时间的锁。务必查阅官方文档对应版本的 online ddl 支持矩阵。
  • 空间与性能: inplace 操作虽然避免了重建整个表,但可能涉及大量的数据重组、日志记录、排序操作,仍然会消耗大量 i/o 和 cpu 资源,可能影响系统性能。instant 操作在这方面开销最小。
  • 复制: online ddl 在 mysql 复制环境(主从)中的行为也需要考虑。通常在主库上执行的 online ddl,其效果也会在从库上以类似的方式应用(可能也是 online 的,取决于从库版本和设置)。
  • 元数据锁 (mdl): 即使算法本身允许并发 dml,长时间的 ddl 操作也可能因为持有 mdl 而阻塞后续需要获取冲突 mdl 的其他 ddl 或某些事务。lock=none 的目标就是最小化 mdl 冲突。
  • instant 的限制: instant 算法虽然强大,但有诸多限制(列的位置、数据类型、索引类型、表格式等),且限制随版本更新而变化。使用前务必确认操作是否支持 algorithm=instant
  • 版本差异: online ddl 的支持程度和具体行为在不同 mysql 版本(5.6, 5.7, 8.0)和 innodb 版本中有显著差异。强烈建议参考对应版本的官方文档。

三、总结

mysql 的 online ddl 通过 copyinplaceinstant 三种算法,极大地提升了 ddl 操作的并发性和可用性。尤其是 instant 算法(mysql 8.0+)对于支持的列操作实现了近乎瞬时的变更,对在线业务影响最小。inplace 算法则是大多数索引和列操作的主力,在执行阶段允许并发读写。copy 算法作为最后的选择,应尽量避免。

最佳实践:

  • 优先使用 mysql 8.0+ 以获得最完善的 instant 支持。
  • 在执行 ddl 前,务必查阅官方文档,明确该操作在你的 mysql 版本上支持的算法和锁定行为。
  • 在 alter table 语句中显式指定 algorithm 和 lock 子句(如 algorithm=instant, lock=none),让 mysql 在无法满足要求时报错,而不是默默使用低效的方式。
  • 对于大表操作,即使使用 inplace,也应在业务低峰期进行,并监控服务器资源(i/o, cpu, memory)。
  • 充分利用 instant 算法进行高频次的表结构变更(如快速加列)。

到此这篇关于深入理解mysql onlineddl的算法的文章就介绍到这了,更多相关mysql onlineddl 内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网! 

(0)

相关文章:

  • MySQL之搜索引擎使用解读

    mysql的存储引擎是什么mysql当中数据用各种不同的技术存储在文件中,每一种技术都使用不同的存储机制,索引技巧 锁定水平,以及最终提供的不同的功能和能力,这些就是我们说的存储引…

    2025年09月27日 数据库
  • Docker MySQL启动问题及解决过程

    Docker MySQL启动问题及解决过程

    问题概述docker 环境中的 mysql 容器启动失败,主要表现为两个核心错误:临时文件权限问题:can't create/write to file '/t... [阅读全文]
  • MySQL误删数据或者丢失?这6种方案能帮你快速恢复!

    前言最近星球中有位小伙伴说:他不小心把测试环境mysql表中所有数据都误删了,问我要如何快速恢复?幸好他误删的是测试环境,非生产环境。我遇到过,之前有同事把生产环境会员表中的数据误…

    2025年09月27日 数据库
  • Nginx配置proxy protocol代理获取真实ip的全过程

    前言在现代开发中有很多场景需要拿到用户的真实ip,比如安全策略,和地区热点信息推送等功能,但是现在代理很多。用户可能会通过代理访问服务,或者黑客攻击的时候也会使用很多肉机隐藏其真实…

    2025年09月26日 数据库
  • CentOS中设置yum源的详细步骤

    CentOS中设置yum源的详细步骤

    在centos中设置yum源可以分为以下几个步骤。我将以设置阿里云镜像源为例进行说明:1. 备份原有yum源# 备份原有repo文件sudo cp -r /et... [阅读全文]
  • MySQL从视图到用户和权限管理操作

    一:视图的定义视图是⼀个虚拟的表,它是基于⼀个或多个基本表或其他视图的查询结果集。视图本⾝不存储数据,⽽是通过执⾏查询来动态⽣成数据。⽤⼾可以像操作普通表⼀样使⽤视图进⾏查询、更新…

    2025年09月26日 数据库

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com