
📘 MySQL - 进阶篇 - 5. 锁
5. 锁
5.1 概述
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除了传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的问题,锁冲突也是影响数据库并发访问性能的重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
MySQL中的锁,按照锁的粒度分为三类:
-
全局锁:锁定数据库中的所有表。
-
表级锁:每次操作锁住整张表。
-
行级锁:每次操作锁住对应的行数据。
🧠 理论理解
锁是计算机协调多个进程或线程并发访问共享资源的重要机制。数据库中,除了传统的 CPU、RAM、IO 的竞争之外,数据本身也作为共享资源,必须通过锁机制保证一致性与并发性能。
MySQL 将锁细分为不同粒度(全局锁、表级锁、行级锁),根据应用场景灵活选择。
🏢 企业实战
-
阿里巴巴(淘宝双11):大量使用行锁,优化库存扣减,高并发秒杀系统。
-
字节跳动(抖音、今日头条):广告计费、推荐系统中广泛使用行锁、意向锁防止资源冲突。
-
Google Spanner:使用精细化锁和多版本控制(MVCC)保证全球范围强一致性。
-
英伟达(GPU云服务平台):后台数据库使用细粒度行锁优化任务调度系统。
5.2 全局锁
5.2.1 介绍
全局锁就是对整个数据库实例加锁,加锁后整个实例处于只读状态,DML写语句、DDL语句、事务提交都会被阻塞。
典型使用场景:全库逻辑备份,加锁获取一致性视图,保证数据完整性。
不加锁存在的问题:
备份过程中若业务系统发生写操作(如下单),则导致备份出来的表数据不一致。
加锁后的效果:
备份前加全局锁,使数据库进入只读状态,期间业务写操作被阻塞,从而保证备份数据的一致性和完整性。
🧠 理论理解
全局锁(Global Lock)会让整个数据库实例进入只读状态。适合做逻辑备份,确保备份数据的一致性,避免备份过程中数据变化导致的数据不一致问题。
不加锁备份风险:
-
备份期间数据修改 → 备份数据不一致,影响恢复。
加锁备份效果:
-
备份期间只能读,不能写,保证数据一致性。
🏢 企业实战
-
MySQL社区版 + 企业版(Google Cloud SQL):全局锁配合逻辑备份(mysqldump)保障备份数据一致性。
-
字节跳动:内部备份系统对部分低频表采用全局锁加备份,但对在线业务高频表使用快照隔离(snapshot)。
-
阿里巴巴 OceanBase:通过“逻辑备份 + 物理备份”双策略,减少全局锁对业务影响。
5.2.2 语法
-- 加全局锁
flush tables with read lock;
-- 进行数据备份
mysqldump -uroot -p密码 数据库名 > 备份文件.sql
-- 释放锁
unlock tables;
🧠 理论理解
-
flush tables with read lock:锁定所有表,只允许读。 -
unlock tables:释放锁,恢复正常读写。
🏢 企业实战
-
Google Cloud SQL:备份前执行 FTWRL(flush tables with read lock)确保数据一致性。
-
京东数据库运维:在业务低峰期(凌晨)短暂加锁完成备份,避免影响高峰期事务。
5.2.3 特点
-
在主库加全局锁会导致业务停摆。
-
在从库加全局锁会导致主从延迟。
-
InnoDB存储引擎中,可以使用
--single-transaction参数进行一致性备份,避免加全局锁。
🧠 理论理解
-
全局锁影响范围大,期间所有DML/DDL暂停。
-
主库加锁影响线上业务,常在从库上加锁备份。
-
InnoDB引擎支持
--single-transaction无锁备份(事务隔离实现)。
🏢 企业实战
-
AWS RDS:备份期间从库加锁而不是主库,确保主库高可用。
-
字节跳动 DBA体系:使用 Percona XtraBackup 工具,做到无需加全局锁的物理备份。
5.3 表级锁
5.3.1 介绍
表级锁每次操作锁住整张表。锁定粒度大,锁冲突概率高,并发度最低。适用于 MyISAM、InnoDB、BDB等存储引擎。
表级锁包括三类:
-
表锁(Table Lock)
-
元数据锁(Meta Data Lock, MDL)
-
意向锁(Intention Lock)
🧠 理论理解
表级锁(Table Lock)是对整张表加锁,粒度大,锁冲突概率高,但加锁释放速度快,开销小。
分为:
-
表锁
-
元数据锁(Meta Data Lock,MDL)
-
意向锁(Intention Lock)
🏢 企业实战
-
淘宝商品表:为了避免大表DDL影响业务,使用 MDL 元数据锁保护表结构。
-
Facebook MyRocks存储引擎:引入意向锁优化表级并发访问。
-
Google Cloud Bigtable:虽然是KV系统,但在管理元数据时类似使用了"表级锁"机制保护 consistency。
5.3.2 表锁
类型
-
共享读锁(read lock)
-
独占写锁(write lock)
语法
-- 加锁
lock tables 表名 read/write;
-- 释放锁
unlock tables;
特点
-
读锁:不会阻塞其他读,但会阻塞写。
-
写锁:阻塞其他读和写。
🧠 理论理解
表锁可以是:
-
读锁(共享锁):允许读,阻塞写。
-
写锁(排它锁):阻塞读与写。
🏢 企业实战
-
阿里云 RDS MySQL:DML操作时避免表锁,控制表锁争用次数提升并发。
-
OpenAI内部日志系统:对于大量追加写入场景,使用短时间表锁加快日志入库。
5.3.3 元数据锁(MDL)
介绍
元数据锁是MySQL自动管理的锁,用于维护表结构(表元数据)的并发一致性。
加锁规则
-
进行 DML(增删改查)操作时,加 MDL读锁。
-
进行 DDL(修改表结构)操作时,加 MDL写锁。
查看元数据锁
select object_type, object_schema, object_name, lock_type, lock_duration
from performance_schema.metadata_locks;
🧠 理论理解
MDL(Meta Data Lock)保护表的结构一致性。在事务活跃时阻止DDL操作(如ALTER TABLE)。
常见加锁规则:
-
查询、增删改 → 加 MDL读锁。
-
表结构变化 → 加 MDL写锁。
查看锁情况:
select * from performance_schema.metadata_locks;
🏢 企业实战
-
腾讯云数据库TDSQL:为了支持热表DDL,设计了非阻塞MDL机制。
-
字节跳动广告投放系统:在线表变更(OSC工具)避免MDL长时间持有导致业务阻塞。
5.3.4 意向锁
介绍
InnoDB引擎引入意向锁,避免表锁与行锁冲突,加速表锁申请。
分类
-
意向共享锁(IS):select ... lock in share mode。
-
意向排他锁(IX):insert、update、delete、select ... for update。
查看意向锁和行锁
select object_schema, object_name, index_name, lock_type, lock_mode, lock_data
from performance_schema.data_locks;
🧠 理论理解
意向锁用于快速判断表是否可以加锁,避免行锁和表锁冲突。分为:
-
IS(意向共享锁)
-
IX(意向排它锁)
事务提交后意向锁自动释放。
查看锁情况:
select * from performance_schema.data_locks;
🏢 企业实战
-
京东金融数据库:在多事务并发操作时,意向锁机制帮助快速申请表锁,避免死锁。
-
字节跳动内容推荐系统:意向锁加速了索引级别锁冲突检测,提高内容实时检索性能。
5.4 行级锁
5.4.1 介绍
行级锁每次锁住具体的行数据,锁定粒度最小,冲突概率最低,并发度最高,应用在InnoDB存储引擎中。
行锁是加在索引项上的,不是直接加在记录上的。
分类:
-
行锁(Record Lock)
-
间隙锁(Gap Lock)
-
临键锁(Next-Key Lock)
🧠 理论理解
行级锁(Row Lock)是InnoDB引擎细粒度锁,对具体数据行加锁,粒度小,并发度高。
类型:
-
行锁(Record Lock)
-
间隙锁(Gap Lock)
-
临键锁(Next-Key Lock)
行锁是加在索引上的,不是加在记录本身上。
🏢 企业实战
-
拼多多大促秒杀系统:采用行锁配合库存扣减,避免超卖。
-
字节跳动评论系统:通过Next-Key锁配合防止幻读,确保评论唯一性。
5.4.2 行锁
类型
-
共享锁(S锁):允许读取,阻止其他写入。
-
排他锁(X锁):允许更新,阻止其他读和写。
常见SQL及加锁情况
| SQL | 行锁类型 | 说明 |
|---|---|---|
| INSERT | 排他锁 | 自动加锁 |
| UPDATE | 排他锁 | 自动加锁 |
| DELETE | 排他锁 | 自动加锁 |
| SELECT(正常) | 无锁 | 不加锁 |
| SELECT ... LOCK IN SHARE MODE | 共享锁 | 需手动加 |
| SELECT ... FOR UPDATE | 排他锁 | 需手动加 |
🧠 理论理解
行锁类型:
-
共享锁(S锁):允许读取,不允许修改。
-
排他锁(X锁):允许修改,阻止其他读写。
常见加锁SQL示例:
| SQL | 行锁类型 | 说明 |
|---|---|---|
INSERT | X锁 | 自动加锁 |
UPDATE | X锁 | 自动加锁 |
SELECT ... LOCK IN SHARE MODE | S锁 | 手动加 |
SELECT ... FOR UPDATE | X锁 | 手动加 |
🏢 企业实战
-
亚马逊仓库系统:出库锁定商品时,使用行锁(而非表锁)提升并发处理速度。
-
英伟达 GPU租赁平台:每块显卡资源加行锁,避免资源冲突预定。
5.4.3 间隙锁 & 临键锁
默认策略
InnoDB在RR(可重复读)隔离级别下,默认使用Next-Key Lock(临键锁)防止幻读。
特殊情况
-
唯一索引等值查询不存在记录 → 退化为间隙锁。
-
普通索引等值查询向右遍历到第一个不满足记录 → 退化为间隙锁。
-
范围查询(>、<、BETWEEN等) → 加Next-Key Lock。
🧠 理论理解
InnoDB默认在RR隔离级别下启用Next-Key锁,防止幻读。
-
间隙锁(Gap Lock):锁定一段区间,防止插入。
-
临键锁(Next-Key Lock):锁定数据 + 前后间隙。
特殊场景:
-
唯一索引等值查询不存在记录 → 优化为Gap锁。
-
非唯一索引查询范围 → 退化为Gap锁。
🏢 企业实战
-
Google Spanner数据库:使用多版本锁(类似Next-Key Lock)保证全球一致性事务。
-
字节跳动直播系统:通过间隙锁防止同一直播房间创建多条重复记录。

999

被折叠的 条评论
为什么被折叠?



