事务原理,以及MVCC如何实现RC,RR隔离级别的

news/2024/12/22 0:15:28/

事务原理

 redo log 保持持久性:

首先原来的情况是我们做一组操作的时候,先去操作bufferpool缓冲区,如果没有,那么后台线程将数据页换入换出到缓冲区,然后我们对这个buffer pool进行修改,为脏页,在写回磁盘的时候宕机了,那么不能保证持久性了,所以引出了redolog

redo log 在这里出现就是将更新的操作立马更新到redologbuffer中,然后等事务提交的时候,那么直接将redologbuffer的文件写回追加到磁盘的 log文件中,实现持久化。这样下次bufferpool中的脏页写回也不担心宕机了

undo log实现原子性

undolog记录的是逻辑日志,redolog记录的是物理日志;

实现原子性就是,当我们delete一条数据的时候,undolog会存有对应的一条insert数据,当执行rollback的时候,就可以从undolog中读取相应的内容进行回滚;保证原子性

mvcc和锁实现隔离性

基本概念:

当前读:执行当前读的时候,读取的是最新的数据版本;

快照读:就是事务读取的是事务开始的版本,有可能是旧版本,RR级别就是这个快照读

原来的两个事务其中一个修改了表的数据,然后另一个是读取不到的,因为事务的隔离级别为RR可重复读,然后我们加了个共享锁,或者是一下排他锁就变成了当前读,就可以读到最新的版本数据了

MVCC:

隐藏字段:事务id,回滚指针(指向上一个版本的事务),隐藏主键

undo log

readview

读已提交的隔离级别:每次执行快照读的时候生成Readview;

可重复读:仅在第一次执行快照读时生成readview,后续都用这个Readview;

MVCC实现原理:

1. 隐藏字段

每一行记录在数据库中(如MySQL InnoDB)都有两个隐藏字段:

  • trx_id(创建事务ID):记录该行是由哪个事务插入或更新的,用于标识哪个事务创建或修改了这个版本的数据。
  • roll_pointer(指向undo log):指向undo log中的前一个版本的记录,形成一个版本链。

这两个字段帮助维护数据的多个版本,在读取时通过这些字段判断数据版本是否可见。

2. undo log版本链

每次对数据行进行更新操作时,并不会直接覆盖数据,而是将旧版本数据保存在undo log中,并且利用roll_pointer指向前一个版本的数据,形成一个版本链。这些旧版本数据存储在undo log中,并可以通过回滚操作恢复或者进行历史版本读取。

undo log版本链允许在并发事务中查询过去某个时刻的数据库状态,而不影响当前正在进行的事务。每个事务可以通过遍历这个版本链来找到符合其可见性规则的数据版本。

3. readview

readview是MVCC在执行查询时创建的一致性视图,它用于决定当前事务能够看到哪些数据版本。readview中保存了当前正在活跃的事务列表,以及当前事务的ID。这个视图确定了当前事务可以看到哪些数据版本,避免读取到其他未提交事务的更改。

关系:
  • trx_id记录了数据的创建时间(以事务为单位),可以通过它来判断某个版本的数据是否是当前事务或其他事务创建的。
  • undo log版本链用于保存历史版本,并通过roll_pointer串联成链,回溯出需要的历史数据版本。
  • readview则是事务在执行查询时生成的,帮助决定当前事务可以看到哪些版本的记录。

MVCC如何实现隔离级别

1. 可重复读(Repeatable Read)

可重复读隔离级别下,数据库为每个事务生成一个固定的readview,该视图在事务开始时创建,并在整个事务期间保持不变。通过readview的规则,每次查询时事务都只会看到在事务开始时已经提交的版本。

具体流程:

  • 当事务开始时,系统生成一个readview,记录当前系统中活跃的事务ID列表。
  • 读取数据时,通过遍历undo log版本链,根据数据的trx_id判断当前事务是否能看到某个版本:
    • 如果数据的trx_id小于当前readview生成时的最小活跃事务ID(即数据在事务开始前已经提交),则该版本可见。
    • 如果数据的trx_id大于当前readview中的最大事务ID,说明这个版本是在当前事务之后创建的,不可见。
    • 如果trx_id在活跃事务列表中,说明该事务还未提交,数据不可见。
  • undo log中的每个版本根据以上规则遍历,找到第一个可见的版本进行返回。

通过这种机制,即使其他事务在当前事务执行期间对数据做了修改,当前事务也只会读取到事务开始时的数据版本,实现了可重复读

2. 读已提交(Read Committed)

读已提交隔离级别下,数据库在每次执行SELECT语句时都会生成一个新的readview。这意味着,每次查询都会看到最近已经提交的版本数据,而不必像可重复读那样锁定在事务开始时的版本。

具体流程:

  • 在每次查询时,数据库生成一个新的readview,包含当前活跃的事务ID列表。
  • 根据与可重复读相同的判断规则,遍历undo log版本链,查找当前readview下可见的数据版本。
  • 因为readview是每次查询都生成的,因此每次查询都会看到最新已提交的数据,从而允许事务在执行期间读取到其他事务已经提交的更新数据。

总结:

  • 隐藏字段存储了记录的事务ID和回滚指针,决定了当前版本的记录由哪个事务修改,并提供了回溯历史版本的路径。
  • Undo Log 记录了历史版本数据,并通过 roll_pointer 构建版本链,确保事务可以基于不同的 ReadView 回溯到合适的历史版本。
  • ReadView 决定了当前事务在读取时能看到哪些事务提交的版本数据。在 可重复读 下,ReadView 在事务启动时生成并固定,而在 读已提交 下,每次读取都会创建新的 ReadView。

http://www.ppmy.cn/news/1534006.html

相关文章

滚雪球学Oracle[8.3讲]:区块链与Oracle

全文目录: 前言一、Oracle Blockchain的架构与应用1.1 Oracle Blockchain的基本架构1.1.1 Oracle Blockchain的核心组件 1.2 Oracle Blockchain的优势示例:Oracle Blockchain的实际应用 二、区块链与传统数据库的集成2.1 区块链与传统数据库的关系2.2 区…

几种操作系统和几种cpu

常见的操作系统:windows,linux,macOS,统信,deepin,raspberry,andriod,iOS,鸿蒙,等等。 常见的cpu:intel,amd,龙芯&#x…

《黑神话:悟空》天命人速通法宝 | 北通鲲鹏20智控游戏手柄评测

《黑神话:悟空》天命人速通法宝 | 北通鲲鹏20智控游戏手柄评测 哈喽小伙伴们好,我是Stark-C~ 截止目前,《黑神话:悟空》已经面世一个多月,不知道还有多少天命人没有通关呢? 作为国内首款真正意义上的3A大作,《黑神话…

Unity给物体添加网格(Wire)绘制的方法参考

先看效果&#xff1a; 再看代码&#xff1a; using System.Collections.Generic; using UnityEngine;public class WireMesh : MonoBehaviour {[SerializeField]Material material;void Start(){Mesh mesh OptimizeMesh(GetComponent<MeshFilter>().mesh);GameO…

力扣 —— 跳跃游戏

题目一(中等) 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&…

Qt(9.28)

widget.cpp #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {QPushButton *btn1 new QPushButton("登录",this);this->setFixedSize(640,480);btn1->resize(80,40);btn1->move(200,300);btn1->setIcon(QIcon("C:…

奔驰EQS450suv升级增强AR抬头显示HUD案例分享

以下是奔驰 EQS450 SUV 升级增强版 AR 抬头显示的一般改装案例步骤及相关信息&#xff1a; 配件&#xff1a;通常包括显示屏、仪表模块、饰板等。 安装步骤&#xff1a; 1. 拆下中控的仪表。 2. 在仪表上预留位置切割出合适的孔位&#xff0c;用于安装显示器。 3. 将显示器…

【算法】分治:归并排序之 315.计算右侧小于当前元素的个数(hard)

hard太难了啦&#xff0c;大家还是酌情做题&#xff0c;不要浪费太多时间。 相关题目&#xff1a;LCR 170. 交易逆序对的总数 - 力扣&#xff08;LeetCode&#xff09; 目录 1、题目链接 2、题目介绍 3、解法 4、代码 1、题目链接 315. 计算右侧小于当前元素的个数 - 力扣…