使用Xtrabackup備份mysql資料庫

datapeng發表於2016-01-07

一、Xtrabackup介紹

1,工作原理
在 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)備份等,透過複製資料檔案,複製日誌檔案和提交日誌到資料檔案(前滾)實現了各種複合備份方式。


2,Xtrabackup是什麼

Xtrabackup是一個對InnoDB做資料備份的工具,支援線上熱備份(備份時不影響資料讀寫),是商業備份工具InnoDB Hotbackup的一個很好的替代品。

Xtrabackup有兩個主要的工具:xtrabackup、innobackupex

1、xtrabackup只能備份InnoDB和XtraDB兩種資料表,而不能備份MyISAM資料表

2、innobackupex是參考了InnoDB Hotbackup的innoback指令碼修改而來的.innobackupex是一個perl指令碼封裝,封裝了xtrabackup。主要是為了方便的 同時備份InnoDB和MyISAM引擎的表,但在處理myisam時需要加一個讀鎖。並且加入了一些使用的選項。如slave-info可以記錄備份恢 復後,作為slave需要的一些資訊,根據這些資訊,可以很方便的利用備份來重做slave。

3,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保持資料的一致。
因為innobackupex支援innodb,myisam,所以本文說一下,怎麼使用innobackupex

二,安裝xtrabackup

1,下載地址

2,安裝

根據需求,選擇不同的版本,我選擇的是rpm安裝包,如果報以下錯誤

[root@localhost xtrabackup]# rpm -ivh percona-xtrabackup-2.2.4-5004.el6.x86_64.rpm
warning: percona-xtrabackup-2.2.4-5004.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID cd2efd2a: NOKEY
error: Failed dependencies:
 perl(Time::HiRes) is needed by percona-xtrabackup-2.2.4-5004.el6.x86_64

解決辦法:

[root@localhost xtrabackup]# yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL //安裝依賴包 
 
[root@localhost xtrabackup]# rpm -ivh percona-xtrabackup-2.2.4-5004.el6.x86_64.rpm   //重新安裝 
warning: percona-xtrabackup-2.2.4-5004.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID cd2efd2a: NOKEY 
Preparing... ########################################### [100%] 
1:percona-xtrabackup ########################################### [100%] 

注意:
xtrabackup 2.2.4不支援mysql 5.1.73,所以如果要用新的xtrabackup,就要用高版本的mysql資料庫,不然就會報以下錯誤:
innobackupex: Error: Unsupported server version: '5.1.73'

二,修改my.cnf

檢視一下mysqld下面有沒有datadir,如果沒有加上
[mysqld] 
datadir=/var/lib/mysql 

不加的話,還原資料的時候,有可能會出現以下問題,

xtrabackup: Error: Please set parameter 'datadir'
innobackupex: fatal error: no 'mysqld' group in MySQL options
innobackupex: fatal error: OR no 'datadir' option in group 'mysqld' in MySQL options

三,全部資料庫備份與還原

1,全部資料庫備份

# innobackupex --defaults-file=/etc/my.cnf --user=root /home/tank/backup/ 

如果報以下錯誤:

InnoDB: Error: log file ./ib_logfile0 is of different size 5242880 bytes
InnoDB: than specified in the .cnf file 50331648 bytes!
innobackupex: Error: The xtrabackup child process has died at /usr/bin/innobackupex line 2679.

解決辦法:在my.cnf的mysqld中加入以下內容

[mysqld] 
innodb_log_file_size = 5M 


2,單資料庫備份

# innobackupex --defaults-file=/etc/my.cnf --user=root --database=backup_test /home/tank/backup/ 

3,資料庫備份並壓縮

# innobackupex --defaults-file=/etc/my.cnf --user=root --stream=tar  /home/tank/backup | gzip > /home/tank/backup/`date +%F_%H-%M-%S`.tar.gz 

4,全資料還原

# /etc/init.d/mysqld stop      //停掉mysql 
# mv /var/lib/mysql /var/lib/mysql_bak   //資料目錄備份 
# mkdir -p /var/lib/mysql  //重建資料目錄 
 
//--apply-log選項的命令是準備在一個備份上啟動mysql服務 
# innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log /home/tank/backup/2014-09-18_16-35-12 
 
//--copy-back 選項的命令從備份目錄複製資料,索引,日誌到my.cnf檔案裡規定的初始位置 
# innobackupex --defaults-file=/etc/my.cnf --user=root --copy-back /home/tank/backup/2014-09-18_16-35-12 
 
# chown -R mysql.mysql /var/lib/mysql  //改變檔案所屬 
# /etc/init.d/mysqld stop  //啟動mysql 

四,增量備份與還原

1,建立測試資料庫和表

create database backup_test;  //建立庫 
 
CREATE TABLE `backup` (  //建立表 
 `id` int(11) NOT NULL AUTO_INCREMENT , 
 `name` varchar(20) NOT NULL DEFAULT '' , 
 `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , 
 `del` tinyint(1) NOT NULL DEFAULT '0', 
 PRIMARY KEY (`id`) 
) ENGINE=myisam DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 

2,增量備份

mysql> INSERT INTO backup (name) VALUES ('tank'),('tank1');  //插入資料 
 
# innobackupex --defaults-file=/etc/my.cnf --user=root --incremental-basedir=/home/tank/backup/2014-09-18_16-35-12 --incremental /home/tank/backup/ 

3,在增量的基礎上在進行增量備份

mysql> INSERT INTO backup (name) VALUES ('tank2'),('tank3'),('tank4'),('tank5'),('tank6');  //在插入資料 
 
//2014-09-18_18-05-20這個目錄,上次增量備份產生的目錄 
# innobackupex --defaults-file=/etc/my.cnf --user=root --incremental-basedir=/home/tank/backup/2014-09-18_18-05-20 --incremental /home/tank/backup/ 

檢視增量備份記錄檔案:

[root@localhost 2014-09-18_16-35-12]# cat xtrabackup_checkpoints   //全備目錄下的檔案 
backup_type = full-prepared 
from_lsn = 0             //全備起始為0 
to_lsn = 23853959 
last_lsn = 23853959 
compact = 0 
 
[root@localhost 2014-09-18_18-05-20]# cat xtrabackup_checkpoints  //第一次增量備份目錄下的檔案 
backup_type = incremental 
from_lsn = 23853959 
to_lsn = 23854112 
last_lsn = 23854112 
compact = 0 
 
[root@localhost 2014-09-18_18-11-43]# cat xtrabackup_checkpoints  //第二次增量備份目錄下的檔案 
backup_type = incremental 
from_lsn = 23854112 
to_lsn = 23854712 
last_lsn = 23854712 
compact = 0 
增量備份做完後,把backup_test這個資料庫刪除掉,drop database backup_test;這樣可以對比還原後

4,增量還原

# innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log --redo-only /home/tank/backup/2014-09-18_16-35-12 
 
# innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log --redo-only /home/tank/backup/2014-09-18_16-35-12 --incremental-dir=/home/tank/backup/2014-09-18_18-05-20 
 
# innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log --redo-only /home/tank/backup/2014-09-18_16-35-12 --incremental-dir=/home/tank/backup/2014-09-18_18-11-43 

在這裡有三個目錄,

1),/home/tank/backup/2014-09-18_16-35-12,全備份目錄

2),/home/tank/backup/2014-09-18_18-05-20,第一次增量備份產生的目錄

3),/home/tank/backup/2014-09-18_18-11-43,第二次增量備份產生的目錄

到這裡增量還原,還沒有結束,還有最重要一步,就是要進行一次全量還原。停止資料庫,刪除/var/lib/mysql,在還原。

增量備份的原理就是,把增量目錄下的資料,整合到全變數目錄下,然後在進行,全資料量的還原。

總體來說,innobackupex速度快,支援innodb,myisam,用起來是還不是很方便,單庫還原,還是增量備份還原,都要進行全部資料庫還原,這個不合理。

五,innobackup 常用引數說明

--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;

--parallel
並行備份,並行程式,可以根據需要定義,如--parallel=4

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

相關文章