您现在的位置是:首页 >技术教程 >Mysql进阶【2】论述锁机制,SQL加锁情况网站首页技术教程
Mysql进阶【2】论述锁机制,SQL加锁情况
简介Mysql进阶【2】论述锁机制,SQL加锁情况
1.MySQL 的锁机制
1.1按粒度分有三种:
- 全局锁:核心服务层实现,锁住数据库,full table with read lock;
- 表级锁:核心服务层实现,锁住数据库中的某张表
- 加表级读锁:本事务不能读取其他未加锁的表的信息
- 行级锁:存储引擎层实现,锁住的是某行的索引,也可以是索引的间隙
- 记录锁(Record Locks):锁定索引中一条记录。
- 间隙锁(Gap Locks):要么锁住索引记录中间的值,要么锁住第一个索引记录前面的值或者最后一个索引记录后面的值。
- 临键锁(Next-Key Locks):是索引记录上的记录锁和在索引记录之前的间隙锁的组合(间隙锁 + 记录锁)。
- 插入意向锁(Insert Intention Locks):做insert操作时添加的对记录id的锁。
行锁的锁是加在索引上,而非数据本身
- 临键锁(Next-Key Locks)相当于记录锁 + 间隙锁【左开右闭区间】
- 间隙锁:未查询到该条语句,则加上间隙锁,保证索引间隙不被插入其他数据,防止幻读。锁住的是一个索引区间,开区间,不包括两边。
- 记录锁:等值查询,锁叫加在该条记录的索引上,而非记录本身
1.2按功能划分两种:
- 共享锁Shared Locks(S锁、读锁):加了读锁的记录,允许其他事务在加读锁(select....lock in share mode)
- 排他锁Exclusive Locks(X锁,写锁):写锁一加,其他事务不能在加其他写锁或者读锁(select for update)
2.分析 SQL 的锁定情况:delete from tt where uid = 123;
2.1读已提交RC
- 如果uid是索引,并且也是主键,并且找到了这台记录的话,会给这条记录加上写锁
- uid是唯一索引,不是主键,首先找到这条记录加上写锁,然后拿着主键去主键索引中找到这个记录也加上写锁。
- uid不是唯一索引,查询结果不唯一,查询到所有的符合条件的记录加锁,并且通过主键找到主键索引并加上锁
- uid不是索引,全表扫描都加上写锁,无论时候符合条件都加上写锁
2.2可重复读【RR】隔离级别
- 如果uid是索引,并且也是主键【查找到这条记录,然后给记录加写锁】
- uid是唯一索引,不是主键,【辅助索引里查找符合条件的记录,加上写锁,在拿主键到主键索引里边查找对应数据,也加上写锁】
- uid不是唯一索引,查询结果不唯一,【查找到符合条件的所有记录,记录不唯一加上写锁,然后再拿主键到主键索引里边查找到对应所有记录也加上写锁,并且记录间的数据加上间隙锁,查找下一个不符合条件的数据加上,符合条件与不符合条件之间的间隙加上间隙锁】
- uid不是索引【全表扫描,所有记录加上写锁与间隙锁,设置innodb_locks_unsafe_for_binlog 参数,对于不满足查询条件的记录,MySQL会提前放写锁,不加间隙锁】
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。