MySQL 在线加索引时怎么判断 ALGORITHM 和 LOCK 选项
来源:17golang原创
时间:2026-09-08 08:25:06 393浏览 收藏
给 InnoDB 表在线新增二级索引时,先记住一个判断:ALGORITHM 决定 MySQL 用什么方式完成结构变更,LOCK 决定你允许它占用多大的并发空间。普通二级索引通常适合 ALGORITHM=INPLACE,并可尝试 LOCK=NONE;但它不是 INSTANT,也不能消除最后阶段的元数据锁等待。
- 新增 InnoDB 二级索引通常是 INPLACE,不是只改数据字典的 INSTANT。
- LOCK=NONE 表示“不支持并发读写就失败”,不是强行把操作变成在线。
- 生产变更前要同时看索引类型、写入量、磁盘临时空间和元数据锁等待。
先看加二级索引到底属于哪种在线 DDL
MySQL 8.4 手册把 COPY、INPLACE、INSTANT 分成三种实现路径。COPY 会复制表数据;INPLACE 不复制整张表的数据,但可能在原地重建结构;INSTANT 只改元数据,表数据不动。
对 InnoDB 普通二级索引,官方在线 DDL 表把它列为“支持 INPLACE、允许并发 DML、不是 INSTANT”。这就是为什么下面的语句通常比强制 COPY 更适合业务运行期间执行:
-- 普通二级索引要求尽量保持业务读写
ALTER TABLE orders
ADD INDEX idx_orders_customer_created (customer_id, created_at),
ALGORITHM=INPLACE,
LOCK=NONE;
这里的 LOCK=NONE 是一个可验证的并发要求。若当前表结构、存储引擎或索引类型不支持它,语句应当报错,而不是悄悄降级成更重的锁模式。图1把表结构、并发写入和锁边界放在同一张图里,重点是理解关系,不是展示一次真实执行。

ALGORITHM 和 LOCK 应该怎么组合
这两个参数不是一回事。可以把 ALGORITHM 看成“实现路径”,把 LOCK 看成“并发合同”。在线加普通二级索引时,常见选择如下:
| 场景 | 建议组合 | 含义 |
|---|---|---|
| 必须保持读写可用 | INPLACE, LOCK=NONE | 不满足并发 DML 条件就失败,适合先演练再上线。 |
| 允许读但不允许写入 | INPLACE, LOCK=SHARED | 只在业务能接受写阻塞时使用。 |
| 默认交给 MySQL 判断 | DEFAULT, DEFAULT | 兼容性更宽,但不把并发承诺写死。 |
| 明确接受表复制 | COPY | 需要额外评估空间与 DML 影响,不是在线首选。 |
LOCK=EXCLUSIVE 会强制独占访问;它不是“更稳的 NONE”,而是主动放弃并发读写。对于 INSTANT 操作,MySQL 只允许 LOCK=DEFAULT,所以不要看到“默认算法”就推断所有锁选项都可用。
图2用三个静态域区分算法候选、并发约束和失败边界。真正的决策顺序是:先确认操作是否支持目标算法,再确认目标锁级别是否被该操作支持,最后才安排变更窗口。

上线前先排除四个变更窗口风险
- 确认索引类别。普通二级索引和主键不是同一件事。主键改变会牵涉聚簇索引和数据重组,不能直接套用普通二级索引的经验。
- 确认短暂元数据锁。即使允许并发 DML,开始和结束阶段仍可能需要拿表级元数据锁。长事务、未提交事务或高峰期 DDL 都可能让它等待。
- 确认临时空间。在线建索引会使用排序和在线变更日志相关空间;并发写入过多时,日志超过
innodb_online_alter_log_max_size也会失败。 - 把失败当成保护机制。如果业务不能接受写阻塞,宁可让
LOCK=NONE报错,也不要让默认策略在无人观察时换成更宽松但更重的锁模式。
-- 先在同版本、同表结构环境确认语句不会隐式换成不接受的路径
ALTER TABLE orders
ADD INDEX idx_orders_status_created (status, created_at),
ALGORITHM=INPLACE,
LOCK=NONE;
-- 上线前同时检查长事务、磁盘余量和业务低峰窗口
常见问题
加二级索引可以写 ALGORITHM=INSTANT 吗?
普通 InnoDB 二级索引创建不是只改元数据的操作,通常应使用 INPLACE;强写 INSTANT 会因操作不兼容而失败。
LOCK=NONE 是否代表完全不会被锁住?
不是。它要求并发读写能力必须满足,但短暂的元数据锁仍可能等待,长事务是常见原因。
为什么不直接省略 ALGORITHM 和 LOCK?
省略后由 MySQL 按操作能力选择默认策略,兼容性更宽;如果你对写入连续性有硬要求,显式写出 NONE 更容易让不满足条件的变更立即失败。
在线加索引失败后要先查什么?
先看错误是否指向算法或锁不兼容,再看元数据锁等待、临时空间和在线变更日志上限,最后确认是否有并发写入造成的约束冲突。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习