Xtrabackup簡介
Percona XtraBackup是一個開源、免費的MySQL熱備份軟件,能夠為InnoDB和XtraDB數據庫執行非阻塞備份,特點如下:
1、快速、可靠的完成備份
2、備份期間不間斷事務處理
3、節省磁盤空間和網絡帶寬
4、自動對備份文件進行驗證
5、恢復快,保障在線運行時間持久性
另外,官網關於Xtrabackup還有如下介紹,它能增量備份MySQL數據庫,通過流壓縮備份MySQL數據到另外一台服務器,在線MySQL服務器之間進行表空間遷移,很easy的創建新的MySQL從服務器,並且備份MySQL數據庫時不會帶來額外的系統壓力。
XtraBackup 有兩個工具:xtrabackup 和 innobackupex:
xtrabackup 本身只能備份 InnoDB 和 XtraDB ,不能備份 MyISAM;
innobackupex 本身是 Hot Backup 腳本修改而來,同時可以備份 MyISAM 和 InnoDB,但是備份 MyISAM 需要加讀鎖。
為什么說Xtrabackup是針對InnoDB引擎的備份工具?
對於MyISAM表只能是溫備,而且也不支持增量備份。而XtraBackup更多高級特性通常只能在innodb存儲引擎上實現,而且高級特性還都依賴於mysql數據庫對innodb引擎實現了單獨表空間,否則沒辦法實現單表或單庫導出,因此可以說Xtrabackup是為InnoDB而生也不為過!
官網軟件下載:https://www.percona.com/downloads/XtraBackup/LATEST/
用戶操作手冊:http://www.percona.com/doc/percona-xtrabackup/2.4/index.html
Xtrabackup備份原理
1、InnoDB的備份原理
在InnoDB內部會維護一個redo日志文件,我們也可以叫做事務日志文件。事務日志會存儲每一個InnoDB表數據的記錄修改。當InnoDB啟動時,InnoDB會檢查數據文件和事務日志,並執行兩個步驟:它應用(前滾)已經提交的事務日志到數據文件,並將修改過但沒有提交的數據進行回滾操作。
-
備份過程
Xtrabackup在啟動時會記住log sequence number(LSN),並且復制所有的數據文件。復制過程需要一些時間,所以這期間如果數據文件有改動,那么將會使數據庫處於一個不同的時間點。這時,xtrabackup會運行一個后台進程,用於監視事務日志,並從事務日志復制最新的修改。Xtrabackup必須持續的做這個操作,是因為事務日志是會輪轉重復的寫入,並且事務日志可以被重用。所以xtrabackup自啟動開始,就不停的將事務日志中每個數據文件的修改都記錄下來。 -
准備過程
上面就是xtrabackup的備份過程。接下來是准備(prepare)過程。在這個過程中,xtrabackup使用之前復制的事務日志,對各個數據文件執行災難恢復(就像mysql剛啟動時要做的一樣)。當這個過程結束后,數據庫就可以做恢復還原了。
2、MyISAM的備份原理
以上的過程在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)備份等,通過復制數據文件,復制日志文件和提交日志到數據文件(前滾)實現了各種復合備份方式。
什么是流備份?
流備份是指備份的數據通過標准輸出STDOUT傳輸給tar程序進行歸檔,而不是單純的將數據文件保存到指定的備份目錄中,參數--stream=tar表示開啟流備份功能並打包。同時也可以利用流備份到遠程服務器上。
Xtrabackup實現細節
XtraBackup以read-write模式打開innodb的數據文件,然后對其進行復制。其實它不會修改此文件。也就是說,運行 XtraBackup的用戶,必須對innodb的數據文件具有讀寫權限。之所以采用read-write模式是因為XtraBackup采用了其內置的 innodb庫來打開文件,而innodb庫打開文件的時候就是rw的。
XtraBackup要從文件系統中復制大量的數據,所以它盡可能地使用posix_fadvise(),來告訴OS不要緩存讀取到的數據,從 而提升性能。因為這些數據不會重用到了,OS卻沒有這么聰明。如果要緩存一下的話,幾個G的數據,會對OS的虛擬內存造成很大的壓力,其它進程,比如 mysqld很有可能被swap出去,這樣系統就會受到很大影響了。
在備份innodb page的過程中,XtraBackup每次讀寫1MB的數據,1MB/16KB=64個page。這個不可配置。讀1MB數據之 后,XtraBackup一頁一頁地遍歷這1MB數據,使用innodb的buf_page_is_corrupted()函數檢查此頁的數據是否正常,如果數據不正常,就重新讀取這一頁,最多重新讀取10次,如果還是失敗,備份就失敗了,退出。在復制transactions log的時候,每次讀寫512KB的數據。同樣不可以配置。
Xtrabackup安裝與卸載
在官網中,復制相關鏈接下載最新版本
https://www.percona.com/downloads/XtraBackup/LATEST/
# 安裝
cd /data/install_packages
wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.5/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.5-1.el6.x86_64.rpm
yum install percona-xtrabackup-24-2.4.5-1.el6.x86_64.rpm
# 如果提示缺失依賴包
# yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL
# 如果版本錯誤,查看已安裝的percona版本
yum list installed |grep percona
percona-xtrabackup-24.x86_64 2.4.5-1.el6 @/percona-xtrabackup-24-2.4.5-1.el6.x86_64
# 卸載
yum remove percona-xtrabackup-24.x86_64
Xtrabackup常用參數
常用參數:
--user=USER 指定備份用戶,不指定的話為當前系統用戶
--password=PASSWD 指定備份用戶密碼
--port=PORT 指定數據庫端口
--defaults-group=GROUP-NAME 在多實例的時候使用
--host=HOST 指定備份的主機,可以為遠程數據庫服務器
--apply-log 回滾日志
--database 指定需要備份的數據庫,多個數據庫之間以空格分開
--defaults-file 指定mysql的配置文件
--copy-back 將備份數據復制回原始位置
--incremental 增量備份,后面跟要增量備份的路徑
--incremental-basedir=DIRECTORY 增量備份時使用指向上一次的增量備份所在的目錄
--incremental-dir=DIRECTORY 增量備份還原的時候用來合並增量備份到全量,用來指定全備路徑
--redo-only 對增量備份進行合並
--rsync 加快本地文件傳輸,適用於non-InnoDB數據庫引擎。不與--stream共用
--safe-slave-backup
--no-timestamp 生成的備份文件不以時間戳為目錄.
完全備份與恢復
完全備份目錄:/data/backup/full
完全備份與增量備份每次命令操作成功的標志是,日志結尾處打印【completed OK!】
# 全量備份
innobackupex --user=root --password=passwd /data/backup/full
# 上個命令在我的 /data/backup/full/ 目錄生成了一個文件夾【2017-01-20_10-52-43】
# 一般情況下,這個備份不能用於恢復,因為備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務,此時數據文件處於不一致的狀態
# 因此,我們現在就是要通過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。
innobackupex --user=root --password --defaults-file=/data/mysql/my.cnf --apply-log /data/backup/full/2017-01-20_10-52-43
# 恢復操作演練
# 關掉服務,遷移已有的數據目錄
service mysql stop
mv /data/mysql/data /data/mysql/data_old
mkdir -p /data/mysql/data
# 執行innobackupex恢復命令
innobackupex --defaults-file=/data/mysql/my.cnf --user=root --password=passwd --copy-back /data/backup/full/2017-01-20_10-52-43
# 對新目錄執行賦權操作,此操作需在innobackupex恢復命令后
chown -R mysql.mysql /data/mysql/data
# 重啟服務,並檢查數據是否恢復
service mysqld start
增量備份與恢復
增量備份目錄1:/data/backup/inc1
增量備份目錄2:/data/backup/inc2
# 全量備份
innobackupex --defaults-file=/data/mysql/my.cnf --user=root --password=passwd /data/backup/full
# 第一次增量備份
innobackupex --defaults-file=/data/mysql/my.cnf --user=root --password=passwd --incremental /data/backup/inc1 --incremental-basedir=/data/backup/full/2017-01-20_10-52-43
# --incremental-basedir指的是完全備份所在的目錄
# 此命令執行結束后,innobackupex命令會在/data/backup目錄中創建一個新的以時間命名的目錄以存放所有的增量備份數據。
# 另外,在執行過增量備份之后再一次進行增量備份時,其--incremental-basedir應該指向上一次的增量備份所在的目錄。
# 需要注意的是,增量備份僅能應用於InnoDB或XtraDB表,對於MyISAM表而言,執行增量備份時其實進行的是完全備份。
# 第二次增量備份
innobackupex --defaults-file=/data/mysql/my.cnf --user=root --password=passwd --incremental /data/backup/inc2 --incremental-basedir=/data/backup/inc1/2017-01-20_11-04-31
# 如果需要恢復的話需要先執行如下操作
innobackupex --apply-log --redo-only /data/backup/full/2017-01-20_10-52-43
innobackupex --apply-log --redo-only /data/backup/full/2017-01-20_10-52-43 --incremental-dir=/data/backup/inc1/2017-01-20_11-04-31
# 如果存在多次增量備份的話,就多次執行如下命令。此處執行針對的是第二次增量備份
innobackupex --apply-log --redo-only /data/backup/full/2017-01-20_10-52-43 --incremental-dir=/data/backup/inc2/2017-01-20_11-06-41
# 恢復操作演練,需先停掉服務器並遷移已有的數據目錄,詳情見全量備份
# 執行恢復命令
innobackupex --defaults-file=/data/mysql/my.cnf --user=root --password=passwd --copy-back /data/backup/full/2017-01-20_10-52-43
備份恢復常見錯誤
錯誤:針對增量備份已經執行了增量恢復,再次執行相關恢復命令時,報如下錯誤
xtrabackup: ########################################################
xtrabackup: # !!WARNING!! #
xtrabackup: # The transaction log file is corrupted. #
xtrabackup: # The log was not applied to the intended LSN! #
xtrabackup: ########################################################
xtrabackup: The intended lsn is 1614986
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
方案:此錯誤是提示你日志已損壞,即上次的恢復命令已經對日志進行了回滾。所以每次對增量備份執行恢復時,可事先備份數據,以防萬一。
錯誤:對備份文件執行恢復命令時,報錯如下:
innobackupex: Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup' as 'root' (using password: YES).
innobackupex: Error: Failed to connect to MySQL server: DBI connect(';mysql_read_default_group=xtrabackup','root',...) failed: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) at /usr/bin/innobackupex line 2995
方案: 說明沒有讀取到my.cnf中的socket路徑,也說明備份連接數據庫時候走的是socket接口形式,我們可以換做走tcp/ip,執行命令中新增參數--host=127.0.0.1即可。如果仍然報錯,檢查相關命令是否有拼錯的單詞,檢查datadir目錄是否有【mysql:mysql】權限等。
錯誤:xtrabackup Error: datadir must be specified.
方案:--defaults-file 對應的 my.cnf 文件沒有指明datadir目錄。如果指明了目錄,執行相關命令仍然報錯。把命令中的 --defaults-file 順序從 --password后移至innobackupex后試試。innobackupex查找datadir不夠智能。
備份方案的選擇
常見的備份有全量備份、增量備份和差異備份。
首先需要弄明白增量備份和差異備份的區別:
增量備份:自從任意類型的上次備份后有所修改做的備份。
差異備份:自上次全備份后有所改變的部分而做的備份。
-
全量備份與差異備份結合
以每周數據備份計划為例,我們可以在周一進行完全備份,在周二至周日進行差異備份。如果在周日數據被破壞了,則你只需要還原周一的全量備份和周六的差異備份。這種策略備份數據需要時間較多,但還原數據使用時間較少。 -
全量備份與增量備份結合
以每周數據備份計划為例,我們可以在周一進行完全備份,在周二至周日進行增量備份。如果在周日數據被破壞了,則你需要還原周一的全量備份和從周二至周六的所有增量備份。這種策略備份數據需要時間較少,但還原數據使用時間較多。且周二至周六任何一個增量數據損壞,所有備份不可用。 -
全量備份、增量備份和差異備份結合
以每周數據備份計划為例,我們可以在周一進行完全備份,在周二至周日進行差異備份,並且每天針對當天的差異備份每隔一段時間(比如半小時)進行增量備份。如果在周日某個時間點數據被破壞了,則你需要還原周一的全量備份和周六的差異備份,然后再還原周日所做的所有增量備份。這種策略操作最復雜,但是數據庫最多損失半個小時的數據。
PS: 備份最大的敵人是不定期做恢復演練。