大家好,这里是架构资源栈!点击上方关注,添加“星标”,一起学习大厂前沿架构!
在高并发系统中,合理的锁策略是保障数据正确性与性能平衡的关键。MySQL 提供了多种锁机制——全局锁(Global Lock)、表锁(Table Lock) 和 行锁(Row Lock),每种锁都适用于不同的场景。本文将带你从原理、应用场景、示例操作和优劣比较四个维度,全面解读这三种锁。
一、全局锁(Global Lock)
1. 原理与作用
- 作用域:锁定整个 MySQL 实例,阻塞所有写操作,读操作仍然被允许
- 典型场景:逻辑备份(如
mysqldump
),防止备份过程中数据发生变更
2. 获取/释放全局锁
-- 获取全局只读锁,所有写操作被阻塞
FLUSH TABLES WITH READ LOCK;
-- 释放全局锁
UNLOCK TABLES;
注意:一旦执行全局锁,所有 schema 下的表都进入只读,慎用于线上高并发环境!
二、表锁(Table Lock)
1. 原理与分类
- 作用域:锁定单张表
- MyISAM 引擎:默认使用表锁;InnoDB 在显式
LOCK TABLES
时可使用表锁 锁类型:
- 读锁 (READ LOCK):允许多个会话并发读,阻塞写
- 写锁 (WRITE LOCK):独占锁,阻塞所有其他读写
2. 示例
-- 加读锁,其他会话只能读不能写
LOCK TABLES orders READ;
-- 加写锁,当前会话独占写权限
LOCK TABLES orders WRITE;
-- 操作完成后释放锁
UNLOCK TABLES;
3. 优劣势
优势 | 劣势 |
---|---|
实现简单、无死锁风险 | 锁粒度较大,高并发写时性能严重受限 |
三、行锁(Row Lock)
1. 原理与特点
- 作用域:只锁定被访问的行
- 引擎:仅 InnoDB 支持,基于 多版本并发控制(MVCC)
锁类型:
- 排他锁(X-lock):写操作时对行加锁,阻塞其他读写
- 共享锁(S‑lock):读操作时对行加锁,允许并发读
2. 自动与显式行锁
- 隐式行锁:比如
UPDATE ... WHERE id = ?
会自动加 X-lock - 显式行锁:使用
SELECT ... FOR UPDATE
/LOCK IN SHARE MODE
BEGIN;
-- 对符合条件行加 X-lock
SELECT *
FROM user
WHERE id = 42
FOR UPDATE;
-- 对符合条件行加 S-lock
SELECT *
FROM user
WHERE status = 'active'
LOCK IN SHARE MODE;
COMMIT; -- 事务提交后自动释放行锁
3. 优劣势
优势 | 劣势 |
---|---|
锁粒度最小,支持高并发读写 | 可能出现死锁,需要谨慎设计事务和访问顺序 |
四、三种锁的对比与选型建议
特性 | 全局锁 | 表锁 | 行锁 |
---|---|---|---|
锁粒度 | 整个实例 | 整张表 | 单条记录 |
并发能力 | 最差 | 一般 | 最佳 |
死锁风险 | 无 | 无 | 存在 |
典型引擎 | MyISAM/InnoDB | MyISAM/InnoDB | InnoDB |
使用场景 | 备份、维护 | 批量写、快速备份 | 日常 OLTP、高并发场景 |
选型建议:
- 首选行锁:默认 InnoDB 引擎已对 DML 操作加行锁,适合绝大多数在线业务。
- 表锁限特殊场景:当需要对整表快速批量处理时,可显式使用表锁。
- 全局锁谨慎用:仅在备份或全库维护时短暂加锁,避免阻塞生产写流量。
五、监控与诊断
查看当前 InnoDB 锁等待与死锁信息:
-- 查看锁等待详情 SELECT * FROM information_schema.INNODB_LOCKS; -- 查看锁等待队列以及死锁 SHOW ENGINE INNODB STATUS\G
- 使用
performance_schema
进一步分析锁争用热点,提升定位精度。
六、实战小贴士
- 短事务:保持事务尽可能短,减少持锁时间。
- 固定访问顺序:多表事务中,按相同顺序操作,降低死锁几率。
- 合理索引:行锁基于索引扫描,加好索引可避免全表锁或间隙锁。
- 监控预警:结合监控平台,对锁等待、长事务进行告警。
▶️ 关注我,带你持续深挖数据库性能与架构优化秘密!
本文由博客一文多发平台 OpenWrite 发布!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。