数据库隔离级别的由来 及其与MVCC的关系

本贴最后更新于 3106 天前,其中的信息可能已经沧海桑田

我们都知道根据SQL92标准,关系数据库有四个隔离级别:脏读,读未提交,可重复读,可序列化。但这几个隔离级别是怎么来的?我们来扯扯把

 

如果数据库像Redis一样是单线程 串行处理所有的事务的话,我们就没有隔离级别这茬事了,或者说隔离级别都是最高的 可序列化。但是我们知道,数据库是一个磁盘IO很高的系统,尤其是用机械硬盘的时候,如果串行处理事务,那么就会导致磁盘不断寻道,处理效率低下。因此积攒一堆读写然后批量读取写入机械磁盘这会大大提高数据库的吞吐量。再加上现在CPU都这么多个核,多线程是必不可少了。

 

但多线程会带来一个问题,就是并发。你想象一下,在一个事务A里,你根据事务B未提交的记录做了一个判断并写了数据库,然后B回滚了,你会有怎样的心情~~于是乎数据库系统决定帮助你处理这个问题,提出了各种层次的隔离级别,让你读取数据的时候感觉就像只有自己在访问数据库一样。(NOSQL产品则没有这些隔离级别,甚至也没有ACID中的A-原子性,因此他们数据之间的关联关系很少,易于水平扩展,要扩展性能的话,加机器就可以了,但有得有失,用NOSQL实现复杂逻辑的时候 就要自己处理掉 事务的原子性,并发时候的脏读 等问题。)

 

数据库决定要让我们读取数据的时候感觉就像只有自己在访问数据库一样,要怎么搞呢?我们先从单线程处理所有事务的场景里开始着手,看看哪里可以改进变成并发把。

 

当两个事务里完全没有处理相同的记录的情况下,他们是天然可并发,无需额外处理。但是如果两个事务里存在相同的记录怎么办?我们分析下,对于同一条数据库记录,在不同的事务中仅存在以下几种关系:

一个事务读了,后续的另一个事务要读,简称读读

一个事务读了,后续的另一个事务要写,简称读写

一个事务写了,后续的另一个事务要读,简称写读

一个事务写了,后续的另一个事务要写,简称写写

 

先看读读,哎,好像天然可并发,怎么搞看起来都是像只有自己在访问数据库一样,棒棒哒。略过。

再看读写,第一个事务读过了,然后第二个事务要写,如果允许写的话,第一个事务不就蒙B了,这哪里是我一个人在访问数据库?!好吧,这样的话 ,根据我们程序员最直观的思维,给这条记录加个锁就好啦(行锁),每条读取的记录都要上锁。上锁后其他事务就不得读取这条记录了,除非等第一个事务完结。但这样读读关系不能并行了,于是大家都想,读读而已呀,这必须能并行呀,能提高不少性能呢。于是乎程序猿们继续发挥聪明才智,设计了读写锁~读读可并行,读写不可并行,这样就OK啦,大大提高了并行的效率。

这个做法嘛,对应的就是我们数据库隔离级别里的 可重复读。这个可重复读嘛,有一个BUG,就是所谓的 幻象读(不知道怎么能起到这么一个名字….)。这个BUG的原因如下:行锁是基于已有记录的,但如果记录不存在的话,怎么搞?如:数据库里只有2条记录,id分别为1、2;事务A第一次执行语句select * from user where id<3 有2条结果,并对这两条记录加了锁,但因没有第三条记录,所以无法加行锁。这时另外一个事务B插入了一条记录把id=3的记录插进去并提交了,那么事务A再次执行上述SQL的时候就会得到与第一次不一样的结果。看来可重复读….其实也并不可重复….

 

虽然引入了读写锁的机制后,数据库性能得到了大大的提升,但是人类追求效率的心是永无止境的,现在在上述 几个关系中,已经实现了 读读关系 并行处理了,那么其他关系能并行么?

现在有读锁和写锁,如果允许某个读锁升级成写锁的话,那么 读写关系也可以并行了,这个时候带来的负面效果是 之前一同获得读锁的事务们 再次读取这条记录的时候,有可能读到 获得写锁的事务更新的数据,于是这个隔离级别我们就称为 读已提交。

 

再继续放松限制,完全去掉读锁,也就使得 写读 也能并行了,这时候,数据库隔离级别就变成 读未提交。这时候保留的写锁,是为了保持ACID中的A,让其能回滚。

 

基于上述的实现方式,专家们定义了4种隔离级别。可见,这个隔离级别并没有其他特殊的含义,仅仅是局限于当时的技术实现形式而已。

 

在后来出现了MVCC这种基于复制记录形式的并发处理形式(具体实现自行再百度吧),指定隔离级别的专家们就蒙B了,MVCC可以做到比 可重复读更高的隔离级别(没有幻象读),且在读多些少的场景下实现比 行锁 机制里 读已提交,可重复读 更高的效率。

但由于 隔离级别在之前已经深入人心了,甚至于有些程序还利用了RC的特性来编写了程序,因此基于MVCC实现的数据库通常也会对应回四种隔离级别:可序列化(不使用MVCC),可重复读(使用MVCC,对应于SQL92里的可重复读,但不会出现幻象读),读已提交(故意减少MVCC的隔离程度,映射回RC这个隔离级别,这种实现相对于RR或许会更消耗数据库性能),以及读未提交。

大家普遍存在一个误区,隔离级别越高,数据库性能越差,这在行锁对应的数据库实现里,是正确的。但在MVCC里可就不一定了,个人认为RR的性能会比RC高,或者至少相差无几。

 

嗯~写完,OVER~

  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    336 引用 • 646 回帖
  • 一致性
    10 引用 • 5 回帖
  • MVCC
    4 引用 • 4 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    7489 引用 • 34059 回帖 • 198 关注
  • OnlyOffice
    4 引用 • 7 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 1 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 721 关注
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4599 回帖 • 700 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    54 引用 • 85 回帖 • 4 关注
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 389 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 608 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 28 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 340 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 325 关注
  • abitmean

    有点意思就行了

    34 关注
  • 创业

    你比 99% 的人都优秀么?

    83 引用 • 1398 回帖 • 1 关注
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 3 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 1 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    122 引用 • 73 回帖
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 730 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    5 引用 • 13 回帖
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    77 引用 • 390 回帖
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 663 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    10 引用 • 32 回帖 • 107 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 20 关注
  • PWL

    组织简介

    用爱发电 (Programming With Love) 是一个以开源精神为核心的民间开源爱好者技术组织,“用爱发电”象征开源与贡献精神,加入组织,代表你将遵守组织的“个人开源爱好者”的各项条款。申请加入:用爱发电组织邀请帖
    用爱发电组织官网:https://programmingwithlove.stackoverflow.wiki/

    用爱发电组织的核心驱动力:

    • 遵守开源守则,体现开源&贡献精神:以分享为目的,拒绝非法牟利。
    • 自我保护:使用适当的 License 保护自己的原创作品。
    • 尊重他人:不以各种理由、各种漏洞进行未经允许的抄袭、散播、洩露;以礼相待,尊重所有对社区做出贡献的开发者;通过他人的分享习得知识,要留下足迹,表示感谢。
    • 热爱编程、热爱学习:加入组织,热爱编程是首当其要的。我们欢迎热爱讨论、分享、提问的朋友,也同样欢迎默默成就的朋友。
    • 倾听:正确并恳切对待、处理问题与建议,及时修复开源项目的 Bug ,及时与反馈者沟通。不抬杠、不无视、不辱骂。
    • 平视:不诋毁、轻视、嘲讽其他开发者,主动提出建议、施以帮助,以和谐为本。只要他人肯努力,你也可能会被昔日小看的人所超越,所以请保持谦虚。
    • 乐观且活跃:你的努力决定了你的高度。不要放弃,多年后回头俯瞰,才会发现自己已经成就往日所仰望的水平。积极地将项目开源,帮助他人学习、改进,自己也会获得相应的提升、成就与成就感。
    1 引用 • 487 回帖
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    5 引用 • 26 回帖
  • HBase

    HBase 是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的 Google 论文 “Bigtable:一个结构化数据的分布式存储系统”。就像 Bigtable 利用了 Google 文件系统所提供的分布式数据存储一样,HBase 在 Hadoop 之上提供了类似于 Bigtable 的能力。

    17 引用 • 6 回帖 • 70 关注
  • 电影

    这是一个不能说的秘密。

    120 引用 • 598 回帖