mysql 中的锁机制是保障事务隔离性和并发控制的核心组件,主要分为以下类型,按作用范围和场景分类如下:
一、按锁粒度分类
1. 表级锁(table-level locking)
特性:锁定整张表,开销小但并发性低。
常见类型:
- 表共享锁(lock tables … read):允许其他事务读表,但禁止写操作。
- 表排他锁(lock tables … write):禁止其他事务读写表。
意向锁(intention locks):
- 意向共享锁(is):事务打算在行上加共享锁。
- 意向排他锁(ix):事务打算在行上加排他锁。
- 作用:作为表级锁,与行级锁兼容性判断的标识,优化锁冲突检测。
2. 行级锁(row-level locking)
特性:仅锁定数据行,开销大但并发性高(innodb 默认支持)。
常见类型:
- 记录锁(record locks):锁定索引中的单条记录。
- 间隙锁(gap locks):锁定索引记录之间的“间隙”,防止插入新数据(解决幻读)。
- 临键锁(next-key locks):记录锁 + 间隙锁的组合,锁定记录本身及前一个间隙(innodb 默认锁模式)。
二、按锁模式分类
1. 共享锁(shared lock,s锁)
- 特性:允许其他事务读取数据,但禁止修改。
- 使用场景:
select ... lock in share mode
。
2. 排他锁(exclusive lock,x锁)
- 特性:禁止其他事务读写数据。
- 使用场景:
select ... for update
或自动由insert/update/delete
触发。
三、特殊场景锁
1. 自增锁(auto-inc locks)
- 特性:针对
auto_increment
列,确保自增值唯一且连续。 - 行为:在插入语句执行时短暂持有,可能成为并发瓶颈。
2. 插入意向锁(insert intention locks)
- 特性:当事务尝试插入数据到已锁定的间隙时,设置插入意向锁,表示等待间隙释放。
- 作用:避免插入冲突,提高并发插入效率。
3. 元数据锁(metadata locks,mdl)
特性:隐式加锁,管理对表结构的并发访问(如 ddl 操作)。
行为:
- 修改表结构时(
alter table
),自动请求元数据排他锁。 - 其他事务若持有该表的元数据锁,需等待释放。
四、存储引擎差异
- innodb:支持行级锁、间隙锁、临键锁,默认隔离级别为
repeatable read
。 - myisam:仅支持表级锁,无行级锁,并发性能较低。
五、锁行为与隔离级别关系
隔离级别 | 锁类型 | 特点 |
---|---|---|
读未提交 | 无间隙锁,仅记录锁 | 允许脏读,锁竞争最少 |
读已提交 | 记录锁(mvcc) | 通过快照读避免脏读,但可能幻读 |
可重复读(默认) | 临键锁(next-key locks) | 默认锁模式,防止幻读,但可能增加锁竞争 |
串行化 | 强制表级锁或间隙锁 | 完全串行执行,性能最低 |
六、使用建议
- 优化索引:合理设计索引可减少锁范围(如唯一索引避免间隙锁)。
- 控制事务粒度:避免长时间持有锁,减少锁竞争。
- 监控锁状态:通过
show engine innodb status
或information_schema.innodb_locks
分析锁冲突。 - 隔离级别选择:根据业务需求权衡一致性与并发性能(如读已提交 + 索引优化)。
通过理解锁类型和行为,可有效优化 mysql 并发性能,避免死锁和性能瓶颈。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论