MySQL - 进阶篇 - 5. 锁

📘 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行锁类型说明
INSERTX锁自动加锁
UPDATEX锁自动加锁
SELECT ... LOCK IN SHARE MODES锁手动加
SELECT ... FOR UPDATEX锁手动加
🏢 企业实战
  • 亚马逊仓库系统:出库锁定商品时,使用行锁(而非表锁)提升并发处理速度。

  • 英伟达 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)保证全球一致性事务。

  • 字节跳动直播系统:通过间隙锁防止同一直播房间创建多条重复记录。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏驰和徐策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值