Xtrabackup 是基於 InnoDB 存儲引擎災難恢復的。它複製 InnoDB 的數據文件,儘管數據文件在內部是非一致性的,但在執行災難恢復時可以保證這些數據文件是一致的,並且可用。
官方原理在 InnoDB 內部會維護一個 redo 日誌文件,我們也可以叫做事務日誌文件。事務日誌會存儲每一個 InnoDB 表數據的記錄修改。當 InnoDB 啟動時,InnoDB 會檢查數據文件和事務日誌,並執行兩個步驟:它應用(前滾)已經提交的事務日誌到數據文件,並將修改過但沒有提交的數據進行回滾操作。
Xtrabackup 在啟動時會記住 log sequence number(LSN),並且複製所有的數據文件。複製過程需要一些時間,所以這期間如果數據文件有改動,那麼將會使資料庫處於一個不同的時間點。這時,xtrabackup 會運行一個後臺進程,用於監視事務日誌,並從事務日誌複製最新的修改。Xtrabackup 必須持續的做這個操作,是因為事務日誌是會輪轉重複的寫入,並且事務日誌可以被重用。所以 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 的數據,同樣不可以配置。
來源:http://op.baidu.com/2014/07/xtrabackup%E5%8E%9F%E7%90%86%E5%8F%8A%E5%AE%9E%E6%96%BD/?qq-pf-to=pcqq.discussion
微運維:vYunWei
伺服器管理、監控、維護、優化
運維業務、運維規劃、運維開發
歡迎有想法、樂於分享的運維人交流學習
現已開通多個微信群,有興趣交流學習的同學
可加若飛的微信:13511421494 進群
合作郵箱:admin@137x.com