MySQL備份mydumper的原理【轉】

jyzhou發表於2016-12-31

本文來自:http://baiyangtx.net/2016/09/04/mydumper-principle/

相對於MySQL官方提供的邏輯備份工具 mysqldump , mydumper最大的特點就是可以採用多執行緒並行備份,大大提高了資料匯出的速度。這裡對mydumper的工作原理做個分析,看一下mydumper如何巧妙的利用Innodb引擎提供的MVCC版本控制的功能,實現多執行緒併發獲取一致性資料。

這裡一致性資料指的是在某個時間點,匯出的資料與匯出的Binlog檔案資訊相匹配,如果匯出了多張表的資料,這些不同表之間的資料都是同一個時間點的資料。

在mydumper進行備份的時候,由一個主執行緒以及多個備份執行緒完成。其主執行緒的流程是:

  1. 連線資料庫
  2. FLUSH TABLES WITH READ LOCK 將髒頁重新整理到磁碟並獲得只讀鎖
  3. START TRANSACTION /!40108 WITH CONSISTENT SNAPSHOT / 開啟事物並獲取一致性快照
  4. SHOW MASTER STATUS 獲得binlog資訊
  5. 建立子執行緒並連線資料庫
  6. 為子執行緒分配任務並push到佇列中
  7. UNLOCK TABLES / FTWRL / 釋放鎖

子執行緒的主要流程是:

  1. 連線資料庫
  2. SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE
  3. START TRANSACTION /!40108 WITH CONSISTENT SNAPSHOT /
  4. 從佇列中pop任務並執行

上述兩個執行緒的流程的關係如圖

從圖中可以看到,主執行緒釋放鎖是在子執行緒開啟事物之後。這裡是保證子執行緒獲得的資料一定為一致性資料的關鍵。
主執行緒在連線到資料庫後立即通過Flush tables with read lock(FTWRL) 操作將髒頁重新整理到磁碟,並獲取一個全域性的只讀鎖,這樣便可以保證在鎖釋放之前由主執行緒看到的資料是一致的。然後立即通過 Start Transaction with consistent snapshot 建立一個快照讀事物,並通過 show master status獲取binlog位置資訊。
然後建立完成dump任務的子執行緒併為其分配任務。

主執行緒在建立子執行緒後通過一個非同步訊息佇列 ready 等待子執行緒準備完畢。 子執行緒在建立後立即建立到MySQL資料庫的連線,然後設定當前事務隔離級別為Repeatable Read。
設定完成之後開始快照讀事務。在完成這一系列操作之後,子執行緒才會通過ready佇列告訴主線自己程準備完畢。主執行緒等待全部子執行緒準備完畢開啟一致性讀Snapshot事務後才會釋放全域性只讀鎖(Unlock Table)。

如果只有Innodb表,那麼只有在建立任務階段會加鎖。但是如果存在MyIsam表或其他不帶有MVCC功能的表,那麼在這些表的匯出任務完成之前都必須對這些表進行加鎖。Mydumper本身維護了一個 non_innodb_table 列表,在建立任務階段會首先為非Innodb表建立任務。同時還維護了一個全域性的unlock_table佇列以及一個原子計數器 non_innodb_table_counter , 子執行緒每完成一個非Innodb表的任務便將 non_innodb_table_counter 減一,如果non_innodb_table_counter 值為0 遍通過向 unlock_table 佇列push一個訊息的方式通知主執行緒完成了非Innodb表的匯出任務可以執行 unlock table操作。

mydumper支援記錄級別的併發匯出。在記錄級別的匯出時,主執行緒在做任務分配的時候會對錶進行拆分,為表的一部分記錄建立一個任務。這樣做一個好處就是當有某個表特別大的時候可以儘可能的利用多執行緒併發以免某個執行緒在匯出一個大表而其他執行緒處於空閒狀態。在分割時,首先選取主鍵(PRIMARY KEY)作為分隔依據,如果沒有主鍵則查詢有無唯一索引(UNIQUE KEY)。在以上嘗試都失敗後,再選取一個區分度比較高的欄位做為記錄劃分的依據(通過 show index 結果集中的cardinality的值確定)。

劃分的方式比較暴力,直接通過 select min(filed),max(filed) from table 獲得劃分欄位的取值範圍,通過 explain select filed from table 獲取欄位記錄的行數,然後通過一個確定的步長獲得每一個子任務的執行時的where條件。這種計算方式只支援數字型別的欄位。

以上就是mydumper的併發獲取一致性資料的方式,其關鍵在於利用了Innodb表的MVCC功能,可以通過快照讀因此只有在任務建立階段才需要加鎖。

 

相關文章