Lecture #19 : Multi-Version Concurrency Control

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 文件中注釋掉兩處即可全局搜索…