Xtrabackup
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進行MySQL備份:
一、安裝
1、簡介
Xtrabackup是由percona提供的mysql資料庫備份工具,據官方介紹,這也是世界上惟一一款開源的能夠對innodb和xtradb資料庫進行熱備的工具。特點:
(1)備份過程快速、可靠;
(2)備份過程不會打斷正在執行的事務;
(3)能夠基于壓縮等功能節約磁盤空間和流量;
(4)自動實作備份檢驗;
(5)還原速度快;
2、安裝
其最新版的軟體可從 http://www.percona.com/software/percona-xtrabackup/ 獲得。本文基于RHEL5.8的系統,是以,直接下載下傳相應版本的rpm包安裝即可,這裡不再示範其過程。
二、備份的實作
1、完全備份
<code># innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/</code>
如果要使用一個最小權限的使用者進行備份,則可基于如下指令建立此類使用者:
<code>mysql> CREATE USER ’bkpuser’@’localhost’ IDENTIFIED BY ’s3cret’;</code>
<code>mysql> REVOKE ALL PRIVILEGES, GRANT OPTION FROM ’bkpuser’;</code>
<code>mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO ’bkpuser’@’localhost’;</code>
<code>mysql> FLUSH PRIVILEGES;</code>
使用innobakupex備份時,其會調用xtrabackup備份所有的InnoDB表,複制所有關于表結構定義的相關檔案(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相關檔案,同時還會備份觸發器和資料庫配置資訊相關的檔案。這些檔案會被儲存至一個以時間指令的目錄中。
在備份的同時,innobackupex還會在備份目錄中建立如下檔案:
(1)xtrabackup_checkpoints —— 備份類型(如完全或增量)、備份狀态(如是否已經為prepared狀态)和LSN(日志序列号)範圍資訊;
每個InnoDB頁(通常為16k大小)都會包含一個日志序列号,即LSN。LSN是整個資料庫系統的系統版本号,每個頁面相關的LSN能夠表明此頁面最近是如何發生改變的。
(2)xtrabackup_binlog_info —— mysql伺服器目前正在使用的二進制日志檔案及至備份這一刻為止二進制日志事件的位置。
(3)xtrabackup_binlog_pos_innodb —— 二進制日志檔案及用于InnoDB或XtraDB表的二進制日志檔案的目前position。
(4)xtrabackup_binary —— 備份中用到的xtrabackup的可執行檔案;
(5)backup-my.cnf —— 備份指令用到的配置選項資訊;
在使用innobackupex進行備份時,還可以使用--no-timestamp選項來阻止指令自動建立一個以時間命名的目錄;如此一來,innobackupex指令将會建立一個BACKUP-DIR目錄來存儲備份資料。
2、準備(prepare)一個完全備份
一般情況下,在備份完成後,資料尚且不能用于恢複操作,因為備份的資料中可能會包含尚未送出的事務或已經送出但尚未同步至資料檔案中的事務。是以,此時資料檔案仍處理不一緻狀态。“準備”的主要作用正是通過復原未送出的事務及同步已經送出的事務至資料檔案也使得資料檔案處于一緻性狀态。
innobakupex指令的--apply-log選項可用于實作上述功能。如下面的指令:
<code># innobackupex --apply-log /path/to/BACKUP-DIR</code>
如果執行正确,其最後輸出的幾行資訊通常如下:
<code>xtrabackup: starting </code><code>shutdown</code> <code>with innodb_fast_shutdown = 1</code>
<code>120407 9:01:36 InnoDB: Starting </code><code>shutdown</code><code>...</code>
<code>120407 9:01:40 InnoDB: Shutdown completed; log sequence number 92036620</code>
<code>120407 09:01:40 innobackupex: completed OK!</code>
在實作“準備”的過程中,innobackupex通常還可以使用--use-memory選項來指定其可以使用的記憶體的大小,預設通常為100M。如果有足夠的記憶體可用,可以多劃分一些記憶體給prepare的過程,以提高其完成速度。
3、從一個完全備份中恢複資料
innobackupex指令的--copy-back選項用于執行恢複操作,其通過複制所有資料相關的檔案至mysql伺服器DATADIR目錄中來執行恢複過程。innobackupex通過backup-my.cnf來擷取DATADIR目錄的相關資訊。
<code># innobackupex --copy-back /path/to/BACKUP-DIR</code>
如果執行正确,其輸出資訊的最後幾行通常如下:
<code>innobackupex: Starting to copy InnoDB log files</code>
<code>innobackupex: </code><code>in</code> <code>'/backup/2012-04-07_08-17-03'</code>
<code>innobackupex: back to original InnoDB log directory </code><code>'/mydata/data'</code>
<code>innobackupex: Finished copying back files.</code>
<code>120407 09:36:10 innobackupex: completed OK!</code>
請確定如上資訊的最行一行出現“innobackupex: completed OK!”。
當資料恢複至DATADIR目錄以後,還需要確定所有資料檔案的屬主和屬組均為正确的使用者,如mysql,否則,在啟動mysqld之前還需要事先修改資料檔案的屬主和屬組。如:
<code># chown -R mysql:mysql /mydata/data/</code>
4、使用innobackupex進行增量備份
每個InnoDB的頁面都會包含一個LSN資訊,每當相關的資料發生改變,相關的頁面的LSN就會自動增長。這正是InnoDB表可以進行增量備份的基礎,即innobackupex通過備份上次完全備份之後發生改變的頁面來實作。
要實作第一次增量備份,可以使用下面的指令進行:
<code># innobackupex --incremental /backup --incremental-basedir=BASEDIR</code>
其中,BASEDIR指的是完全備份所在的目錄,此指令執行結束後,innobackupex指令會在/backup目錄中建立一個新的以時間命名的目錄以存放所有的增量備份資料。另外,在執行過增量備份之後再一次進行增量備份時,其--incremental-basedir應該指向上一次的增量備份所在的目錄。
需要注意的是,增量備份僅能應用于InnoDB或XtraDB表,對于MyISAM表而言,執行增量備份時其實進行的是完全備份。
“準備”(prepare)增量備份與整理完全備份有着一些不同,尤其要注意的是:
(1)需要在每個備份(包括完全和各個增量備份)上,将已經送出的事務進行“重放”。“重放”之後,所有的備份資料将合并到完全備份上。
(2)基于所有的備份将未送出的事務進行“復原”。
于是,操作就變成了:
<code># innobackupex --apply-log --redo-only BASE-DIR</code>
接着執行:
<code># innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1</code>
而後是第二個增量:
<code># innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2</code>
其中BASE-DIR指的是完全備份所在的目錄,而INCREMENTAL-DIR-1指的是第一次增量備份的目錄,INCREMENTAL-DIR-2指的是第二次增量備份的目錄,其它依次類推,即如果有多次增量備份,每一次都要執行如上操作;
5、Xtrabackup的“流”及“備份壓縮”功能
Xtrabackup對備份的資料檔案支援“流”功能,即可以将備份的資料通過STDOUT傳輸給tar程式進行歸檔,而不是預設的直接儲存至某備份目錄中。要使用此功能,僅需要使用--stream選項即可。如:
<code># innobackupex --stream=tar /backup | gzip > /backup/`date +%F_%H-%M-%S`.tar.gz</code>
甚至也可以使用類似如下指令将資料備份至其它伺服器:
<code># innobackupex --stream=tar /backup | ssh user@XXX "cat - > /backups/`date +%F_%H-%M-%S`.tar"</code>
此外,在執行本地備份時,還可以使用--parallel選項對多個檔案進行并行複制。此選項用于指定在複制時啟動的線程數目。當然,在實際進行備份時要利用此功能的便利性,也需要啟用innodb_file_per_table選項或共享的表空間通過innodb_data_file_path選項存儲在多個ibdata檔案中。對某一資料庫的多個檔案的複制無法利用到此功能。其簡單使用方法如下:
<code># innobackupex --parallel /path/to/backup</code>
同時,innobackupex備份的資料檔案也可以存儲至遠端主機,這可以使用--remote-host選項來實作:
<code># innobackupex --remote-host=root@XXX /path/IN/REMOTE/HOST/to/backup</code>
6、導入或導出單張表
預設情況下,InnoDB表不能通過直接複制表檔案的方式在mysql伺服器之間進行移植,即便使用了innodb_file_per_table選項。而使用Xtrabackup工具可以實作此種功能,不過,此時需要“導出”表的mysql伺服器啟用了innodb_file_per_table選項(嚴格來說,是要“導出”的表在其建立之前,mysql伺服器就啟用了innodb_file_per_table選項),并且“導入”表的伺服器同時啟用了innodb_file_per_table和innodb_expand_import選項。
(1)“導出”表
導出表是在備份的prepare階段進行的,是以,一旦完全備份完成,就可以在prepare過程中通過--export選項将某表導出了:
<code># innobackupex --apply-log --export /path/to/backup</code>
此指令會為每個innodb表的表空間建立一個以.exp結尾的檔案,這些以.exp結尾的檔案則可以用于導入至其它伺服器。
(2)“導入”表
要在mysql伺服器上導入來自于其它伺服器的某innodb表,需要先在目前伺服器上建立一個跟原表表結構一緻的表,而後才能實作将表導入:
<code>mysql> CREATE TABLE mytable (...) ENGINE=InnoDB;</code>
然後将此表的表空間删除:
<code>mysql> ALTER TABLE mydatabase.mytable DISCARD TABLESPACE;</code>
接下來,将來自于“導出”表的伺服器的mytable表的mytable.ibd和mytable.exp檔案複制到目前伺服器的資料目錄,然後使用如下指令将其“導入”:
<code>mysql> ALTER TABLE mydatabase.mytable IMPORT TABLESPACE;</code>
7、使用Xtrabackup對資料庫進行部分備份
Xtrabackup也可以實作部分備份,即隻備份某個或某些指定的資料庫或某資料庫中的某個或某些表。但要使用此功能,必須啟用innodb_file_per_table選項,即每張表儲存為一個獨立的檔案。同時,其也不支援--stream選項,即不支援将資料通過管道傳輸給其它程式進行處理。
此外,還原部分備份跟還原全部資料的備份也有所不同,即你不能通過簡單地将prepared的部分備份使用--copy-back選項直接複制回資料目錄,而是要通過導入表的方向來實作還原。當然,有些情況下,部分備份也可以直接通過--copy-back進行還原,但這種方式還原而來的資料多數會産生資料不一緻的問題,是以,無論如何不推薦使用這種方式。
(1)建立部分備份
建立部分備份的方式有三種:正規表達式(--include), 枚舉表檔案(--tables-file)和列出要備份的資料庫(--databases)。
(a)使用--include
使用--include時,要求為其指定要備份的表的完整名稱,即形如databasename.tablename,如:
<code># innobackupex --include='^xxx[.]tb1' /path/to/backup</code>
(b)使用--tables-file
此選項的參數需要是一個檔案名,此檔案中每行包含一個要備份的表的完整名稱;如:
<code># echo -e 'xxx.tb1\nxxx.tb2' > /tmp/tables.txt</code>
<code># innobackupex --tables-file=/tmp/tables.txt /path/to/backup</code>
(c)使用--databases
此選項接受的參數為資料名,如果要指定多個資料庫,彼此間需要以空格隔開;同時,在指定某資料庫時,也可以隻指定其中的某張表。此外,此選項也可以接受一個檔案為參數,檔案中每一行為一個要備份的對象。如:
<code># innobackupex --databases="xxx testdb" /path/to/backup</code>
(2)整理(preparing)部分備份
prepare部分備份的過程類似于導出表的過程,要使用--export選項進行:
<code># innobackupex --apply-log --export /pat/to/partial/backup</code>
此指令執行過程中,innobackupex會調用xtrabackup指令從資料字典中移除缺失的表,是以,會顯示出許多關于“表不存在”類的警告資訊。同時,也會顯示出為備份檔案中存在的表建立.exp檔案的相關資訊。
(3)還原部分備份
還原部分備份的過程跟導入表的過程相同。當然,也可以通過直接複制prepared狀态的備份直接至資料目錄中實作還原,不要此時要求資料目錄處于一緻狀态。
本文轉自 SoulMio 51CTO部落格,原文連結:http://blog.51cto.com/bovin/1858179,如需轉載請自行聯系原作者