1. MySQL锁的基本概念
- 共享锁(Shared Lock):允许多个事务读取同一数据,不阻塞其他读操作。
- 排它锁(Exclusive Lock):写锁,阻塞其他读写操作。
2. 锁的分类
- 全局锁:锁定整个数据库实例,仅支持读操作。
- 表级锁:锁定特定表,分为读锁和写锁。
- 行级锁:锁定数据行或索引间隙。
3. 全局锁
- 使用场景:全库逻辑备份,保证数据一致性。
- 命令:
flush tables with read lock;
加锁,unlock tables;
解锁。
4. 表级锁
- 表读锁:允许读操作,阻塞写操作。
- 表写锁:阻塞读写操作。
- 元数据锁(MDL):自动加锁,保证表结构变更安全。
- 自增锁(AUTO-INC Lock):事务性插入时产生。
5. 行级锁(InnoDB)
- 记录锁:锁定索引记录。
- 间隙锁:锁定索引间隙,防幻读。
- 临键锁:组合记录锁和间隙锁。
- 插入意向锁:INSERT操作前的间隙锁。
6. 意向锁
- 表明事务准备持有行锁或正在某些行上持有锁。
- 协调行锁和表锁的关系。
7. 加锁规则
- 主键索引和辅助索引在等值条件和范围条件下的加锁行为不同。
- 根据是否命中索引和查询条件,决定加记录锁或间隙锁。
8. 锁相关的参数
show status like 'innodb_row_lock%';
查看行级锁定状态。
9. SQL加锁分析
- 根据隔离级别和索引使用情况,分析SQL语句的加锁行为。
- 考虑不同组合下(主键、唯一索引、非唯一索引、无索引)SQL的加锁情况。
10. 死锁产生原因与排查
- 死锁原因:多个session加锁顺序不一致。
- 排查方法 :
show engine innodb status
查看死锁日志。
11. 避免死锁的策略
- 保持事务轻量,减少资源占用。
- 提高事务速度,避免子查询,使用主键。
- 快速提交事务,减少锁持有时间。
12. 隔离级别对加锁的影响
- 读已提交(RC):快照读,不加锁。
- 可重复读(RR):可能加间隙锁防幻读。
- 串行化(Serializable):所有读操作为当前读,加锁。
13. 复杂SQL加锁分析
- 分析WHERE条件,确定index key范围、index filter和table filter。
- 根据隔离级别和索引支持情况,确定加锁类型。
结论
- MySQL锁机制复杂,涉及全局锁、表级锁和行级锁。
- 加锁规则受隔离级别影响,不同级别下SQL加锁行为不同。
- 死锁可通过优化事务逻辑和减少锁持有时间避免。
- 深入理解锁机制有助于编写高效且避免死锁的SQL语句。