1. 程式人生 > >MySQL技術內幕:InnoDB儲存引擎-筆記

MySQL技術內幕:InnoDB儲存引擎-筆記

  • Innodb將通過主鍵聚集資料,如果沒有定義主鍵,Innodb會選擇第一個非空的唯一索引代替,如果沒有非空唯一索引,Innodb會隱式定義一個6位元組的rowid主鍵來作為聚集索引。
  • 索引的底層原理(Page164)
    • B+樹是為磁碟或其他直接存取輔助裝置而設計的一種平衡查詢樹,在B+樹中,所有記錄節點都是按鍵值的大小順序存放在同一層的葉節點中,各葉節點指標進行連線。
    • B+樹索引可以分為聚集索引和輔助索引,他們不同點是,聚集索引的行資料和主鍵B+樹儲存在一起,輔助索引只儲存輔助鍵和主鍵。
      • 聚集索引
        • 聚集索引是按每張表的主鍵構造的一顆B+樹,並且葉節點中存放著整張表的行記錄資料,因此也讓聚集索引的節點成為資料頁,這個特性決定了索引組織表中資料也是索引的一部分。由於實際的資料頁只能按照一顆B+樹進行排序,所以每張表只能擁有一個聚集索引。查詢優化器非常傾向於採用聚集索引,因為其直接儲存行資料,所以主鍵的排序查詢和範圍查詢速度非常快。
        • 不是物理上的連續,而是邏輯上的,不過在剛開始時資料是順序插入的所以是物理上的連續,隨著資料增刪,物理上不再連續。
      • 輔助索引
        • 輔助索引頁級別不包含行的全部資料。葉節點除了包含鍵值以外,每個葉級別中的索引行中還包含了一個書籤,該書籤用來告訴InnoDB哪裡可以找到與索引相對應的行資料。其中存的就是聚集索引的鍵。
        • 輔助索引的存在並不影響資料在聚集索引的結構組織。InnoDB會遍歷輔助索引並通過葉級別的指標獲得指向主鍵索引的主鍵,然後通過主鍵索引找到一個完整的行記錄。當然如果只是需要輔助索引的值和主鍵索引的值,那麼只需要查詢輔助索引就可以查詢出索要的資料,就不用再去查主鍵索引了。
  • 多版本控制和事物(MVCC)
    • 一致性的非鎖定行讀(consistent nonlocking read)是指InnoDB儲存引擎通過行多版本控制(multi versioning)的方式來讀取當前執行時間資料庫中行的資料。如果讀取的行正在進行DELETE、UPDATE操作,這時讀取操作不會因此而會等待行上鎖的釋放,相反,InnoDB儲存引擎會去讀取行的一個快照資料。
    • 之所以稱之為非鎖定讀,因為不需要等待訪問的行上鎖的釋放。快照資料是指該行之前版本的資料,該實現是通過Undo段來實現。而Undo用來在事物中回滾資料,因此快照本身是沒有額外開銷的。此外,讀取快照資料是不需要上鎖的,因為沒有必要對歷史的資料進行修改。
    • 非鎖定讀的機制大大提高了資料讀取的併發性,在InnoDB儲存引擎預設的設定,即讀取不會佔用和等待表上的鎖。但是在不同事物隔離級別下,讀取的方式不同,並不是每個事物隔離級別下讀取的都是一致性讀。同樣,即使都是使用一致性讀,但是對於快照的定義也不相同。
    • 快照資料起始就是當前行資料之前的歷史版本,可能有多個版本。一個行可能有不止一個快照資料,稱這種技術為行多版本技術。由此帶來的併發控制,稱之為多版本併發控制(Multi Version Concurrency Control,MVCC)。
    • 在Read Committed和Repeat Read下,InnoDB儲存引擎使用非鎖定的一致性讀。然而,對於快照資料的定義卻不相同。在Read Committed事物隔離級別下,對於快照資料,非一致性讀總是讀取被鎖定行的最新一份快照資料。在Repeatable隔離級別下和Repeatable Read事物隔離級別下,對於快照資料,非一致性讀總是讀取事物開始時的行資料版本。
  • 鎖帶來的3種問題
    • a. 丟失更新
    • 將事物變成序列操作。
    • b. 髒讀
    • 髒讀發生的條件是需要事物的隔離級別為Read Uncommitted,而目前絕大部分資料庫都至少設定成Read Committed。InnoDB儲存引擎預設的事物隔離級別為Read Reapeatable,Oracle資料庫的預設隔離級別是Read Committed。
    • c. 不可重複讀
    • InnoDB儲存引擎中,通過使用Next-Key Lock演算法來避免不可重複讀的問題。在Next-Key Lock演算法下,對於索引的掃描,不僅僅是鎖住掃描到的索引,而且還鎖住這些索引覆蓋的範圍(gap)。因此對於這個範圍內的插入都是不允許的。這樣就避免了另外的事物在這個範圍內插入資料導致不可重複讀的問題。因此,InnoDB儲存引擎的預設事物隔離級別是Read Repeatable,採用Next-Key Lock演算法,就避免了不可重複讀的現象。
  • 事物
    • 原子性:整個資料庫事物是不可分割的工作單位,只有使事物中所有的資料庫操作執行都成功,才算整個事物成功。如果事物中任何一個SQL語句執行失敗,那麼已經執行成功的SQL語句也必須撤銷,資料庫狀態應該退回到執行事物前的狀態。
    • 隔離性:一個事物的影響在該事物提交前對其他事物都不可見——通過鎖來實現。
    • 一致性:事物將資料庫從一種狀態轉變為下一種一致的狀態。在事物開始之前和事物結束以後,資料庫的完整性約束沒有被破壞。
    • 永續性:事物一旦提交,其結果就是永久的。即使發生宕機等故障,資料庫也能將資料恢復。
  • 事物的實現
    • redo
    • InnoDB儲存引擎中,事物日誌通過重做(redo)日誌檔案和InnoDB儲存引擎的日誌緩衝(InnoDB Log Buffer)來實現。
    • InnoDB儲存引擎通過預寫日誌的方式來保證事物的完整性。磁碟上儲存的資料頁和記憶體緩衝池中的頁是不同步的,對於記憶體緩衝池中頁的修改,先是寫入重做日誌檔案,然後再寫入磁碟,因此是一種非同步的方式。
    • undo
    • 重做日誌記錄了事物的行為,可以很好地通過其進行“重做”。但是事物有時還需要撤銷,這時就需要undo。對資料庫進行修改時,資料庫不但會產生redo,而且還會產生一定量的undo。即使執行的事物或語句由於某種原因失敗了,或者用一條ROLLBACK語句請求回滾,就可以利用這些undo資訊將資料回滾到修改之前的樣子。
  • 分散式事物
    • InnoDB儲存引擎支援XA事物。分散式事物指的是允許多個獨立的事物資源參與到一個全域性的事物中。事物資源通常是關係型資料庫系統。全域性事物要求在其中所有參與的事物要麼都提交,要麼都回滾。
    • 使用分散式事物時,InnoDB儲存引擎的事物隔離級別必須是SERIALIABLE。