目录
- InnoDB 行锁锁排查可以用的视图和数据字典InnoDB 行锁兼容性
- InnoDB行锁之共享锁共享锁:
- 查看InnoDB锁InnoDB行锁实现机制对普通索引上锁InnoDB隐式、显式锁
通过索引实现行锁,在索引记录上加锁。
没有索引就无法实现行锁,升级成全表记录锁,等同于表锁。
理解InnoDB独特的行锁运行机制,认识特有的四种行锁粒度——lock_ordinary、lock_gap、lock_rec_not_gap、lock_insert_intention
InnoDB 行锁
- 默认都是加lock_ordinary锁
- 如果是唯一索引列上的等值查询,则退化成lock_rec_not_gap
- 所有版本,非唯一索引列上的范围查询,遇到第一个不符合条件的记录也会加上lock_ordinary。
- 8.0.18版本以前,主要指<=场景:唯一索引列上的范围查询,遇到第一个不符合条件的记录也会加上lock_ordinary ,在RC下会释放,RR下不会释放。
- 8.0.18版本以前,非唯一索引列上的等值查询,向右遍历遇到第一个不符合条件的记录时,先加上lock_ordinary,再退化成lock_gap。
锁排查可以用的视图和数据字典
mysql> show engine innodb status \G
mysql> select * from performance_schema.data_lock_waits;
mysql> select * from performance_schema.data_locks;
mysql> select * from performance_schema.metadata_locks;
InnoDB 行锁兼容性
请求的锁类型请求的锁类型请求的锁类型请求的锁类型lock_ordinarylock_rec_not_gaplock_gaplock_insert_intention已获得的锁类型lock_ordinaryXXOX已获得的锁类型lock_rec_not_gapXXOO已获得的锁类型lock_gapOOOX已获得的锁类型lock_insert_intentionOOOO
- gap只和insert intention锁冲突
- insert intention和任何锁都不冲突,除非也在相同位置做意向插入锁
- 先获得意向插入锁的,再尝试上gap lock是可以的
- 但是反过来 ,先获得gap lock的,再尝试加上意向插入锁便会阻塞,
- 原因是:先获得意向插入锁时,实际上插入已经成功,意向插入锁会被转变为对具体记录的ordinary 或 rec_not_gap ,此时二者都与lock gap兼容。
InnoDB行锁之共享锁
共享锁:
- 不允许其他事务修改被锁定的行,只能读
- select .. for share/ lock in share mode
- 自动提交模式下的普通select是一致性非锁定读,不加锁。
自动提交模式下, 不使用begin开启事务,直接select的话:
select * from xxx where .. 不加锁
select * from xxx where .. for share ,也查询不到加锁, 但是实际上是加锁的,只不过锁的时间极其的短暂。
验证:
此时,用排他锁来验证自动提交模式的for share究竟是否产生锁动作。
可以看出