xtrabackup
xtrabackup 是 percona 的一個開源項目,可以熱備份innodb ,XtraDB,和MyISAM(會鎖表)。對MyISAM存儲引擎會鎖表,也是很郁悶的因為線上使用的是Innodb和MyISAM兩種存儲引擎,比較 頭疼!! Xtrabackup是一個對InnoDB做資料備份的工具,支援線上熱備份(備份時不影響資料讀寫),是商業備份工具InnoDB Hotbackup的一個很好的替代品。lamp兄弟連
官方原理
在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”
當然了,如果你使用了流備份,那麼增量備份也就不能用了,因為增量備份需要參考次備份情況,而上次備份卻被打包或者壓縮了。
在我們現實使用中,更多的使用增量備份,至于歸檔壓縮我們可以通過腳本自主完成。
部分備份和恢複
xtrabackup可以隻備份/恢複部分庫表,可以正則模式比對或者是你想備份庫表的清單,但InnoDB表必須是獨立表空間,同時不能使用流備份功能。
1)、使用正則模式比對備份部分庫表,需要使用參數--include,語句類似如下:
$ innobackupex --include=’^qb.*’ ${BACKUP_DIR}/part-base
2)、使用資料庫清單備份部分庫,需要使用參數--databases,語句類似如下:
$ innobackupex --databases=qb0 qb1 qb2 qb3 ${BACKUP_DIR}/part-base
3) 、使用表清單備份部分表,需要使用參數--tables-file,語句類似如下:
$ innobackupex --tables-list=${CONF_DIR}/tab.conf ${BACKUP_DIR}/part-base
注:在我們的現實應用中,很少會隻備份叢集中部分庫表,是以隻是了解此功能即可,若有現實需要可以參考percona官方資料以擷取更多資訊。
能備份部分庫表,也就能根據完全備份集進行部分庫表的恢複,在現實中很少會用到,但還是說一下吧。
首先在“準備prepare”的過程中,使用參數--export将表導出,這個導出會将每個InnoDB表建立一個以.exp結尾的檔案,這些檔案為之後的導入過程服務。
$ 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;
這樣的導出導入就可以保住恢複的表可以與資料庫其他表保持一緻性了。
并行備份
xtrbackup 還支援并行備份,預設情況下xtrabackup備份時隻會開啟一個程序進行資料檔案的備份,若配置參數--parallel=N可以讓 xtrabackup開啟N個子程序對多個資料檔案進行并發備份,這樣可以加快備份的速度。當然伺服器的IO處理能力以及對伺服器的影響也是要考慮的,所 以另一個參數--throttle=IOS會與它同時使用,這個參數用來限制備份過程中每秒讀寫的IO次數,對伺服器的IO是一個保護。
這兩個參數xtrabackup和innobackupex都支援,舉例如下:
$ innobackupex --parallel=4 --throttle=400 ${BACKUP_DIR}/part-base
注意:對同一個資料檔案隻會有一個程序在備份。
其他
xtrabackup 在備份時主要的工作是做資料檔案複制,它每次隻會讀寫1MB的資料(即64個page,不能修改),xtrabackup逐頁通路1MB資料,使用 innodb的buf_page_is_corrupted()函數檢查此頁的資料是否正常,如果資料不正常,就重新讀取這一頁,最多重新讀取10次,如 果還是失敗,備份就失敗了,退出。
在複制事務日志的時候,每次讀寫512KB的資料,同樣不可以配置。
之前我在維護 mysql資料庫的時候,使用mysqldump來進行備份與恢複,在備份的時候鎖住表,然後全部備份,在資料少的時候沒問題,但如果資料很多,不允許鎖 表,同時需要恢複資料塊的情況,mysqldump就不适合了,我在恢複一個4G資料檔案的資料庫的時候,恢複的資料是使用mysqldump的資料,恢 複了3個小時還沒有反應,造成的影響很嚴重,是以我開始尋找其他的别發軟體來滿足以上的需求,幸好找到了,就是使用xtrabackup來進行備份與恢 複,恢複4G資料檔案的資料庫,僅需要14秒,同時在備份的時候不會鎖表,而且支援增量備份,是以把我的比較分享給大家,希望對大家有益!
安裝:
yum install perl-Time-HiRes -y
yum -y install perl-DBD-MySQL.x86_64
tar xvf percona-xtrabackup-2.1.5-680-Linux-x86_64.tar.gz
cd percona-xtrabackup-2.1.5-Linux-x86_64/
cp bin/* /usr/bin/
innobackupex 使用參數介紹由于innobackupex能同時備份InnoDB和MyISAM引擎的表,這裡重點介紹innobackupex的備份與恢複使用通常一 般都直接使用innobackupex,因為它能同時備份InnoDB和MyISAM引擎的表。要注意的是my.cnf裡datadir這個參數是必須要 指定的,xtrabackup_55是根據它去定位innodb資料檔案的位置。
innobackupex 文法及參數說明innobackup [--sleep=MS] [--compress[=LEVEL]] [--include=REGEXP] [--user=NAME] [--password=WORD] [--port=PORT] [--socket=SOCKET] [--no-timest a mp] [--ibbackup=IBBACKUP-BINARY] [--slave-info] [--stream=tar] [--defaults-file=MY.CNF] [--databases=LIST] [--remote-host=HOSTNAME] BACKUP-ROOT-DIR
innobackup --apply-log [--use-memory=MB] [--uncompress] [--defaults-file=MY.CNF] [--ibbackup=IBBACKUP-BINARY] BACKUP-DIR
innobackup --copy-back [--defaults-file=MY.CNF] BACKUP-DIR
各參數說明:
--defaults- file指定mysql的配置檔案my.cnf的位置,如--defaults-file=/etc/my.cnf如果不該參數,xtrabackup将 從依次從以下位置查找配置檔案/etc/my.cnf、/etc/mysql/my.cnf、/usr/local/etc/my.cnf、~ /.my.cnf,并讀取配置檔案中的[mysqld]和[xtrabackup]配置段。[mysqld]中隻需要指定datadir、 innodb_data_home_dir、innodb_data_file_path、innodb_log_group_home_dir、 innodb_log_files_in_group、innodb_log_file_size6個參數即可讓xtrabackup正常工作 --apply-log對xtrabackup的--prepare參數的封裝
--copy-back做資料恢複時将備份資料檔案拷貝到MySQL伺服器的datadir ;
--remote-host=HOSTNAME通過ssh将備份資料存儲到程序伺服器上,HOSTNAME是遠端IP位址;
--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.
注意:innobackupex 增量備份僅針對InnoDB這類支援事務的引擎,對于MyISAM等引擎,則仍然是全備。
操作:
對資料庫全庫備份:
innobackupex --defaults-file=/etc/my.cnf --user=root --password=111111 --port=3306 /tmp/
解釋:
--defaults-file=/etc/my.cnf #指定my.cnf位置
--user=root #指定mysql帳号
--password=111111 #指定mysql密碼
--port=3306 #指定mysql端口
/tmp/ #指定備份好的檔案存放目錄,我這放在/tmp/下面,
執行完成後,如下多了個時間為名了的目錄,裡面就是備份檔案了:
[root@drfdai-17 tmp]# ls
2013-10-29_16-06-41
[root@drfdai-17 tmp]# ls 2013-10-29_16-06-41/
aa ibdata1 test xtrabackup_checkpoints
backup-my.cnf mysql xtrabackup_binary xtrabackup_logfile
drfdai performance_schema xtrabackup_binlog_info
備份drfdai庫:
innobackupex --defaults-file=/etc/my.cnf --user=root --password=111111 --port=3306 --database=drfdai /tmp/
--database=drfdai #指定需要備份的資料庫名
[root@drfdai-17 2013-10-29_16-23-53]# ls
backup-my.cnf ibdata1 xtrabackup_binlog_info xtrabackup_logfile
drfdai xtrabackup_binary xtrabackup_checkpoints
備份多個庫:
innobackupex --defaults-file=/etc/my.cnf --user=root --password=111111 --port=3306 --database='drfdai mysql' /tmp/
--database='drfdai mysql' #指定你需要備份的那幾個庫名,用單引号把這些庫名引起來,每個庫中間用空格隔開。
[root@drfdai-17 2013-10-29_16-33-09]# ls
backup-my.cnf ibdata1 xtrabackup_binary xtrabackup_checkpoints
drfdai mysql xtrabackup_binlog_info xtrabackup_logfile
備份多個表:
innobackupex --defaults-file=/etc/my.cnf --user=root --password=111111 --port=3306 --database='drfdai.aa1 drfdai.aa2' /tmp/
--database='drfdai.aa1 drfdai.aa2' #指定備份drfdai庫下面的aa1表和aa2表
還原操作:
停止mysql資料庫并删除欲恢複的資料庫檔案夾
如我的mysql資料庫檔案夾是在/data/mysql/data中,是以我删掉這個檔案夾
然後重建一個/data/mysql/data/
rm -rf /data/mysql/data
mkdir /data/mysql/data
還原完整備份:
innobackupex --defaults-file=/etc/my.cnf --user=root --password=111111 --port=3306 --apply-log /tmp/2013-10-29_17-17-47/
這裡的--apply-log指明是将日志應用到資料檔案上,完成之後将備份檔案中的資料恢複到資料庫中
innobackupex --defaults-file=/etc/my.cnf --user=root --password=111111 --port=3306 --copy-back /tmp/2013-10-29_17-17-47/
這裡的—copy-back指明是進行資料恢複。資料恢複完成之後,需要修改相關檔案的權限mysql資料庫才能正常啟動。
chown -R mysql:mysql /data/mysql/data
增量備份:
次先進行完備:
innobackupex --defaults-file=/etc/my.cnf --user=root --password=111111 --port=3306 /tmp/
備份完後,會生成最新的目錄,名為:2013-10-29_17-17-47
進行第一次增量備份:
innobackupex --defaults-file=/etc/my.cnf --user=root --password=111111 --port=3306 --incremental --incremental-basedir=/tmp/2013-10-29_17-17-47 /tmp
備份完成後,會生成最新增量備份,名為:2013-10-29_17-57-21
--incremental #指定為此次為增量備份
--incremental-basedir=/tmp/2013-10-29_17-17-47 #指定是從哪個備份目錄為參考點進行增量備份
進行第二次增量備份:
innobackupex --defaults-file=/etc/my.cnf --user=root --password=111111 --port=3306 --incremental --incremental-basedir=/tmp/2013-10-29_17-57-21/ /tmp
以此類推,第三,第四 ……
增量備份恢複:
增量備份恢複的步驟和完整備份恢複的步驟基本一緻,隻是應用日志的過程稍有不同。增量備份恢複時,是先将所有的增量備份挨個應用到完整備份的資料檔案中,然後再将完整備份中的資料恢複到資料庫中。指令如下:
應用第一個增量備份
innobackupex --user=root --password=MySQLPASSWORD --defaults-file=/etc/my.cnf --apply-log /mysqlbackup/full/2011-08-09_14-50-20/ --incremental-dir=/mysqlbackup/trn/2011-08-09_15-12-43/
應用第二個增量備份
innobackupex --user=root --password=MySQLPASSWORD --defaults-file=/etc/my.cnf --apply-log /mysqlbackup/full/2011-08-09_14-50-20/ --incremental-dir=/mysqlbackup/trn/2011-08-05_15-15-47/
将完整備份中的資料恢複到資料庫中。
innobackupex --user=root --password=MySQLPASSWORD --defaults-file=/etc/my.cnf --copy-back /mysqlbackup/full/2011-08-05_14-50-20/
其中,--incremental-dir指定要恢複的增量備份的位置。
本文轉自 Tenderrain 51CTO部落格,原文連結:http://blog.51cto.com/tenderrain/1612103