【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.hqwc.cn/news/691816.html

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

相关文章

打印图案(金字塔)头歌作业

题目: 任务描述 本关任务&#xff1a;编写一个程序&#xff0c;输出堆叠式的金字塔图案。 输入n个字符&#xff0c;按以下原则输出&#xff1a;【参考样例】 1)第1个字符为一层金字塔图案&#xff0c;第2个字符为两层金字塔图案&#xff0c;第3个字符为三层金字塔图案&#x…

一文弄懂 Linux 系统调用函数之 exec 函数族

目录 简介函数原型参数说明返回值函数区别使用示例采用参数列表传递参数&#xff0c;以 execl 为例采用参数数组传递参数&#xff0c;以 execv 为例调用 PATH 下可执行文件&#xff0c;以 execlp 为例使用新的环境变量给新进程&#xff0c;以 execle 为例 更多内容 简介 exec …

每日OJ题_贪心算法四④_力扣397. 整数替换

目录 力扣397. 整数替换 解析代码 力扣397. 整数替换 397. 整数替换 难度 中等 给定一个正整数 n &#xff0c;你可以做如下操作&#xff1a; 如果 n 是偶数&#xff0c;则用 n / 2替换 n 。如果 n 是奇数&#xff0c;则可以用 n 1或n - 1替换 n 。 返回 n 变为 1 所需…

解决常见的Android问题

常见问题&#xff1a; 1、查杀&#xff1a; 查杀一般分为两个方向一种是内存不足的查杀&#xff0c;一种的是因为温度限频查杀&#xff0c;统称为内存查杀&#xff0c;两个问题的分析思路不同 1、内存不足查杀&#xff1a; 主要是因为当用户出现后台运行多个APP或者是相机等…

【020】基于JavaWeb实现的批报管理系统

项目介绍 基于jspservlet实现的批报管理系统采用B/S架构,该项目设计了一个角色管理员&#xff0c;管理员实现了我的案件、查询统计、项目维护等三大功能模块 技术栈 开发工具&#xff1a;Idea2020.3 运行环境&#xff1a;jdk1.8tomcat9.0mysql5.7 服务端技术&#xff1a;j…

Vue3实战笔记(13)—pinia安装笔记

文章目录 前言安装和配置pinia总结 前言 Pinia 是 Vue 的专属状态管理库&#xff0c;它允许你跨组件或页面共享状态。 Pinia是一个轻量级的状态管理库&#xff0c;它专注于提供一个简单的API来管理应用程序的状态。相比之下&#xff0c;Vuex是一个更完整的状态管理库&#xf…

WVP-GB28181摄像头管理平台 user 信息泄露漏洞复现

0x01 产品简介 GB28181是公共安全视频监控联网系统信息传输、交换、控制技术要求的标准。该标准主要定义了基于IP网络的音视频监控系统的整体架构&#xff0c;包括前端设备、存储设备、管理平台等组成部分&#xff0c;以及设备接入、流媒体传输、信令交互、存储管理、安全防护…

[muduo网络库]——muduo库Buffer类(剖析muduo网络库核心部分、设计思想)

接着之前我们[muduo网络库]——muduo库Socket类&#xff08;剖析muduo网络库核心部分、设计思想&#xff09;&#xff0c;我们接下来继续看muduo库中的Buffer类。其实Buffer在我的另一篇博客里面已经介绍过了深究muduo网络库的Buffer类&#xff01;&#xff01;&#xff01;&am…

IPv6路由配置:ripng、ospfv3、静态路由

本次主要是对ipv6路由的配置&#xff0c;先了解ipv6&#xff0c;再进行实验配置 目录 一、&#x1f349; 什么是IPV6&#xff1f;&#x1f31f;IPv6的主要特点 二、&#x1f349;IPv6和IPv4的对比&#x1f31f; 共同点:&#x1f31f; IPv4的优缺点:&#x1f31f; IPv6的优缺点:…

Python多线程与互斥锁模拟抢购余票的示例

一、示例代码&#xff1a; from threading import Thread from threading import Lock import timen 100 # 共100张票def task():global nmutex.acquire() # 上锁temp ntime.sleep(0.1)n temp - 1print(购票成…

Java入门基础学习笔记18——赋值运算符

赋值运算符&#xff1a; 就是“”&#xff0c;就是给变量赋值的&#xff0c;从右边往左边看。 int a 10; // 把数据赋值给左边的变量a存储。 扩展赋值运算符&#xff1a; 注意&#xff1a;扩展的赋值运算符隐含了强制类型转换。 package cn.ensource.operator;public class…

使用Three.js绘制快速而逼真的水

本文将利用GPUComputationRenderer来实现水波纹的绘制&#xff0c;相似的案例可以看threejs官方的GPGPU Water示例。更多精彩内容尽在数字孪生平台。 什么是 GPGPU GPGPU代表通用图形处理单元&#xff08;General-Purpose Graphic Processing Unit&#xff09;&#xff0c;意思…