MySQL學習第五篇:Xtrabackup的一些使用筆記

1. XtraBackup 簡介
官網: https://www.percona.com
下載: http://www.percona.com/software/percona-xtrabackup   
https://www.percona.com/downloads/XtraBackup/LATEST/
參考文檔: http://www.cnblogs.com/Amaranthus/archive/2014/08/19/3922570.html
http://www.cnblogs.com/gomysql/p/3650645.html
http://blog.chinaunix.net/uid-10661836-id-4131696.html  
http://blog.chinaunix.net/uid-10661836-id-4123246.html  
http://blog.chinaunix.net/uid-10661836-id-4124968.html  
http://blog.chinaunix.net/uid-10661836-id-4099769.html
2. Xtrabackup主要包含兩個工具
xtrabackup:用於熱備份innodb、xtradb表中數據,不能備份其他引擎類型的表,也不能備份數據表結構;
innobackupex:將xtrabackup和tar4ibd進行封裝的perl腳本,可以備份和恢復innodb和MYISAM引擎的表結構及數據,但是對MYISAM備份時需要加全局的讀鎖(因爲MYISAM引擎是讀寫互鎖的,select也會加表鎖,會阻塞其他DML語句),且MYISAM不支持增量備份。

3. 原理(具體圖解可參考《http://www.cnblogs.com/gomysql/p/3650645.html》)
1. xtrabackup原理
完整備份
XtraBackup對Innodb的備份之所以是熱備,無需鎖表,因爲xtrabackup是基於Innodb的crash恢復機制,它首先複製所有的Innodb數據文件,但是數據是不一致的,然後對每個文件進行崩潰恢復處理,最終達到一致。
就和MySQL在啓動Innodb的時候一樣,會通過比較數據文件頭和redo log文件頭信息來檢查數據是否是一致的,如果不一致就嘗試通過前滾(把redo log中所有提交的事務寫入數據文件)和回滾(從數據文件中撤銷所有redo log中未提交的事務引起的修改)來使數據達到最終一致。
XtraBackup在啓動前先記錄LSN(log sequence number),然後啓動,然後複製所有的Innodb數據文件,同時xtrabackup啓動一個後臺進程用來監控日誌文件,然後複製修改,這個進程在備份期間一直是運行的,直到備份完成;
以上的操作是由xtrabackup二進制程序(比如xtrabackup_55)完成的,如果使用innobackupex 腳本,剛纔的步驟完成以後,innobackupex就會去備份MyISAM表和.frm文件,這時要保證數據的一致性就會先鎖表了,通過FLUSH TABLES WITH READ LOCK命令鎖表然後把文件複製出來,再釋放掉這個鎖。
在恢復數據的時候,要經過prepare(recovery)和restore兩個步驟。在prepare結束以後,Innodb的表恢復到了複製Innodb文件結束的時間點,這個時間點也就是鎖表複製MyISAM表的起點,所以最終數據是一致的。一般我們在恢復的時候執行兩次prepare,是因爲第二次prepare會幫助我們生成redo log文件,從而加快MySQL數據庫啓動的速度。
增量備份:
在InnoDB中,每個page中都記錄LSN信息,每當相關數據發生改變,page的LSN就會自動增加,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保持數據的一致。

2. innobackupex工作原理
備份
如果在程序啓動階段未指定模式,innobackupex將會默認以備份模式啓動。默認情況下,此腳本以--suspend-at-end選項啓動xtrabackup,然後xtrabackup程序開始拷貝InnoDB數據文件。當xtrabackup程序執行結束,innobackupex將會發現xtrabackup創建了xtrabackupsuspended2文件,然後執行FLUSH TABLES WITH READ LOCK,此語句對所有的數據庫表加讀鎖,然後開始拷貝其他類型的文件。
如果--ibbackup未指定,innobackupex將會自行嘗試確定使用的xtrabackup的binary。其確定binary的邏輯如下:首先判斷備份目錄中xtrabackup_binary文件是否存在,如果存在,此腳本將會依據此文件確定使用的xtrabackup binary。否則,腳本將會嘗試連接database server,通過server版本確定binary。如果連接無法建立,xtrabackup將會失敗,需要自行指定binary文件。
在binary被確定後,將會檢查到數據庫server的連接是否可以建立。其執行邏輯是:建立連接、執行query、關閉連接。若一切正常,xtrabackup將以子進程的方式啓動。
FLUSH TABLES WITH READ LOCK是爲了備份MyISAM和其他非InnoDB類型的表,此語句在xtrabackup已經備份InnoDB數據和日誌文件後執行。在這之後,將會備份 .frm, .MRG, .MYD, .MYI, .TRG, .TRN, .ARM, .ARZ, .CSM, .CSV, .par, and .opt 類型的文件。
當所有上述文件備份完成後,innobackupex腳本將會恢復xtrabackup的執行,等待其備份上述邏輯執行過程中生成的事務日誌文件。接下來,表被解鎖,slave被啓動,到server的連接被關閉。接下來,腳本會刪掉xtrabackupsuspended2文件,允許xtrabackup進程退出。

恢復
爲了恢復一個備份,innobackupex需要以--copy-back選項啓動。
innobackupex將會首先通過my.cnf文件讀取如下變量:datadir, innodb_data_home_dir, innodb_data_file_path, innodb_log_group_home_dir,並確定這些目錄存在。
接下來,此腳本將會首先拷貝MyISAM表、索引文件、其他類型的文件(如:.frm, .MRG, .MYD, .MYI, .TRG, .TRN, .ARM, .ARZ, .CSM, .CSV, par and .opt files),接下來拷貝InnoDB表數據文件,最後拷貝日誌文件。拷貝執行時將會保留文件屬性,在使用備份文件啓動MySQL前,可能需要更改文件的owener(如從拷貝文件的user更改到mysql用戶)。

4. innobackupex 使用示例

1. 安裝xtrabackup,在此使用二進制編譯好的rpm包,如果需要定製功能可以使用yum源碼安裝

[root@dba189 tool]# wget https://www.percona.com/downloads/XtraBackup/XtraBackup-2.2.9/binary/tarball/percona-xtrabackup-2.2.9-5067-Linux-x86_64.tar.gz
[root@dba189 tool]# tar xvf percona-xtrabackup-2.2.9-5067-Linux-x86_64.tar.gz -C /usr/local/xtrabackup
[root@dba189 tool]# echo  "export PATH=\$PATH:/usr/local/xtrabackup/percona-xtrabackup-2.2.9-Linux-x86_64/bin" >> /etc/profile 
[root@dba189 tool]# source /etc/profile
[root@dba189 tool]# yum list | grep percona #檢查是否安裝

2.權限和連接

xtrabackup或innobackupex需要連接到數據庫和datadir操作權限,共涉及2類用戶權限:1.系統用戶,用來調用innobackupex或者xtrabackup;2.數據庫用戶,用來執行備份。
連接到服務:innobackupex通過 --user 和 --password 連接到數據庫服務器 ;其他連接選項: --port --socket --host
需要的權限:在datadir上有read、write、execute權限;
數據庫中需要:reload 和 lock tables權限爲了執行flush tables with read lock ;replication client 爲了獲取binary log位置;create tablespace爲了導入表、用戶表級別的恢復;super權限在slave環境下備份用來啓動和關閉slave線程。
mysql> show privileges;
mysql> grant reload,lock tables,replication client,create tablespace,super on *.* to 'bkpuser'@'%' identified  by 'bkpuser';
3. 備份
3.1 創建全備份
[root@dba189 local]# innobackupex --default-file=/etc/my.cnf --user=root --password=mima+123 /data/backup/  #竟然報錯,如下:
########################################################################################
Can't locate Time/HiRes.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/local/xtrabackup/percona-xtrabackup-2.2.9-Linux-x86_64/bin/innobackupex line 24.
BEGIN failed--compilation aborted at /usr/local/xtrabackup/percona-xtrabackup-2.2.9-Linux-x86_64/bin/innobackupex line 24.
########################################################################################
額,缺少插件,安裝插件:
[root@dba189 ~]# yum -y install perl-DBI
[root@dba189 ~]# yum -y install perl-DBD-MySQL
[root@dba189 ~]# yum -y install perl-Time-HiRes
[root@dba189 ~]# yum -y install perl-IO-Socket-SSL
再次執行全備:
[root@dba189 local]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=mima+123 /data/backup/  #拷貝數據文件(由my.cnf裏的變量datadir指定)至備份目錄下(/data/backup/),注意:如果不指定--defaults-file,默認值爲/etc/my.cnf。innobackupex會自動創建一個文件夾,是當前系統的時間戳
##########################################################################################
innobackupex: Backup created in directory '/data/backup/2016-09-10_16-59-34'
innobackupex: MySQL binlog position: filename 'mysql_bin.000010', position 369
160910 16:59:41  innobackupex: Connection to database server closed
160910 16:59:41  innobackupex: completed OK!
##########################################################################################
[root@dba189 ~]# ll /data/backup/2016-09-10_16-59-34/  # 已成功備份
[root@dba189 ~]# cat /data/backup/2016-09-10_16-59-34/xtrabackup_checkpoints 
#########內容:可以看見相關文件記錄了LSN,日誌偏移量,還可以看見這次是全備份###################################################
backup_type = full-backuped
from_lsn = 0
to_lsn = 1625900
last_lsn = 1625900
compact = 0
#########內容###################################################
[root@dba189 ~]# cat /data/backup/2016-09-10_16-59-34/xtrabackup_binlog_info  #內容: mysql_bin.000010	369
其他備份選項:--no-timestamp,指定了這個選項備份會直接備份在BACKUP-DIR,不再創建時間戳文件夾。--default-file,指定配置文件,用來配置innobackupex的選項。
3.2 恢復全備份:恢復備份到mysql的數據文件目錄,這一過程要先關閉mysql數據庫,重命名或者刪除原數據文件目錄都可以,再創建一個新的數據文件目錄,將備份數據複製到新的數據文件目錄下,賦權,修改權限,啓動數據庫。--apply-log預備全備份:創建完備份之後的數據不能馬上用來還原,需要使用 --apply-log 回滾未提交事務,前滾已提交是會務,讓數據庫文件保持一致性。內部機制:讀取備份文件夾中的配置文件,然後innobackupex重做已提交事務,回滾未提交事務,之後數據就被寫到了備份的數據文件(innodb文件)中,並重建日誌文件。這一步隱式調用了2次xtrabackup –prepare
[root@dba189 ~]# service mysql stop
[root@dba189 ~]# mkdir /data/mysql/data.old
[root@dba189 ~]# mv /data/mysql/data/* /data/mysql/data.old/
[root@dba189 ~]# innobackupex --apply-log /data/backup/2016-09-10_16-59-34  #成功如下
#################################################################################
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1626134
160910 17:27:08  innobackupex: completed OK!
#################################################################################
其他選項: --use-memory 指定預備階段可使用的內存,內存多則速度快,默認是10MB 如: [root@dba189 ~]# innobackupex --apply-log --use-memory=4G /data/backup/2016-09-10_16-59-34
--copy-back還原備份:根據my.cnf複製所有備份到datadir下,datadir必須是爲空的,innobackupex –copy-back不會覆蓋已存在的文件,還要注意,還原時需要先關閉服務,如果服務是啓動的,那麼就不能還原到datadir。
[root@dba189 ~]# innobackupex --defaults-file=/data/mysql/my.cnf --copy-back /data/backup/2016-09-10_16-59-34/     #注意如果此處不加--defaults-file選項,默認使用備份的backup-my.cnf文件
#################################################################################
innobackupex: Starting to copy InnoDB log files
innobackupex: in '/data/backup/2016-09-10_16-59-34'
innobackupex: back to original InnoDB log directory '/data/mysql/data/'
innobackupex: Copying '/data/backup/2016-09-10_16-59-34/ib_logfile2' to '/data/mysql/data/ib_logfile2'
innobackupex: Copying '/data/backup/2016-09-10_16-59-34/ib_logfile0' to '/data/mysql/data/ib_logfile0'
innobackupex: Copying '/data/backup/2016-09-10_16-59-34/ib_logfile1' to '/data/mysql/data/ib_logfile1'
innobackupex: Finished copying back files.
160910 17:45:29  innobackupex: completed OK!
#################################################################################
修改文件所有者權限
[root@dba189 data]# chown mysql:mysql /data/mysql #可能會授權不成功,導致啓動mysql報錯: Starting MySQL.. ERROR! The server quit without updating PID file (/data/mysql/data//dba189.mysql.com.pid).
[root@dba189 data]# chown -R mysql /data/mysql/
[root@dba189 data]# chgrp -R mysql /data/mysql/	
3.3 增量備份和還原
增量備份是爲了減少空間使用和備份時間,其實現依賴於innodb頁面上的LSN(log sequence number),每次對數據庫的修改都會導致LSN自增,增量備份會複製指定LSN之後的所有數據頁。第一次增量備份是基於全備的,之後的增量備份是基於上一次的增量備份,以此類推。
創建增量備份: --incremental
[root@dba189 data]# innobackupex --defaults-file=/data/mysql/my.cnf --user=root --password='mima+123' --incremental /data/backup/ --incremental-basedir=/data/backup/2016-09-10_16-59-34/ #注意 --incremental-basedir 是上一個完整備份的路徑
########################################################################################################
innobackupex: Backup created in directory '/data/backup/2016-09-11_06-53-08'
innobackupex: MySQL binlog position: filename 'mysql_bin.000015', position 120
160911 06:53:13  innobackupex: Connection to database server closed
160911 06:53:13  innobackupex: completed OK!
##########################################################################################################
[root@dba189 data]# cat backup/2016-09-11_06-53-08/xtrabackup_checkpoints 
#####################################################################
backup_type = incremental
from_lsn = 1625900
to_lsn = 1626164
last_lsn = 1626164
compact = 0
#########################################################################
在上一個增量備份的基礎上再創建一個增量備份
[root@dba189 data]# innobackupex --defaults-file=/data/mysql/my.cnf --user=root --password='mima+123' --incremental /data/backup/ --incremental-basedir=/data/backup/2016-09-11_06-53-08/ #注意此時的--incremental-basedir 是上一個增量備份的路徑,而不是完整備份的	
[root@dba189 data]# cat backup/2016-09-11_07-03-51/xtrabackup_checkpoints 
#########################################################################
backup_type = incremental
from_lsn = 1626164
to_lsn = 1631617
last_lsn = 1631617
compact = 0
#########################################################################
增量備份替代方法:可以使用 --incremental-lsn 來代替 --incremental-basedir 的方法創建增量備份:即上面兩個增量備份的--incremental-basedir可以分別使用 --incremental-lsn=1625900  和 --incremental-lsn=1626164 代替
注意:xtrabackup只會影響xtradb或者innodb的表,其他引擎的表在增量備份的時候只會複製整個文件,不會差異。
增量備份的還原3步驟:1.恢復完整備份;2.恢復增量備份到完整備份(第一個恢復的增量備份要添加--redo-only參數,最後一個恢復的增量備份去掉--redo-only參數);3.對整體的完整備份進行恢復,回滾未提交的數據。
預備增量備份:1.需要先預備全備,但是隻重做已提交事務,不回滾未提交事務,然後應用到全備,也是隻重做已提交事務,不回滾未提交事務 ;2.回滾未提交事務
注:在mariadb 10.0 上測試發現不加—redo-only預備全備,然後使用 –redo-only應用增量備份,mysql服務能夠正常啓動並且數據被成功還原
具體操作步驟:以之前備份爲例
恢復完整備份
[root@dba189 mysql]# innobackupex --apply-log --redo-only /data/backup/2016-09-10_16-59-34/
###################################################################################################
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1626134
160911 07:43:41  innobackupex: completed OK!
###################################################################################################
恢復第一個增量備份
[root@dba189 data]# innobackupex --apply-log --redo-only /data/backup/2016-09-10_16-59-34/ --incremental-dir=/data/backup/2016-09-11_06-53-08/ #如果沒有指定—incremental-dir,那麼innobackupex會使用最近的一個在basedir中被創建的子目錄。
############################################################################################################
innobackupex: Copying '/data/backup/2016-09-11_06-53-08/mysql/general_log.frm' to '/data/backup/2016-09-10_16-59-34/mysql/general_log.frm'
innobackupex: Copying '/data/backup/2016-09-11_06-53-08/mysql/procs_priv.MYD' to '/data/backup/2016-09-10_16-59-34/mysql/procs_priv.MYD'
160911 08:50:27  innobackupex: completed OK!
############################################################################################################
恢復第二個增量備份:注意恢復最後一個增量備份時需要去掉--redo-only參數,回滾xtrabackup日誌中那些還未提交的數據,應用增量備份的時候只能按照備份的順序來應用。如果應用順序錯誤,那麼備份就不可用。如果無法確定順序,可以使用xtrabackup-checkpoints來確定順序。
[root@dba189 data]# innobackupex --apply-log /data/backup/2016-09-10_16-59-34/ --incremental-dir=/data/backup/2016-09-11_07-03-51/
#####################################################################################################################
innobackupex: Copying '/data/backup/2016-09-11_07-03-51/mysql/procs_priv.MYD' to '/data/backup/2016-09-10_16-59-34/mysql/procs_priv.MYD'
innobackupex: Copying '/data/backup/2016-09-11_07-03-51/abc/tt01.frm' to '/data/backup/2016-09-10_16-59-34/abc/tt01.frm'
innobackupex: Copying '/data/backup/2016-09-11_07-03-51/abc/db.opt' to '/data/backup/2016-09-10_16-59-34/abc/db.opt'
160911 09:03:41  innobackupex: completed OK!
#####################################################################################################################
所有合在一起的完全備份整體apply一次
[root@dba189 data]# innobackupex --apply-log /data/backup/2016-09-10_16-59-34/
####################################################################
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1626154
160911 09:07:22  innobackupex: completed OK!
####################################################################
恢復:恢復完的備份複製到數據庫目錄文件中,賦權,然後啓動mysql數據庫,檢測數據正確性
[root@dba189 data]# innobackupex --defaults-file=/data/mysql/my.cnf --copy-back --rsync /data/backup/2016-09-10_16-59-34/
##################################################################################################################
innobackupex: Starting to copy InnoDB log files
innobackupex: in '/data/backup/2016-09-10_16-59-34'
innobackupex: back to original InnoDB log directory '/data/mysql/data/'
innobackupex: Copying '/data/backup/2016-09-10_16-59-34/ib_logfile2' to '/data/mysql/data/ib_logfile2'
innobackupex: Copying '/data/backup/2016-09-10_16-59-34/ib_logfile0' to '/data/mysql/data/ib_logfile0'
innobackupex: Copying '/data/backup/2016-09-10_16-59-34/ib_logfile1' to '/data/mysql/data/ib_logfile1'
innobackupex: Finished copying back files.
160911 09:10:40  innobackupex: completed OK!
#####################################################################################################################
[root@dba189 data]# chown -R mysql.mysql /data/mysql/
[root@dba189 data]# service mysql start

4. 使用Xtrabackup實現主從複製---下一節

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章