1. 程式人生 > >MySQL中的xtrabackup的原理解析

MySQL中的xtrabackup的原理解析

xtrabackup的官方下載地址為 

http://www.percona.com/software/percona-xtrabackup。

 

xtrabackup包含兩個主要的工具,即xtrabackup和innobackupex,二者區別如下:

1 xtrabackup只能備份innodb和xtradb兩種引擎的表,而不能備份myisam引擎的表;

2 innobackupex是一個封裝了xtrabackup的Perl指令碼,支援同時備份innodb和myisam,但在對myisam備份時需要加一個全域性的讀鎖。還有就是myisam不支援增量備份。

innobackupex工具的備份過程原理圖

如圖,備份開始的時候

複製程式碼
1 首先會啟動一個xtrabackup_log後臺檢測的程序,實時檢測mysql redo的變化,一旦發現redo有新的日誌寫入,立刻將日誌寫入到日誌檔案xtrabackup_log中

2 複製innodb的資料檔案和系統表空間檔案idbdata1到對應的以預設時間戳為備份目錄的地方

3 複製結束後,執行flush table with read lock操作

4 複製.frm .myd .myi檔案

5 並且在這一時刻獲得binary log 的位置

6 將表進行解鎖unlock tables

7 停止xtrabackup_log程序
複製程式碼

 

全庫恢復的過程

這一階段會啟動xtrabackup內嵌的innodb例項,將xtrabackup日誌xtrabackup_Log進行回放,將提交的事務資訊變更應用到innodb資料或表空間,同時回滾未提交的事務

 

增量備份

增量備份主要是通過拷貝innodb中有變更的頁(指的是LSN大於xtrabackup_checkpoints中的LSN號)。增量備份是基於全備的,第一次增量備份的資料是基於上一次全備,之後的每一次增倍都是基於上一次的增倍,最終達到一致性的增倍,增倍的過程中,和全備很類似,區別在於第二步

增量備份的恢復

和全庫恢復類似,也需要兩步

1 資料檔案的恢復 分3部分 全備 增量備份和xtrabackup_log

2 對未提交事務的回滾

 

=================================================================================

innobackupex的使用案例

rpm -Uhv http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
yum -y install percona-xtrabackup

1 建立備份使用者

mysql> grant reload,lock tables,replication client on *.* to 'dbbak'@'localhost' identified by 'bk2016' ; 
mysql> flush privileges; 

進行資料庫全備

mkdir -pv /data/dbbak
cd /data/dbbak

使用以下引數進行全庫備份

複製程式碼
[[email protected]_03 dbbak]#  innobackupex --defaults-file=/etc/my.cnf --user=dbbak --password=bk2016 --socket=/data/3306/tmp/mysql.sock  /data/dbbak/

xtrabackup: Stopping log copying thread.
.160204 00:36:20 >> log scanned up to (1095197210)

160204 00:36:20 Executing UNLOCK TABLES
160204 00:36:20 All tables unlocked
160204 00:36:20 Backup created in directory '/data/dbbak//2016-02-04_00-35-36'
MySQL binlog position: filename 'mysql-bin.000011', position '1338619'
160204 00:36:20 [00] Writing backup-my.cnf
160204 00:36:20 [00] ...done
160204 00:36:20 [00] Writing xtrabackup_info
160204 00:36:20 [00] ...done
xtrabackup: Transaction log of lsn (1095197210) to (1095197210) was copied.
160204 00:36:20 completed OK!說明備份成功




複製程式碼

檢視對應生成的檔案

複製程式碼
[[email protected]_03 dbbak]# ll 2016-02-04_00-35-36/
total 1048648
-rw-r-----. 1 root root        387 Feb  4 00:36 backup-my.cnf
-rw-r-----. 1 root root 1073741824 Feb  4 00:35 ibdata1
drwx------. 2 root root       4096 Feb  4 00:36 iot
drwx------. 2 root root      12288 Feb  4 00:36 iot2
drwx------. 2 root root       4096 Feb  4 00:36 iot3
drwx------. 2 root root       4096 Feb  4 00:36 lsn
drwx------. 2 root root       4096 Feb  4 00:36 mysql
drwx------. 2 root root       4096 Feb  4 00:36 performance_schema
drwx------. 2 root root       4096 Feb  4 00:36 sakila
drwx------. 2 root root       4096 Feb  4 00:36 sbtest
drwx------. 2 root root       4096 Feb  4 00:36 test
drwx------. 2 root root       4096 Feb  4 00:36 xtrabackup0219
-rw-r-----. 1 root root         25 Feb  4 00:36 xtrabackup_binlog_info
-rw-r-----. 1 root root        119 Feb  4 00:36 xtrabackup_checkpoints
-rw-r-----. 1 root root        539 Feb  4 00:36 xtrabackup_info
-rw-r-----. 1 root root       2560 Feb  4 00:36 xtrabackup_logfile
複製程式碼

需要注意的幾個檔案

複製程式碼
[[email protected]_03 dbbak]# cat 2016-02-04_00-35-36/xtrabackup_checkpoints 
backup_type = full-backuped ###全備
from_lsn = 0
to_lsn = 1095197210
last_lsn = 1095197210  #####LSN號
compact = 0
recover_binlog_info = 0
[[email protected]_03 dbbak]# cat 2016-02-04_00-35-36/xtrabackup_binlog_info 
mysql-bin.000011    1338619
複製程式碼

刪掉某個資料庫,進行全庫恢復

mysql> drop database iot2;
Query OK, 49 rows affected (7.93 sec)

關閉資料庫

[[email protected]_03 dbbak]# /etc/init.d/mysqld stop
Shutting down MySQL.......... SUCCESS! 
[[email protected]_03 dbbak]# mv /data/3306/data /data/3306/data_bak
[[email protected]_03 dbbak]# mkdir /data/3306/data

恢復

複製程式碼
[[email protected]_03 dbbak]# innobackupex --apply-log /data/dbbak/2016-02-04_00-35-36/
160204 00:56:47 innobackupex: Starting the apply-log operation

IMPORTANT: Please check that the apply-log run completes successfully.
           At the end of a successful apply-log run innobackupex
           prints "completed OK!".

innobackupex version 2.3.3 based on MySQL server 5.6.24 Linux (x86_64) (revision id: 525ca7d)
xtrabackup: cd to /data/dbbak/2016-02-04_00-35-36/
xtrabackup: This target seems to be not prepared yet.
xtrabackup: xtrabackup_logfile detected: size=2097152, start_lsn=(1095197210)
xtrabackup: using the following InnoDB configuration for recovery:
xtrabackup:   innodb_data_home_dir = ./
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = ./
xtrabackup:   innodb_log_files_in_group = 1
xtrabackup:   innodb_log_file_size = 2097152
xtrabackup: using the following InnoDB configuration for recovery:
xtrabackup:   innodb_data_home_dir = ./
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = ./
xtrabackup:   innodb_log_files_in_group = 1
xtrabackup:   innodb_log_file_size = 2097152
xtrabackup: Starting InnoDB instance for recovery.
xtrabackup: Using 104857600 bytes for buffer pool (set by --use-memory parameter)
InnoDB: Using atomics to ref count buffer pool pages
InnoDB: The InnoDB memory heap is disabled
InnoDB: Mutexes and rw_locks use GCC atomic builtins
InnoDB: Memory barrier is not used
InnoDB: Compressed tables use zlib 1.2.3
InnoDB: Using CPU crc32 instructions
InnoDB: Initializing buffer pool, size = 100.0M
InnoDB: Completed initialization of buffer pool
InnoDB: Highest supported file format is Barracuda.
InnoDB: The log sequence numbers 532847032 and 532847032 in ibdata files do not match the log sequence number 1095197210 in the ib_logfiles!
InnoDB: Database was not shutdown normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages 
InnoDB: from the doublewrite buffer...
InnoDB: 128 rollback segment(s) are active.
InnoDB: Waiting for purge to start
InnoDB: 5.6.24 started; log sequence number 1095197210
xtrabackup: Last MySQL binlog file position 1337268, file name mysql-bin.000011

xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1095198530
xtrabackup: using the following InnoDB configuration for recovery:
xtrabackup:   innodb_data_home_dir = ./
xtrabackup:   innodb_data_file_path = ibdata1:1G:autoextend
xtrabackup:   innodb_log_group_home_dir = ./
xtrabackup:   innodb_log_files_in_group = 3
xtrabackup:   innodb_log_file_size = 1073741824
InnoDB: Using atomics to ref count buffer pool pages
InnoDB: The InnoDB memory heap is disabled
InnoDB: Mutexes and rw_locks use GCC atomic builtins
InnoDB: Memory barrier is not used
InnoDB: Compressed tables use zlib 1.2.3
InnoDB: Using CPU crc32 instructions
InnoDB: Initializing buffer pool, size = 100.0M
InnoDB: Completed initialization of buffer pool
InnoDB: Setting log file ./ib_logfile101 size to 1024 MB
InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000
InnoDB: Setting log file ./ib_logfile1 size to 1024 MB
InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000
InnoDB: Setting log file ./ib_logfile2 size to 1024 MB
InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000
InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
InnoDB: New log files created, LSN=1095198530
InnoDB: Highest supported file format is Barracuda.
InnoDB: 128 rollback segment(s) are active.
InnoDB: Waiting for purge to start
InnoDB: 5.6.24 started; log sequence number 1095198732
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1095202631
160204 00:57:31 completed OK!
複製程式碼

以上對應的目錄就是innobackupex全備份自己建立的目錄

複製程式碼
[[email protected]_03 dbbak]# innobackupex --defaults-file=/etc/my.cnf --copy-back --rsync /data/dbbak/2016-02-04_00-35-36/

160204 01:08:39 [01] ...done
160204 01:08:39 [01] Copying ./iot2/t_hash1#P#p3.ibd to /data/3306/data/iot2/t_hash1#P#p3.ibd
160204 01:08:39 [01] ...done
160204 01:08:39 [01] Copying ./iot2/db.opt to /data/3306/data/iot2/db.opt
160204 01:08:39 [01] ...done
160204 01:08:39 [01] Copying ./xtrabackup0219/db.opt to /data/3306/data/xtrabackup0219/db.opt
160204 01:08:39 [01] ...done
160204 01:08:39 completed OK!

 

複製程式碼

更改許可權

[[email protected]_03 tmp]# chown -R mysql.mysql /data/3306/data/

啟動mysqld

[[email protected]_03 tmp]# /etc/init.d/mysqld start

複製程式碼
[[email protected]_03 tmp]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.28-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| iot                |
| iot2               |  ###被刪除的庫
| iot3               |
| lsn                |
| mysql              |
| performance_schema |
| sakila             |
| sbtest             |
| test               |
| xtrabackup0219     |
+--------------------+
11 rows in set (0.00 sec)
複製程式碼

發現數據是已經成功恢復

 

 

先全備

mysql> use xtrabackup0219;
mysql> create table t1(id int(5) primary key auto_increment,name varchar(20));

innobackupex --defaults-file=/etc/my.cnf --user=dbbak --password=bk2016 --socket=/data/3306/tmp/mysql.sock /data/dbbak/

 

 

增量備份

複製程式碼
#####往表裡插入資料

mysql> insert into t1 select 1,'love sql';
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t1 select 2,'love sql';
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t1 select 3,'love sql';
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql> select * from t1;
+----+----------+
| id | name |
+----+----------+
| 1 | love sql |
| 2 | love sql |
| 3 | love sql |
+----+----------+
3 rows in set (0.00 sec)

 

[[email protected]_03 dbbak]# innobackupex --defaults-file=/etc/my.cnf --user=dbbak --password=bk2016 --socket=/data/3306/tmp/mysql.sock --incremental /data/dbbak/ --incremental-basedir=/data/dbbak/2016-02-04_01-44-24/ --parallel=2

[[email protected]_03 dbbak]# du -sh *
1.5G 2016-02-04_01-44-24
6.0M 2016-02-04_01-46-48

 

[[email protected]_03 dbbak]# cat 2016-02-04_01-46-48/xtrabackup_checkpoints 
backup_type = incremental   ###說明是增量的
from_lsn = 1095215215
to_lsn = 1095217565
last_lsn = 1095217565
compact = 0
recover_binlog_info = 0

複製程式碼

 

此時再插入資料

mysql> insert into t1 select 4,'mysql dba';
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0

增量備份2

複製程式碼

[[email protected]_03 dbbak]# innobackupex --defaults-file=/etc/my.cnf --user=dbbak --password=bk2016 --socket=/data/3306/tmp/mysql.sock --incremental /data/dbbak/ --incremental-basedir=/data/dbbak/2016-02-04_01-46-48/ --parallel=2

[[email protected]_03 dbbak]# du -sh *
1.5G 2016-02-04_01-44-24
6.0M 2016-02-04_01-46-48
5.9M 2016-02-04_01-49-21

複製程式碼

 

增量備份的恢復

增量備份的恢復需要有3個步驟

1 恢復完全備份

2 恢復增量備份到完全備份(開始恢復的增量備份要新增--redo-only引數,到最後一次增量備份要去掉--redo-only)

3 對整體的完全備份進行恢復,回滾未提交的資料

複製程式碼

[[email protected]_03 dbbak]# innobackupex --apply-log --redo-only /data/dbbak/2016-02-04_01-44-24/

xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1095209828
160204 01:27:09 completed OK!

將增量1應用到完全備份

[[email protected]_03 dbbak]# innobackupex --apply-log --redo-only /data/dbbak/2016-02-04_01-44-24/ --incremental-dir=/data/dbbak/2016-02-04_01-46-48/

[[email protected]_03 dbbak]# innobackupex --apply-log /data/dbbak/2016-02-04_01-44-24/ --incremental-dir=/data/dbbak/2016-02-04_01-49-21/

把所有合在一起的完全備份整體進行一次apply操作,回滾未提交的資料

[[email protected]_03 dbbak]# innobackupex --apply-log /data/dbbak/2016-02-04_01-44-24/

 

 

複製程式碼

模擬測試

複製程式碼
mysql> drop table t1;
Query OK, 0 rows affected (0.05 sec)

[[email protected]_03 dbbak]# rm -rf /data/3306/data/
[[email protected]_03 dbbak]# mkdir /data/3306/data
[[email protected]_03 dbbak]# innobackupex --defaults-file=/etc/my.cnf --copy-back --rsync /data/dbbak/2016-02-04_01-44-24/
[[email protected]_03 dbbak]# chown -R mysql.mysql /data/3306/data/
登入檢視

mysql> select * from t1;
+----+-----------+
| id | name |
+----+-----------+
| 1 | love sql |
| 2 | love sql |
| 3 | love sql |
| 4 | mysql dba |
+----+-----------+
4 rows in set (0.05 sec)

 

發現數據是已經正確

 




************************************************************************************






    • 摘要:Xtrabackup是基於InnoDB儲存引擎災難恢復的。它複製InnoDB的資料檔案,儘管資料檔案在內部是非一致性的,但在執行災難恢復時可以保證這些資料檔案是一致的,並且可用。官方原理在InnoDB內部會維護一個redo日誌檔案,我們也可以叫做事務日誌檔案。事務日誌會儲存每一個InnoDB表資料的記錄修改。當InnoDB啟動時,InnoDB會檢查資料檔案和事務日誌,並執行兩個步驟:它應用(前滾)已經提交的事務日誌到資料檔案,並將修改過但沒有提交的資料進行回滾操作。Xtrab
    • Xtrabackup是基於InnoDB儲存引擎災難恢復的。它複製InnoDB的資料檔案,儘管資料檔案在內部是非一致性的,但在執行災難恢復時可以保證這些資料檔案是一致的,並且可用。


      官方原理

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


      自己的理解

      Xtrabackup只能備份和恢復InnoDB表,而且只有ibd檔案,frm檔案它不管,恢復時就需要DBA提供frm。innobackupex可以備份和恢復MyISAM表以及frm檔案,並且對xtrabackup也做了很好的封裝,所以可以使用innobackupex來備份MySQL資料庫。還有一個問題,就是innobackupex備份MyISAM表之前要對全庫進行加READ LOCK,阻塞寫操作,若備份是在從庫上進行的話會影響主從同步,造成延遲。對InnoDB表備份不會阻塞讀寫。


      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保持資料的一致。


      Xtrabackup的增量備份只能用於InnoDB表,不能用在MyISAM表上。採用增量備份MySQL資料庫時xtrabackup會依據上次全備份或增量備份目錄對InnoDB表進行增量備份,對MyISAM表會進行全表複製。


      流備份(streaming)可以將備份直接儲存到遠端伺服器上。


      當執行恢復時,由於複製是不鎖表的所以此時資料檔案都是不一致的,xtrabackup使用之前儲存的redo log對各個資料檔案檢查是否與事務日誌的checkpoint一致,執行恢復:

      1)根據複製資料檔案時以及之後已提交事務產生的事務日誌進行前滾;

      2)將未提交的事務進行回滾。


      這個過程就是MySQL資料庫宕機之後執行的crash recovery。


      增量備份

      在InnoDB中,每個page中都記錄LSN資訊,每當相關資料發生改變,page的LSN就會自動增加,xtrabackup的增量備份就是依據這一原理進行的。Xtrabackup將上次備份(完全備份集或者也是一個增量備份集)以來LSN改變的page進行備份。


      所以,要做增量備份第一次就要做一個完全備份(就是將MySQL例項或者說要備份的資料庫表做一個完全複製,同時記錄LSN),之後可以基於此進行增量備份以及恢復。


      增量備份優點:

      1)資料庫太大沒有足夠的空間全量備份,增量備份能有效節省空間,並且效率高。

      2)支援熱備份,備份過程不鎖表(針對InnoDB而言),不阻塞資料庫的讀寫。

      3)每日備份只產生少量資料,也可採用遠端備份,節省本地空間。

      4)備份恢復基於檔案操作,降低直接對資料庫操作風險。

      5)備份效率更高,恢復效率更高。


      恢復與還原

      backup的恢復過程中包括恢復和還原兩個部分。


      我們前面已經說了xtrabackup只備份InnoDB表的ibd檔案,而innobackupex可以備份包括InnoDB表在內的其他儲存引擎的表的所有資料檔案。由於不同引擎表備份時的不同,也會讓恢復過程看起來不一樣。


      先來看看完全備份集的恢復。


      在InnoDB表的備份或者更直接的說ibd資料檔案複製的過程中,資料庫處於不一致的狀態,所以要將xtraback_logfile中尚未提交的事務進行回滾,以及將已經提交的事務進行前滾,


      使各個資料檔案處於一個一致性狀態,這個過程叫做“準備(prepare)”。


      如果你是在一個從庫上執行的備份,那說明你沒有東西需要回滾,只是簡單的apply redo log就可以了。另外在prepare過程中可以使用引數--use-memory增大使用系統記憶體量從而提高恢復速度。


      之後,我們就可以根據backup-my.cnf中的配置把資料檔案複製回對應的目錄了,當然你也可以自己複製回去,但innobackupex都會幫我們完成。在這裡,對於InnoDB表來說是完成“後準備”動作,我們稱之為“恢復(recovery)”,而對於MyISAM表來說由於備份時是採用鎖表方式複製的,所以此時只是簡單的複製回來,不需要apply log,這個我們稱之為“還原(restore)”。


      注:本文件裡之所以使用恢復和還原,也是和其他資料庫比如Oracle看起來一樣。


      對於增量備份的恢復過程,與完全備份集的恢復類似,只是有少許不同:

      1)恢復過程需要使用完全備份集和各個增量備份集,各個備份集的恢復與前面說的一樣(前滾和回滾),之後各個增量備份集的redo log都會應用到完全備份集中;

      2)對於完全備機集之後產生的新表,要有特殊處理方式,以便恢復後不丟表;

      3)要以完全備份集為基礎,然後按順序應用各個增量備份集。


      流備份和壓縮

      提到流備份(streaming)就要說遠端備份和備份壓縮,先說流備份吧。


      流備份是指備份的資料通過標準輸出STDOUT傳輸給tar程式進行歸檔,而不是單純的將資料檔案儲存到指定的備份目錄中,引數--stream=tar表示開啟流備份功能並打包。同時也可以利用流備份到遠端伺服器上。


      舉例來說,

      $ innobackupex --stream=TAR ${BACKUP_DIR}/base | gzip > ${BACKUP_DIR}/base.tar.gz 
      $ innobackupex --stream=TAR ${BACKUP_DIR}/base|ssh somebackupaddr “cat > ${DIR}/base.tar” 

      12 

      $ innobackupex --stream=TAR ${BACKUP_DIR}/base | gzip > ${BACKUP_DIR}/base.tar.gz $ innobackupex --stream=TAR ${BACKUP_DIR}/base|ssh somebackupaddr “cat > ${DIR}/base.tar” 

      當然了,如果你使用了流備份,那麼增量備份也就不能用了,因為增量備份需要參考次備份情況,而上次備份卻被打包或者壓縮了。


      在我們現實使用中,更多的使用增量備份,至於歸檔壓縮我們可以通過指令碼自主完成。


      部分備份和恢復

      Xtrabackup可以只備份/恢復部分庫表,可以正則模式匹配或者是你想備份庫表的列表,但InnoDB表必須是獨立表空間,同時不能使用流備份功能。


      1)使用正則模式匹配備份部分庫表,需要使用引數--include,語句類似如下:

      $ innobackupex --include=’^qb.*’ ${BACKUP_DIR}/part-base 



      $ innobackupex --include=’^qb.*’ ${BACKUP_DIR}/part-base 

      2)使用資料庫列表備份部分庫,需要使用引數--databases,語句類似如下:

      $ innobackupex --databases=qb0 qb1 qb2 qb3 ${BACKUP_DIR}/part-base 



      $ innobackupex --databases=qb0 qb1 qb2 qb3 ${BACKUP_DIR}/part-base 

      3) 使用表列表備份部分表,需要使用引數--tables-file,語句類似如下:

      $ innobackupex --tables-list=${CONF_DIR}/tab.conf ${BACKUP_DIR}/part-base 



      $ innobackupex --tables-list=${CONF_DIR}/tab.conf ${BACKUP_DIR}/part-base 

      注:在我們的現實應用中,很少會只備份叢集中部分庫表,所以只是瞭解此功能即可,若有現實需要可以參考percona官方資料以獲取更多資訊。


      能備份部分庫表,也就能根據完全備份集進行部分庫表的恢復,在現實中很少會用到,但還是說一下吧。


      首先在“準備prepare”的過程中,使用引數--export將表匯出,這個匯出會將每個InnoDB表建立一個以.exp結尾的檔案,這些檔案為之後的匯入過程服務。

      $ innobackupex --apply-log --export ${BACKUP_DIR}/base 



      $ innobackupex --apply-log --export ${BACKUP_DIR}/base 

      然後將你需要恢復的表的ibd和exp檔案複製到目標機器,在目標機器上執行匯入:

      mysql> create table t() engine=innodb; //此處需要DBA手動建立一個同結構的表或表已存在 
      mysql> ALTER TABLE t DISCARD TABLESPACE; 
      $ cp t.ibd t.exp ${DATA_DIR}/${DB}/ 
      mysql> ALTER TABLE t IMPORT TABLESPACE; 

      1234 

      mysql> create table t() engine=innodb; //此處需要DBA手動建立一個同結構的表或表已存在 mysql> ALTER TABLE t DISCARD TABLESPACE; $ cp t.ibd t.exp ${DATA_DIR}/${DB}/ mysql> ALTER TABLE t IMPORT TABLESPACE; 

      這樣的匯出匯入就可以保住恢復的表可以與資料庫其他表保持一致性了。


      並行備份

      Xtrbackup還支援並行備份,預設情況下xtrabackup備份時只會開啟一個程序進行資料檔案的備份,若配置引數--parallel=N可以讓xtrabackup開啟N個子程序對多個數據檔案進行併發備份,這樣可以加快備份的速度。當然伺服器的IO處理能力以及對伺服器的影響也是要考慮的,所以另一個引數--throttle=IOS會與它同時使用,這個引數用來限制備份過程中每秒讀寫的IO次數,對伺服器的IO是一個保護。


      這兩個引數xtrabackup和innobackupex都支援,舉例如下:

      $ innobackupex --parallel=4 --throttle=400 ${BACKUP_DIR}/part-base 



      $ innobackupex --parallel=4 --throttle=400 ${BACKUP_DIR}/part-base 

      注意:對同一個資料檔案只會有一個程序在備份。


      其他

      Xtrabackup在備份時主要的工作是做資料檔案複製,它每次只會讀寫1MB的資料(即64個page,不能修改),xtrabackup逐頁訪問1MB資料,使用innodb的buf_page_is_corrupted()函式檢查此頁的資料是否正常,如果資料不正常,就重新讀取這一頁,最多重新讀取10次,如果還是失敗,備份就失敗了,退出。


      在複製事務日誌的時候,每次讀寫512KB的資料,同樣不可以配置。