博客 / 詳情

返回

一名合格的後端開發,到底需要多瞭解mysql - 6&7

6 - 鎖

lock 和 latch

latch:內存中的輕量級互斥量或讀寫鎖,其目的是為了保證併發線程操作臨界資源的正確性。無死鎖檢測和處理機制。
lock:鎖定數據庫中的對象,比如表,頁,行等,其目的是為了保證併發事務操作表對象的正確性。可通過 等待有向圖 和 超時機制進行死鎖檢測和處理。

以下討論的內容都是和lock相關的

Innodb中鎖的類型

行級鎖:

  • 共享鎖(讀鎖):可以和其他共享鎖並行
  • 排它鎖(寫鎖):不能和任何其他鎖並行

表級鎖:

  • 共享鎖
  • 排他鎖
  • 意向共享鎖
  • 意向排他鎖
    意向鎖之間不互斥,意向鎖和任何行級鎖之間不互斥
    意向鎖只和表級鎖互斥,其存在目的是為了快速判斷該表是否有行級讀鎖或寫鎖,便於快速阻塞表鎖獲取。

一致性非鎖定讀 by MVCC

MVCC:每個被更新行記錄在事務提交之前,會在undo中存儲該行之前版本的數據快照。每行記錄可能會有多條undo保存多個版本的快照,因此稱為多版本併發控制。

不同隔離級別對使用的快照定義不同
Read Committed:總是讀取最新一條快照的數據
Read Repeatable:總是讀取事務開始時的快照數據

一致性鎖定讀:

對讀取的記錄加X鎖:select ... for update
對讀取的記錄加S鎖:select ... lock in share mode

行級鎖的算法

  • Record Lock:行鎖,鎖定單條記錄
  • Gap Lock:間隙鎖,鎖定一個範圍,但不包括記錄本身
  • Next-Key Lock:行鎖+間隙鎖,鎖定一個範圍,且包括記錄本身
    Next-Key Lock的存在目的是為了解決Read Repeatable隔離級別下的幻讀問題。當按索引範圍查詢數據時,其鎖定範圍上界到上一個索引以及下界到下一個索引,使這個範圍內無法添加或刪除行記錄,保證多次讀取的行數據一致。

鎖問題

  • 髒讀:
    讀到其他事務還未提交的數據。Fix: I >= Read Committed
  • 不可重複讀/幻讀
    事務內多次讀取同一數據集合,由於中途有其他事務提交,導致兩次讀取讀到的數據可能是不一樣的。 有兩種不一樣的可能:數據內容不一致 OR 數據行數不一致。I >= Read Repeatable
  • 丟失更新
    業務邏輯導致的數據更新丟失,可以考慮將數據獲取-更新邏輯串行化,或採用樂觀鎖機制來保證數據一致性。

死鎖檢測

對事務-鎖進行建模,將其依賴關係構建成一個有向依賴圖,當有向圖中出現環的時候,即代表出現了死鎖。

7 - 事務

事務的基礎 ACID

  • A 原子性:一個事務要麼全部執行,要麼全部不執行
  • C 一致性:事務執行總是從一個滿足一致性的狀態到另一個一致性狀態
  • I 隔離性:事務和事務之間在執行中互相隔離
  • D 持久性:事務執行一旦成功,其結果就是永久性的

事務的實現

  • redo log: 持久性
  • undo log: 原子性
  • 鎖: 隔離性,一致性

undo log

不同於redo log的物理修改,undo log存儲的是回滾的邏輯修改。

undo log分為兩種類型
  • insert undolog:對應insert操作,新增的數據只對事務本身可見,因此提交後可直接刪除。
  • update undolog:對應update,delete操作。該類undolog需要提供MVCC機制,因此提交後被放入待purge鏈表,在不被任何事務引用後被purge刪除。
undo 和 MVCC

每行數據裏記錄了最後一條修改該行的trx_id,同時記錄了最後一次修改的roll_back_ptr。和行數據類似,update undolog裏也記錄了trx_id和roll_back_ptr。事務執行時,可以通過比對trx_id(trx_id單調遞增)沿着roll_back_ptr一直找到事務開始前的最新一條記錄,即RR級別下的行快照。

分佈式事務 & 二階段提交

分佈式事務使用兩段式提交,第一階段,所有參與事務的節點都進行準備,告知事務管理器它們準備好了。第二階段,由事務管理器告知節點執行rollback還是commit。

binlog和redo log間的二階段提交

binlog和redo log的寫入需要是原子的,以防止在複製從節點時出現數據異常問題。mysql通過在binlog和innodb間使用二階段提交來解決該問題。具體執行順序如下:

  1. innodb prepare 事務,將事務的xid寫入
  2. mysql 寫入 binlog
  3. 事務提交,innodb 寫入 redolog

宕機後,檢查xid事務是否提交,如未提交則主動進行一次提交,如果binlog沒寫入,那麼額外寫入一次binlog。因此在2,3任一環節宕機,都可以保證數據一致性。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.