加锁算法?

MySQL不同隔离级别下的加锁情况 | Exploring

MySQL/mysql-storage-engines/innodb/1.5.5.InnoDB锁——lock之不同SQL加锁分析.md at master · asdbex1078/MySQL

抛开隔离级别谈上锁都是耍流氓!

读未提交

- 增:插入数据后,给新插入的数据上<font style="color:#DF2A3F;">记录锁</font>,防止其它事务更改这条记录 
- 删:需要获取到要删除的记录的<font style="color:#DF2A3F;">记录锁</font>,保证删除的时候其它事务没在使用这些数据,并保证删除后其它事务无法对这些数据进行操作 
- 改:给需要更改的数据上<font style="color:#DF2A3F;">记录锁 </font>
- 查:任何读都不加锁

读已提交

- 增:插入数据后,给新插入的数据上<font style="color:#DF2A3F;">记录锁</font>,防止其它事务更改这条记录 
- 删:需要获取到要删除的记录的<font style="color:#DF2A3F;">记录锁</font>,保证删除的时候其它事务没在使用这些数据,并保证删除后其它事务无法对这些数据进行操作 
- 改:给需要更改的数据上<font style="color:#DF2A3F;">记录锁 </font>
- 查:快照读不加锁,当前读只加记录锁

可重复读

- 增:使用<font style="color:#DF2A3F;">插入意向锁</font>,进行插入,插入后给插入的数据上<font style="color:#DF2A3F;">记录锁</font>(隐式锁,其实这个记录锁不是这个时候上的) 
- 删:使用<font style="color:#DF2A3F;">临键锁</font>,防止其它事务在删除的区间内插入数据 
- 改:给需要更改的数据上<font style="color:#DF2A3F;">临键锁 </font>
- 查:快照读不加锁,当前读:加临键锁和间隙锁,唯一索引则加记录锁

序列化

- 增:使用<font style="color:#DF2A3F;">插入意向锁</font>,进行插入,插入后给插入的数据上<font style="color:#DF2A3F;">记录锁</font>(隐式锁,其实这个记录锁不是这个时候上的) 
- 删:使用<font style="color:#DF2A3F;">临键锁</font>,防止其它事务在删除的区间内插入数据 
- 改:给需要更改的数据上<font style="color:#DF2A3F;">临键锁</font> 
- 查:普通查询自动变为select … lock in share mode,上<font style="color:#DF2A3F;">临键锁,锁间隙</font>! 唯一索引加记录锁

细节

锁的对象是索引,而不是记录

二级索引的记录加了排他锁,聚簇索引也会加对应的锁。

如果没有合适的索引,那么MySQL就会扫表来处理,那么表的每一行都会被锁定,从而阻塞其他用户对 表的所有插入

临键锁只存在于可重复读和串行化事务隔离级别下

MVCC只存在于读已提交和可重复读

next-key lock 是前开后闭((x,y])区间,而间隙锁是前开后开区间((x,y))

临键锁上锁的优化:

临键锁锁的是一个间隙以及一个间隙后面的行记录,锁粒度比较大,在一些情况下会对其进行一定优化

总结起来就是 在加间隙锁or记录锁能避免幻读的情况下,临键锁就会退化成记录or间隙

唯一索引等值查询:

当查询的记录存在时,定位到了在索引树上的位置,那么原先在扫描时加的临键锁就会退化成记录锁

当查询的记录不存在时,在索引树找到比它大的第一条记录时,那么临建锁就会退化成 间隙锁

唯一索引范围查询情况

唯一索引扫描索引树时,会对扫描到的每一个索引加临键锁,如果满足一些条件就有可能发生锁退化

非唯一索引等值查询

非唯一索引范围查询情况

临键锁无法进行退化

非索引扫描情况

每一条记录的索引上都会加 next-key 锁,这样就相当于锁住的全表**:****从负无穷到正无穷(全表记**

录 + 所有间隙)

以上加锁的机制都是围绕着如何避免幻读来展开的

ps:锁全表的数据(临建锁)时,那这时候往表的最后一行后插入数据会被阻塞吗。会的,锁到正无穷,如果插入头部,负无穷也会被锁住

MySQL只操作同一条记录,也会发生死锁吗?

会的。mysql锁的是索引,而不是记录。如果是根据二级索引查询(加锁查询orDML),那么它会

先获取二级索引上的锁,然后再去对主键索引上的锁。如果有两线程同时获取锁的顺序不一样了,

那么就会发生死锁

加锁原则:两个原则两个优化一个bug