使用xtrabackup對mariadb數據庫進行增量備份以及恢復

因爲最近的老生常談的問題,zabbix數據庫裏面的數據量開始愈來愈大了,常規的mysqldump工具有份數據庫的時候將致使zabbix服務異常,產生大量報警。因而,就有了以前那篇文章關於zabbix數據庫的備份以及表分區。mysql

由於個人zabbix是使用的innodb存儲引擎,而percona公司開發的xtradbbackup數據庫備份軟件對於innodb數據庫備份比mysqldump效率高不少,並且能夠實現增量備份,不鎖表備份。因此很適合個人需求,今天閒來無事就來研究一下xtradbbackup這款數據庫備份工具。sql

首先,須要在percona官網下載xtradbbackup,連接在這:https://www.percona.com/downloads/XtraBackup/LATEST/ 數據庫

能夠下載源碼包安裝,也能夠下載rpm包安裝,我這裏下載的是centos 7的rpm包安裝的,包名是:percona-xtrabackup-2.2.12-1.el7.x86_64.rpmcentos

在安裝rpm包以前須要安裝bash

yum -y install perl-DBD-MySQL

以後安裝的時候發現還有兩個報錯,須要安裝兩個包:服務器

yum -y install libaio
yum -y install perl-Digest-MD5

而後再安裝xtradbbackup:app

rpm -ivh percona-xtrabackup-2.2.12-1.el7.x86_64.rpm

安裝好後可使用innobackupex --help查看命令參數。ide


語法:innobackupex --user=DBUSER --password=DBUSERPASS  /path/to/BACKUP-DIR/工具

/path/to/BACKUP-DIR/文件爲xtrabackup的備份文件,在備份的同時,innobackupex還會在備份目錄中建立以下文件:測試

xtrabackup_checkpoints —— 備份類型(如徹底或增量)、備份狀態(如是否已經爲prepared狀態)和LSN(日誌序列號)範圍信息; 每一個InnoDB頁(一般爲16k大小)都會包含一個日誌序列號,即LSN。LSN是整個數據庫系統的系統版本號,每一個頁面相關的LSN可以代表此頁面最近是如何發生改變的。 

xtrabackup_binlog_info —— mysql服務器當前正在使用的二進制日誌文件及至備份這一刻爲止二進制日誌事件的位置。 

xtrabackup_binlog_pos_innodb —— 二進制日誌文件及用於InnoDB或XtraDB表的二進制日誌文件的當前position。 

xtrabackup_binary —— 備份中用到的xtrabackup的可執行文件; 

backup-my.cnf —— 備份命令用到的配置選項信息;

   說明:在使用innobackupex進行備份時,還可使用--no-timestamp選項來阻止命令自動建立一個以時間命名的目錄;如此一來,innobackupex命令將會建立一個BACKUP-DIR目錄來存儲備份數據。

經常使用選項:

--defaults-file            #數據庫的配置文件路徑,感受本地備份不寫也能夠,遠程沒測試過。

--apply-log                #準備在一個備份上啓動mysql服務。

--copy-back               #從備份目錄拷貝數據,索引,日誌到my.cnf文件裏規定的初始位置。

--no-timestamp         #建立備份時不自動生成時間目錄,能夠自定義備份目錄名例如: /backups/mysql/base 

--databases                #用於指定要備份的數據庫, 多個庫文件使用方法: 「database1 database2″ 

--incremental             #在全備份的基礎上進行增量備份,後跟增量備份存貯目錄路徑 

--incremental-basedir=DIRECTORY      #增量備份所須要的全備份路徑目錄或上次作增量備份的目錄路徑 

--incremental-dir=DIRECTORY             #增量備份存貯的目錄路徑 

--redo-only                 #用於準備增量備分內容把數據合併到全備份目錄,配合–incremental-dir 增量備份目錄使用。 

--force-non-empty-directories            #若是是特定庫備份還原,不須要刪掉整個mysql目錄,只是特定庫的及相關文件就能夠,還原時加上此參數就不會報錯。

好了,接下來就須要測試使用xtradbbackup對數據庫進行全備以及恢復的過程了。


首先建立備份目錄:

mkdir -p /opt/backup

注意在使用innobackupex進行備份時,還可使用--no-timestamp選項來阻止命令自動建立一個以時間命名的目錄;如此一來,innobackupex命令將會建立一個BACKUP-DIR目錄來存儲備份數據。

innobackupex --user=root --password=xxxxxx /opt/backup (PS:該狀況將會自動在/opt/backup下面建立一個以時間命名的全備目錄)
innobackupex --user=root --password=xxxxxx --no-timestamp /opt/backup1(PS:這樣將會在/opt/backup1目錄下生成全備的文件及目錄)

下面是備份出來的目錄文件:

ls 2015-10-12_16-09-18/
backup-my.cnf  CrazyEyes  ibdata1  mysql  performance_schema  test  xtrabackup_binlog_info  xtrabackup_checkpoints  xtrabackup_info  xtrabackup_logfile  zabbix

備份的文件說明:

(1)xtrabackup_checkpoints —— 備份類型(如徹底或增量)、備份狀態(如是否已經爲prepared狀態)和LSN(日誌序列號)範圍信息;

每一個InnoDB頁(一般爲16k大小)都會包含一個日誌序列號,即LSN。LSN是整個數據庫系統的系統版本號,每一個頁面相關的LSN可以代表此頁面最近是如何發生改變的。

cat xtrabackup_checkpoints 
backup_type = full-backuped        #註明這是全備
from_lsn = 0                  #全備的lsn起始號
to_lsn = 2026561686             #全備記錄到的最大序列號
last_lsn = 2026562643           #全備完成後當前的日誌序列號
compact = 0                  #註明沒有進行打包

(2)xtrabackup_binlog_info —— mysql服務器當前正在使用的二進制日誌文件及至備份這一刻爲止二進制日誌事件的位置。

cat xtrabackup_binlog_info 
mysql-bin.0000011371180-1-175

(3)backup-my.cnf —— 備份命令用到的配置選項信息和備份無關的不會記錄,備份配置文件的話須要單獨備份。

cat backup-my.cnf 
# This MySQL options file was generated by innobackupex.
# The MySQL server
[mysqld]
innodb_checksum_algorithm=innodb
innodb_log_checksum_algorithm=innodb
innodb_data_file_path=ibdata1:12M:autoextend
innodb_log_files_in_group=2
innodb_log_file_size=50331648
innodb_page_size=16384
innodb_log_block_size=512
innodb_undo_directory=.
innodb_undo_tablespaces=0

(4)xtrabackup_info —— 記錄了mariadb的版本信息和一些屬性信息,還原是檢測版本匹配度時用到。

cat xtrabackup_info 
uuid = a2443721-70b8-11e5-ae53-000c29bc81b7
name = 
tool_name = innobackupex
tool_command = --user=root --password=... /backup/
tool_version = 1.5.1-xtrabackup
ibbackup_version = xtrabackup version 2.2.12 based on MySQL server 5.6.24 Linux (x86_64) (revision id: 8726828)
server_version = 10.0.17-MariaDB-log
start_time = 2015-10-12 16:09:18
end_time = 2015-10-12 16:10:00
lock_time = 3
binlog_pos = filename 'mysql-bin.000001', position 137118, GTID of the last change '0-1-175'
innodb_from_lsn = 0
innodb_to_lsn = 2026561686
partial = N
incremental = N
format = file
compact = N
compressed = N

建立好備份文件後這時數據尚且不能用於恢復操做,由於備份的數據中可能會包含還沒有提交的事務或已經提交但還沒有同步至數據文件中的事務。所以,此時數據文件仍處於不一致狀態。「準備」的主要做用正是經過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。

須要使用innobakupex命令的--apply-log選項來使數據文件同步。

innobackupex --apply-log 2015-10-12_16-09-18
同步後的目錄結構:
ls 2015-10-12_16-09-18
backup-my.cnf  ibdata1      ib_logfile1  performance_schema  xtrabackup_binlog_info        xtrabackup_checkpoints  xtrabackup_logfile
CrazyEyes      ib_logfile0  mysql        test                xtrabackup_binlog_pos_innodb  xtrabackup_info         zabbix

在實現「準備」的過程當中,innobackupex一般還可使用--use-memory選項來指定其可使用的內存的大小,默認一般爲100M。若是有足夠的內存可用,能夠多劃分一些內存給prepare的過程,以提升其完成速度。

命令以下:

innobackupex --user=root --password=xxxxx --no-timestamp --use-memory=500MB /backup2

設定準備數據時使用的內存限定爲500M,而且不建立以時間命名的文件夾。


模擬數據庫損壞以及恢復數據:

首先,刪除mysql數據庫的data目錄下的全部數據:

rm -fr /data/mysql/*
ll /data/mysql/

總用量 0

這時候沒法直接關閉數據庫:

service mysqld stop
 ERROR! MySQL server PID file could not be found!

可使用pkill殺死數據庫主進程:

pkill mysql
ps aux|grep mysql
root     27381  0.0  0.0 112656   976 pts/1    R+   18:10   0:00 grep --color=auto mysql

而後檢查數據庫配置文件中是否在[mysqld]設置了datadir路徑(PS:若是這裏沒有設置路徑的話在恢復數據的時候將會報錯,我這裏設置的路徑爲:datadir=/data/mysql)

my.cnf文件所在路徑爲/etc/my.cnf

如今須要進行數據恢復:

(PS:在還原數據以前,首先須要檢查datadir路徑中是否含有文件,假如含有文件,恢復時將會報錯)

innobackupex命令的--copy-back選項用於執行恢復操做,其經過複製全部數據相關的文件至mysql服務器DATADIR目錄中來執行恢復過程。innobackupex經過backup-my.cnf來獲取DATADIR目錄的相關信息。

語法:

innobackupex --copy-back /path/to/BACKUP-DIR

當數據恢復至DATADIR目錄之後,還須要確保全部數據文件的屬主和屬組均爲正確的用戶,如mysql,不然,在啓動mysqld以前還須要事先修改數據文件的屬主和屬組。

innobackupex --copy-back /backup2/

就能夠恢復數據了。以後修改數據庫datadir路徑的文件屬主和屬組:

chown -R mysql.mysql /data/mysql/

這時候能夠正常的啓動數據庫了。

service mysqld start
Starting MySQL. SUCCESS!

這個時候啓動起來是從新記錄二進制日誌的。這樣,一次全備以及數據庫全備恢復的過程就結束了。


數據庫增量備份以及對增量備份數據恢復:

提示:在恢復完成以後應該再次作一次徹底備份,後期的增量備份都依照此次的徹底備份來作。

innobackupex --user=root --password=xxxxxx --use-memory=500MB /backup3
innobackupex --apply-log /backup3/2015-10-13_08-48-25/
ls /backup3
2015-10-13_08-48-25


以後就可使用innobackupex進行增量備份

每一個InnoDB的頁面都會包含一個LSN信息,每當相關的數據發生改變,相關的頁面的LSN就會自動增加。這正是InnoDB表能夠進行增量備份的基礎,即innobackupex經過備份上次徹底備份以後發生改變的頁面來實現。

要實現第一次增量備份,可使用下面的命令進行:

innobackupex --user=root --password=xxxxxx --incremental /backup/ --incremental-basedir=BASEDIR

其中,BASEDIR指的是徹底備份所在的目錄,此命令執行結束後,innobackupex命令會在/backup/目錄中建立一個新的以時間命名的目錄以存放全部的增量備份數據。另外,在執行過增量備份以後再一次進行增量備份時,其--incremental-basedir應該指向上一次的增量備份所在的目錄。

須要注意的是,增量備份僅能應用於InnoDB或XtraDB表,對於MyISAM表而言,執行增量備份時其實進行的是徹底備份。

命令以下:

第一次增量備份:innobackupex --user=root --password=xxxxxx --incremental /backup3/ --incremental-basedir=/backup3/2015-10-13_08-48-25/
第二次增量備份:innobackupex --user=root --password=xxxxxx --incremental /backup3/ --incremental-basedir=/backup3/2015-10-13_08-52-12/

「準備」(prepare)增量備份與整理徹底備份有着一些不一樣,尤爲要注意的是:

(1)須要在每一個備份(包括徹底和各個增量備份)上,將已經提交的事務進行「重放」。「重放」以後,全部的備份數據將合併到徹底備份上。

(2)基於全部的備份將未提交的事務進行「回滾」。 

因而,操做就變成了:

innobackupex --apply-log --redo-onlyBASE-DIR
innobackupex --apply-log --redo-only /backup3/2015-10-13_08-48-25/
接着執行:
innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1
innobackupex --apply-log --redo-only /backup3/2015-10-13_08-48-25/ --incremental-dir=/backup3/2015-10-13_08-52-12/
然後是第二個增量:
innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2
innobackupex --apply-log --redo-only /backup3/2015-10-13_08-48-25/ --incremental-dir=/backup3/2015-10-13_08-52-59/

             

其中BASE-DIR指的是徹底備份所在的目錄,而INCREMENTAL-DIR-1指的是第一次增量備份的目錄,INCREMENTAL-DIR-2指的是第二次增量備份的目錄,其它依次類推,即若是有屢次增量備份,每一次都要執行如上操做;

cat /backup3/2015-10-13_08-48-25/xtrabackup_checkpoints 
backup_type = log-applied
from_lsn = 0
to_lsn = 2063010964
last_lsn = 2063010964
compact = 0
cat /backup3/2015-10-13_08-52-59/xtrabackup_checkpoints 
backup_type = incremental
from_lsn = 2062984015
to_lsn = 2063010964
last_lsn = 2063010964
compact = 0

能夠看到目前全部的增量備份都還原到了全備上面,這時候就能夠進行數據恢復了。

rm -fr /data/mysql/*
pkill mysql
ps aux|grep mysql
root     15699  0.0  0.0 112656   980 pts/1    R+   09:29   0:00 grep --color=auto mysql
rm -fr /data/mysql/*
innobackupex --copy-back /backup3/2015-10-13_08-48-25/
chown -R mysql.mysql /data/mysql/
service mysqld start
Starting MySQL...... SUCCESS!

好了,模擬數據丟失以及增量備份恢復作完了,假如在數據損毀不像我這樣直接rm -fr這麼幹淨的話能夠在最近的一次增量備份合併到全備上面並恢復數據庫以後將最近的一個binlog日誌導入並恢復數據。

cat /backup3/2015-10-13_08-48-25/xtrabackup_binlog_info 
mysql-bin.000001133183220-1-31629
mysqlbinlog --start-position=13318322 /data/mysql/mysql-bin.000001 > /tmp/statements.sql

這樣就能夠恢復到出故障前的數據庫狀態了。(PS這個操做要在啓動數據庫以前進行操做)

相關文章
相關標籤/搜索