xtrabackup原理,整庫,單表,部分備份恢復


物理備份xtrabackup原理

Percona XtraBackup(簡稱PXB)是 Percona 公司開發的一個用於 MySQL 數據庫物理熱備的備份工具,支持 MySQl(Oracle)、Percona Server 和 MariaDB

1.innobackupex在執行后會fork一個xtrabackup的進程,然后就等待xtrabackup的ibd數據文件。
2.xtrabackup在備份innoDB相關數據會啟動倆個線程進行備份,一個是redo拷貝線程,負責拷貝redo文件在備份開始后新產生的數據文件。redo線程只有一個,在ibd拷貝線程之前啟動,在ibd拷貝線程結束后結束。xtrabackup進程開始執行后,先啟動redo拷貝線程,從最新的checkpoint點開始順序拷貝redo日志;然后再啟動ibd數據拷貝線程,在xtrabackup拷貝ibd過程中,innobackupex進程一直處於等待狀態(等待文件被創建)。
3.xtrabackup拷貝完成ibd后,通知innobackupex(通過創建文件),同時自己進入等待(redo線程仍然進行拷貝);
4.innobackupex收到xtrabackup通知后,執行FLUSH TABLES WITH READ LOCK(FTWRL),去的一致性點位,開始拷貝非ibd文件可選copy或者rsync方式倆種,拷貝非 InnoDB 文件過程中,因為數據庫處於全局只讀狀態,如果在業務的主庫備份的話,要特別小心,非 InnoDB 表(主要是MyISAM)比較多的話整庫只讀時間就會比較長,這個影響一定要評估到。
5.當 innobackupex 拷貝完所有非 InnoDB 表文件后,通知 xtrabackup(通過刪文件) ,同時自己進入等待(等待另一個文件被創建)
6.xtrabackup 收到 innobackupex 備份完非 InnoDB 通知后,就停止 redo 拷貝線程,然后通知 innobackupex redo log 拷貝完成(通過創建文件);
7.innobackupex 收到 redo 備份完成通知后,就開始解鎖,執行 UNLOCK TABLES;
8.最后 innobackupex 和 xtrabackup 進程各自完成收尾工作,如資源的釋放、寫備份元數據信息等,innobackupex 等待 xtrabackup 子進程結束后退出。 

簡略的Xtrabackup流程

Xtrabackup實質上是利用了InnoDB Crash Recovery機制

 

xtrabackup備份原理分析:

對於Innodb,它是基於Innodb的crash recovery功能進行備份。

XtraBackup 在備份的時候並不鎖定表,而是一頁一頁地復制 InnoDB 的數據,與此同時,XtraBackup 還有另外一個線程監視着 transactions log,一旦 log 發生變化,
就把變化過的 log pages 復制走。在全部數據文件復制完成之后,停止復制 logfile。

XtraBackup聯機備份:
專注於InnoDB、XtraBackup的熱備工具,是C語言開發的程序,專用於備份InnoDB及XtraDB引擎對象
備份集高效、完整、可用
備份任務執行過程中不會阻塞事務
節省磁盤空間,降低網絡帶寬占用
備份集自動驗證機制
恢復更快
[root@mysql1 /]# rpm -ivh percona-xtrabackup-2.2.3-4982.el6.x86_64.rpm
MySQL5.7安裝percona-xtrabackup
# rpm -ivh libev-4.15-1.el6.rf.x86_64.rpm
# rpm -ivh percona-xtrabackup-24-2.4.5-1.el6.x86_64.rpm
[mysql@mysql1 ~]$ echo "export PATH=/usr/bin:\$PATH" >> /home/mysql/.bash_profile
(system@localhost) [(none)]> create user xtrabk@'localhost' identified by 'onlybackup';
(system@localhost) [(none)]> grant reload,lock tables,process,Replication client,super on *.* to xtrabk@'localhost';
使用xtrabackup命令進行備份
xtrabackup命令有兩種模式,--backup(備份模式)和--prepare(恢復准備模式)
--backup指定當前的操作模式,backup就是說要創建備份集
--target-dir指定備份集的存儲路徑
--defaults-file從MySQL的選項文件中讀取參數
[mysql@mysql1 ~]$ xtrabackup --defaults-file=/data/mysqldata/3306/my.cnf --backup --target-dir=/data/mysqldata/backup/full_bak
使用innobackupex命令進行備份,還能備份非InnoDB對象
[mysql@mysql1 ~]$ innobackupex --defaults-file=/data/mysqldata/3306/my.cnf --user=xtrabk --password='onlybackup' /data/mysqldata/backup/
創建增量備份:
[mysql@mysql2 ~]$ innobackupex --defaults-file=/data/mysqldata/3306/my.cnf --user=xtrabk --password='onlybackup' --incremental --incremental-basedir=/data/mysqldata/backup/2014-07-10_09-29-32 /data/mysqldata/backup_inc
--incremental:告訴xtrabackup這次是要創建增量備份
--incremental-basedir:指定一個全量備份的路徑,作為增量備份的基礎
--incremental-lsn:指定備份開始時的LSN
MySQL的增量備份對應Oracle的差異增量備份
InnoDB的Log Sequence Number日志序列號LSN。InnoDB的每個頁(Page)都保存有LSN,這個序號能夠標識該頁最后修改時間,增量備份正是根據這個LSN來的,因為每次備份(含xtrabackup和innobackupex),XtraBackup都會在備份集中創建一個xtrabackup_checkpoints文件,這個文件中的內容就記錄了最后修改的LSN序號。創建增量備份集時,只需要從上次的備份集中找到xtrabackup_checkpoints文件,讀取最新的LSN,而后在創建增量是,選擇LSN大於這個序號的頁,以及這期間產生的二進制日志就可以了,甚至不需要對比全量備份集和當前數據庫的數據文件
XtraBackup備份工作機制:
XtraBackup本質是基於InnoDB的故障恢復(crash-recovery)機制,先復制InnoDB的數據文件,復制的時候數據仍有可能正在讀寫,復制出的文件可能是不一致的狀態,所以在備份過程中,需要定時掃描日志並作記錄,而后通過備份的日志文件執行故障恢復,使文件恢復到一個一致的狀態,使數據庫達到可用狀態。核心就是InnoDB維護的重做日志(redo log)。XtraBackup會在啟動時先記錄下當前的日志序列號(LSN),然后開始復制數據文件,同時XtraBackup運行一個后台進程,監控着事務日志,並復制新發生的修改。這項操作會在XtraBackup備份執行過程中一直執行,就是log scanned up to信息,以確保記錄下所有備份期間數據庫發生的修改。接下來是准備進程(prepare process),在這一步中,XtraBackup對復制的數據文件執行故障恢復,將數據庫恢復到可用狀態
執行恢復:全量恢復和增量恢復:
准備恢復(prepare):就是為恢復做准備。備份集沒有辦法直接拿來用,所有需要一個對備份集做准備的過程
對於xtrabackup對應的參數是--prepare,對於innobackupex對應的參數是--apply-log
執行恢復(copy-back):備份集准備好以后,可以執行恢復了
對於xtrabackup沒有特殊說明,簡單cp/mv過程,對於innobackupex對應的參數是--copy-back,它的功能是將制定的備份集,恢復到指定的路徑下
首先對全量備份做恢復的准備工作
[mysql@mysql1 ~]$ innobackupex --defaults-file=/data/mysqldata/3306/my.cnf --apply-log --redo-only /data/mysqldata/backup/2014-07-08_16-24-07/
--apply-log從指定的選項文件中讀取配置信息並應用日志等,表示要做的是對備份集做恢復的准備工作
--redo-only如果進行准備工作的備份集操作完成后,還有其他增量備份集待處理,那么就必須指定本參數
繼續執行innobackupex命令,應用增量備份,這次要操作的備份集就是最后一份,不需要再指定--redo-only參數
[mysql@mysql1 ~]$ innobackupex --defaults-file=/data/mysqldata/3306/my.cnf --apply-log /data/mysqldata/backup/2014-07-08_16-24-07/ --incremental-dir=/data/mysqldata/backup_inc/2014-07-08_16-29-44/
注意在備份集進行恢復的准備過程中,不要隨意中斷該任務,否則有可能導致備份集處於不一致狀態。由於XtraBackup是直接在備份集中進行准備,一旦有異常,搞不好想恢復都沒辦法。建議操作之前,將備份集備份一次。
建議再執行一遍innobackupex --apply-log
[mysql@mysql1 ~]$ innobackupex --defaults-file=/data/mysqldata/3306/my.cnf --apply-log  /data/mysqldata/backup/2014-07-08_16-24-07/
執行文件的恢復
[mysql@mysql1 ~]$ innobackupex --defaults-file=/data/mysqldata/3306/my.cnf --copy-back /data/mysqldata/backup/2014-07-08_16-24-07/
恢復操作可以在任意機器上執行,只要您擁有完整備份集,可以把XtraBackup當做數據庫遷移工具
打包和壓縮備份集
XtraBackup支持流(stream)模式,能夠直接將備份輸出到指定的格式進行處理,比如tar或xbstream
[mysql@mysql1 ~]$ innobackupex --defaults-file=/data/mysqldata/3306/my.cnf --user=xtrabk --password=onlybackup --stream=tar /tmp | gzip -> /data/mysqldata/backup/xtra_fullbackup.tar.gz
自動化備份腳本
[mysql@mysql1 ~]$ more mysql_full_backup_by_xtra.sh
#!/bin/bash
#create by allen
source /data/mysqldata/scripts/mysql_env.ini
DATA_PATH=/data/mysqldata/backup/mysql_full
DATA_FILE=${DATA_PATH}/xtra_fullbak_`date +%F`.tar.gz
LOG_FILE=${DATA_PATH}/xtra_fullbak_`date +%F`.log
ORI_CONF_FILE=/data/mysqldata/3306/my.cnf
NEW_CONF_FILE=${DATA_PATH}/my_3306_`date +%F`.cnf
MYSQL_PATH=/usr/bin
MYSQL_CMD="${MYSQL_PATH}/innobackupex --defaults-file=${ORI_CONF_FILE} --user=xtrabk --password=onlybackup --stream=tar /tmp"
echo > ${LOG_FILE}
echo -e "=== Jobs started at `date +%F' '%T' '%w` ===\n" >> ${LOG_FILE}
echo -e "=== First cp my.cnf file to backup directory ===" >> ${LOG_FILE}
/bin/cp ${ORI_CONF_FILE} ${NEW_CONF_FILE}
echo > ${LOG_FILE}
echo -e "*** Executed command:${MYSQL_CMD} | gzip > ${DATA_FILE}" >> ${LOG_FILE}
${MYSQL_CMD} | gzip > ${DATA_FILE}
echo -e "*** Executed finished at `date +%F' '%T' '%w` ===" >> ${LOG_FILE}
echo -e "*** Backup file size:`du -sh ${DATA_FILE}` ===\n" >> ${LOG_FILE}
echo -e "--- Find expired backup and delete those files ---" >> ${LOG_FILE}
for tfile in $(/usr/bin/find $DATA_PATH -mtime +6)
do
 if [ -d $tfile ] ; then
  rmdir $tfile
 elif [ -f $tfile ] ; then
  rm -f $tfile
 fi
 echo -e "--- Delete file:$tfile ---" >> ${LOG_FILE}
done
echo -e "\n=== Jobs ended at `date +%F' '%T' '%w` ===\n" >> ${LOG_FILE}
差一個自動化增量備份腳本

innodb_force_recovery參數的使用
參數值為0到6
每次加1進行恢復測試

使用xtrabackup注意事項

設置一個超時時間,避免無限期的等待。Xtrabackup提供了以下參數實現該功能:
--lock-wait-timeout=SECONDS, ,一旦Flush table with read lock被阻塞超過預定時間,則XtraBackup出錯返回退出,該值默認為0,也就是說一旦阻塞,立即返回失敗。
--lock-wait-query-type=all|update,該參數允許用戶指定,哪類的SQL語句是需要Flush table with read lock等待的,同時用戶可以通過--lock-wait-threshold=SECONDS設置等待的時間,如果不在query-type指定的類型范圍內或者超過了wait-threshold指定的時間,XtraBackup均返回錯誤。如果指定update類型,則UPDATE/ALTER/REPLACE/INSERT 均會等待,ALL表示所有的SQL語句。
kill 其他阻塞線程
Kill掉所有阻塞Flush table with read lock的線程:
--kill-long-queries-timeout=SECONDS參數允許用戶指定了超過該閾值時間的查詢會被Kill,同時也允許用戶指定Kill
SQL語句的類型。
--kill-long-query-type=all|select
默認值為ALL,如果選擇Select,只有Select語句會被Kill,如果Flush table with read lock是被Update語句阻塞,則XtraBackup不會處理。
 

創建部分備份(Creating Partial Backups)

部分備份共有三種方式,分別是:
1. 用正則表達式表示要備份的庫名及表名(參數為--include)
2. 將要備份的表名或庫名都寫在一個文本文件中(參數為--tables-file)
3. 將要備份表名或庫名完整的寫在命令行中(參數為:--databases)。
(譯者注:不管你備份哪個庫或是哪張表,強烈推薦把mysql庫也一起備份,恢復的時候要用。)

方式一:使用--include參數
使用正則模式匹配備份部分庫表,需要使用參數--include
innobackupex --include='test.test*' /backup --user=root --password=msds007
 
方式二:使用表列表備份部分表,需要使用參數--tables-file,語句類似如下:
cat /tmp/tables.txt
test.t
test.testflashback2
innobackupex --tables-file=/tmp/tables.txt /backup --user=root --password=msds007
 
方式三:使用--databases參數
innobackupex --databases=test,mysql /backup --user=root --password=msds007
 
准備部分備份(Preparing Partial Backups)
執行preparing partial backups,與恢復獨立的表(Restoring Individual Tables)很類似:使用--apply-log和--export參數,並包含上一步生成的時間戳文件夾
innobackupex --apply-log --export /backup/2018-05-10_19-38-44
 
恢復部分備份(Restoring Partial Backups)
1)查看備份集中的文件
[root@mydb1 test]# pwd
/backup/2018-05-10_19-38-44/test
[root@mydb1 test]# ll
total 256
-rw-r--r--. 1 root root   390 May 10 19:58 t.cfg
-rw-r--r--. 1 root root  1087 May 10 19:58 testflashback2.cfg
-rw-r--r--. 1 root root 16384 May 10 19:58 testflashback2.exp
-rw-r-----. 1 root root  9030 May 10 19:38 testflashback2.frm
-rw-r-----. 1 root root 98304 May 10 19:38 testflashback2.ibd
-rw-r--r--. 1 root root 16384 May 10 19:58 t.exp
-rw-r-----. 1 root root  8586 May 10 19:38 t.frm
-rw-r-----. 1 root root 98304 May 10 19:38 t.ibd
 
2)建表,可以從frm文件中解析出建表語句
# mysqlfrm --diagnostic t.frm
# WARNING: Cannot generate character set or collation names without the --server option.
# CAUTION: The diagnostic mode is a best-effort parse of the .frm file. As such, it may not identify all of the components of the table correctly. This is especially true for damaged files. It will also not read the default values for the columns and the resulting statement may not be syntactically correct.
# Reading .frm file for t.frm:
# The .frm file is a TABLE.
# CREATE TABLE Statement:
[root@mydb1 ~]# mysqlfrm --server=dba_user:msds007@192.168.1.101 /app/mysqldata/3306/data/test/tt.frm --user=root --port=2323
--server=dba_user:msds007@192.168.1.101     遠端服務器,要讀取的數據字典
/app/mysqldata/3306/data/test/tt.frm                  frm源文件放置的本地位置
--user=root --port=2323                                     Starting the spawned server on port 2323
CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
PRIMARY KEY `PRIMARY` (`id`)
) ENGINE=InnoDB;
#...done.
 
3)導入數據
ALTER TABLE test.t DISCARD TABLESPACE;
After this, copy t.ibd and t.exp ( or t.cfg if importing to MySQL 5.6) files to database’s home, and import its tablespace:
chown mysql:mysql t.ibd t.exp t.cfg
ALTER TABLE test.t IMPORT TABLESPACE;
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM