在MySQL Workbench添加索引后表查询超时疑似损坏,该如何恢复?
问题描述
操作步骤
右键点击目标表 > Table Inspector > 点击「Columns」标签 > 右键选择Create Index
该环节保留了如下默认配置:
- Algo: Default
- Locking: Default (允许最大并发)
问题现象
操作返回超时错误,之后尝试执行简单的SELECT *查询也一直超时。此前认为添加索引不会损坏表所以没有备份,需要回滚当前操作。
执行show full processlist命令后结果如下:
核心查询结果如下:
| 状态 | 执行语句 |
|---|---|
Waiting for table metadata lock | CREATE INDEX idx_all_mls_2_Centris_No ON mcgillim_matrix.all_mls_2 (Centris_No) COMMENT '' ALGORITHM DEFAULT LOCK DEFAULT |
解决方案
根因说明
当前是表元数据锁等待导致的阻塞,未执行完成的建索引DDL进入了元数据锁等待队列,后续所有访问该表的请求(包括普通SELECT)都会被阻塞,并非表数据损坏,不会丢失原有数据,无需担心。
操作步骤
- 杀掉卡住的建索引进程
从show full processlist结果中找到上述建索引语句对应的进程ID(即Id列的数值),执行命令:
该操作会直接终止未完成的DDL,MySQL会自动回滚该操作,不会残留无效索引,也不会修改原表任何数据,操作完全安全。KILL 对应进程ID; - 清理残留长事务(仅杀建索引进程后仍查询超时的情况执行)
执行以下命令查询当前运行中的长事务:
找到运行时间超过1分钟的非必要活跃事务,同样用SELECT * FROM information_schema.innodb_trx;KILL命令杀掉对应会话进程即可释放所有残留的元数据锁。 - 验证表状态
执行简单查询验证表恢复正常:
正常返回结果即代表表完全正常,之前的操作未造成任何影响。SELECT * FROM mcgillim_matrix.all_mls_2 LIMIT 1;
后续优化建议
- 大表加索引尽量选业务低峰期操作,避免高峰期触发锁等待影响业务
- 建议直接写SQL执行DDL,不要用可视化工具的图形化操作,可显式指定在线DDL参数避免阻塞读写(MySQL5.6及以上版本支持):
CREATE INDEX idx_all_mls_2_Centris_No ON mcgillim_matrix.all_mls_2 (Centris_No) ALGORITHM=INPLACE LOCK=NONE; - 执行DDL前可先查询表体积预估执行时间:
SELECT table_name,round(((data_length + index_length)/1024/1024),2) AS '表大小(MB)' FROM information_schema.TABLES WHERE table_schema = 'mcgillim_matrix' AND table_name = 'all_mls_2';
内容的提问来源于stack exchange,提问作者Robert Sinclair
相关产品推荐
相关产品推荐

