MySQL 在线 DDL评估加索引时的锁与空间的实现方法
给 InnoDB 大表加二级索引时,真正要评估的不是“在线 DDL 会不会锁表”,而是两个更具体的问题:DDL 在构建索引期间允许多少并发,以及最后提交新表定义时有没有长事务挡住元数据锁。空间也不能只看新索引本身,还要预留并发变更日志、临时排序文件,某些操作还会出现短暂的中间表文件。
- 新增二级索引通常可以采用
ALGORITHM=INPLACE, LOCK=NONE,但不代表全程零等待。 - 长事务持有的 metadata lock 可能卡住 DDL 的提交阶段,排队的 DDL 还会影响后续访问。
- 磁盘预算至少覆盖新索引、在线变更日志和临时排序目录,余量不足时应先演练或改窗口。
先把在线 DDL 的目标写进 ALTER TABLE
如果只是希望“尽量在线”,直接执行默认 ALTER TABLE 很难在发布前证明它没有退化。更稳妥的做法是把算法和锁级别写出来,让 MySQL 在能力不满足时立即报错。
-- 只新增二级索引;如果当前表不支持这组约束,让语句立即失败 ALTER TABLE orders ADD INDEX idx_customer_created (customer_id, created_at), ALGORITHM=INPLACE, LOCK=NONE;
LOCK=NONE 的含义是允许并发查询和 DML;它不是“完全没有锁”,而是要求这项原地变更不能阻断正常读写。对新增索引来说,构建阶段会读取表数据并接收并发修改,结束时仍需要把这些修改合并到索引并提交新的表定义。

锁的风险集中在元数据提交,不只看 LOCK=NONE
MySQL 官方把在线 DDL 分为初始化、执行和提交表定义几个阶段。初始化会取得可升级的共享元数据锁;执行阶段主要构建索引;提交阶段需要升级为排他元数据锁,以替换旧的表定义。这个排他锁通常很短,但必须等持有表元数据锁的事务提交或回滚。
因此,发布前要查的不是有没有普通行锁,而是有没有“打开事务后长时间不结束”的会话。可以先从进程列表观察:
-- 查找 DDL 本身和可能阻塞它的会话;Time 较大时优先核对事务状态
SHOW FULL PROCESSLIST;
-- MySQL 8.0+ 可查看元数据锁依赖;只读查询,不会改变锁状态
SELECT OBJECT_SCHEMA, OBJECT_NAME, LOCK_TYPE, LOCK_DURATION,
LOCK_STATUS, OWNER_THREAD_ID
FROM performance_schema.metadata_locks
WHERE OBJECT_NAME = 'orders';
如果 DDL 显示 Waiting for table metadata lock,先定位持锁事务和业务连接池,而不是反复重跑 ALTER。还要注意排队效应:DDL 正在等待排他元数据锁时,后续访问同一表的事务也可能被它挡住,短 DDL 也会因此放大成请求延迟。
空间预算要覆盖三种临时对象
新增索引的磁盘准备可以按三类对象拆开。第一类是最终二级索引本身;第二类是在线 DDL 为记录并发 DML 而增长的临时日志,其上限受 innodb_online_alter_log_max_size 控制;第三类是索引构建过程的临时排序文件,它们通常写入 tmpdir 或 innodb_tmpdir。
对需要重建表的在线操作,官方还提示可能创建以 #sql-ib 开头的中间表文件,空间可能接近原表大小。新增二级索引常见的是在线索引构建,但不要只按“新索引大小”做统一承诺,应先在同版本、相近数据量的副本或克隆表上测量。

| 检查对象 | 要回答的问题 | 处理建议 |
|---|---|---|
| 锁级别 | 能否保持 LOCK=NONE? | 写入约束,失败即停,不接受静默退化 |
| 长事务 | 谁持有 orders 的 metadata lock? | 先结束事务或调整发布窗口 |
| 变更日志 | 高写入量会不会触及上限? | 预留余量并关注 DB_ONLINE_LOG_TOO_BIG |
| 临时目录 | 排序文件写到哪里,剩余空间多少? | 检查 tmpdir/innodb_tmpdir 及数据目录 |
用小规模演练验证时间、行数和余量
生产表很大时,先克隆表结构,灌入一小批具有相似索引分布的数据,再执行同一条 ALTER。命令结束后的 rows affected 可以帮助判断是否发生了表数据复制:新增索引常见为 0 行受影响,而修改列类型等重建类操作会出现非零值。这个信号不是完整性能报告,却足以筛掉明显不适合在线窗口的方案。
演练记录四个数:DDL 总耗时、提交阶段等待时间、临时目录峰值、在线变更日志峰值。再把生产写入峰值代入复核。若磁盘余量只够静态索引、没有日志和排序空间,或者演练已经出现明显 metadata lock 等待,就应该改用副本逐台变更、低峰执行或专门的在线变更工具,而不是把 LOCK=NONE 当作保证。
常见问题
LOCK=NONE 是不是完全不会锁表?
不是。它允许并发读写,但提交表定义时仍可能短暂申请排他元数据锁,并等待长事务释放。
innodb_online_alter_log_max_size 越大越好吗?
不是。上限更大能容纳更多并发 DML,但收尾时需要应用更多变更,最终锁定阶段可能变长,也会增加空间预算。
加一个二级索引为什么还要检查临时目录?
索引创建可能使用临时排序文件,文件通常写入 MySQL 临时目录;目录空间不足会让在线 DDL 失败。
评估在线加索引时,把“锁”和“空间”放在同一张发布清单里:算法约束保证不会静默退化,元数据锁检查避免长事务卡住提交,临时对象预算则决定这次变更是否真的具备上线条件。
Go embed.FS把静态资源交给 HTTP 服务的挂载方法
- 上一篇
- Go embed.FS把静态资源交给 HTTP 服务的挂载方法
- 下一篇
- 墨刀AI做UI原型能到什么程度?用页面结构、交互状态和评审交付判断
-
- 数据库 · MySQL | 2小时前 | MySQL · SQL查询 · 窗口函数 · ROW_NUMBER · 数据分组 · ROW_NUMBER PARTITION BY MySQL 窗口函数 每组最新记录 分组取最新
- MySQL 窗口函数按分组取每组最新记录的实现方法
- 185浏览 收藏
-
- 数据库 · MySQL | 5小时前 | MySQL · 数据库性能 · mysql 临时表 Performance Schema temptable_max_ram tmp_table_size
- MySQL temptable_max_ram 观察临时表内存阈值如何设置
- 409浏览 收藏
-
- 数据库 · MySQL | 7小时前 | MySQL · 索引优化 · mysql Invisible Index 索引可见性
- MySQL invisible index 试验结束后如何恢复可见
- 118浏览 收藏
-
- 数据库 · MySQL | 8小时前 |
- MySQL 角色继承权限后 SHOW GRANTS 如何解读
- 101浏览 收藏
-
- 数据库 · MySQL | 9小时前 |
- MySQL 复制状态中 Retrieved_Gtid_Set 如何辅助定位缺口
- 221浏览 收藏
-
- 数据库 · MySQL | 10小时前 | MySQL · 性能分析 · Performance Schema · SQL耗时 · mysql Performance Schema events_statements 平均耗时
- MySQL Performance Schema events_statements 如何找平均耗时
- 125浏览 收藏
-
- 数据库 · MySQL | 13小时前 |
- MySQL LOAD DATA 导入 TSV 时如何处理字段内制表符
- 253浏览 收藏
-
- 数据库 · MySQL | 15小时前 |
- MySQL 窗口函数按时间去重时如何保留最新行
- 312浏览 收藏
-
- 数据库 · MySQL | 16小时前 |
- MySQL CTE 递归深度如何避免意外超限
- 191浏览 收藏
-
- 数据库 · MySQL | 17小时前 | MySQL · JSON · 数据校验 · mysql CHECK JSON Schema JSON_SCHEMA_VALID
- MySQL JSON_SCHEMA_VALID 如何在入库前拒绝结构错误
- 446浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 43次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 138次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 75次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 39次使用
-
- CMMLU
- 深入了解CMMLU中文评估基准,涵盖67个学科主题,提供数据集下载、Zero-shot/Five-shot评估方法及排行榜,助力优化中文语言模型性能。
- 26次使用
-
- MySQL JSON_TABLE 展开数组时如何保留缺失字段
- 2026-09-10 501浏览
-
- MySQL 分区表怎么处理跨分区唯一键:分区列约束与建表取舍
- 2026-08-30 501浏览
-
- MySQL权限管理设置全攻略
- 2026-03-29 501浏览
-
- MySQL分片实现方法及常见方案解析
- 2025-06-24 501浏览
-
- MySQL表空间碎片怎么清理?超详细优化教程
- 2025-06-13 501浏览

