7. 在RR(可重复读)的隔离级别下,对查询条件是普通索引的场景,除了会加X
锁,还会加间隙Gap
锁 。Gap锁的提出,是为了解决幻读问题引入的,它是一种加在两个索引之间的锁 。
8. 在RR(可重复读)的隔离级别下,对查询条件是无索引的场景,查询条件列没有索引,主键索引的所有记录,都将加上X锁
,每条记录间也都加上间隙Gap锁
。任何加锁并发的SQL,都是不能执行的,全表都是锁死的状态 。
RR隔离级别下加锁规则两个原则
、两个优化
和一个bug
- 原则1:加锁的基本单位都是
next-key lock
。next-key lock(临键锁)
是前开后闭区间 。 - 原则2:查找过程中访问到的对象才会加锁 。
- 优化1:索引上的等值查询,给唯一索引加锁的时候,
next-key lock
退化为行锁(Record lock)
。 - 优化 2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,
next-key lock
退化为间隙锁(Gap lock) 。 - 一个 bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止 。
总结
- 如果查询没有命中索引,则退化为表锁;
- 如果等值查询唯一索引且命中唯一一条记录,则退化为行锁;
- 如果等值查询唯一索引且没有命中记录,则退化为临近结点的间隙锁;
- 如果等值查询非唯一索引且没有命中记录,退化为临近结点的间隙锁(包括结点也被锁定);如果命中记录,则锁定所有命中行的临键锁,并同时锁定最大记录行下一个区间的间隙锁 。
- 如果范围查询唯一索引或查询非唯一索引且命中记录,则锁定所有命中行的临键锁 ,并同时锁定最大记录行下一个区间的间隙锁 。
- 如果范围查询索引且没有命中记录,退化为临近结点的间隙锁(包括结点也被锁定) 。
有没有可能,进一步提高并发呢?
即使写任务没有完成,其他读任务也可能并发,这就引出了数据多版本 。
数据多版本是一种能够进一步提高并发的方法,它的核心原理是:
(1)写任务发生时,将数据克隆一份,以版本号区分;
(2)写任务操作新克隆的数据,直至提交;
(3)并发读任务可以继续读取旧版本的数据,不至于阻塞;
MVCC 实现的原理大致:
InnoDB 每一行数据都有一个隐藏的回滚指针,用于指向该行修改前的最后一个历史版本,这个历史版本存放在 undo log 中 。如果要执行更新操作,会将原记录放入 undo log 中,并通过隐藏的回滚指针指向 undo log 中的原记录 。其它事务此时需要查询时,就是查询 undo log 中这行数据的最后一个历史版本 。MVCC 最大的好处是读不加锁,读写不冲突,极大地增加了 MySQL 的并发性 。通过 MVCC,保证了事务 ACID 中的 I(隔离性)特性 。
redo、undo为什么要有redo日志?
redo log 指事务中操作的任何数据,将最新的数据备份到一个地方
数据库事务提交后,必须将更新后的数据刷到磁盘上,以保证ACID特性 。磁盘随机写性能较低,如果每次都刷盘,会极大影响数据库的吞吐量 。优化方式是,将修改行为先写到redo日志里(此时变成了顺序写),再定期将数据刷到磁盘上,这样能极大提高性能
redo log 不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入 redo 中 。具体的落盘策略可以进行配置。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启 MySQL 服务的时候,根据 redo log 进行重做,从而达到事务的未入磁盘数据进行持久化这一特性 。
经验总结扩展阅读
- 抽烟会引起胸闷气短吗
- 关于兔子的恐怖故事
- 关于山高的比喻句
- 关于安逸的格言
- 关于受的四字词语
- 关于少林寺的动画片有哪些
- 关于蜂巢素的问题
- 生活中关于诚信的例子有哪些
- 引擎之旅 Chapter.4 日志系统
- 到寺庙烧香有什么讲究