回覆列表
  • 1 # 手機使用者85445304064

    資料庫的物理儲存會分成許多個頁(Page),記錄都儲存在頁中,資料每一次IO,操作的最小單位是一個頁。資料庫執行時,會在記憶體中維護一個緩衝區(Buffer Pool)。緩衝區快取部分的頁(因為記憶體有限,所有不能把所有資料都快取進來)。每次對資料的操作,都需要把磁碟中的頁讀入緩衝區,然後再進行操作;如果緩衝區中有對應的頁,就不需要讀磁碟。如果資料庫要讀入一個頁,而此時需要緩衝區已經被用完了,這個時候就要替換出一個頁面,騰出一塊記憶體給新讀入的頁面。如果被換出的頁被改過(在記憶體中每個頁會有個Dirty標記,標識當前頁面是否被修改過),就要把記憶體頁寫入到磁碟中。

    資料庫為了實現事務,需要併發控制和恢復機制。

    恢復機制,可以用log實現,多采用steal(未提交的資料可以寫入磁碟),no-force(提交的資料可以不寫入磁碟)策略。

    併發控制,現在的多數資料庫用MVCC(MVCC+2PL或MVCC+SSI),由於steal、no-force策略,這個部分完全就相當於在記憶體中做,直接更新的是記憶體頁中的元組。只有發生頁換出,或是checkpoint(定期的刷髒頁)時,才會寫磁碟。

    所以,不管提交之前還是提交之後,資料在記憶體中,或是被寫入磁碟,都是有可能的。

    補充說明下恢復機制。以上是針對儲存元組的頁面和緩衝區來說的,log還是要在接交時寫入磁碟的,以保證已提交的事務是持久化的。

    以MySQL為例,MySQL使用REDO和UNDO來實現恢復。其中,REDO 為了重做對資料更改儲存的資訊,用於恢復;UNDO是與事務相關的, 為了撤銷對資料更改儲存的資訊,用於回滾。每一條REDO日誌記錄都有一個LSN(Log Sequence NO) 日誌號,一個遞增的64位整數,一個LSN表示一個redo log結構。

    在三個階段涉及到日誌的操作,分別是寫入資料時,事務提交時,資料庫恢復時。

    一)寫入資料,以update為例, Insert與之類似

    1.計算更新後tuple到原tuple的delta資訊,把這個delta複製到rollback segment中的undo

    2.寫redo log,記錄對rollback segment的更改

    3.把buffer pool中的對應tuple更新成新值,把新值的rollback pointer指向第1部生成的undo

    4.寫redo log,記錄對資料page的更改

    5.將page改成dirty

    二)事務提交

    force log, flush當前事務的redo log到磁碟

    三)資料庫恢復

    1.啟動開始時檢測是否發生崩潰

    2.定位到最近的一個checkpoint

    3.定位在這個checkpoint flush到磁碟的資料,檢查checksum。如果不正確,說明這個頁在上次寫入是不完整的,從doublewrite buffer裡把正確的page讀出來,更新到buffer中的page

    4.分析redo log,標識出未提交事務

    5.順序執行redo

    6.rollback未提交的事務

  • 中秋節和大豐收的關聯?
  • 怎樣才能掙大錢呢?