幻读
幻读是前后两次相同范围查询语句,查询的数据行不一样,即第二次查询到新数据行。这是可重复读隔离条件下当前读才会出现的问题。可重复读隔离条件下快照读的MVCC可以防止幻读。
间隙锁
InnoDB 认为幻读出现的原因是只锁住了已存在的数据行,没有锁住数据行之间的空隙。空隙中可以插入新的数据,导致出现幻读。因此提出间隙锁。
间隙锁与间隙锁不冲突,间隙锁与“往间隙范围插入数据行”冲突。
临键锁
间隙锁与行锁组合就是临键锁,临键锁是左开右闭
区间。
行锁锁一行,临键锁锁一个范围。临键锁降低并发度。
临键锁加锁规则
- 加锁的基本单位是左开右闭的临键锁。
- 加锁的对象是用到的索引。
- 如果是等值查询,且索引是唯一索引,临键锁退化为行锁。
- 如果是等值查询,且最后一个值不满足等值条件,临键锁退化为间隙锁。
临键锁的加锁的顺序是从左到右,先加间隙锁,再加行锁。分别遵循各自的冲突条件。
排查死锁和慢查询
如果查询语句长时间不返回,可能情况
- 等待MDL写锁,排查方式:
show processlist
,State
为Waiting for table metadata lock
- 等待flush。
State
为Waiting for table flush
- 等行锁。查看 sys.innodb_lock_waits 表
如果查询语句很慢,可能情况
- 查询行数多,比如没有索引,全表扫描。排查方式:slowlog查看扫描行数,是否符合手动计算预期。
- 使用MVCC, undolog过多。排查方式:对比当前读和快照读的结果差距。