show processlist 会显示状态为“waiting for table level lock”的locked线程;alter table因拷贝表流程持write锁致全表阻塞;迁innodb需注意fulltext索引、auto_increment锁行为及外键约束差异。

MyISAM 表锁阻塞时,SHOW PROCESSLIST 看到什么?
你执行一条 UPDATE 或 INSERT 后,其他查询突然卡住,SELECT 也变慢——这时立刻运行 SHOW PROCESSLIST,大概率会看到一堆 Locked 状态的线程,状态列写着 Waiting for table level lock。这不是死锁,是 MyISAM 的天然行为:写操作(哪怕只是 INSERT)会锁整张表,所有后续读写都排队。
为什么 ALTER TABLE 会让整个库“假死”?
MyISAM 执行 ALTER TABLE 时默认走「拷贝表」流程:先建新表、逐行复制数据、重建索引、再原子替换。整个过程持有 WRITE 表锁,期间任何对原表的 SELECT 都得等。尤其在大表上,这个等待可能持续几分钟甚至更久。
- 小表(ALTER TABLE 影响有限,但别在高峰期做
- 中大表(>100 万行)务必改用
pt-online-schema-change工具,它通过触发器+影子表绕过锁 -
CONCURRENT INSERT对INSERT有帮助,但对UPDATE/DELETE无效,别指望它解决核心阻塞
从 MyISAM 切到 InnoDB,哪些地方必须改?
直接改存储引擎不等于万事大吉。ALTER TABLE t ENGINE=InnoDB 虽能执行,但容易踩三个坑:
-
FULLTEXT索引:MyISAM 支持,InnoDB 5.6+ 才支持,且语法和分词行为有差异,迁移后要重测搜索逻辑 -
AUTO_INCREMENT行为:InnoDB 的自增锁更严格,高并发插入可能引发间隙锁等待,不是性能下降,而是锁表现不同 - 外键约束:InnoDB 支持,MyISAM 不支持;加了外键后
DELETE可能触发级联检查,变慢——这反而是正确性保障,别为提速删外键
临时救急:怎么快速释放被锁住的 MyISAM 表?
如果已经卡住,别重启 MySQL。先用 SHOW PROCESSLIST 找出 State 是 Locked 且 Command 是 Query 的长耗时线程,记下它的 ID,然后执行:KILL [ID]。注意:KILL 对正在写磁盘的线程可能延迟生效,且被杀的语句会回滚,已写入部分不丢,但事务完整性由应用层兜底。
真正难处理的是那种没出现在 PROCESSLIST 里、但实际卡住的锁——往往是未提交的 LOCK TABLES ... WRITE 语句,这种只能靠 FLUSH TABLES 强制关闭所有表缓存来清掉,代价是下次访问会重新加载。
MyISAM 的锁机制是设计使然,不是 bug。想彻底避开阻塞,唯一可靠路径是迁移到 InnoDB,并接受它带来的事务语义变化。那些“加个索引就能提速”的优化,在表级锁面前基本无效。











