An Empirical Evaluation of In-Memory Multi-Version Concurrency Control 論文閱讀筆記

An Empirical Evaluation of In-Memory Multi-Version Concurrency Control 論文閱讀筆記

Ref[1]中他講了這篇論文名字的變化歷程。。。
上課筆記:03 Multi-Version Concurrency Control Design Decisions

DB meta data

在這裏插入圖片描述

  • txn-id:ts,作爲寫鎖
  • begin-ts:tuple version lifetime
  • end-ts:tuple version lifetime
  • pointer:指向之前的 version

都是64bit,使用 CAS update

Concurrency Control Protocol

在這裏插入圖片描述

這裏只討論 serializable execution

我這裏儘量把 MVCC 和 Version Storage 結合起來考慮,因爲這倆關係密切。如果考慮 GC 的話,就太複雜了,就先單獨考慮 GC。
由於 Time-Travel Storage 和 Delta Storage 只差一個壓縮,就認爲是同一種,稱作 new table 和 old table

MVTO

在這裏插入圖片描述

  • version-data 是一個 pointer,指向數據(可以帶 ref count,GC 時清除順便管理)
  • txn-id 表示時間戳,爲0表示沒有人在寫,非0表示正在寫
  • 每個 tuple 還有一個 pointer,指向 older tuple,指針的讀寫是 atomic
  • txn-id 和 read-ts 只有 new table 有,old table 沒有。相當於 old table 只有 (version, begin-ts, end-ts, pointer)
  • 事實上 new table 中的 end-ts 總是 infinity

我覺得這裏應該把 version-data, txn-id,read-ts 和 begin-ts 放到一個256bit寄存器,然後 CAS
下面是我結合自己的理解寫的,統一了 MVTO 和 Version Storage

讀操作

  • 先訪問 new table,原子讀 (version-data, txn-id, read-ts, begin-ts),如果 txn-id 非0就 spin
  • 如果命中區間 (beign-ts, inf)
    • 若 Tid > read-ts,則 CAS 更新 (version-data, txn-id, Tid, begin-ts),如果失敗
      • 如果失敗原因是 txn-id 被持有寫鎖,那麼 abort-restart
      • 如果是 read-ts 被修改,那麼重新嘗試
    • 讀 version-data
  • 如果 begin-ts 比 Tid 大,進入 old table
    • 除了 GC 以外根本不可能 overwrite old table,寫操作是 append
    • 所以隨便讀,不需要 read-ts

如果讀不存在怎麼辦?

寫操作

  • 準備 new-version-data
  • 訪問 new table,原子讀 (version-data, txn-id, read-ts, begin-ts)
  • 如果
    • read-ts, begin-ts > Tid,就 abort-restart
    • txn-id 非0就 spin
  • latch:CAS 更新 (version-data, Tid, read-ts, begin-ts)
  • 把這個 tuple copy-append 到 old table,即 (version-data, begin-ts, Tid)
  • CAS 更新 (new-version-data, 0, read-ts, Tid),絕對不會失敗因爲自己拿着寫鎖

注:overhead 大概是寫操作時的 tuple copy-append 到 old table

MVOCC

  • read phase (start-ts),和 MVTO 差不多
  • validation phase (commit-ts)
  • write phase

MV2PL

在這裏插入圖片描述

  • (txn-id, read-cnt) 整個原子操作,作爲 write-read lock
  • commit 時先獲取 commit-ts,更新 begin-ts,然後釋放鎖
  • deadlock protocol:No_Wait 性能不錯

Serializability

SSI:鎖 + 前驅圖

Version Storage

在這裏插入圖片描述

我有一個問題一直沒搞明白,如果試圖訪問一個不存在的 tuple 怎麼辦,這時候好像必須要上鎖了,然後還得面臨一大堆問題。。。
比如 Tid=8 write©,Tid=10 read©。如果 T8 還沒有開始,T10 難道還要自己創建一個 C(更新 index,然後 return null),然後 T8 發現 null-C 的 read-ts=10>8 所以 abort?
感覺可行的方案也就是 index 上鎖,但是這樣就太 overhead,其他優化基本就沒有意義了
或者是 index 使用 hash + atomic-list???

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

GC

在這裏插入圖片描述

  • detect expired versions: check whether a version’s end-ts < Tids of all active txns
  • unlink those versions from their associated chains and indexes
  • reclaim their storage space

在這裏插入圖片描述

在這裏插入圖片描述

Index Management

在這裏插入圖片描述

logical pointer 好,update 時方便

實驗分析

很重要的一部分,但是他課上(Ref[1])講了不少,就不寫了。

Reference

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章