MySQL之Xtrabackup備份恢復數據庫

一、Xtrabackup介紹 

1、Xtrabackup是什麼 

Xtrabackup是一個對InnoDB做數據備份的工具,支持在線熱備份(備份時不影響數據讀寫),是商業備份工具InnoDB Hotbackup的一個很好的替代品。 
Xtrabackup有兩個主要的工具:xtrabackup、innobackupex 

  • xtrabackup只能備份InnoDB和XtraDB兩種數據表,而不能備份MyISAM數據表。
  • innobackupex是參考了InnoDB Hotbackup的innoback腳本修改而來的。innobackupex是一個perl腳本封裝,封裝了xtrabackup。主要是爲了方便同時備份InnoDB和MyISAM引擎的表,但在處理myisam時需要加一個讀鎖。並且加入了一些使用的選項。如slave-info可以記錄備份恢 復後,作爲slave需要的一些信息,根據這些信息,可以很方便的利用備份來重做slave。 
2、Xtrabackup可以做什麼 

在線(熱)備份整個庫的InnoDB、 XtraDB表 
在xtrabackup的上一次整庫備份基礎上做增量備份(innodb only) 
以流的形式產生備份,可以直接保存到遠程機器上(本機硬盤空間不足時很有用) 

MySQL數據庫本身提供的工具並不支持真正的增量備份,二進制日誌恢復是point-in-time(時間點)的恢復而不是增量備份。 
Xtrabackup工具支持對InnoDB存儲引擎的增量備份,工作原理如下: 
(1)、首先完成一個完全備份,並記錄下此時檢查點的LSN(Log Sequence Number)。 
(2)、在進程增量備份時,比較表空間中每個頁的LSN是否大於上次備份時的LSN,如果是,則備份該頁,同時記錄當前檢查點的LSN。 
首先,在logfile中找到並記錄最後一個checkpoint(“last checkpoint LSN”),然後開始從LSN的位置開始拷貝InnoDB的logfile到xtrabackup_logfile;接着,開始拷貝全部的數據文件.ibd;在拷貝全部數據文件結束之後,才停止拷貝logfile。 
因爲logfile裏面記錄全部的數據修改情況,所以,即時在備份過程中數據文件被修改過了,恢復時仍然能夠通過解析xtrabackup_logfile保持數據的一致。 

3、Xtrabackup備份原理 

XtraBackup基於InnoDB的crash-recovery功能。它會複製innodb的data file,由於不鎖表,複製出來的數據是不一致的,在恢復的時候使用crash-recovery,使得數據恢復一致。 : 
InnoDB維護了一個redo log,又稱爲transaction log,事務日誌,它包含了innodb數據的所有改動情況。當InnoDB啓動的時候,它會先去檢查data file和transaction log,並且會做二步操作:XtraBackup在備份的時候, 一頁一頁地複製innodb的數據,而且不鎖定表,與此同時,XtraBackup還有另外一個線程監視着transactions log,一旦log發生變化,就把變化過的log pages複製走。爲什麼要急着複製走呢?因爲transactions log文件大小有限,寫滿之後,就會從頭再開始寫,所以新數據可能會覆蓋到舊的數據。 
在prepare過程中,XtraBackup使用複製到的transactions log對備份出來的innodb data file進行crash recovery。 

4、實現細節 
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的數據。同樣不可以配置。

5、innobackupex 相關參數

注:xtrabackup命令只備份數據文件,並不備份數據表結構(.frm),所以使用xtrabackup恢復的時候,你必須有對應表結構文件(.frm),所以,個人推薦採用innobackupex命令 [此命令相當於冷備份,複製數據目錄的索引,數據,結構文件,但會有短暫的鎖表(時間依賴於MyISAM大小)]。

參數說明如下:

--defaults-file:指定my.cnf參數文件的位置[此配置文件裏必須指定datadir]。

--apply-log:同xtrabackup的--prepare參數,一般情況下,在備份完成後,數據尚且不能用於恢復操作,因爲備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。因此,此時數據 文件仍處理不一致狀態。--apply-log的作用是通過回滾未提交的事務及同步已經提交的事務至數據文件使數據文件處於一致性狀態。

--copy-back:做數據恢復時將備份數據文件拷貝到MySQL服務器的datadir。

--remote-host=HOSTNAME: 通過ssh將備份數據存儲到進程服務器上。

--stream=[tar]:備份文件輸出格式, 該文件可在XtarBackup binary文件中獲得. 在使用參數stream=tar備份的時候,你的xtrabackup_logfile可能會臨時放在/tmp目錄下,如果你備份的時候併發寫入較大的話,xtrabackup_logfile可能會很大(5G+),很可能會撐滿你的/tmp目錄,可以通過參數--tmpdir指定目錄來解決這個問題。

--tmpdir=DIRECTORY:當有指定--remote-host or --stream時, 事務日誌臨時存儲的目錄, 默認採用MySQL配置文件中所指定的臨時目錄tmpdir。

--redo-only --apply-log:強制備份日誌時只redo,跳過rollback,這在做增量備份時非常必要。

--use-memory=*:該參數在prepare的時候使用,控制prepare時innodb實例使用的內存。

--databases=LIST:列出需要備份的databases,如果沒有指定該參數,所有包含MyISAM和InnoDB表的database都會被備份。

--slave-info:備份從庫, 加上--slave-info備份目錄下會多生成一個xtrabackup_slave_info 文件, 這裏會保存主日誌文件以及偏移, 文件內容類似於:CHANGE MASTER TO MASTER_LOG_FILE='', MASTER_LOG_POS=0。

--socket=SOCKET:指定mysql.sock所在位置,以便備份進程登錄mysql。

二、xtrabackup-2.1.6-702安裝

本文通過源碼方式安裝xtrabackup-2.1.6-702

下載地址:http://www.percona.com/downloads/XtraBackup/

1、編譯所需的依賴包

查看編譯所需的依賴包是否安裝,如果沒有安裝,則安裝之。

rpm -q libaio libaio-devel perl-Time-HiRes curl curl-devel zlib-devel openssl-devel perl cpio expat-devel gettext-devel perl-ExtUtils-MakeMaker perl-DBD-MySQL.*

yum -y install 包名

2、安裝

tar -zxvf percona-xtrabackup-2.1.6-702-Linux-x86_64.tar.gz

cd percona-xtrabackup-2.1.6-702-Linux-x86_64/bin

將innobackupex、xtrabackup等文件copy到mysql程序目錄下/bin目錄 
cp * /mysql/bin/ 
將mysql安裝目錄下的文件做軟鏈接到/usr/bin/目錄下。這個比變量方便,這樣就完成了部署安裝!!!!!!!!!!! 
ln -s /mysql/bin/* /usr/bin/ 

三、innobackupex使用參數介紹 

由於innobackupex能同時備份InnoDB和MyISAM引擎的表,這裏重點介紹innobackupex的備份與恢復使用通常一般都直接使用innobackupex,因爲它能同時備份InnoDB和MyISAM引擎的表。要注意的是my.cnf裏datadir這個參數是必須要指定的,xtrabackup_55是根據它去定位innodb數據文件的位置。 

1、 innobackupex語法及參數說明 

innobackup [--sleep=MS] [--compress[=LEVEL]] [--include=REGEXP] [--user=NAME] [--password=WORD] 
[--port=PORT] [--socket=SOCKET] [--no-timest a mp] [--ibbackup=IBBACKUP-BINARY] [--slave-info] [--stream=tar] 
[--defaults-file=MY.CNF] [--databases=LIST] [--remote-host=HOSTNAME] BACKUP-ROOT-DIR 

innobackup --apply-log [--use-memory=MB] [--uncompress] [--defaults-file=MY.CNF] [--ibbackup=IBBACKUP-BINARY] BACKUP-DIR 

innobackup --copy-back [--defaults-file=MY.CNF] BACKUP-DIR 

各參數說明: 
--defaults-file 
同xtrabackup的--defaults-file參數 

--apply-log 
對xtrabackup的--prepare參數的封裝 

--copy-back 
做數據恢復時將備份數據文件拷貝到MySQL服務器的datadir ; 

--remote-host=HOSTNAME 
通過ssh將備份數據存儲到進程服務器上; 

--stream=[tar] 
備份文件輸出格式, tar時使用tar4ibd , 該文件可在XtarBackup binary文件中獲得.如果備份時有指定--stream=tar, 則tar4ibd文件所處目錄一定要在$PATH中(因爲使用的是tar4ibd去壓縮, 在XtraBackup的binary包中可獲得該文件)。 

在使用參數stream=tar備份的時候,你的xtrabackup_logfile可能會臨時放在/tmp目錄下,如果你備份的時候併發寫入較大的話xtrabackup_logfile可能會很大(5G+),很可能會撐滿你的/tmp目錄,可以通過參數--tmpdir指定目錄來解決這個問題。 

--tmpdir=DIRECTORY 
當有指定--remote-host or --stream時, 事務日誌臨時存儲的目錄, 默認採用MySQL配置文件中所指定的臨時目錄tmpdir 

--redo-only --apply-log組, 
強制備份日誌時只redo ,跳過rollback。這在做增量備份時非常必要。 

--use-memory=# 
該參數在prepare的時候使用,控制prepare時innodb實例使用的內存量 

--throttle=IOS 
同xtrabackup的--throttle參數 

--sleep=#

是給ibbackup使用的,指定每備份1M數據,過程停止拷貝多少毫秒,也是爲了在備份時儘量減小對正常業務的影響,具體可以查看ibbackup的手冊 ; 

--compress[=LEVEL] 
對備份數據迚行壓縮,僅支持ibbackup,xtrabackup還沒有實現; 

--include=REGEXP 
對xtrabackup參數--tables的封裝,也支持ibbackup。備份包含的庫表,例如:--include="test.*",意思是要備份test庫中所有的表。如果需要全備份,則省略這個參數;如果需要備份test庫下的2個表:test1和test2,則寫成:--include="test.test1|test.test2"。也可以使用通配符,如:--include="test.test*"。 

--databases=LIST 
列出需要備份的databases,如果沒有指定該參數,所有包含MyISAM和InnoDB表的database都會被備份; 

--uncompress 
解壓備份的數據文件,支持ibbackup,xtrabackup還沒有實現該功能; 

--slave-info
備份從庫, 加上--slave-info備份目錄下會多生成一個xtrabackup_slave_info 文件, 這裏會保存主日誌文件以及偏移, 文件內容類似於:CHANGE MASTER TO MASTER_LOG_FILE='', MASTER_LOG_POS=0 

--socket=SOCKET 
指定mysql.sock所在位置,以便備份進程登錄mysql。

四、備份與恢復

1、備份

# 全備
 innobackupex --defaults-file=/etc/my.cnf --no-timestamp  --port=3306 --user=backup --password=backup  /backupdir/bak_data/full_bak >/backupdir/bak_data/innoback.log 2>&1

# 第一次增量備份

innobackupex --defaults-file=/etc/my.cnf --no-timestamp  --port=3306 --user=backup --password=backup --incremental --incremental-basedir=/backupdir/bak_data/full_bak /backupdir/bak_data/one_backup >/backupdir/bak_data/innoback.log 2>&1

# 第二次增量備份

innobackupex --defaults-file=/etc/my.cnf --no-timestamp  --port=3306 --user=backup --password=backup --incremental --incremental-basedir=/backupdir/bak_data/one_backup  /backupdir/bak_data/two_backup >/backupdir/bak_data/innoback.log 2>&1

# 第三次增量備份

innobackupex --defaults-file=/etc/my.cnf --no-timestamp  --port=3306 --user=backup --password=backup --incremental --incremental-basedir=/backupdir/bak_data/two_backup /backupdir/bak_data/three_backup >/backupdir/bak_data/innoback.log 2>&1

2、恢復
# 備份應用日誌,保證數據一致,將增量備份的合併到全備上,恢復使用全備恢復

是否用--redo-only --apply-log 組合參數,我也搞不清,測試用和不用--redo-only,感覺數據都沒有問題?????

# 全備應用日誌
innobackupex  --defaults-file=/etc/my3308.cnf --apply-log /backupdir/bak_data/full_bak

# 第一次的增量備份應用日誌,應用完日誌後,將合併到全備上,恢復使用全備恢復
 innobackupex  --defaults-file=/etc/my3308.cnf --apply-log /backupdir/bak_data/full_bak --incremental-dir=/backupdir/bak_data/one_backup

# 第二次的增量備份應用日誌,應用完日誌後,將合併到全備上,恢復使用全備恢復
 innobackupex  --defaults-file=/etc/my3308.cnf --apply-log /backupdir/bak_data/full_bak --incremental-dir=/backupdir/bak_data/two_backup
 
# 第二次的增量備份應用日誌,應用完日誌後,將合併到全備上,恢復使用全備恢復
 innobackupex  --defaults-file=/etc/my3308.cnf --apply-log /backupdir/bak_data/full_bak --incremental-dir=/backupdir/bak_data/three_backup
 
# 此時三次增量備份其實都合併到全備上了,恢復是只需要使用全備進行恢復就可以了。
# 模擬數據故障[刪除數據庫的數據目錄,執行如下命令還原]
 innobackupex --defaults-file=/etc/my3308.cnf --copy-back /backupdir/bak_data/full_bak

# 恢復後的數據默認權限是有問題的,所以需要修改數據目錄權限,如下
 chown -R mysql:mysql /var/lib/mysql3308/
# 此時數據恢復完成,重啓數據庫服務,進行測試就可以了。

五、錯誤處理

特別說明:

如果出現如下錯誤,說明沒有裝 dbi和dbd 

innobackupex: Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_file=/etc/my.cnf;mysql_read_default_group=xtrabackup' as 'root'  (using password: YES).

innobackupex: Error: Failed to connect to MySQL server as DBD::mysql module is not installed at /usr/bin/innobackupex line 


則按如下步驟進行操作:

Percona Toolkit 的安裝:

1、下載percona toolkit的包:(可以是源碼包,或者RPM)

訪問:http://www.percona.com/software/percona-toolkit/ 下載最新穩定的版本。也可以如下命令行的方式下載最新版本。

wget percona.com/get/percona-toolkit.tar.gz

wget percona.com/get/percona-toolkit.rpm

2、安裝於Perl相關的模塊


yum install perl-DBI

yum install perl-DBD-MySQL

yum install perl-Time-HiRes

yum install perl-IO-Socket-SSL


3、安裝Percona Toolkit

rpm -ivh percona-toolkit-2.2.6-1.noarch.rpm


OK,就這麼簡單,安裝完畢。


安裝錯誤:在yum install perl-DBD-MySQL時,出現如下錯誤信息


---> Package perl-DBD-MySQL.x86_64 0:3.0007-2.el5 set to be updated

--> Processing Dependency: libmysqlclient.so.15(libmysqlclient_15)(64bit) for package: perl-DBD-MySQL

--> Processing Dependency: libmysqlclient.so.15()(64bit) for package: perl-DBD-MySQL

--> Running transaction check

---> Package mysql.x86_64 0:5.0.95-5.el5_9 set to be updated

--> Processing Conflict: mysql conflicts MySQL

--> Finished Dependency Resolution mysql-5.0.95-5.el5_9.x86_64 from updates has depsolving problems mysql conflicts with MySQL-server

Error: mysql conflicts with MySQL-server


由於我安裝的是5.6.xx的MySQL版本,而系統自帶的是5.1xx版本的,而libmysqlclient.so.15是由5.0版本提供的,所以就 出錯了。如果你的系統是centos6.X系列的,MySQL自帶的爲5.1以上,可能不會出現這個問題了。解決方案如下:


rpm -ivh MySQL-shared-compat-5.5.31-1.rhel5.x86_64.rpm

MySQL-shared-compat爲客戶端的libraries ,向下兼容。

在yum install perl-DBD-MySQL就沒有問題了。




  

發佈了55 篇原創文章 · 獲贊 5 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章