ARTICLE DETAIL

资讯详情

深耕网站SEO优化与搜索引擎排名提升的一线实战洞察。

5.4.1 锁分类

5.4.1 锁分类 MySQL 锁分类完全指南锁是数据库并发控制的“交通警察”。在 MySQL InnoDB 中锁的分类维度非常多可以按粒度、模式、算法、意图等多种维度划分。理解锁的分类是读懂死锁日志、优化高并发性能的必修课。锁的本质就是对共享资源数据行、表、间隙的访问权限控制。为了精确描述锁InnoDB 引入了多维度的分类体系一、按锁粒度作用范围分类这是最直观的分类方式决定了锁锁住多大的数据范围。锁粒度作用对象特点典型场景表级锁Table Lock整张表开销小、加锁快、并发度低DDL 操作ALTER TABLE、LOCK TABLES显式锁定行级锁Row Lock索引记录单行或多行开销大、加锁慢、并发度最高InnoDB 默认的UPDATE/DELETE操作页级锁Page Lock数据页16KB介于表锁和行锁之间仅 BDB 引擎支持InnoDB 不支持关键认知InnoDB 的行锁实际上是锁在索引记录Index Record上而不是直接锁在数据行上。如果表没有索引行锁会退化为全表扫描并加表锁。元数据锁MDLMetadata Lock这是 MySQL Server 层维护的一种特殊的表级锁不属于存储引擎层但非常重要。它用于保护表结构在事务执行期间不被修改DDL 操作。读锁MDL_SHARED执行SELECT、INSERT、UPDATE、DELETE时自动获取允许多个事务并发读取表结构。写锁MDL_EXCLUSIVE执行ALTER TABLE、DROP TABLE等 DDL 操作时获取阻塞所有其他读写操作。生产隐患长事务持有 MDL 读锁会阻塞后续的 DDL 操作而阻塞的 DDL 又会排队阻塞后续所有对该表的查询瞬间引发连接池耗尽常表现为“Waiting for table metadata lock”。二、按锁模式读写类型分类这是基于操作类型对锁的最基本划分决定锁是用于“读”还是“写”。2.1 共享锁S 锁 / Shared Lock含义允许持有锁的事务读取一行数据禁止修改。兼容性多个事务可以同时持有同一行数据的共享锁。加锁方式SELECT ... LOCK IN SHARE MODEMySQL 8.0 后推荐用FOR SHARE。2.2 排他锁X 锁 / Exclusive Lock含义允许持有锁的事务修改一行数据其他事务既不能读也不能写。兼容性同一时刻只有一个事务能持有排他锁。加锁方式SELECT ... FOR UPDATE、UPDATE、DELETE、INSERT自动加。兼容矩阵锁模式共享锁 (S)排他锁 (X)共享锁 (S)✅ 兼容❌ 冲突排他锁 (X)❌ 冲突❌ 冲突三、按锁意图表级门卫分类“意图锁”是表级锁用于表明事务打算在表中加行锁。其作用是在加表锁时快速判断表中是否已有行锁避免逐行检查提升效率。3.1 意向共享锁IS 锁事务打算给表中某些行加S 锁。执行SELECT ... LOCK IN SHARE MODE前先加 IS 锁。3.2 意向排他锁IX 锁事务打算给表中某些行加X 锁。执行UPDATE/DELETE/SELECT ... FOR UPDATE前先加 IX 锁。完整兼容矩阵含意向锁锁模式XIXSISX排他❌❌❌❌IX意向排他❌✅❌✅S共享❌❌✅✅IS意向共享❌✅✅✅注意意向锁相互兼容IS 和 IX 兼容不会阻塞正常的行级读写只阻塞表级锁如LOCK TABLES ... WRITE。四、行锁的具体算法InnoDB 核心特色这一层分类是 InnoDB 最精妙的部分决定了如何精确锁定行。行锁算法作用范围使用的隔离级别作用记录锁Record Lock单个索引记录精确匹配的行RC、RR锁定已存在的某一行间隙锁Gap Lock索引记录之间的间隙不包含记录本身仅 RR以及更高阻止其他事务在间隙内插入防止幻读Next-Key Lock记录锁 间隙锁包含记录本身及前间隙仅 RR以及更高InnoDB 在 RR 级别解决幻读的杀手锏4.1 记录锁Record Lock锁定索引树上的叶子节点即具体的索引记录。如果使用id 10进行查询且id是主键或唯一索引只会在id10这条记录上加记录锁。4.2 间隙锁Gap Lock锁定索引记录之间的“空隙”。例如SELECT * FROM t WHERE id BETWEEN 5 AND 10 FOR UPDATE如果表中没有id7的记录但存在 5 和 10间隙锁会封锁(5,10)这个区间阻止插入id7或id8等。间隙锁的特点它是“纯排他”的两个间隙锁永远是冲突的即使是两个读事务也不能在同一个间隙上加间隙锁。4.3 Next-Key Lock这是 InnoDB RR 级别的“默认行锁模式”。它的锁范围是(上一个记录值, 当前记录值]即间隙该记录本身。例如数据行有1, 5, 10对id5加锁实际上是锁住了(1, 5]区间阻止在区间(1,5]内插入新值如2,3,4,5均被锁。RC 与 RR 的锁算法差异RC 级别仅记录锁无间隙锁。因此不会阻塞其他事务插入新数据并发性能更好但可能出现幻读。RR 级别默认Next-Key Lock但当查询条件命中最优索引如主键唯一等值匹配时Next-Key Lock 会退化为记录锁。五、其他特殊锁5.1 插入意向锁Insert Intention Lock这是一种特殊的间隙锁由INSERT操作触发。它不是用来阻塞插入的而是用于协调不同插入操作之间的间隙冲突。原理事务 A 在(10, 20)间隙插入id15会在该间隙加“插入意向锁”IX 的变种。冲突规则多个事务可以在同一个间隙插入不同位置的数据如插入 12 和 18它们不会冲突但如果插入位置重复则会被排他锁阻塞。5.2 自增锁AUTO-INC Lock为了保证自增主键AUTO_INCREMENT的连续性和唯一性InnoDB 提供了自增锁机制。工作原理当一个事务向有自增列的表插入数据时InnoDB 会获取一个特殊的表级锁直到插入完成。参数控制innodb_autoinc_lock_mode可设为 0传统表锁、1连续默认、2交错最大并发适合ROW复制模式。5.3 谓词锁Predicate Lock—— 空间索引专用用于SPATIAL INDEX空间索引的场景目前使用较少。六、基于策略的分类应用视角从应用开发的角度锁也分为悲观锁和乐观锁。这并非 MySQL 原生锁类型而是应用层对锁机制的使用策略。策略实现方式适用场景悲观锁直接使用SELECT ... FOR UPDATEX 锁写冲突频繁如库存扣减乐观锁使用version字段或时间戳不加原生锁读多写少冲突率低七、锁信息的查看与诊断实战当发生死锁或锁等待时学会查看锁信息至关重要。7.1 当前锁持有与等待MySQL 8.0 推荐-- 查看当前持有的锁替代旧版 INNODB_LOCKSSELECT*FROMperformance_schema.data_locks\G;-- 查看锁等待关系谁在等谁SELECT*FROMperformance_schema.data_lock_waits\G;7.2 查看 InnoDB 整体状态含死锁详情SHOWENGINEINNODBSTATUS\G;-- 重点查看 TRANSACTIONS 部分中的 LATEST DETECTED DEADLOCK7.3 查看当前事务信息SELECT*FROMinformation_schema.innodb_trx\G;八、核心总结与实战建议分类维度核心要点粒度行锁InnoDB 默认 表锁DDL/MDL模式S 锁读与 X 锁写互斥但 S 锁之间兼容意图IS/IX 是表级门卫用于快速判断表冲突相互兼容算法行级RC 只有记录锁RR 有 Next-Key记录间隙但唯一索引等值匹配时退化为记录锁特殊锁插入意向锁协调并发插入、自增锁保证自增连续性应用策略悲观锁FOR UPDATE适合写多乐观锁版本号适合读多生产环境黄金法则隔离级别选 RC 可以大幅减少间隙锁从而降低死锁概率适合高并发 OLTP 系统。索引是关键没索引的行锁会升级为表锁瞬间摧毁并发能力。长事务是万恶之源它会让 MDL 锁和行锁长时间不释放阻塞整个系统。死锁不可怕不重试才可怕——应用层必须捕获死锁异常1213并自动重试。
返回列表