CMU15445课程笔记

多版本并发控制

多版本并发控制讲的是Mvcc。 即维护单个逻辑对象的多个物理版本, 这样当一个事务读取某个对象的时候不会阻塞其他事务写入该对象; 反之亦然。 但是Mvcc不保护写写冲突, 对于这种情况, 可能需要其两阶段锁之类的其他控制协议。

Mvcc可以实现: 只读事务并发时, 无需使用锁, 即可达成读层次的一致性快照; 并且在Mvcc中, 时间戳是用来确定某个对象的某个版本对于事务的可见性; 不带垃圾回收机制的Mvcc允许DBMS支持时间旅行查询(基于某个时间点的状态进行的查询)

时间旅行查询的一个例子: 比如对方想要查询这个表三星期前的某个数据, 现在我们只需要找到三星期前的时间戳, 然后读取即可。——这是在不做垃圾回收机制的情况下。 Postgres有一开始推崇时间旅行查询到砍掉这一机制的原因就是因为要支持垃圾回收机制, 因为如果不支持垃圾回收机制, 那么存储空间很快就会耗尽。

快照隔离

实现的基本思路是: 对于事务TS(1)和事务TS(2)。 然后对于对象A, 两个事务要对A做一系列操作如下:

      TS(1)             TS(2)
|     Begin      |                |       
|                |                |
|     R(A)       |                |
|     W(A)       |     Begin      |
|                |     R(A)       |
|                |     W(A)       |
|     R(A)       |                |
|                |                |
|     COMMIT     |                |
  • 首先, TS(1)事务和TS(2)事务开始时, 要建立一个一致性视图, 视图有一个时间戳, TS(1)先Begin, 建立时间戳为1的视图。

  • Database(Buffer Pool)中要维护一个对于A的版本链, 一开始版本A0, 开始时间戳begin-ts 为0, 结束时间戳end-ts为∞;

    •     A0 | 0 | ∞ |
      
  • 然后, TS(1)进来了, 他一开始读取R(A), 对于A的版本链没有任何影响。

    •     A0 | 0 | ∞ |
      
  • TS(1) 执行W(A), A被修改出新版本A1, A1的开始时间戳就是TS(1)的时间戳1, 并且因为A被修改了, 所以上一个版本, 也就是A0被限制了, 它的结束时间戳不再是无穷大了, 变成了版本A1出现的时间戳。

    •     A0 | 0 | 1 |A1 | 1 | ∞ |
      
    • begin-ts和end-ts就可以理解为某个版本所持续的时间。这就可以理解为如果没有人修改A, 那么最新的版本就是版本链的最后一个版本, 并且这个版本的有效性可以持续到无穷时间以后, 但是有人修改A了, 这个版本的持续时间就只存在于这一段时间了。
  • 然后对于TS(2), 他Begin了, 创建一致性视图, TS(2)的时间戳为2。 然后TS(2)此时想要读取A, 能否读取一个对象要看三个规则:

    • 自身携带的时间戳是否大于版本的end-ts, 如果大于, 则看不到。
    • 如果自身携带的时间戳处于begin-ts ~ end-ts之间, 那么观察一下active table(这也是一张表, 包含了当前正在活跃的事务) 中这个版本的begin-ts所在事务是否在活跃, 即没有提交。 如果提交了, 可以看到, 没提交, 看不到。
    • 如果自身携带的时间戳等于begin-ts, 即是这个版本的创建者, 可以看到。
  • 所以这里TS(2)读取A得到了A0版本。 然后W(A), 但是TS(1)此时正在持有锁, TS(2)要阻塞, 直到TS(1)提交。 当然, 中间TS(1)还有一次R(A), 但是因为TS(1)是A1的创建者, 则可以看到A1。然后提交。

  • TS(2)获取写锁,W(A), 此时最新的版本变成了A2, begin-ts为2, end-ts为∞;A1则修改end-ts变成2,因为A1只存在于A1 ~ A2这段时间就被TS(2)写入A2逻辑上覆盖了。

    •     A0 | 0 | 1 |A1 | 1 | 2 |A2 | 2 | ∞ |
      

版本存储

对于版本控制有不同的版本控制方案。 版本控制总是一个类似链表的数据结构。 链表内存放了保存的逻辑元组, 以及连接到这个逻辑元组的下一个逻辑元组, 可以是单链表,也可以是双链表。

不同点是这个链表的头指针是新是旧, 遍历方式是从新到旧还是从旧到新, 亦或者这个逻辑元组里面存储的具体内容。

仅追加存储

仅追加存储就是每当更新新的版本, 就将旧的版本作为新元组追加到版本链中。

具体细节就是当来了一个新的元组, 然后就把他插入这张表中, 因为对于数据库中的每一张表, 都会被分配一个表空间存储这些元组。然后每次更新元组, 比如更新A, 那么就要跟新A的版本链, 让A的版本链中最新的节点指向新更新的节点。 这里的问题就是每次链接版本链, 都要从表中查找该数据的头节点。

并且版本链的排序也很重要, 因为如果是从新到旧, 那么插入新元组的时候直接找到版本链的头节点就可以了; 但是如果是从旧到新, 那么插入新元组的时候就不仅仅需要找到版本链的头节点, 还要遍历整个版本链。

另外对于从旧到新, 我们这里查找表头可能索引, 比如我利用索引查找到对应的记录ID,然后找到版本链的链头, 然后遍历整个链表, 根据节点的begin-ts和end-ts查找当前版本是否符合要求或者追加新节点。

对于从新到旧, 虽然让你我们查找到链头, 可以很快的查找到最新的节点, 但是这只是听起来很棒。 这只是查询, 如果我们要追加新节点, 那么我们因为维护大量了的索引。 就要更新所有指向这个头结点的索引, 确保他们都指向新的链头。

这里面有很多细节问题, 目前不知道, 比如: 这些跟踪索引利用索引键跟踪,如果索引键也修改了怎么办? 为什么要有索引? 如果没有索引, SeqScan不就更慢了吗? (TODO)

在这里插入图片描述

在这里插入图片描述

时间旅行存储

本质上和仅追加存储一样。 只不过对于时间旅行存储将表划分为了主表和时间旅行表, 新元组不再是只追加到一张表中, 而是插入到指定的时间旅行表。

在这里插入图片描述

时间旅行存储并不比追加存储好, 只是它出现在了并没有那么多Mvcc设计的年代, 并且如果采用从旧到新的方式, 进行垃圾回收的时候, 要进行数据压缩, 版本新的Time-TravelTable称为新的Main Table。

增量存储(类似Git的版本控制)

增量存储要比前两种策略要好, 如果一个元组一共有1000列, 更新了其中的10列, 那么对于增量存储就只是存储这10列的信息, 而前两种方法要全部存储。

它的策略是: 假如一开始是111, 然后插入了新的数据222, 那么增量表中就要保存原始的A的被修改的列信息, 然后主表中的新元组指向它。 也就是新的修改总是在主表中的, 而历史的值是在增量表中的。这类似于LSMTree(TODO, 日志结构合并树)
在这里插入图片描述
在这里插入图片描述

垃圾回收

如果在快照隔离级别下一个版本没有事务可以看到它并且这个版本是因为事务终止创建的, 那么这个就可以移除它。这里有两个问题:

  • 如何查找过期的版本?
  • 如何确定何时可以安全的回收这些记录所占用的空间或存储呢?

元组级GC

遍历所有版本, 并尝试找到可以回收的版本。 —— 这个可以使用后台的worker线程进行; 也可以在扫描数据的同时清理,即协同清理。

对于使用后台的worker线程:

在这里插入图片描述

上图就是比如现在有两个事务, 事务12和事务25。 那么我们遍历整个表, 返现A100和B100不可见, 因为这里的A100和B100的生效时间段是1 ~ 9,所以对两个事务都不可见。 B101对事务1可见, 对事务2不可见。

在这里插入图片描述

对于协同清理:

这里不太理解, 大概的意思可能就是对于worker线程来说, 他知道哪些元组是对所有事务都不可见, 那么扫描到这个元组的时候,就把他删除。 (TODO)。

事务级别GC

事务级别GC就是需要跟踪所有事务以及他们修改的内容。 比如这里事务1, 修改了A, B。 然后记录下AB的旧版本。然后再COMMIT的时候获得一个新的事务ID。然后将这些OldVersions的信息传给vacuum进程。由vacuum进程判断一个最小时间戳, 任何小于这个最小时间戳的事务都可以删除了。

这里同样不太理解, 因为如果vacuum只处理单个事务的最小时间戳那么就不正确, 所以这里vacuum应该处理的是所有事物的最小时间戳。但是这样要一边修改一遍记录, 然后交给后台进程处理, 相当于元组GC的后台worker了。 (TODO)

在这里插入图片描述

在这里插入图片描述

索引管理

如果有二级索引, 他们指向的是什么, 即值指向的是什么。

逻辑指针

一种是逻辑指针, 工作是帮助我们找到链头的实际物理地址。这种方法最简单的是使用主键, 因为主键是现成的, 先使用二级索引找到主键, 然后利用主键索引去找到对应的物理地址。 另一种方法是合成ID, 但是这还需要重新维护一个合成ID到逻辑指针的索引, 并不划算。

物理指针

另一种就是直接存物理地址。 二级索引精确的指向了要访问的物理地址。

在数据库中可能有大量的二级索引, 这些二级索引都指向了版本链的头部。 此时就可以根据二级索引来找到具体的物理地址。但是如果更新元组, 即便不更新这个元素中二级索引所依赖的属性, 那么这个依旧要更新所有二级索引指向新链头。

Postgres这里采用了其他优化, 就是他们在索引中添加了一个新的条目, 如果新的版本和之前的版本在同一个页中, 他们不会选择更新链头, 而是直接在条目中显示:这个元组不是最新的版本, 最新的版本应该是那边的那个。

在这里插入图片描述

MySQL的处理方法就是二级索引提供主键, 然后利用主键找到对应物理地址,和上面的逻辑指针一样。

关于不同快照的重复键问题

这个问题是有一个场景:

在这里插入图片描述

就是假如一开始T1读取到了A, T2读取A, 然后删除了A。 并且T1读取的是A1, T2读取的是A2, 删除的也是自己可见的A2。 那么T3插入一个A, 他插入的应该是从时间戳30开始生效。 所以, 这里就要保证两个东西:

  • 对于T1来说, 如果正在运行, 在T2删除的时候, 他应该仍能够看到A1。
  • 对于时间戳30以后的事务, 他应该能看到A3。(图中的是笔误)

在这种情况下, 如果索引的版本链还是A1这一条。 要确保30以后的事务能够看到A3, 他在遍历版本链的时候, 可能直接就发现版本链运行结束后,也没有看到A3。所以就需要其他的信息来维护一种跳转功能, 能够在索引中存在相同值的时候(此时A的版本链有两条, 说明有相同值), 能够正确跳转。

删除

删除就是利用墓碑。

删除标志

删除标志就是在元组的头部设置删除标记

墓碑元组

墓碑元组就是将元组设置成默认的“空“元组。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/88396.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/88396.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/88396.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

imx6ul Qt运行qml报错This plugin does not support createPlatformOpenGLContext!

imx6ul运行qml的Qt程序报错This plugin does not support createPlatformOpenGLContext!1、开发环境2、问题复现3、解决办法第一种方法第二种方法4、结论1、开发环境 主板:imx6ul Qt版本:5.9.6 文件系统:buildroot 问题描述:现需…

软考中项系统集成第 5 章:软件工程全流程考点拆解,备考逻辑清晰

备考系统集成项目管理工程师的小伙伴们,福利来啦!今天开始为大家带来《系统集成项目管理工程师(第 3 版)》考点的思维导图,今天带来的是第5章。第 5 章聚焦软件工程,涵盖软件工程定义、软件需求、软件设计、…

ICLR 2025 | InterpGN:时间序列分类的透明革命,Shapelet+DNN双引擎驱动!

在Rensselaer理工学院、Stony Brook大学与IBM Research的合作下,本文聚焦于如何在时间序列分类任务中兼顾性能与可解释性。传统深度学习模型虽然准确率高,却常被诟病为“黑盒”,难以赢得如医疗等高风险领域的信任。为此,作者提出了…

使用ENO将您的JSON对象生成HTML显示

ENO 是简单易用,性能卓越,自由灵活开源的 WEB 前端组件;实现 JSON 与 HTML 互操作的 JavaScript 函数库。没有任何其它依赖,足够轻量。 WEBPack NPM 工程安装。 npm install joyzl/eno 然后在JS中引用 import "joyzl/eno…

7.12 卷积 | 最小生成树 prim

lc1900.模拟比赛算出两个指定选手最早和最晚能在第几轮碰到。还是建议dfs捏模拟比赛,找出两个特定选手(firstPlayer和secondPlayer)最早和最晚相遇的轮次。1. 定义了一个“选手”结构体,包含两个属性a(战斗力&#xff…

LVS-NAT模式配置

目录 1、负载调度器配置 配置IP地址 安装ipvsadm 开启路由转发功能 加载ip_vs模块 启动ipvsadm服务 配置负载分配策略 查看验证 2、web节点配置 3、测试 1、负载调度器配置 配置IP地址 增加一块网卡 cd /etc/sysconfig/network-scripts/ cp ifcfg-ens192 ifcfg-ens…

中国银联豪掷1亿采购海光C86架构服务器

近日,中国银联国产服务器采购大单正式敲定,基于海光C86架构的服务器产品中标,项目金额超过1亿元。接下来,C86服务器将用于支撑中国银联的虚拟化、大数据、人工智能、研发测试等技术场景,进一步提升其业务处理能力、用户…

web网页,在线%食谱推荐系统%分析系统demo,基于vscode,uniapp,vue,java,jdk,springboot,mysql数据库

经验心得两业务单,项目前端在VSCode、HBuilder环境下整合Uniapp、Vue。后端使用Java、SpringBoot和MySQL,使用这些技术栈咱们就可以搭建在线食谱推荐与分析功能的系统,技术栈虽涉及前后端及数据库跨度不小,但咱们拆分模块去开发它难度就会变小…

MCP架构:AI时代的标准化上下文交互协议

本文深入解析Model Context Protocol(MCP)架构的创新设计,这是一种由Anthropic提出的标准化协议,旨在解决大型语言模型(LLM)与外部工具和数据源交互的碎片化问题。MCP采用客户端-服务器架构,通过…

机器学习数据集加载全攻略:从本地到网络

目录 一、加载内置数据集 1.1 Iris鸢尾花数据集 1.2 其他常用内置数据集 二、加载网络数据集 2.1 20 Newsgroups数据集 三、加载本地数据集 3.1 使用pandas加载CSV文件 3.2 处理常见问题 四、数据加载最佳实践 五、总结 在机器学习项目中,数据的加载是第一…

【操作系统】进程(二)内存管理、通信

JavaEE—进程(二)内存管理、通信 一、内存管理 1.映射访问 2.独立分布 防崩溃 二、通信 1.独立性保障 2.方式 2.1管道 2.1.2特点 2.1.2.1进程条件 2.1.2.2方向 2.1.2.3同步性 2.1.2.4性能 2.2消息队列 2.2.1特点 2.2.1.1方向 2.2.1.2同步性 2.2.1.3性能 2.3…

windows 装了 python2 和 python3 如何切换默认版本

现在执行 python --version 是Python 3.11.3怎么让 python 默认是 python2,而 python3 --version 是执行 pyhon3 呢cmd 执行 where pythonC:\Users\huyun\AppData\Local\Programs\Python\Python311-32\python.exe C:\Users\huyun\AppData\Local\Microsoft\WindowsAp…

二次封装element ui pagination组件

vue2中二次封装element ui pagination组件 html部分 <template><div class"table-pagination"><el-pagination:current-page.sync"currentPage":page-sizes"pageSizes":page-size"pageSize":layout"paginationLay…

SAP学习笔记 - 开发39 - RAP开发 BTP /DMO 官方既存测试数据的使用

上一章讲了 RAP开发流程的具体步骤&#xff0c;建表 》建Data Model View 》建 Projection View 》建Service Definition 》 建Service Binding 》Publish 服务。 SAP学习笔记 - 开发37 - RAP开发流程的具体步骤&#xff0c; 建表&#xff0c;Data Model View&#xff0c;Proj…

SQLite - C/C++ 开发与应用详解

SQLite - C/C++ 开发与应用详解 引言 SQLite 是一个轻量级的数据库引擎,它被设计成不需要服务器进程就可以独立运行。SQLite 在 C/C++ 开发领域具有广泛的应用,由于其体积小、性能高、易于集成等优点,深受开发者的喜爱。本文将详细介绍 SQLite 在 C/C++ 开发中的应用,包括…

蔚来测开一面:HashMap从1.7开始到1.8的过程,既然都解决不了并发安全问题,为什么还要进一步解决环形链表的问题?

文章目录问题的根源&#xff1a;JDK 1.7 的设计缺陷为什么必须解决这个问题&#xff1f;1\. 故障等级完全不同 &#x1f4a3;2\. JDK 1.8 的解决方案&#xff1a;一石二鸟 &#x1f985;3\. 为“不小心”的开发者提供一层保障 &#x1f6e1;️结论这是一个非常好的问题&#xf…

AI技术正以前所未有的速度重塑职业生态与行业格局,尤其在自动化测试领域,AI驱动的测试框架通过智能化、低代码化重构传统测试流程。

AI技术正以前所未有的速度重塑职业生态与行业格局&#xff0c;尤其在自动化测试领域&#xff0c;AI驱动的测试框架通过智能化、低代码化重构传统测试流程。以下从职业影响、技术架构、行业应用及应对策略四个维度展开分析&#xff0c;结合代码示例与框架设计图解&#xff1a;一…

在 Mac 上安装 Java 和 IntelliJ IDEA(完整笔记)

目录 检查是否已安装 Java安装 Java&#xff08;JDK&#xff09;设置 JAVA_HOME 环境变量安装 IntelliJ IDEA配置 IntelliJ IDEA 使用 JDK验证和测试环境是否成功 1. 检查是否已安装 Java 打开终端&#xff08;Terminal&#xff09;&#xff0c;输入&#xff1a; java -vers…

基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(2)对框架加入业务逻辑层

在上篇中&#xff0c;我们已经搭建好了框架的基本雏形&#xff0c;但只是引入了页面层、用例层的思想&#xff0c;我们在实际使用中会发现&#xff0c;如果我们很多的用例需要很多前置工作&#xff0c;这些前置工作又有可能涉及到多个页面&#xff0c;那么我们在维护的时候就会…

uniapp ruoyi-app 中使用checkbox 无法选中问题

<view class"flex align-center"> <checkbox-group> <label> <checkbox value"cb" checked"true" /> 记住密码 </label> </checkbox-group> </view>colorui.css 文件中注释掉两处即可全局搜索…