iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >PostgreSQL的MVCC vs InnoDB的MVCC
  • 756
分享到

PostgreSQL的MVCC vs InnoDB的MVCC

2024-04-02 19:04:59 756人浏览 薄情痞子
摘要

任何一个数据库最主要功能之一是可扩展。如果不删除彼此,则尽可能较少锁竞争从而达到这个目的。由于read、write、update、delete是数据库中最主要且频繁进行的操作,所以并发执行这些操作时不被阻塞

PostgreSQL的MVCC vs InnoDB的MVCC

任何一个数据库最主要功能之一是可扩展。如果不删除彼此,则尽可能较少竞争从而达到这个目的。由于read、write、update、delete是数据库中最主要且频繁进行的操作,所以并发执行这些操作时不被阻塞则显得非常重要。为了达到这种目的,大部分数据库使用多版本并发控制(Multi-Version Concurrency Control)这种并发模型。这种模型能够将竞争减少到最低限度。

mvcC是什么

Multi Version Concurrency Control ( MVCC)是这样的一种算法:通过对同一个对象维护多个版本,提供一种很好的并发控制技术,这种技术能够使READ和WRITE操作不发生冲突。这里的WRITE指的是UPDATE和DELETE,不包含Insert是因为新插入的记录可以通过各自的隔离级别进行保护。每个WRITE操作使对象产生一个新版本,每个并发读操作依赖于隔离级别读取对象不同的版本。由于READ和WRITE操作同一个对象的不同版本,所以这些操作不需要将对象完全锁住,因此这些操作能够并发执行。当然当两个并发事务WRITE同一个记录时,这些锁竞争还是会存在的。

当前大部分数据库系统都支持MVCC。这个算法的核心是对相同对象维护不同版本,因此不同数据库创建并维护多版本的方式不同,其实现方式也不同。相应地,数据库操作和数据存储也发生变化。

实现MVCC最常见的方法:postgresql使用的方法、InnoDB和oracle的使用方法。下面我们会详细讨论PG和InnoDB的实现方式。

Postgresql中的MVCC

为了支持多版本,PG对每个对象(PG术语:Tuple)增加了额外的字段:

1、xmin:进行插入或更新操作事务的事务ID。UPDATE中,对tuple的新版本分配该事务ID。

2、xmax:进行删除或更新操作事务的事务ID。UPDATE中,对当前存在的tuple分配该事务ID。新创建的tuple,该字段默认为null。

PostgreSQL将所有数据存储在HEAP中(每页默认8KB)。新记录的xmin为创建该记录的事务的事务ID;老版本(进行update或delete)其xmax为进行操作的事务的ID。会有一个链表将老版本和新版本连接起来。在回滚的过程中,老版本记录可以被重用;依赖于隔离级别,READ语句读取一个老版本记录进行返回。

例如下面两条记录:T1(值为1)、T2(值为2),通过下面3步对记录的创建进行演示:

PostgreSQL的MVCC vs InnoDB的MVCC

从图中可以看出,数据库中初始时存在两个记录:1和2。

第二步,将2更新为3。此时创建一个新值,并存放到同一个存储区域的下一个位置。老版本2为其xmax分配该事务的ID,并且指向最新的版本记录。

同理,第三步,当T1被删除时,对记录进行虚拟删除(为其xmax分配当前事务ID),该操作不存在创建新记录版本。

下面,通过实例讲解每个操作如何创建多版本,不用加锁如何实现事务的隔离级别。下面例子中使用默认隔离级别“READ COMMITTED”。

INSERT

每次insert一个记录,都会新创建一个tuple并将其存储到表文件的页中。

PostgreSQL的MVCC vs InnoDB的MVCC

可以看到:

1、Session-A开启一个事务,其事务ID为495

2、Session-B开启一个事务,其事务ID为496

3、Session-A插入一个tuple,存储到HEAP

4、新tuple的xmin为495,而xmax为null

5、由于Session-A的事务没有提交,session-B看不到第3步插入的值

6、Session-A提交

7、都可以看到新插入的tuple

UPDATE

PostgreSQL的UPDATE不是“IN-PLACE”更新,不会将现有对象更新替换为新值,而是新创建一个新对象。因此UPDATE涉及以下几步:

1、将当前对象标记为deleted

2、插入对象的一个新版本

3、将对象的老版本指向新版本

因此,即使许多记录保持不变,HEAP也会占用空间,就像新插入另一个记录一样。

PostgreSQL的MVCC vs InnoDB的MVCC

如上所示:

1、Session-A开启一个事务,其事务ID为497

2、Session-B开启一个事务,其事务ID为498

3、Session-A更新一个现有记录

4、Session-A可以看到tuple的最新版本而Session-B看到另一个老版本。Session-A看到新记录的xmin为497,xmax为null;Session-B看到老版本xmin是495,xmax为497即Session-A的事务ID。这两个tuple版本都存在HEAP中,如果空间允许甚至存在同一页中。

5、Session-A提交事务,老版本消失

6、现在所有会话都可以看到记录的同一个版本。

DELETE

DELETE操作和UPDATE类似,只是不会添加一个新版本。如UPDATE,只是将当前对象标记为已删除。

PostgreSQL的MVCC vs InnoDB的MVCC

1、Session-A开启一个事务,事务ID为499

2、Session-B开启一个事务,事务ID为500

3、Session-A删除现有记录

4、Session-A看不到当前事务已删除的记录;Session-B看到老版本,其xmax为499,499的事务删除的该记录

5、Session-A提交事务,老版本记录消失

6、所有会话都看不到之前的老版本

可以看到,这些操作都不会直接删除现有记录,如果需要会添加一个附加版本。

我们来看看SELECT在多版本中怎么执行:依赖于隔离级别,SELECT需要读取tuple的所有版本直到找到合适的tuple。假设有一个tuple T1,被更新为新版本T1’,然后再被更新为T1’’:

1、SELECT操作进入这个表的heap中,首先检查T1,如果T1的xmax事务已提交,查找该tuple的下一个版本

2、T1’也被提交,查找下一个版本

3、]最后找到T1’’看到xmax未提交或者为null,然后T1’’的xmin可见,最后读取T1’’这个tuple。

可以看到需要遍历该tuple的3个版本才能找到合适的可见版本,直到VACUUM进程回收了打上delete标签的记录。

InnoDB中的MVCC

为了支持多版本,InnoDB对行记录又额外维护了几个字段:

1、DB_TRX_ID:插入或更新航记录的事务的事务ID

2、DB_ROLL_PTR:即回滚指针,指向回滚段中的undo log record

与PostgreSQL相比,InnoDB也会创建行记录的多版本,但是存储老版本的方式不同。

InnoDB将行记录的老版本存放到独立的表空间/存储空间(回滚段)。和PostgreSQL不同,InnoDB仅将行记录最新版本存储到表的表空间中,而将老版本存放到回滚段。回滚段中的undo log作用:用来进行回滚操作;依赖于隔离级别,进行多版本读,读取老版本。

例如,两行记录:T1(值为1),T2(值为2),可以通过下面3步说明新记录的创建过程:

PostgreSQL的MVCC vs InnoDB的MVCC

从上图可以看到,初始时,表中有两条记录1和2。

第二阶段,行记录T2值2被更新为3。此时记录创建一个新版本并替代老版本。老版本存储到回滚段(注意,回滚段中的数据仅包含更改值,即delta value),同时新版本行记录中的回滚指针指向回滚段中的老版本。和PostgreSQL不同,InnoDB更新是“IN-PLACE”。

同理,第三步,删除T1然后将其标记为虚拟删除(仅在行记录指定的一个bit位上打上delete标签)并在回滚段中插入一个对应的新版本。同样回滚指针指向回滚段中undo log。

从表面上看,所有操作表象与PostgreSQL相同,只是多版本在内部存储方式不同。

MVCC:PostgreSQL vs InnoDB

下面分析PostgreSQL和InnoDB的MVCC主要不同在哪几方面:

1、老版本的大小

PostgreSQL仅更新tuple老版本的xmax,因此老版本的大小和相应插入的记录大小相同。这意味着,如果一个older tuple有3个版本,那么他们大小都相同(如果更新的值大小不同,每次更新时实际大小就不同)。

InnoDB的老版本存储到回滚段,且比对应的插入记录小,因为InnoDB仅将变化的值写到undo log。

2、INSERT操作

INSERT时,InnoDB会向回滚段写入额外的记录,而PostgreSQL仅在UPDATE中创建新版本。

3、回滚时恢复老版本

回滚时,PostgreSQL不用任何特定内容,需注意老版本的xmax等于update该记录的事务ID。因此在并发快照中该记录认为是alive的直到该事务ID的事务提交。

而InnoDB,一旦回滚,需要重新构造对象的老版本。

4、]回收老版本占用的空间

PG中,老版本占用的空间仅在没有并发快照使用时才可以被回收,此时被认为dead。然后VACCUM可以回收空间。VACCUM可以手动触发也可以依赖于配置在后台任务中触发。

InnoDB的undo log分为INSERT UNDO和UPDATE UNDO。事务提交后,就会立即释放INSERT UNDO。当没有其他并发快照使用时,才可以释放UPDATE UNDO。InnoDB没有显示VACUUM操作但是有类似的PURGE回收undo log。

5、延迟vacuum的影响

如前所示,PostgreSQL延迟vacuum存在很大影响。即使频繁执行delete,它将会引起表膨胀造成占用的存储空间暴增。这还会造成到达一个点后,需要执行一个高额代价的操作VACUUM FULL。

6、表膨胀时的顺序扫描

即使所有记录都是dead状态,PostgreSQL的顺序扫描也会扫描对象所有的老版本,直到执行vacuum将dead的记录删除。这是PG中常见且经常讨论的问题。主要PG将一个tuple的所有老版本都存储到同一个存储区域。

而InnoDB,除非需要,否则不需要读取undo log。如果所有undo记录都已失效,那么只需要读取所有对象的最新版本既可。

7、索引

PostgreSQL独立存储索引,并将索引连接到HEAP中的真实数据。因此即使没有更改索引,有时也需要更新索引。随后这个问题被HOT(Heap Only Tuple)解决,但是仍有限制,如果相同页空间不足,则退回到正常UPDATE操作。

InnoDB由于使用聚集索引,不会有这样的问题。

结论

PostgreSQL的MVCC有一些缺点,尤其是具有频繁UPDATE/DELETE负载时,会引起表膨胀。因此决定选择PG时,需要慎重配置VACUUM。

PG社区已经意识到这个问题,已经开始涉及基于undo的MVCC(暂命名为ZHEAP),我们在未来版本可以看到这个特性。

原文

https://severalnines.com/blog/comparing-data-stores-postgresql-mvcc-vs-innodb


您可能感兴趣的文档:

--结束END--

本文标题: PostgreSQL的MVCC vs InnoDB的MVCC

本文链接: https://www.lsjlt.com/news/40309.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PostgreSQL的MVCC vs InnoDB的MVCC
    任何一个数据库最主要功能之一是可扩展。如果不删除彼此,则尽可能较少锁竞争从而达到这个目的。由于read、write、update、delete是数据库中最主要且频繁进行的操作,所以并发执行这些操作时不被阻塞...
    99+
    2022-10-18
  • InnoDB MVCC的工作原理是什么
    这篇文章给大家分享的是有关InnoDB MVCC的工作原理是什么的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。InnoDB 的 MVCC,是通过在每行记录后面保存两个隐藏的列实现...
    99+
    2022-10-18
  • PostgreSQL MVCC源码的示例分析
    这篇文章主要为大家展示了“PostgreSQL MVCC源码的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“PostgreSQL MVCC源码的示例分析...
    99+
    2022-10-19
  • PostgreSQL DBA(24) - MVCC#4(快照中的xmax)
    本节通过源码解释了snapsho...
    99+
    2022-10-18
  • mvcc中的read_view
    innodb的mvcc和read view 最近读High Performance MySQL,里面提到了innodb事务隔离级别是REPEATABLE-READ时,有这样一段话 引用 ...
    99+
    2022-10-18
  • PostgreSQL、Oracle/MySQL和SQL Server的MVCC实现原理方式
    转: http://www.bkjia.com/oracle/1068936.html PostgreSQL、Oracle/MySQL和SQL Server的MVCC实现原理方式 关...
    99+
    2022-10-18
  • MySQL中的事务和MVCC
    本篇博客参考掘金小册——MySQL 是怎样运行的:从根儿上理解 MySQL 以及极客时间——MySQL实战45讲。 虽然我们不是DBA,可能对数据库没那么了解,但是对于数据库中的索引、事务、锁,我们还是必须要有一个较为浅显的认识,...
    99+
    2014-11-23
    MySQL中的事务和MVCC
  • MVCC的概念是什么
    本篇内容主要讲解“MVCC的概念是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MVCC的概念是什么”吧!MVCC作用MVCC使得大部分支持行锁的事务引擎,...
    99+
    2022-10-19
  • mysql中的mvcc 原理详解
    目录简介前言一、mysql 数据写入磁盘流程二、redo log1、redolog 的整体流程 2、为什么需要 redo log三、undo log1、undo&...
    99+
    2022-11-13
    mysql mvcc 原理 mysql mvcc 
  • MySQL MVCC的知识点总结
    本篇内容介绍了“MySQL MVCC的知识点总结”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1).Mul...
    99+
    2022-10-18
  • 怎么理解MySQL中的MVCC
    这篇文章将为大家详细讲解有关怎么理解MySQL中的MVCC,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。关系数据库管理系统使用MVCC(Multiversi...
    99+
    2022-10-19
  • MySQL MVCC的详解之Read View
    文章目录 概要一、基于UNDO LOG的版本链1.1、行记录结构1.2、了解UNDO LOG1.3、版本链 二、Read View2.1、判定机制2.2、源码 三、参考 概要 在上文中,我们提到了...
    99+
    2023-08-30
    MVCC READ VIEW MySQL
  • MySQL mvcc奇怪的现象分析
    这篇文章主要讲解了“MySQL mvcc奇怪的现象分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL mvcc奇怪的现象分析”吧! 奇怪的现象1...
    99+
    2022-10-19
  • MVCC中快照怎么工作的
    这篇文章将为大家详细讲解有关MVCC中快照怎么工作的,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。MVCC在 MySQL 中(innodb存储引擎),实际上每条记录在更新...
    99+
    2022-10-19
  • mysql中MVCC的作用是什么
    本篇文章为大家展示了mysql中MVCC的作用是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1、说明多版并发控制MVCC是MySQL InnoDB存储引擎实现隔离等级的具体方法,用于实现提交阅...
    99+
    2023-06-15
  • MYSQL事务的隔离级别与MVCC
    目录前言1. 事务(transaction)的起源1.1. 事务的定义1.2. 哪些存储引擎支持事务2. MySQL的事务语法2.1. 自动提交2.2. 手动操作事务2.2.1. 开...
    99+
    2022-11-13
  • 【Mysql】MVCC版本机制的多并发
    🌇个人主页:平凡的小苏 📚学习格言:命运给你一个低的起点,是想看你精彩的翻盘,而不是让你自甘堕落,脚下的路虽然难走,但我还能走,比起向阳而生,我更想尝试逆风翻盘。 🛸Mysql专栏:Mys...
    99+
    2023-08-24
    mysql 数据库
  • MySQL中MVCC的正确打开方式
     最近在学习MySQL中的MVCC,看了网上的各种版本,什么创建版本号、删除版本号,一开始看的时候,好像很对的样子,但实际上很多都是错误的。经过好几天的查阅对比,在几篇博客的帮助下,才算是觉得正确理解了MySQL中的MVCC。       ...
    99+
    2021-07-01
    MySQL中MVCC的正确打开方式
  • MySQL中MVCC机制的实现原理
    目录前言什么是当前读和快照读?MVCC的实现原理前言 MVCC全称为Multi Version Concurrency Control,直译为多版本并发控制,是MySQL中一种并发控制的方法,他主要是为了提高数据库的读写...
    99+
    2022-08-10
    MySQL中MVCC机制实现 MySQL的MVCC机制
  • MVCC, ACID,BASIC 和Pasox的示例分析
    这期内容当中小编将会给大家带来有关MVCC, ACID,BASIC 和Pasox的示例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。MVCC是Multi-Versio...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作