它的本质是**S 锁不是一把“禁止进入”的锁而是一张“允许共存”的通行证。核心定义S 锁 (Shared Lock)又称读锁。当事务对数据行加上 S 锁后其他事务也可以对该行加 S 锁但不能加 X 锁排他锁/写锁。X 锁 (Exclusive Lock)又称写锁。当事务对数据行加上 X 锁后其他事务既不能加 S 锁也不能加 X 锁。存在理由支持并发读多个用户可以同时读取同一份数据互不干扰。这是数据库高并发读的基石。保证一致性读在需要强一致性的场景下如金融转账前的余额查询防止在读的过程中数据被修改。与 MVCC 互补普通SELECT使用 MVCC快照读不加锁SELECT ... LOCK IN SHARE MODE使用 S 锁当前读加锁。核心逻辑别把 S 锁当成“只读保护”。把它当成读者俱乐部的会员卡。持有会员卡的人可以一起看书并发读但如果有人想撕书或改书加 X 锁必须等所有持卡人都离开后才能进行。如果把数据行比作图书馆的一本书无锁谁都可以拿容易抢起来。S 锁 (共享锁)张三借走了书加了 S 锁。李四也想看也可以借走再加一个 S 锁。王五也想看也可以借走再加一个 S 锁。赵六想修改书里的内容加 X 锁管理员说“不行现在还有三个人在看呢等他们还回来再说。” -阻塞。X 锁 (排他锁)张三借走书并说要修改加了 X 锁。李四想看不行等着。王五想改不行等着。核心逻辑S 锁的核心价值在于读读兼容 (Read-Read Compatible)但读写互斥 (Read-Write Exclusive)。一、底层实现机制锁在哪里1. 锁存储在索引上事实和行锁一样S 锁也是加在索引记录 (Index Record)上的。机制InnoDB 在 B 树的叶子节点中为每个索引记录维护一个锁列表 (Lock List)。锁列表中包含持有该锁的事务 ID 和锁类型S 或 X。当新事务请求 S 锁时InnoDB 遍历锁列表如果列表中只有 S 锁批准加入列表。如果列表中有 X 锁拒绝进入等待队列。2. 意向锁 (Intention Locks) —— 表级的快速检查问题如果我要给整张表加锁难道要检查每一行的锁吗太慢了。解决方案意向锁。IS (Intention Shared)事务打算在某行加 S 锁前先在表级别加 IS 锁。IX (Intention Exclusive)事务打算在某行加 X 锁前先在表级别加 IX 锁。作用如果我想给全表加 S 锁我只需检查表上是否有 IX 锁。如果有说明有人要在某行写全表 S 锁失败。价值将表锁的检查复杂度从 O(N) 降为 O(1)。 核心洞察S 锁是细粒度的行级但通过意向锁实现了粗粒度表级的快速冲突检测。二、兼容性矩阵谁能和谁共存这是理解 S 锁的关键。当前锁 \ 请求锁S (共享)X (排他)S (共享)✅ 兼容❌ 冲突X (排他)❌ 冲突❌ 冲突S S OK大家都能读。S X Wait有人在读写的必须等。X S Wait有人在写读的必须等。X X Wait有人在写另一个写的也必须等。 核心洞察S 锁的唯一天敌是 X 锁。只要没有写操作S 锁可以无限叠加。三、获取方式PHP 中如何触发 S 锁在 MySQL 中有两种主要方式获取 S 锁1. 显式锁定读 (Explicit Locking Read)SQLSELECT ... LOCK IN SHARE MODE;(MySQL 8.0 推荐SELECT ... FOR SHARE)场景你需要读取一行数据并确保在你处理完业务逻辑并提交之前其他人不能修改它。例如检查父记录是否存在然后插入子记录。PHP 代码$pdo-beginTransaction();// 加 S 锁$stmt$pdo-query(SELECT * FROM categories WHERE id 1 FOR SHARE);$category$stmt-fetch();if($category){// 此时其他事务可以读 category但不能修改它// 直到本事务 commit$pdo-exec(INSERT INTO products (cat_id, name) VALUES (1, Book));}$pdo-commit();2. 外键约束检查 (Foreign Key Checks)机制当你在子表中插入或更新外键字段时InnoDB 会自动在父表的对应记录上加S 锁。目的确保父记录在子记录引用期间不会被删除或修改主键。价值自动维护参照完整性无需手动加锁。四、S 锁 vs. MVCC为什么平时 SELECT 不加锁这是初学者最大的困惑。1. 快照读 (Snapshot Read)语句普通SELECT * FROM t;机制不加任何锁。通过Undo Log和Read View读取历史版本。价值极高的并发读性能。读写完全互不阻塞。缺点读到的是旧数据不可重复读或幻读取决于隔离级别。2. 当前读 (Current Read)语句SELECT ... FOR SHARE,SELECT ... FOR UPDATE,UPDATE,DELETE.机制加锁S 或 X。读取最新数据。价值保证数据的新鲜性和一致性。缺点有锁竞争并发度低于快照读。 核心洞察MySQL 默认使用 MVCC 来实现“读不加锁”只有在显式要求或写操作时才使用 S/X 锁。这是 MySQL 高并发的秘密武器。五、认知牢笼常见误区1. 误区“S 锁会阻塞其他 S 锁。”真相不会。S 锁之间是完全兼容的。对策放心让多个用户同时执行FOR SHARE。2. 误区“普通的 SELECT 也会加 S 锁。”真相不会。普通 SELECT 是快照读不加锁。对策只有FOR SHARE/LOCK IN SHARE MODE才加 S 锁。3. 误区“S 锁能防止幻读。”真相单独 S 锁不能防止幻读。需要配合Next-Key Lock(S 锁 Gap Lock) 才能在 RR 级别下防止幻读。对策理解 S 锁只是记录锁范围查询时会自动升级为 Next-Key Lock。4. 误区“S 锁性能很差。”真相相比 X 锁S 锁的并发度高得多。相比 MVCCS 锁有开销。对策仅在需要强一致性读时使用FOR SHARE否则用普通SELECT。5. 误区“S 锁只在 RR 级别有效。”真相S 锁在所有隔离级别下都有效。但在 RC 级别下S 锁的范围可能不同无 Gap Lock。对策根据业务需求选择隔离级别。 总结原子化“MySQL S 锁”全景图维度关键点本质允许多个事务同时读取同一资源的共享机制核心特性读读兼容读写互斥实现位置索引记录 意向锁 (表级)获取方式SELECT ... FOR SHARE, 外键检查与 MVCC 关系MVCC 用于快照读无锁S 锁用于当前读有锁PHP 隐喻Library Reading Room (S Lock) vs. Editing Desk (X Lock)公式Concurrency (Shared_Access × Compatibility) ^ Write_Exclusion终极心法S 锁的本质是“对共享的优雅管理”。它让阅读变得自由让写入变得有序。它是并发世界中温柔的一面。于兼容中见效率于互斥中见秩序以共享为尺解独占之牛于数据交互中求和谐之真。行动指令实验兼容性开启两个事务。事务 A 执行SELECT ... FOR SHARE。事务 B 也执行SELECT ... FOR SHARE。观察是否阻塞不应阻塞。测试互斥事务 A 执行SELECT ... FOR SHARE。事务 B 执行UPDATE。观察事务 B 是否阻塞应阻塞。对比 MVCC对比普通SELECT和SELECT ... FOR SHARE在并发下的表现差异。思维升级记住S 锁是强一致性读的利器但 MVCC 是高并发读的基石。明智地选择两者才能平衡一致性与性能。
MySQL如何实现S锁?
发布时间:2026/6/12 2:33:18
它的本质是**S 锁不是一把“禁止进入”的锁而是一张“允许共存”的通行证。核心定义S 锁 (Shared Lock)又称读锁。当事务对数据行加上 S 锁后其他事务也可以对该行加 S 锁但不能加 X 锁排他锁/写锁。X 锁 (Exclusive Lock)又称写锁。当事务对数据行加上 X 锁后其他事务既不能加 S 锁也不能加 X 锁。存在理由支持并发读多个用户可以同时读取同一份数据互不干扰。这是数据库高并发读的基石。保证一致性读在需要强一致性的场景下如金融转账前的余额查询防止在读的过程中数据被修改。与 MVCC 互补普通SELECT使用 MVCC快照读不加锁SELECT ... LOCK IN SHARE MODE使用 S 锁当前读加锁。核心逻辑别把 S 锁当成“只读保护”。把它当成读者俱乐部的会员卡。持有会员卡的人可以一起看书并发读但如果有人想撕书或改书加 X 锁必须等所有持卡人都离开后才能进行。如果把数据行比作图书馆的一本书无锁谁都可以拿容易抢起来。S 锁 (共享锁)张三借走了书加了 S 锁。李四也想看也可以借走再加一个 S 锁。王五也想看也可以借走再加一个 S 锁。赵六想修改书里的内容加 X 锁管理员说“不行现在还有三个人在看呢等他们还回来再说。” -阻塞。X 锁 (排他锁)张三借走书并说要修改加了 X 锁。李四想看不行等着。王五想改不行等着。核心逻辑S 锁的核心价值在于读读兼容 (Read-Read Compatible)但读写互斥 (Read-Write Exclusive)。一、底层实现机制锁在哪里1. 锁存储在索引上事实和行锁一样S 锁也是加在索引记录 (Index Record)上的。机制InnoDB 在 B 树的叶子节点中为每个索引记录维护一个锁列表 (Lock List)。锁列表中包含持有该锁的事务 ID 和锁类型S 或 X。当新事务请求 S 锁时InnoDB 遍历锁列表如果列表中只有 S 锁批准加入列表。如果列表中有 X 锁拒绝进入等待队列。2. 意向锁 (Intention Locks) —— 表级的快速检查问题如果我要给整张表加锁难道要检查每一行的锁吗太慢了。解决方案意向锁。IS (Intention Shared)事务打算在某行加 S 锁前先在表级别加 IS 锁。IX (Intention Exclusive)事务打算在某行加 X 锁前先在表级别加 IX 锁。作用如果我想给全表加 S 锁我只需检查表上是否有 IX 锁。如果有说明有人要在某行写全表 S 锁失败。价值将表锁的检查复杂度从 O(N) 降为 O(1)。 核心洞察S 锁是细粒度的行级但通过意向锁实现了粗粒度表级的快速冲突检测。二、兼容性矩阵谁能和谁共存这是理解 S 锁的关键。当前锁 \ 请求锁S (共享)X (排他)S (共享)✅ 兼容❌ 冲突X (排他)❌ 冲突❌ 冲突S S OK大家都能读。S X Wait有人在读写的必须等。X S Wait有人在写读的必须等。X X Wait有人在写另一个写的也必须等。 核心洞察S 锁的唯一天敌是 X 锁。只要没有写操作S 锁可以无限叠加。三、获取方式PHP 中如何触发 S 锁在 MySQL 中有两种主要方式获取 S 锁1. 显式锁定读 (Explicit Locking Read)SQLSELECT ... LOCK IN SHARE MODE;(MySQL 8.0 推荐SELECT ... FOR SHARE)场景你需要读取一行数据并确保在你处理完业务逻辑并提交之前其他人不能修改它。例如检查父记录是否存在然后插入子记录。PHP 代码$pdo-beginTransaction();// 加 S 锁$stmt$pdo-query(SELECT * FROM categories WHERE id 1 FOR SHARE);$category$stmt-fetch();if($category){// 此时其他事务可以读 category但不能修改它// 直到本事务 commit$pdo-exec(INSERT INTO products (cat_id, name) VALUES (1, Book));}$pdo-commit();2. 外键约束检查 (Foreign Key Checks)机制当你在子表中插入或更新外键字段时InnoDB 会自动在父表的对应记录上加S 锁。目的确保父记录在子记录引用期间不会被删除或修改主键。价值自动维护参照完整性无需手动加锁。四、S 锁 vs. MVCC为什么平时 SELECT 不加锁这是初学者最大的困惑。1. 快照读 (Snapshot Read)语句普通SELECT * FROM t;机制不加任何锁。通过Undo Log和Read View读取历史版本。价值极高的并发读性能。读写完全互不阻塞。缺点读到的是旧数据不可重复读或幻读取决于隔离级别。2. 当前读 (Current Read)语句SELECT ... FOR SHARE,SELECT ... FOR UPDATE,UPDATE,DELETE.机制加锁S 或 X。读取最新数据。价值保证数据的新鲜性和一致性。缺点有锁竞争并发度低于快照读。 核心洞察MySQL 默认使用 MVCC 来实现“读不加锁”只有在显式要求或写操作时才使用 S/X 锁。这是 MySQL 高并发的秘密武器。五、认知牢笼常见误区1. 误区“S 锁会阻塞其他 S 锁。”真相不会。S 锁之间是完全兼容的。对策放心让多个用户同时执行FOR SHARE。2. 误区“普通的 SELECT 也会加 S 锁。”真相不会。普通 SELECT 是快照读不加锁。对策只有FOR SHARE/LOCK IN SHARE MODE才加 S 锁。3. 误区“S 锁能防止幻读。”真相单独 S 锁不能防止幻读。需要配合Next-Key Lock(S 锁 Gap Lock) 才能在 RR 级别下防止幻读。对策理解 S 锁只是记录锁范围查询时会自动升级为 Next-Key Lock。4. 误区“S 锁性能很差。”真相相比 X 锁S 锁的并发度高得多。相比 MVCCS 锁有开销。对策仅在需要强一致性读时使用FOR SHARE否则用普通SELECT。5. 误区“S 锁只在 RR 级别有效。”真相S 锁在所有隔离级别下都有效。但在 RC 级别下S 锁的范围可能不同无 Gap Lock。对策根据业务需求选择隔离级别。 总结原子化“MySQL S 锁”全景图维度关键点本质允许多个事务同时读取同一资源的共享机制核心特性读读兼容读写互斥实现位置索引记录 意向锁 (表级)获取方式SELECT ... FOR SHARE, 外键检查与 MVCC 关系MVCC 用于快照读无锁S 锁用于当前读有锁PHP 隐喻Library Reading Room (S Lock) vs. Editing Desk (X Lock)公式Concurrency (Shared_Access × Compatibility) ^ Write_Exclusion终极心法S 锁的本质是“对共享的优雅管理”。它让阅读变得自由让写入变得有序。它是并发世界中温柔的一面。于兼容中见效率于互斥中见秩序以共享为尺解独占之牛于数据交互中求和谐之真。行动指令实验兼容性开启两个事务。事务 A 执行SELECT ... FOR SHARE。事务 B 也执行SELECT ... FOR SHARE。观察是否阻塞不应阻塞。测试互斥事务 A 执行SELECT ... FOR SHARE。事务 B 执行UPDATE。观察事务 B 是否阻塞应阻塞。对比 MVCC对比普通SELECT和SELECT ... FOR SHARE在并发下的表现差异。思维升级记住S 锁是强一致性读的利器但 MVCC 是高并发读的基石。明智地选择两者才能平衡一致性与性能。