MySQL锁实际作用于事务和数据库资源,包括表、行、间隙、元数据等;InnoDB实现Lock(参与事务与死锁检测),而Latch是底层内存同步机制;意向锁和MDL锁虽不显式可见,却常导致DDL卡死。

MySQL锁到底锁的是什么?
MySQL的锁不是抽象概念,而是真实作用在数据结构上的控制机制:锁的对象是事务,锁的目标是数据库资源(表、页、行、间隙、元数据等)。关键在于——Lock由InnoDB存储引擎实现,而Latch(如mutex、rwlock)是更底层的内存同步机制,不归事务管理,也不参与死锁检测。初学者常把二者混淆,结果用SHOW ENGINE INNODB STATUS查不到Latch信息,却误以为“没加锁”。
按粒度分:表锁、行锁、间隙锁、临键锁怎么选?
粒度决定并发能力,也决定你是否会被“莫名其妙卡住”:
-
表锁(LOCK TABLES t1 READ/WRITE):整张表堵死,适合备份或DDL前的强制只读;但MyISAM默认用它,InnoDB仅在显式调用或无索引条件时退化使用 -
Record Lock:只锁索引记录本身,比如WHERE id = 10(id是主键),RR/RC隔离级别都支持 -
Gap Lock:锁区间,如(5, 10)(开区间),防止幻读,**仅在RR隔离级别生效**;RC下不启用,这也是RC可能产生幻读的根本原因 -
Next-Key Lock:Record Lock + Gap Lock,即(5, 10](前开后闭),InnoDB在RR下默认行为;但遇到唯一索引等值查询(如WHERE uniq_col = 'x')会自动优化为纯Record Lock,不锁间隙
意向锁(IX/IS)为什么不能忽略?
意向锁是InnoDB实现多粒度加锁的“预告机制”,属于表级锁,但不阻塞读写,只阻塞冲突的表级操作。常见误区是以为“没显式加表锁就不用管它”,其实只要事务对某行加了X锁,InnoDB会自动在表上加IX锁;此时若另一事务执行ALTER TABLE,就会被IX阻塞——因为ALTER需要S锁(共享表锁),而IX与S互斥。
典型现象:ALTER TABLE t1 ADD COLUMN c1 INT卡住,查INFORMATION_SCHEMA.INNODB_TRX发现有活跃事务,再看INFORMATION_SCHEMA.INNODB_LOCK_WAITS,源头往往就是未提交的DML触发了IX,拦住了DDL。
本程序源码为asp与acc编写,并没有花哨的界面与繁琐的功能,维护简单方便,只要你有一些点点asp的基础,二次开发易如反掌。 1.功能包括产品,新闻,留言簿,招聘,下载,...是大部分中小型的企业建站的首选。本程序是免费开源,只为大家学习之用。如果用于商业,版权问题概不负责。1.采用asp+access更加适合中小企业的网站模式。 2.网站页面div+css兼容目前所有主流浏览器,ie6+,Ch
MDL锁(元数据锁)是隐形杀手
MDL锁在Server层统一管理,只要执行任何涉及表结构的操作(哪怕只是SELECT),都会隐式加MDL读锁;而DROP/ALTER/TRUNCATE需MDL写锁。它的坑在于:它不显示在INNODB_LOCKS里,只出现在performance_schema.metadata_locks(MySQL 5.7+)或SHOW PROCESSLIST的State字段(如Waiting for table metadata lock)。
一个高频场景:SELECT * FROM t1在长事务中执行后未提交,紧接着有人执行ALTER TABLE t1 ADD INDEX——后者会一直等待,且不会被KILL掉,直到长事务结束。这是因为MDL写锁必须等所有MDL读锁释放。
真正难调试的从来不是“有没有锁”,而是“谁在持有一个你看不见的锁,又拦住了谁”。MDL和意向锁都不出现在传统InnoDB锁视图里,却常常是线上DDL卡死、慢查询堆积的根因。









