共計 8044 個字符,預(yù)計需要花費 21 分鐘才能閱讀完成。
這篇文章給大家介紹如何進行 MySQL 中的 xtrabackup 備份恢復(fù),內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
XtraBackup 是 Percona 推出的一款備份工具,算是對于 mysqldump 的一個補充。對于大批量數(shù)據(jù)的導(dǎo)入使用 mysqldump 會出現(xiàn)一定的瓶頸,這一點做過一些數(shù)據(jù)遷移項目的同學(xué)可能感同身受。
數(shù)據(jù)遷移中的數(shù)據(jù)量,小有小的好,大有大的招,見招拆招,找到適合的場景是最佳的。
如果現(xiàn)在去 Percona 官網(wǎng)下載,就會發(fā)現(xiàn)最新的版本已經(jīng)是 2.4.6 了。下載可以選擇一個完整的打包,或者逐個的 rpm 根據(jù)需求來安裝也可以。完整的工具大概在 60M 左右。
而目前的 MySQL 版本大多都在 5.5,5.6, 對于 5.7 相對來說要新一些。中間會有一些時間的過渡,在多年前,可能相對來說用 2.0 版本一下的還比較多。
XtraBackup 其實包含兩個工具,一個是 xtrabackup,另外一個是 innobackupex。我們暫且以一個較早的版本作為演示,然后使用新版本來對比下。
# xtrabackup –version
xtrabackup version 1.6.5 for Percona Server 5.1.59
innobackupex –version
InnoDB Backup Utility v1.5.1-xtrabackup; Copyright 2003, 2009 Innobase Oy
and Percona Inc 2009-2012. All Rights Reserved.
可以看到這兩個工具的版本還有一些差別,
xtrabackup 主要是用于熱備份 innodb, 或者是 xtradb 表中數(shù)據(jù)的工具,不能備份其他類型的表,也不能備份數(shù)據(jù)表結(jié)構(gòu);
innobackupex 是將 xtrabackup 進行封裝的 perl 腳本,可以備份和恢復(fù) MyISAM 表以及數(shù)據(jù)表結(jié)構(gòu)。
所以總體來看 InnoDB 的使用場景雖然最為普遍,但是還得考慮到 MyISAM, 兩者總體來說,使用 innobackex 的場景會多一些。
備份淺析
使用 innobackupex 備份,命令選項還不少,可以使用 innobackupex –help 來查看明細的參數(shù)使用。
比如我需要做一個全備。可以采用如下類似的方式,在備份命令中加幾個輔助選項,備份使用 socket 連接,備份目錄在 /home/databak/full/20170322 下。
innobackupex –socket=/home/mysql/mysql.sock /home/databak/full/20170322 –no-timestamp –no-lock –throttle=100 備份后查看對應(yīng)的目錄,備份的數(shù)據(jù)情況如下,其中紅色的幾個文件是備份中額外生成的。整體看來和源庫的目錄結(jié)構(gòu)一樣。
# du -sh ./*
2.6G ./backend
4.0K ./backup-my.cnf
646M ./gm
1.0G ./ibdata1
99M ./mobile_activity
5.0G ./mobile_billing
1.1M ./mysql
2.0G ./oem_mon
212K ./performance_schema
112K ./test
4.0K ./xtrabackup_binary
4.0K ./xtrabackup_checkpoints
4.0K ./xtrabackup_logfile 對于上面生成的文件,我們簡單看一下。
binary 結(jié)尾的文件是備份中用到的可執(zhí)行文件,這個可以對應(yīng)幾個版本,比如 xtrabackup_51,xtrabackup_55 等
# more xtrabackup_binary
xtrabackup_55logfile 結(jié)尾的文件的內(nèi)容無法直接查看,但是可以用 strings 來看。通過 strings 解析可以看到對應(yīng)的二進制日志,當然事務(wù)的 Xid 也有的。
# strings xtrabackup_logfile
xtrabkup 170322 16:33:40
{ {
{
MySQLXid
./mysql-bin.000009
393102654
08360000000039DB 下面的這個文件就更特別了,這個是作為數(shù)據(jù)的備份恢復(fù)的關(guān)鍵,里面有著備份恢復(fù)所有的檢查點 LSN, 從下面的數(shù)據(jù)來看,這是一個全備,因為 from_lsn=0.
# cat xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 30754980731
last_lsn = 30754980731
而在源庫的目錄結(jié)構(gòu)下,我們稍作過濾,也會得到一個幾乎和這個工具備份出來一樣的目錄結(jié)構(gòu)來。
# du -sh ./*|grep -v mysql-bin|grep -v innodb|grep -v log
2.6G ./backend
646M ./gm
1.0G ./ibdata1
4.5M ./ib_lru_dump
99M ./mobile_activity
5.0G ./mobile_billing
1.1M ./mysql
4.0K ./mysql.pid
0 ./mysql.sock
2.0G ./oem_mon
212K ./performance_schema
112K ./test 所以 xtrabackup 這樣一個工具就是一個熱備工具,有點類似有文件級別的拷貝,但是不止于此,我們往下看。
全庫恢復(fù)模擬
數(shù)據(jù)恢復(fù)是 DBA 最重要的工作之一,多年之前,這個“之一“的字眼還要去掉。數(shù)據(jù)無法恢復(fù),則備份無意義。
數(shù)據(jù)的恢復(fù)還是使用 innobackupex 這個工具,這是參數(shù)有些差別。
這里的數(shù)據(jù)恢復(fù)分為兩個步驟,prepare 和還原恢復(fù),prepare 的意義就在于,如果我們備份數(shù)據(jù)的時候,存在未提交的事務(wù),但是數(shù)據(jù)卻存在于備份中,這樣就是一個數(shù)據(jù)不一致的狀態(tài),在啟動數(shù)據(jù)庫的時候需要走一個前滾,然后是一個回滾的操作。這個體現(xiàn)主要就在于 logfile 和 ibdata。是使用 apply-log 這個選項實現(xiàn)的。
我們使用如下的方式來做。
innobackupex –defaults-file=/home/databak/full/20170322/backup-my.cnf –user=root –apply-log /home/databak/full/20170322 這個過程其實就會隱式調(diào)用 xtrabackup_55 這個可執(zhí)行文件,調(diào)用的命令類似于:
xtrabackup_55 –defaults-file= /home/databak/full/20170322/backup-my.cnf 默認會使用 100M 的內(nèi)存,也可以使用選項 –use-memory 來調(diào)整,整個過程會重構(gòu) redo 日志文件和 ibdata.
這個步驟完成之后就是最關(guān)鍵的地方了,還原恢復(fù)。這個過程是使用 copy-back 的選項實現(xiàn)的。
innobackupex –defaults-file=/home/databak/full/20170322/backup-my.cnf –user=root –copy-back /home/databak/full/20170322 整個過程就是大量的拷貝工作。
完成之后需要修改一下文件的屬主,默認是 root, 然后啟動即可。
增量備份恢復(fù)
我們接下來看看增量備份和恢復(fù),先來創(chuàng)建一些數(shù)據(jù)。我們在數(shù)據(jù)庫 test 下創(chuàng)建一個表 test2.
create table test2 (id int);
Query OK, 0 rows affected (0.01 sec)
insert into test2 values(1),(2);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
因為剛剛已經(jīng)做了全備,我們繼續(xù)做一個增備。
使用的命令如下:
innobackupex –defaults-file=/etc/my.cnf –user=root –incremental-basedir=/home/databak/incre/20170322 –incremental
/home/databak/incre/20170322 但是很不幸,執(zhí)行失敗了。這個錯誤帶有典型的意義。
170322 18:05:34 innobackupex: Starting ibbackup with command: xtrabackup_55 –defaults-file= /etc/my.cnf –backup –suspend-at-end –target-dir=/home/databak/incre/20170322/2017-03-22_18-05-32 –incremental-basedir= /home/databak/incre/20170322
innobackupex: Waiting for ibbackup (pid=4079) to suspend
innobackupex: Suspend file /home/databak/incre/20170322/2017-03-22_18-05-32/xtrabackup_suspended
…
xtrabackup: Error: cannot open /home/databak/incre/20170322/xtrabackup_checkpoints
xtrabackup: error: failed to read metadata from /home/databak/incre/20170322/xtrabackup_checkpoints
innobackupex: Error: ibbackup child process has died at /usr/bin/innobackupex line 349. 原因就在于里面的一個關(guān)鍵文件 _checkpoints
使用增備得有一個參考點,從哪里開始,即從哪個 LSN 開始,這個 LSN 在指定的參數(shù) –incremental-basedir=/home/databak/incre/20170322 下不存在,因為這個是一個新目錄,所以需要指向全庫備份的目錄。
然后修復(fù)后備份就沒問題了,英為有了這個參考點 LSN,所以需要要說明的是這個備份其實有累計增量和差異增量了。
這個怎么理解呢,比如周日做一個全備,周一做一個增備,周二做一個周日全備到周二的一個增備,這就是一個累計增量備份,而周三的時候做一個周二至周三數(shù)據(jù)變化的備份,就是一個差異增量備份。
下面的是一個累計增量備份。因為基準是上次的一個全備,備份后會自動生成一個目錄,比如 2017-03-22_18-07-38
innobackupex –defaults-file=/etc/my.cnf –user=root –incremental-basedir=/home/databak/full/20170322 –incremental
/home/databak/incre/20170322 為了區(qū)別兩次增量,我繼續(xù)插入兩行數(shù)據(jù)。
insert into test2 values (3),(4);
Query OK, 2 rows affected (0.00 sec) 這樣表 test2 就有 4 條數(shù)據(jù)了,每次插入 2 條。
下面的是一個差異增量備份。基于上一次的增備。
innobackupex –defaults-file=/etc/my.cnf –user=root –incremental-basedir=/home/databak/incre/20170322/2017-03-22_18-07-38 –incremental /home/databak/incre/20170322 整個恢復(fù)的過程是下面的形式,還是一個 prepare 的過程,首先是全備:
innobackupex –defaults-file=/etc/my.cnf –user=root –apply-log –redo-only /home/databak/full/20170322 然后是增備,注意這里標紅的參數(shù)。
innobackupex –defaults-file=/etc/my.cnf –user=root –apply-log –redo-only /home/databak/full/20170322 –incremental-dir=/home/databak/incre/20170322/2017-03-22_18-07-38 這樣做其實是一個 merge 的過程,對于增備來說,會生成如下的幾個文件,都是.delta, .meta 之類的文件。
[test]# ll
total 132
-rw-r–r– 1 mysql mysql 61 Mar 22 17:58 db.opt
-rw-rw—- 1 mysql mysql 8556 Mar 22 18:03 test2.frm
-rw-r–r– 1 root root 81920 Mar 22 18:08 test2.ibd.delta
-rw-r–r– 1 root root 18 Mar 22 18:08 test2.ibd.meta
增備目錄下的 checkpoint 文件就有意思了。有一個很清晰的 LSN 的增量描述。
[2017-03-22_18-07-38]# cat *checkpoints
backup_type = incremental
from_lsn = 30754980731
to_lsn = 30754984465
last_lsn = 30754984465 而 prepare 之后的全備里面的 checkpoint 文件其實已經(jīng)發(fā)生了變化
# cat *checkpoints
backup_type = full-prepared
from_lsn = 0
to_lsn = 30754984465
last_lsn = 30754984465 這個時候我們使用如下的方式來還原恢復(fù)。
#innobackupex –defaults-file=/etc/my.cnf –user=root –copy-back /home/databak/incre/20170322/2017-03-22_18-07-38 這個時候表 test2 里面的數(shù)據(jù)是幾條?是 2 條。
這個過程我們相當于完成了一個全備 + 一個增備的數(shù)據(jù)恢復(fù)過程。
而我們在一個增備之后又插入了一些數(shù)據(jù),這個怎么繼續(xù)恢復(fù)呢,還是 prepare 的過程。這個路徑需要注意,還是 merge 到全備中。
innobackupex –defaults-file=/etc/my.cnf –user=root –apply-log –redo-only /home/databak/full/20170322
–incremental-dir=/home/databak/incre/20170322/2017-03-22_18-11-26 繼續(xù)還原恢復(fù)。
innobackupex –defaults-file=/etc/my.cnf –user=root –copy-back /home/databak/full/20170322 再次查看數(shù)據(jù), 我們要恢復(fù)的 4 條數(shù)據(jù)都恢復(fù)回來了。
select *from test2;
+——+
| id |
+——+
| 1 |
| 2 |
| 3 |
| 4 |
+——+
4 rows in set (0.06 sec)
備份中的選項補充
innobackupex 中的選項很多,有幾個還是比較有特色的,比如 stream 選項,–slave-info 選項能夠方便搭建從庫,生成偏移量的信息,比如并行 –parallel 等,還可以根據(jù) LSN 來備份,選項是 –incremental-lsn
對于 stream 選項,默認是打包,可以結(jié)合管道來實現(xiàn)壓縮,比如:innobackupex –defaults-file=/etc/my.cnf –user=root –stream=tar
/home/databak/full/20170322_2 | gzip
/home/databak/full/20170322_2/20170322_2.tar.gz
備份中的常用場景
很多時候其實我不想備份整個庫,我只想備份一個表,那么這個操作如何來實現(xiàn)呢。
innobackupex –defaults-file=/etc/my.cnf –user=root –include= test.test2 /home/databak/full/20170322_2 這里有幾點需要注意,工具還是會逐個去掃描,只是那些不符合的會被忽略掉,也就意味著備份出來的情況和全備的目錄結(jié)構(gòu)是一樣的,但是指定的表會備份出 ibd,frm 文件。
[test]# ll
total 1036
-rw-r–r– 1 mysql mysql 8556 Mar 22 18:34 test2.frm
-rw-r–r– 1 root root 1048576 Mar 22 19:26 test2.ibd
[test]# cd ../mysql
[mysql]# ll
total 0 而且有一點值得吐槽一下的是,ibdata 也會完整備份出來,如果這個文件很大,那就相當不給力了。
不過也別對這種備份失去信心,有一個場景還是很實用的。那就是遷移表。
遷移表
還是剛剛的這個場景,如果表 test2 需要拷貝到另外一套環(huán)境中,我們可以使用 Innobackupex 來做物理備份,然后還原導(dǎo)入,達到遷移的目的。
下面的命令會聲明指定目錄下的備份需要導(dǎo)出對象。 innobackupex –apply-log –export /home/databak/full/20170322_2/2017-03-22_19-26-46 這個過程的直接產(chǎn)物就是生成了一個.exp 文件,在 MySQL 原生版本中是.cfg 文件
[test]# ll
total 1052
-rw-r–r– 1 root root 16384 Mar 22 19:29 test2.exp
-rw-r–r– 1 mysql mysql 8556 Mar 22 18:34 test2.frm
-rw-r–r– 1 root root 1048576 Mar 22 19:26 test2.ibd 對表 test2 做數(shù)據(jù)信息截斷。
alter table test2 discard tablespace;
Query OK, 0 rows affected (0.07 sec) 然后就是物理拷貝,復(fù)制.exp 文件和.ibd 文件到指定目錄下,修改屬主權(quán)限。
然后使用 import 的方式即可完成導(dǎo)入。
alter table test2 import tablespace;
Query OK, 0 rows affected (0.00 sec) 有另外一點值得說的是,這個.exp 文件是不是必須的,其實也不是。
我們只拷貝.ibd 文件也照樣可以。可能在新版本中會有一些警告提示,我們重新來做一下。
[test] alter table test2 discard tablespace;
Query OK, 0 rows affected (0.03 sec) 同時刪除剛剛拷貝過來的.exp 文件。
然后拷貝 ibd 文件到指定目錄,賦權(quán)限
導(dǎo)入表空間信息。
[test] alter table test2 import tablespace;
Query OK, 0 rows affected (0.00 sec) 查看數(shù)據(jù)的情況,發(fā)現(xiàn)數(shù)據(jù)還是回來了。
[test] select *from test2;
+——+
| id |
+——+
| 1 |
| 2 |
| 3 |
| 4 |
+——+
4 rows in set (0.00 sec) 當然這個過程中還是有很多需要注意的地方。
關(guān)于如何進行 MySQL 中的 xtrabackup 備份恢復(fù)就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。