【CMU 15-445】Proj4 Concurrency Control

Concurrency Control

  • 通关记录
  • Task1 Timestamps
  • Task2 Storage Format and Sequential Scan
  • Task3 MVCC Executors
    • Task3.1 Insert Executor
    • Task3.2 Commit
    • Task3.3 Update and Delete Executor
    • Task3.4 Stop-the-world Garbage Collection
  • Task4 Primary Key Index
    • Task4.0 Index Scan
    • Task4.1 Inserts
    • Task4.2 Index Scan, Deletes and Updates
    • Task4.3 Primary Key Updates
  • Bonus1 Abort

CMU-15445汇总
本文对应的project版本为CMU-Fall-2023的project4
由于Andy要求,本博客只提供思路,不会公开任何代码
终于要完结15445的所有project了(一些leaderboard没写,以后再说吧,至少基础的部分都完成啦)
拖了好久,期间有实习毕设等各种各样的事情阻碍了进程

通关记录

本project用时约6天
在这里插入图片描述

Task1 Timestamps

Task1比较简单,就是为事务维护读取时间戳与提交时间戳,并维护watermark值(系统中所有活跃事务的最小读取时间戳,后续用于垃圾回收)。
transaction_manager.cpp中,设置事务的读取时间戳与提交时间戳,当前事务的读取时间戳为系统中最新提交事务的提交时间戳(last_commit_ts_);当前事务的提交时间戳是系统中最新提交事务的提交时间戳+1(last_commit_ts_ + 1)。
watermark值用map简单维护一下即可(current_reads_)。

Task2 Storage Format and Sequential Scan

Task2也相对简单,实现版本的重构与sequential scan逻辑的重写(需要根据事务的读取时间戳查找可见版本)。
由于在bustub中,版本链的维护采用undo log的形式(每个undo log只存放partial tuple),最新记录存放在table heap中,需要沿着版本链逐步复原可见版本,故Task2需要实现一个版本重构函数ReconstructTuple
该函数接收一个undo log数组和base_tuple,需要以base_tuple为初始记录,遍历该undo log数组,恢复出最终的版本,逻辑并不复杂。对undo log的每一次迭代大致分为三部分:

  • 遍历undo log的modified_fields字段,提取出需要修改的列
  • 根据提取出的需要修改的列,利用Schema::CopySchema函数,提取出对应的partial schema
  • 利用partial schema,提取出partial tuple各个字段的值,并进行修改

实现完ReconstructTuple函数后,则可以重写seq_scan_executor.cpp中的记录扫描逻辑。原始的扫描逻辑只会查看table heap上的所有记录,而在新增了MVCC的版本链之后,可能需要从表堆开始,沿着版本链查找可见版本。
根据当前事务的read_ts与表堆中tuple的时间戳ts的大小关系,分为以下两种情况:

  • ts <= read_tsts == txn_id:表堆中的tuple对当前事务可见,直接返回
  • else:表堆中的tuple对当前事务不可见,需要沿着版本链查找可见版本

undo log之间通过undo link进行连接(undo link存放下一个undo log的位置,undo log存放着下一个undo link),在版本链上查找可见版本时,获取第一个undo link需要通过GetUndoLink函数,后续的undo link则存放于undo log中。

Task3 MVCC Executors

Task3任务量会大一些,但拆分后也不难。

Task3.1 Insert Executor

首先重写insert executor,由于insert操作不会影响版本链(因为是新纪录,版本链是空的),故只是添加上设置tuple时间戳的代码,需要设置时间戳为当前事务id。同时,需要将该tuple的rid添加到当前事务的write set中,方便commit时修改tuple时间戳。

Task3.2 Commit

当一个事务commit时,我们需要将该事务write set中的所有记录的时间戳设置为该事务的提交时间戳。

Task3.3 Update and Delete Executor

需要重写update executor和delete executor,它们的逻辑非常类似,因此需要将一些代码打包成函数放在execution_common.cpp中,方便重用。
以更新逻辑为例,主要分为以下步骤:

  • 检查是否产生Write-Write Conflict,若产生则终止事务,否则继续往下
  • 判断当前事务是否第一次更新该记录(查看表堆记录的时间戳与当前事务id是否一致)
    • 若为第一次更新,则需要创建新的undo log,并更新table heap中的记录以及undo link
    • 若不是第一次更新,则只需要修改之前创建过的undo log,更新table heap中的记录(确保事务在每条tuple上只存在一个undo log)

Task3.4 Stop-the-world Garbage Collection

由于bustub中的undo log管理在事务中,所以垃圾回收也以事务为单位,主要步骤如下:

  • 遍历txn_map_的所有事务
    • 遍历当前事务的write set,从table heap中遍历write set中的每个记录,如果该事务创建的所有undo log均无效,则标记
  • 回收被标记且已提交的事务

Task4 Primary Key Index

Task4会考虑主键依赖,并开始出现多线程的测试,debug会痛苦一些

Task4.0 Index Scan

与Task2顺序扫描类似,加上版本链查找逻辑即可

Task4.1 Inserts

插入逻辑需要考虑主键依赖,在插入之前,首先检测所插入的记录是否包含主键索引,如果所包含的主键索引在数据库中已存在,那么分为以下两种情况(如果只完成Task4.1及之前的所有任务,则不需要考虑这两种情况,均终止事务即可)。

  • 若主键索引指向的记录已被删除,走更新流程
  • 若主键索引指向的记录未被删除,终止当前事务
    若主键索引不存在,则插入记录,并更新索引。若更新索引时更新失败(因为可能有多个线程并行运行),那么也要终止当前事务。

Task4.2 Index Scan, Deletes and Updates

删除与更新逻辑均涉及版本链的更新,在多线程环境下,需要保证删除与更新逻辑的线程安全性。这里采用VersionLInk类中的in_progress字段实现无锁安全性,具体方法是:

  1. 检查写写冲突
  2. 循环获取in_progress字段,直到它的值为false或者循环超时(我设置的超时次数为100次)
  3. 备份version_link
  4. 更新in_progress字段为true(使用UpdateVersionLink函数,参数中的check函数需要检查之前保存的version_link是否被修改过)
  5. in_progress字段更新成功,则进行记录的删除或更新逻辑;若更新失败,则回到第一步重新进行

记录的更新与删除逻辑与Task3.3一致,不再赘述

Task4.3 Primary Key Updates

当Update算子涉及到对主键的更新时,使用以前的更新逻辑会导致主键索引所指向的记录出错(因为主键的值被更新了,会映射到新的索引上)。
因此,这里的处理方法是,将记录删除后添加,不修改索引。

Bonus1 Abort

在事务终止时,需要回退事务的修改,遍历事务的writeset,根据undo log修改表堆记录即可。这里有两种实现方法,第一种是直接修改表堆记录,不改变version link,这会导致undo log的冗余;第二种是修改完表堆记录后,修改version link,跳过第一个undo log(因为它已经没用了)。

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

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

相关文章

Springboot+logback 详细配置

一、添加依赖 这里使用springboot3.0.2 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><dependency><groupId>org.projectlombok</grou…

macos使用yarn创建vite时出现Usage Error: The nearest package directory问题

步骤是macos上使用了yarn create vite在window上是直接可以使用了yarn但是在macos上就出现报错 我们仔细看&#xff0c;它说的If /Users/chentianyu isnt intended to be a project, remove any yarn.lock and/or package.json file there.说是要我们清除yarn.lock和package.js…

yolo world 瑞芯微芯片rknn部署、地平线芯片Horizon部署、TensorRT部署

特别说明&#xff1a;参考官方开源的 yoloworld 代码、瑞芯微官方文档、地平线的官方文档&#xff0c;如有侵权告知删&#xff0c;谢谢。 模型和完整仿真测试代码&#xff0c;放在github上参考链接 模型和代码。 yoloworld出来的有一段时间了&#xff0c;还没有盘到板端上玩一玩…

芸众商城电商专业版400+插件源码+搭建教程

介绍&#xff1a; 芸众商城社交电商系统SAAS平台前端基于vue开发&#xff0c;后端基于研发积分商城系统源码 php&#xff0c;本文安装芸众商城全插件&#xff08;400多个&#xff09;商业版平台源码&#xff0c;可同时支持多端口部署运行&#xff1b;使用宝塔面板一键部署的形…

LibreNMS简介

目录 1 LibreNMS简单介绍1.1 LibreNMS介绍 2 安装2.1 Ubuntu安装1、安装依赖2、添加 librenms 用户3、下载 LibreNMS4、设置权限5、安装 PHP 依赖项6、设置时区7、配置 MariaDB8、配置 PHP-FPM9、配置 Web 服务器10、启用 lnms 命令11、配置 snmpd12、cron13、启用调度程序14、…

贪吃蛇(c实现)

目录 游戏说明&#xff1a; 第一个是又是封面&#xff0c;第二个为提示信息&#xff0c;第三个是游戏运行界面 游戏效果展示&#xff1a; 游戏代码展示&#xff1a; snack.c test.c snack.h 控制台程序的准备&#xff1a; 控制台程序名字修改&#xff1a; 参考&#xff1a…

练习队列的相关操作:循环队列

1. 思路解析 循环队列就是在只有有限的空间时使用队列实现循环存储数据&#xff0c;有双向链表和数组两种选择&#xff0c;这里我们使用数组实现循环队列&#xff08;因为链表我不会 >-<&#xff09; 2. 相关函数及其实现 2.1 判空与判满 判空&#xff1a;直接返回头尾…

Leetcode—946. 验证栈序列【中等】

2024每日刷题&#xff08;133&#xff09; Leetcode—946. 验证栈序列 实现代码 class Solution { public:bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {int left 0;for(int i 0; i < popped.size(); i) {while(left &…

关于我转生从零开始学C++这件事:获得神器

❀❀❀ 文章由不准备秃的大伟原创 ❀❀❀ ♪♪♪ 若有转载&#xff0c;请联系博主哦~ ♪♪♪ ❤❤❤ 致力学好编程的宝藏博主&#xff0c;代码兴国&#xff01;❤❤❤ 几天不见 &#xff0c;甚是想念&#xff01;哈咯大家好又是我大伟&#xff0c;五一的假期已经结束&#xff0…

超绝git

我们应该学会使用超绝git了&#xff0c;首先&#xff0c;什么是git&#xff1f; git是超绝版本控制器&#xff08;去中心化的分布式系统&#xff09;&#xff0c;什么又是版本控制&#xff0c;git和Gitee又有什么牵扯&#xff1f; git安装 这是安装git&#xff1a; yum ins…

Kexp 动态展示 k8s 资源对象依赖关系

kexp[1] 旨在以可视化的方式帮助用户理解和探索 Kubernetes 的能力。 适用场景&#xff1a; 学习和探索 Kubernetes 的功能。 应用开发&#xff0c;提供每个应用的对象图预设。 控制器和操作器的开发&#xff0c;支持动态对象图。 即将推出类似 Postman 的 Kubernetes API …

Python深度学习基于Tensorflow(9)注意力机制

文章目录 注意力机制是怎么工作的注意力机制的类型 构建Transformer模型Embedding层注意力机制的实现Encoder实现Decoder实现Transformer实现 注意力机制的主要思想是将注意力集中在信息的重要部分&#xff0c;对重要部分投入更多的资源&#xff0c;以获取更多所关注目标的细节…

GoF之代理模式(静态代理+动态代理(JDK动态代理+CGLIB动态代理带有一步一步详细步骤))

1. GoF之代理模式&#xff08;静态代理动态代理(JDK动态代理CGLIB动态代理带有一步一步详细步骤)&#xff09; 文章目录 1. GoF之代理模式&#xff08;静态代理动态代理(JDK动态代理CGLIB动态代理带有一步一步详细步骤)&#xff09;每博一文案2. 代理模式的理解3. 静态代理4. 动…

整理好的中债国债3年期到期收益率数据集(2002-2023年)

01、数据简介 国债&#xff0c;又称国家公债&#xff0c;是由国家发行的债券&#xff0c;是中央ZF为筹集CZ资金而发行的一种ZF债券&#xff0c;是中央ZF向投资者出具的、承诺在一定时期支付利息和到期偿还本金的债权债务凭证。 中债&#xff0c;是指由中国中债登记结算有限责…

Jetpack Compose一:初步了解Compose

Intellij IDEA构建Android开发环境 IntelliJ IDEA 2023.2.1 Android开发变化 IDEA配置使用Gradle 新建Compose工程&#xff0c;取名ComposeStudy 可以看到的是IDEA为项目初始化了部分代码 使用Compose开发不再需要使用xml文件来设计布局了 Compose中的Text也不同于Android V…

机器学习特征降维

目录 特征降维概念 低方差过滤法 PCA主成分分析 相关系数法 小结 特征降维概念 特征对训练模型时非常重要的&#xff1b;用于训练的数据集包含一些不重要的特征&#xff0c;可能导致模型性能不好、泛化性能不佳&#xff1b;例如&#xff1a; 某些特征的取值较为接近&…

部署Gerapy

1.Gerapy 是什么&#xff1f; Gerapy 是一款基于 Python 3 的分布式爬虫管理框架&#xff0c;它旨在简化和优化分布式爬虫的部署、管理和监控过程。 2.作用与功能&#xff1f; 2.1分布式管理&#xff1a; Gerapy 允许用户在多台机器上部署和管理Scrapy爬虫&#xff0c;实现爬虫…

Oracle数据库之 常用数据库对象(二)

目录 1.视图 1.1.什么是视图&#xff1f; 1.2.创建视图的语法 1.3.简单视图和复杂视图 1.4.创建复杂视图 1.4.1.创建复杂视图的步骤 1.4.2.示例 1.4.3.注意事项 1.5.视图中使用DML的规定 1.5.1.屏蔽DML操作 1.6.删除视图 2.序列 2.1.语法&#xff1a; 2.2.查询序…

HNU-操作系统OS-2024期中考试

前言 该卷为22计科/智能OS期中考卷。 感谢智能22毕宿同学记忆了考卷考题。 同学评价&#xff1a;总体简单&#xff1b;第1&#xff0c;7概念题较难需要看书&#xff1b;第4&#xff0c;5题原题。 欢迎同学分享答案。 【1】共10分 操作系统的设计目标有哪些&#xff1f; 【…

安卓surfaceview的使用方式

1. 什么是surfaceview surfaceview内部机制和外部层次结构 在安卓开发中&#xff0c;我们经常会遇到一些需要高性能、高帧率、高画质的应用场景&#xff0c;例如视频播放、游戏开发、相机预览等。这些场景中&#xff0c;我们需要直接操作图像数据&#xff0c;并且实时地显示到…