MySQL 表级锁

397 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

根据加锁的范围,MySQL 里面的锁大致可以分为:全局锁、表级锁、行锁三类。今天学习一下表级锁。

MySQL 表级锁有两种:一种是表锁,一种是元数据锁(meta data lock,MDL)。

表锁

加锁

 lock tables ... read/write

解锁

 unlock tables

应用场景

对于不支持行锁的引擎(MyISAM 仅支持表锁),使用它控制并发

意向锁

意向锁是一种协作机制,用于表锁和行锁的共生场景。(InnoDB 引擎)

意向共享锁(IS):事务想获得表中某些记录的共享锁,需要在表上先加意向共享锁。

意向互斥锁(IX):事务想获得表中某些记录的互斥锁,需要在表上先加意向互斥锁。

自增锁(autoinc_lock)

autoinc_lock 是一种特殊的表级锁,和 autoinc_lock、表级 S 锁和 X 锁不相容。

autoinc_lock 加锁逻辑,受 indodb_autoinc_lock_mode 控制。

  • 模式 0-传统锁定模式

    语句执行结束后才释放自增锁。

  • 模式 1-自动模式(默认)

    普通 insert 语句,自增锁在申请之后马上释放。

    类似 insert...select 语句,自增锁在语句结束之后才释放。

  • 模式 2

    所有 insert 语句都在申请后马上释放。

元数据锁(MDL 锁)

MDL 锁,分为 MDL 读锁和 MDL 写锁,读锁和读锁不冲突,读锁和写锁互斥,写锁和写锁互斥。

加锁

在访问一个表的时候会被自动加上。

当对一个表做增删改查操作的时候,申请 MDL 读锁。

当对表结构进行变更的时候,申请 MDL 写锁,获取写锁时需要等待读锁释放,且申请写锁会阻塞后续所有 MDL 锁的获取

解锁

事务中的 MDL 锁,在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后再释放。

应用场景

系统自动使用,用于避免 DDL 和 DML 并发冲突。

总结

MySQL 的表级锁主要有两种,第一个是表锁,注意特殊的意向锁、自增锁。

第二个是元数据锁,由于系统默认加锁、解锁,平时可能感觉不到,但是操作表结构时,务必注意这个锁。

参考

《MySQL 实战 45 讲》

《SQL必知必会》

《网易云课堂》