【Mysql】xtrabacupk備份原理

小亮520cl發表於2015-10-22

轉載於:


xtrabackup是基於InnoDB儲存引擎災難恢復的。它複製InnoDB的資料檔案,儘管資料檔案在內部是非一致性的,但在執行災難恢復時可以保證這些資料檔案是一致的,並且可用。


官方原理

在InnoDB內部會維護一個redo日誌檔案,我們也可以叫做事務日誌檔案。事務日誌會儲存每一個InnoDB表資料的記錄修改。當InnoDB啟動時,InnoDB會檢查資料檔案和事務日誌,並執行兩個步驟:它應用(前滾)已經提交的事務日誌到資料檔案,並將修改過但沒有提交的資料進行回滾操作。


xtrabackup在啟動時會記住log sequence number(LSN),並且複製所有的資料檔案。複製過程需要一些時間,所以這期間如果資料檔案有改動,那麼將會使資料庫處於一個不同的時間點。這時,xtrabackup會執行一個後臺程式,用於監視事務日誌,並從事務日誌複製最新的修改。xtrabackup必須持續的做這個操作,是因為事務日誌是會輪轉重複的寫入,並且事務日誌可以被重用。所以xtrabackup自啟動開始,就不停的將事務日誌中每個資料檔案的修改都記錄下來。

  1. 更詳細點就是:
  2. 1.innobackupex 在啟動後,會先 fork 一個程式,啟動 xtrabackup程式,然後就等待 xtrabackup 備份完 ibd 資料檔案;
    2.xtrabackup 在備份 InnoDB 相關資料時,是有2種執行緒的,1種是 redo 複製執行緒,負責複製 redo 檔案,1種是 ibd 複製執行緒,負責複製 ibd 檔案;redo 複製執行緒只有一個,在 ibd 複製執行緒之前啟動,在 ibd 執行緒結束後結束。xtrabackup 程式開始執行後,先啟動 redo 複製執行緒,從最新的 checkpoint 點開始順序複製 redo 日誌;然後再啟動 ibd 資料複製執行緒,在 xtrabackup 複製 ibd 過程中,innobackupex 程式一直處於等待狀態(等待檔案被建立)。
    3.xtrabackup 複製完成idb後,通知 innobackupex(透過建立檔案),同時自己進入等待(redo 執行緒仍然繼續複製);
    4.innobackupex 收到 xtrabackup 通知後,執行FLUSH TABLES WITH READ LOCK (FTWRL),取得一致性位點,然後開始備份非 InnoDB 檔案(包括 frm、MYD、MYI、CSV、opt、par等)。複製非 InnoDB 檔案過程中,因為資料庫處於全域性只讀狀態,如果在業務的主庫備份的話,要特別小心,非 InnoDB 表(主要是MyISAM)比較多的話整庫只讀時間就會比較長,這個影響一定要評估到。
    5.當 innobackupex 複製完所有非 InnoDB 表檔案後,通知 xtrabackup(透過刪檔案) ,同時自己進入等待(等待另一個檔案被建立);
    6.xtrabackup 收到 innobackupex 備份完非 InnoDB 通知後,就停止 redo 複製執行緒,然後通知 innobackupex redo log 複製完成(透過建立檔案);
    7.innobackupex 收到 redo 備份完成通知後,就開始解鎖,執行 UNLOCK TABLES;
    8.最後 innobackupex 和 xtrabackup 程式各自完成收尾工作,如資源的釋放、寫備份後設資料資訊等,innobackupex 等待 xtrabackup 子程式結束後退出。






上面就是xtrabackup的備份過程。接下來是準備(prepare)過程:相當於一個前滾和一個回滾的過程。在這個過程中,xtrabackup使用之前複製的事務日誌,對各個資料檔案執行災難恢復(就像MySQL剛啟動時要做的一樣)。當這個過程結束後,資料庫就可以做恢復還原了。

以上的過程在xtrabackup的編譯二進位制程式中實現。程式innobackupex可以允許我們備份MyISAM表和frm檔案從而增加了便捷和功能。Innobackupex會啟動xtrabackup,直到xtrabackup複製資料檔案後,然後執行FLUSH TABLES WITH READ LOCK來阻止新的寫入進來並把MyISAM表資料刷到硬碟上,之後複製MyISAM資料檔案,最後釋放鎖。


備份MyISAM和InnoDB表最終會處於一致,在準備(prepare)過程結束後,InnoDB表資料已經前滾到整個備份結束的點,而不是回滾到xtrabackup剛開始時的點。這個時間點與執行FLUSH TABLES WITH READ LOCK的時間點相同,所以MyISAM表資料與InnoDB表資料是同步的。類似Oracle的,InnoDB的prepare過程可以稱為recover(恢復),MyISAM的資料複製過程可以稱為restore(還原)。


xtrabackup和innobackupex這兩個工具都提供了許多前文沒有提到的功能特點。手冊上有對各個功能都有詳細的介紹。簡單介紹下,這些工具提供瞭如流(streaming)備份,增量(incremental)備份等,透過複製資料檔案,複製日誌檔案和提交日誌到資料檔案(前滾)實現了各種複合備份方式。


自己的理解

xtrabackup只能備份和恢復InnoDB表,而且只有ibd檔案,frm檔案它不管,恢復時就需要DBA提供frm。innobackupex可以備份和恢復MyISAM表以及frm檔案,並且對xtrabackup也做了很好的封裝,所以可以使用innobackupex來備份MySQL資料庫。還有一個問題,就是innobackupex備份MyISAM表之前要對全庫進行加READ LOCK,阻塞寫操作,若備份是在從庫上進行的話會影響主從同步,造成延遲。對InnoDB表備份不會阻塞讀寫。


xtrabackup增量備份的原理是:

1)、首先完成一個完全備份,並記錄下此時檢查點LSN;

2)、然後增量備份時,比較表空間中每個頁的LSN是否大於上次備份的LSN,若是則備份該頁並記錄當前檢查點的LSN。


具體來說,首先在logfile中找到並記錄最後一個checkpoint(“last checkpoint LSN),然後開始從LSN的位置開始複製InnoDB的logfile到xtrabackup_logfile;然後開始複製全部的資料檔案.ibd;在複製全部資料檔案結束之後,才停止複製logfile。


所以xtrabackup_logfile檔案在併發寫入很大時也會變得很大,佔用很多空間,需要注意。另外當我們使用--stream=tar或者遠端備份--remote-host時預設使用/tmp,但最好顯示用引數--tmpdir指定,以免把/tmp目錄佔滿影響備份以及系統其它正常服務。

因為logfile裡面記錄全部的資料修改情況,所以即使在備份過程中資料檔案被修改過了,恢復時仍然能夠透過解析xtrabackup_logfile保持資料的一致。

xtrabackup的增量備份只能用於InnoDB表,不能用在MyISAM表上。採用增量備份MySQL資料庫時xtrabackup會依據上次全備份或增量備份目錄對InnoDB表進行增量備份,對MyISAM表會進行全表複製。


流備份(streaming)可以將備份直接儲存到遠端伺服器上。

當執行恢復時,由於複製是不鎖表的所以此時資料檔案都是不一致的,xtrabackup使用之前儲存的redo log對各個資料檔案檢查是否與事務日誌的checkpoint一致,執行恢復:

1)、根據複製資料檔案時以及之後已提交事務產生的事務日誌進行前滾;

2)、將未提交的事務進行回滾。


這個過程就是MySQL資料庫當機之後執行的crash recovery。


增量備份

在InnoDB中,每個page中都記錄LSN資訊,每當相關資料發生改變,page的LSN就會自動增加,xtrabackup的增量備份就是依據這一原理進行的。xtrabackup將上次備份(完全備份集或者也是一個增量備份集)以來LSN改變的page進行備份。

所以,要做增量備份第一次就要做一個完全備份(就是將MySQL例項或者說要備份的資料庫表做一個完全複製,同時記錄LSN),之後可以基於此進行增量備份以及恢復。


增量備份優點:

1)、資料庫太大沒有足夠的空間全量備份,增量備份能有效節省空間,並且效率高;

2)、支援熱備份,備份過程不鎖表(針對InnoDB而言),不阻塞資料庫的讀寫;

3)、每日備份只產生少量資料,也可採用遠端備份,節省本地空間;

4)、備份恢復基於檔案操作,降低直接對資料庫操作風險;

5)、備份效率更高,恢復效率更高。


恢復與還原

backup的恢復過程中包括恢復和還原兩個部分。

我們前面已經說了xtrabackup只備份InnoDB表的ibd檔案,而innobackupex可以備份包括InnoDB表在內的其他儲存引擎的表的所有資料檔案。由於不同引擎表備份時的不同,也會讓恢復過程看起來不一樣。


先來看看完全備份集的恢復。

在InnoDB表的備份或者更直接的說ibd資料檔案複製的過程中,資料庫處於不一致的狀態,所以要將xtraback_logfile中尚未提交的事務進行回滾,以及將已經提交的事務進行前滾,使各個資料檔案處於一個一致性狀態,這個過程叫做準備(prepare)


如果你是在一個從庫上執行的備份,那說明你沒有東西需要回滾,只是簡單的apply redo log就可以了。另外在prepare過程中可以使用引數--use-memory增大使用系統記憶體量從而提高恢復速度。


之後,我們就可以根據backup-my.cnf中的配置把資料檔案複製回對應的目錄了,當然你也可以自己複製回去,但innobackupex都會幫我們完成。在這裡,對於InnoDB表來說是完成後準備動作,我們稱之為恢復(recovery),而對於MyISAM表來說由於備份時是採用鎖表方式複製的,所以此時只是簡單的複製回來,不需要apply log,這個我們稱之為還原(restore)

注:本文件裡之所以使用恢復和還原,也是和其他資料庫比如Oracle看起來一樣。


對於增量備份的恢復過程,與完全備份集的恢復類似,只是有少許不同:

1)、恢復過程需要使用完全備份集和各個增量備份集,各個備份集的恢復與前面說的一樣(前滾和回滾),之後各個增量備份集的redo log都會應用到完全備份集中;

2)、對於完全備機集之後產生的新表,要有特殊處理方式,以便恢復後不丟表;

3)、要以完全備份集為基礎,然後按順序應用各個增量備份集。


流備份和壓縮

提到流備份(streaming)就要說遠端備份和備份壓縮,先說流備份吧。

流備份是指備份的資料透過標準輸出STDOUT傳輸給tar程式進行歸檔,而不是單純的將資料檔案儲存到指定的備份目錄中,引數--stream=tar表示開啟流備份功能並打包。同時也可以利用流備份到遠端伺服器上。

舉例來說,

$ innobackupex --stream=TAR ${BACKUP_DIR}/base | gzip > ${BACKUP_DIR}/base.tar.gz $ innobackupex --stream=TAR ${BACKUP_DIR}/base|ssh somebackupaddr “cat > ${DIR}/base.tar” 


當然了,如果你使用了流備份,那麼增量備份也就不能用了,因為增量備份需要參考次備份情況,而上次備份卻被打包或者壓縮了。

在我們現實使用中,更多的使用增量備份,至於歸檔壓縮我們可以透過指令碼自主完成。


部分備份和恢復

xtrabackup可以只備份/恢復部分庫表,可以正則模式匹配或者是你想備份庫表的列表,但InnoDB表必須是獨立表空間,同時不能使用流備份功能。

1)、使用正則模式匹配備份部分庫表,需要使用引數--include,語句類似如下:

$ innobackupex --include=’^qb.*’ ${BACKUP_DIR}/part-base 


2)、使用資料庫列表備份部分庫,需要使用引數--databases,語句類似如下:

$ innobackupex --databases=qb0 qb1 qb2 qb3 ${BACKUP_DIR}/part-base 


3) 、使用表列表備份部分表,需要使用引數--tables-file,語句類似如下:

$ innobackupex --tables-list=${CONF_DIR}/tab.conf ${BACKUP_DIR}/part-base 


注:在我們的現實應用中,很少會只備份叢集中部分庫表,所以只是瞭解此功能即可,若有現實需要可以參考percona官方資料以獲取更多資訊。


能備份部分庫表,也就能根據完全備份集進行部分庫表的恢復,在現實中很少會用到,但還是說一下吧。

首先在準備prepare的過程中,使用引數--export將表匯出,這個匯出會將每個InnoDB表建立一個以.exp結尾的檔案,這些檔案為之後的匯入過程服務。

$ innobackupex --apply-log --export ${BACKUP_DIR}/base 


然後將你需要恢復的表的ibd和exp檔案複製到目標機器,在目標機器上執行匯入:

mysql> create table t()engine=innodb; //此處需要DBA手動建立一個同結構的表或表已存在 mysql> ALTER TABLE t DISCARD TABLESPACE; $ cp t.ibd t.exp ${DATA_DIR}/${DB}/ mysql> ALTER TABLE t IMPORT TABLESPACE; 

這樣的匯出匯入就可以保住恢復的表可以與資料庫其他表保持一致性了。


並行備份

xtrbackup還支援並行備份,預設情況下xtrabackup備份時只會開啟一個程式進行資料檔案的備份,若配置引數--parallel=N可以讓xtrabackup開啟N個子程式對多個資料檔案進行併發備份,這樣可以加快備份的速度。當然伺服器的IO處理能力以及對伺服器的影響也是要考慮的,所以另一個引數--throttle=IOS會與它同時使用,這個引數用來限制備份過程中每秒讀寫的IO次數,對伺服器的IO是一個保護。


這兩個引數xtrabackup和innobackupex都支援,舉例如下:

$ innobackupex --parallel=4 --throttle=400 ${BACKUP_DIR}/part-base 

注意:對同一個資料檔案只會有一個程式在備份。


其他

xtrabackup在備份時主要的工作是做資料檔案複製,它每次只會讀寫1MB的資料(即64個page,不能修改),xtrabackup逐頁訪問1MB資料,使用innodb的buf_page_is_corrupted()函式檢查此頁的資料是否正常,如果資料不正常,就重新讀取這一頁,最多重新讀取10次,如果還是失敗,備份就失敗了,退出。

在複製事務日誌的時候,每次讀寫512KB的資料,同樣不可以配置。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29096438/viewspace-1815593/,如需轉載,請註明出處,否則將追究法律責任。

相關文章