前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mysql 隔离级别的实现

mysql 隔离级别的实现

作者头像
平凡的学生族
发布2019-06-17 13:44:34
1.5K0
发布2019-06-17 13:44:34
举报
文章被收录于专栏:后端技术后端技术

简介

本文探讨innodb如何使用mvcc和各种锁机制,保障mysql的四层隔离等级的。

0. 前置知识

0.1 锁

为了保证并发事务的正常执行,innodb使用了各种锁,总结如下图0.1.1和图0.1.2。比如,在解决幻读问题时,用到了gap lock。读者最好查阅其它文章,对下面的锁的行为、作用有所理解。尤其应当理解record lock、gap lock、next-key lockX lock、S lock。 至于IX lock(意向排他锁)和IS lock(意向共享锁), 暂时不是讨论重点。

图0.1.1 innodb的锁 表格分类

图0.1.2 innodb的锁 树形分类

0.2 并发问题

有四大并发问题,更新丢失(第一类和第二类)、脏读、不可重复读、幻读。你需要事先了解这四个问题是怎样的。

0.3 事务的四个隔离等级

为了解决这些并发问题,mysql提出了事务的四大隔离等级:RU、RC、RR、SR。你需要事先了解四个隔离等级所解决的并发问题。我总结了如下:

图0.3.1

  • 第一类更新丢失在各种隔离等级下都已规避,是数据库在实现时默认解决的问题。
  • 第二类更新丢失的解决是利用锁,而不依赖隔离等级。
  • 由于mvcc机制和gap lock,mysql的RR等级就已经解决了大部分幻读问题了,但有一个例外(读者自行查阅,简单讲就是事务A select后,事务B修改了查询范围的某一行并提交,事务A再修改了那一行,并第二次select,会看到刚修改的那一行。原因是,多出的那一行是A自己改的,其记录的版本号便是A的版本号,自然对A可见)。为了规避这个例外,需要在后端代码中避开。

1. 文章目的

我们研究这些方法,都是为了理解并发问题是如何被解决的。不管是锁也好,隔离等级也好,都是为了解决那些并发问题。

  • 有人用了三种封锁协议,但读锁消耗大。
  • 而mysql实现的mvcc和gap lock,能使RC、RR不使用读锁也解决对应的问题。(在RU等级下,读不加锁,写加X锁[1]。在SR等级下,依旧会使用读锁)。

关于这些方案的总结见图1.1。

图1.1 并发问题的解决方案

2. 封锁协议

为了解决并发问题,有人提出了三种封锁协议,级别越高,解决的并发问题越多。 图2.1描述了三种封锁协议的做法,和它们解决的并发问题。图中的三种封锁协议,显然都是基于对数据加X锁和S锁实现的[2]

图2.1 封锁协议解决并发问题

加锁的办法固然有效,但在读多写少的实际场景中,每次读取都加锁的做法太影响效率。

3. 隔离等级

针对解决脏读、不可重复读问题时加读锁会影响效率的问题,innodb提出了mvcc。为了解决幻读问题,还另外使用了record lock、gap lock等锁。各个隔离等级用到的技术如图3.1:

图3.1 各个隔离等级用到的技术

  • RU之下
    • 读取时不加锁
    • 但修改时默认加锁
  • RC之下
    • 快照读(普通select)时不加锁,但启用语句级别的mvcc——每次快照读时都生成ReadView,读完就销毁。
    • 查找索引时,不管单行还是范围查找,都不会用到gap lock。(gap lock用在外键约束检测和重复键检测中)因此当前读(select...for update、update、delete、insert)下只会启用record lock。
  • RR下的加锁机制,参考MySQL的锁机制和加锁原理,也可以看我的文章。
    • 快照读(普通select)时不加锁,但启用事务级别的mvcc——第一次快照读时生成ReadView,事务提交时销毁。
    • 当前读(select...for update、update、delete、insert)不生成ReadView,而是使用record lock、gap lock、next-key lock来保证并发下的正确性(但update、delete、insert会更改记录存储的事务id值,从而影响mvcc,从而影响快照读)。
  1. 参考自[mysql(InnoDB)事务隔离级别(READ UNCOMMITTED) 与 锁。不过一般也没人用RU等级吧,都是用RR的。我也懒得深究了。
  2. 个人认为,图中的"更新丢失"问题与《0. 前置知识》章节所说的"更新丢失"问题不属于一个层面。前者是数据库内核层面的,后者是后端框架层面的。问题的描述可以查阅【眼见为实】数据库并发问题 封锁协议 隔离级别
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.06.16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 0. 前置知识
    • 0.1 锁
      • 0.2 并发问题
        • 0.3 事务的四个隔离等级
        • 1. 文章目的
        • 2. 封锁协议
        • 3. 隔离等级
        相关产品与服务
        云数据库 SQL Server
        腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档