当前位置: 首页 > news >正文

MySQL 的锁机制

​1. 锁的作用与分类​

锁的核心目标是解决并发事务中的资源竞争问题,防止数据不一致。MySQL 的锁可以从多个维度分类:

​1.1 按锁的粒度(锁定范围)​
锁类型描述适用引擎特点
​表级锁​锁定整张表,其他事务无法修改表结构或数据。MyISAM、InnoDB开销小,并发性低
​行级锁​仅锁定某一行或多行数据,其他行仍可访问。InnoDB开销大,并发性高
​页级锁​锁定数据页(一组连续的记录),介于表锁和行锁之间。BDB较少使用
​1.2 按锁的模式(访问权限)​
锁类型描述兼容性
​共享锁 (S Lock)​允许事务读取数据,其他事务可加共享锁,但不可加排他锁。共享锁之间兼容
​排他锁 (X Lock)​允许事务修改数据,其他事务无法加任何锁(包括共享锁和排他锁)。与所有锁冲突
​1.3 按锁的实现方式​
锁类型描述
​悲观锁​默认认为并发冲突会发生,先加锁再操作(如 SELECT ... FOR UPDATE)。
​乐观锁​假设冲突较少,通过版本号或时间戳控制(需应用层实现,如 CAS 机制)。

​2. InnoDB 的锁机制​

InnoDB 是 MySQL 默认支持事务的存储引擎,其锁机制最为复杂和常用。

​2.1 行级锁​
  • ​共享锁 (S Lock)​
    语法:SELECT ... LOCK IN SHARE MODE
    用途:允许其他事务读,但禁止修改或加排他锁。

  • ​排他锁 (X Lock)​
    语法:SELECT ... FOR UPDATE 或 DML 语句(如 UPDATEDELETE
    用途:禁止其他事务读(取决于隔离级别)或修改。

​示例​​:

-- 事务 A 对 id=1 的行加排他锁
BEGIN;
SELECT * FROM users WHERE id = 1 FOR UPDATE;
-- 事务 B 尝试修改会被阻塞
UPDATE users SET name = 'Bob' WHERE id = 1; -- 等待事务 A 提交或回滚
​2.2 意向锁(Intention Locks)​
  • ​意向共享锁 (IS Lock)​​:事务打算在某些行上加共享锁,需先在表上加 IS 锁。
  • ​意向排他锁 (IX Lock)​​:事务打算在某些行上加排他锁,需先在表上加 IX 锁。

​作用​​:快速判断表级锁是否冲突,避免逐行检查。

​2.3 间隙锁(Gap Locks)​
  • ​锁定范围​​:索引记录的间隙(如 WHERE id BETWEEN 10 AND 20),防止其他事务在此范围内插入数据。
  • ​用途​​:解决幻读问题(在 REPEATABLE READ 隔离级别下生效)。

​示例​​:

-- 事务 A 锁定 id > 10 的间隙
SELECT * FROM users WHERE id > 10 FOR UPDATE;
-- 事务 B 插入 id=15 会被阻塞
INSERT INTO users (id, name) VALUES (15, 'Charlie');
​2.4 临键锁(Next-Key Locks)​
  • ​组成​​:行锁 + 间隙锁,锁定索引记录及其前面的间隙。
  • ​默认行为​​:InnoDB 在 REPEATABLE READ 隔离级别下使用临键锁。
​2.5 插入意向锁(Insert Intention Locks)​
  • 一种特殊的间隙锁,表示事务打算在某个间隙插入数据。
  • 允许多个事务在同一个间隙插入不同的数据(只要不冲突)。

​3. 锁的兼容性​

不同锁之间的兼容性如下表:

当前锁 \ 请求锁共享锁 (S)排他锁 (X)意向共享 (IS)意向排他 (IX)
​共享锁 (S)​✔️✔️
​排他锁 (X)​
​意向共享 (IS)​✔️✔️✔️
​意向排他 (IX)​✔️✔️

​4. 死锁(Deadlock)​

​4.1 死锁的产生​

两个或多个事务互相等待对方释放锁,形成循环依赖。
​示例​​:

  1. 事务 A 锁定行 1,请求行 2。
  2. 事务 B 锁定行 2,请求行 1。
  3. 双方互相等待,导致死锁。
​4.2 死锁检测与处理​
  • ​自动检测​​:InnoDB 使用等待图(Wait-for Graph)检测死锁。
  • ​处理方式​​:回滚代价最小的事务,另一个事务继续执行。
  • ​查看死锁日志​​:SHOW ENGINE INNODB STATUS;
​4.3 避免死锁的方法​
  1. 保持事务短小,尽快提交或回滚。
  2. 按固定顺序访问资源(如按主键排序更新)。
  3. 使用索引减少锁范围。
  4. 设置合理的隔离级别(如 READ COMMITTED 减少间隙锁)。

​5. 锁的监控​

​5.1 查看当前锁信息​
-- 查看 InnoDB 锁状态
SHOW ENGINE INNODB STATUS;-- 通过系统表查询锁信息(MySQL 5.7+)
SELECT * FROM information_schema.INNODB_LOCKS;
SELECT * FROM information_schema.INNODB_LOCK_WAITS;
​5.2 监控锁等待​
-- 查看正在等待锁的事务
SELECT * FROM information_schema.INNODB_TRX 
WHERE trx_state = 'LOCK WAIT';

​6. 锁的优化与实践​

​6.1 减少锁冲突​
  1. ​合理设计索引​​:缩小锁范围(如使用唯一索引)。
  2. ​避免长事务​​:尽快提交事务,减少锁持有时间。
  3. ​使用低隔离级别​​:如 READ COMMITTED 减少间隙锁的使用。
​6.2 显式锁的使用场景​
  1. ​悲观锁​​:高并发写场景(如库存扣减)。
    BEGIN;
    SELECT stock FROM products WHERE id = 100 FOR UPDATE;
    UPDATE products SET stock = stock - 1 WHERE id = 100;
    COMMIT;
  2. ​乐观锁​​:低冲突场景(通过版本号控制)。
    -- 更新时检查版本号
    UPDATE products 
    SET stock = stock - 1, version = version + 1 
    WHERE id = 100 AND version = 5;

​7. 不同存储引擎的锁差异​

存储引擎锁机制特点
​InnoDB​支持行锁、表锁默认行级锁,支持事务和 MVCC
​MyISAM​仅支持表锁读写互斥,并发性能差
​Memory​表锁数据存储在内存,锁竞争较少

​8. 总结​

MySQL 的锁机制是保障数据一致性和高并发的核心,理解以下关键点至关重要:

  1. ​锁的粒度​​:行级锁 vs 表级锁。
  2. ​锁的模式​​:共享锁、排他锁、意向锁。
  3. ​锁的兼容性​​:不同锁之间的冲突关系。
  4. ​死锁处理​​:检测、回滚与避免策略。
  5. ​优化实践​​:索引设计、事务时长控制、隔离级别选择。

通过合理使用锁机制,可以在高并发场景下平衡数据一致性和系统性能。

相关文章:

  • Webug4.0靶场通关笔记24- 第29关Webshell爆破
  • Linux 大于2T磁盘分区
  • opencv中的图像特征提取
  • RK3588 Ubuntu安装Qt6
  • 从代码学习深度学习 - 区域卷积神经网络(R-CNN)系列 PyTorch版
  • levelDB的数据查看(非常详细)
  • 【面板数据】各省双向FDI协调发展水平数据集(2005-2022年)
  • 并发 vs 并行编程详解
  • el-form的label星号位置如何修改
  • Vue3 路由配置与跳转传参完整指南
  • MySQL主从同步(主从复制)
  • RDD行动算子案例
  • 论文分享➲ ICLR2025 Oral | Scaling and evaluating sparse autoencoders
  • 使用 Spring 和 Redis 创建处理敏感数据的服务
  • 剪映学习03
  • 常见图像融合算法(图像泊松融合)
  • neo4j图数据库基本概念和向量使用
  • python小区物业管理系统-小区物业报修系统
  • Missashe高数强化学习笔记(随时更新)
  • Redis 存储原理与数据模型(三)
  • 欧洲史上最严重停电事故敲响警钟:能源转型如何保证电网稳定?
  • 金融监管局:已设立74支私募股权投资基金,支持投资科技创新企业
  • 罗氏制药全新生物制药生产基地投资项目在沪启动:预计投资20.4亿元,2031年投产
  • 波音公司计划于2027年交付新版“空军一号”飞机
  • 马上评|演出服“穿过就退货”的闹剧不该一再重演
  • 《蓦然回首》:现代动画的践行与寓言