在這篇論文之前 — 它所降落的世界
到 1980 年代末,兩條主流的復原技術路線都各有破口。System R 與 SQL/DS 走 shadow page:復原從整個資料庫的 action-consistent 影子版本開始,因此不需要 page LSN、不寫補償記錄,索引與空間管理的變更也完全不記日誌,代價是 checkpoint 極其昂貴、資料實體叢集性被破壞,且相關物件必須同步、鎖步地一起復原。DB2、IMS、Encompass、NonStop SQL 等以 WAL 為基礎的產品雖然採用了 WAL,卻沿用了 System R 的思維,其中最關鍵的就是 selective redo:重啟時只重做已提交與 in-doubt 交易的更新。selective redo 在那些系統中之所以能運作,靠的是頁層級鎖定或位元組範圍的實體式日誌;而它帶來的日誌行為相當病態:DB2 與 Encompass 會去 undo 自己寫的補償記錄,於是重啟過程中反覆當機時,日誌量在最壞情況下呈指數成長。與此同時,客戶要的是記錄層級鎖定、能處理 hot spot 的 increment/decrement 鎖模式、不必離線重組的變動長度記錄,以及快到足以支撐 hot standby 的重啟速度——當時沒有任何一套方法能同時滿足這些需求。
術語 — 依本篇論文的用法
- LSN(log sequence number)
- 每筆日誌記錄在附加到日誌時被指派的單調遞增識別碼,通常就是該記錄在不斷成長的日誌位址空間中的邏輯位址。它是排序,以及把日誌位置與頁面狀態關聯起來的通用貨幣。
- page LSN
- 每個資料庫頁面中的一個欄位,存放描述該頁最近一次更新的日誌記錄的 LSN,不論那是一般更新記錄還是 CLR。ARIES 就是靠它與日誌記錄 LSN 的比較,判斷某筆更新是否已反映在頁面上。
- CLR(compensation log record,補償日誌記錄)
- 用來描述回滾期間所執行更新的日誌記錄。在 ARIES 中 CLR 是 redo-only 且永遠不會被撤銷,因此不需要帶前影像,也永遠不會引發針對自己的補償。
- UndoNxtLSN
- 只存在於 CLR 中的欄位,內容是該 CLR 所補償記錄的 PrevLSN,也就是該交易下一筆仍待撤銷的記錄位置。日後回滾時沿著它走,就能跳過所有已撤銷的內容。
- RecLSN(recovery LSN)
- 當一個乾淨頁面首次以修改意圖被 fix 住時,記入 dirty pages 表的值,等於當下的 end-of-log LSN。它標示出該頁面的更新最早可能從日誌的哪個位置開始尚未落到非揮發性儲存上。
- Repeating history(重演歷史)
- ARIES 的重啟原則:在任何回滾開始之前,先把所有在頁面上缺席的已記錄更新全部 redo,包含從未提交的交易的更新。這讓資料庫回到失效當下的精確狀態,使 undo 可以無條件進行。
- Loser 交易
- 系統失效時既未提交、也未進入 two-phase commit 之 in-doubt 狀態的交易。loser 的更新在 redo 階段和其他交易一樣被重做,之後才在 undo 階段被回滾掉。
- Nested top action
- 交易中的一段動作子序列,一旦完成就不得被撤銷,即使外層交易回滾也一樣,但它本身仍必須具備原子性。ARIES 的實作方式是在序列結尾寫一筆 dummy CLR,其 UndoNxtLSN 指回序列開始之前的位置。
- Latch
- 類似 semaphore 的輕量原語,用來在讀取或修改頁面期間保證頁面的實體一致性;相對地,鎖保證的是資料的邏輯一致性。latch 持有時間很短,不納入死結偵測器追蹤,且其請求方式被設計成永遠不會參與死結。