您好,登錄后才能下訂單哦!
Percona XtraBackup怎樣實現全備及增量備份與恢復,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
percona-xtrabackup主要是有兩個工具,其中一個是xtrabackup,一個是innobackupex,后者是前者封裝后的一個腳本。
在針對MySQL的物理備份工具中,大概是最流行也是最強大的工具了,此外著名的物理備份工具還有官方的mysqlbackup。
xtrabackup只可備份事務表,不能用于備份非事務表,而innobackupex不僅可用于備份事務表,也可以備份非事務表如MyISAM
主要介紹innobakcupex的使用和原理。
本文所用到的版本:
xtrabackup 2.3.7 + MySQL 5.6.30
若MySQL版本為5.7.x,建議使用xtrabackup 2.4.x
〇 xtrabackup可以做的
對InnoDB引擎的表做熱備
增量備份
流壓縮傳輸到另外的服務器上
在線移動表
更簡單的創建從庫
備份時不增加服務器負載
〇 原理
備份及恢復大致涉及三個步驟:備份 -> prepare -> 恢復
備份運行時,工具會記住當時的LSN號,并打開xtrabackup_logfile,然后開始對datafile進行copy,即ibdata1及ibd文件。
復制需要一定的時間,在復制期間,如果文件被修改,工具將監視redo log file并將每一次更變記錄下來,保存在xtrabackup_logfile中。
接下來處理非事務表如MyISAM的備份操作,innobackupex通過FLUSH TABLES WITH READ LOCK來阻塞DML。
并在此時獲取binlog的position[和GTID](此處我理解為和mysqldump --single-transaction處理方式類似)
在做完非事務表的copy之后,執行UNLOCK TABLES,完成備份,并停止記錄xtrabackup_logfile。
接下來就是需要做prepare的過程,該過程類似InnoDB的crash-recovery。
對redo log進行前滾(到數據文件),并將沒提交的事務進行回滾操作(rollback),這樣便可以保證數據的一致性,所以對于事務表,整個過程是不會影響寫操作的。
注:InnoDB、XtraDB、MyISAM是肯定支持的,其他的存儲引擎不確定,待測。
〇 權限需求
操作系統:
對datadir需要有rwx的權限。
MySQL:
最小所需要的權限有:
RELOAD
LOCK TABLES(如果加上--no-lock的話可以不要)
REPLICATION CLIENT(為了獲得binary log的position)
PROCESS(為了執行show engine innodb status,并且需要查看所有運行的線程)
其他可能需要用到的權限:
CREATE TABLESPACE(如果需要通過5.6+ 的TTS恢復/遷移單個表的話)
SUPER(可能需要在復制環境里啟動或者停止slave線程)
CREATE\INSERT\SELECT(對PERCONA_SCHEMA.xtrabackup_history進行操作)
〇 安裝
安裝超簡單(只能在linux上用,不過但這就夠了)
https://www.percona.com/downloads/XtraBackup/LATEST/
戳進去選擇版本down下來很容易就可以用了。
有RPM包、DEB包、源碼包、二進制包。
個人推薦使用二進制包,解壓,配置環境變量即可使用,在debian系或RHEL系通用,方便的一比。
源碼包的安裝,可以參考我這篇博文:
http://blog.itpub.net/29773961/viewspace-1853405/
〇 配置
默認讀取my.cnf的選項,讀取優先級與MySQL相同。
比如在備份和恢復的時候無需指定datadir等,因為可以讀取[mysqld]組下的選項。
同樣也可以讀取[client]的信息,比如可以將socket,user,password加載到(雖然因為安全因素不建議使用,但是可以這么做)。
當然也可以通過innobackupex --defaults-file=xxxx/my.cnf 去指定將要讀取的配置文件。
〇 全備
① 備份:
若加上--no-timestamp,則不會在所指定的目錄里生成一個時間戳目錄,而是直接放在所指定的目錄里,我一般是加的:
innobackupex --user= --password= $basedir [--no-timestamp](當然--user/--password可以直接寫作 -u $username -p $password)
在備份的文件夾中,有幾個文件值得注意:
xtrabackup_binlog_info記錄了binlog的position,若開啟了GTID,也會將GTID取出。
在用于備份+binlog恢復或建立slave的場景里十分有用。
xtrabackup_checkpoints記錄了此次備份的類型和lsn號的起始值,是否壓縮等
xtrabackup_info則記錄了備份工具的信息,時間,備份對象(是針對全實例還是某庫表),是否是增量,binlog位置等
# cat xtrabackup_binlog_info
binlog.000001 2321 931d11a2-9a8b-11e6-829f-000c298e914c:1-8
# cat xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 304247338
last_lsn = 304247338
compact = 0
recover_binlog_info = 0
# cat xtrabackup_info
uuid = cfb49b5f-02e8-11e7-94b4-000c298e914c
name =
tool_name = innobackupex
tool_command = --password=... /data/dbbak
tool_version = 2.3.7
ibbackup_version = 2.3.7
server_version = 5.6.30-log
start_time = 2017-03-07 11:47:36
end_time = 2017-03-07 11:47:39
lock_time = 0
binlog_pos = filename 'binlog.000001', position '2321', GTID of the last change '931d11a2-9a8b-11e6-829f-000c298e914c:1-8'
innodb_from_lsn = 0
innodb_to_lsn = 304247338
partial = N
incremental = N
format = file
compact = N
compressed = N
encrypted = N
還有一個backup-my.cnf文件,則記錄了備份時可能涉及到的選項參數,比如系統表空間信息,獨立undo表空間信息,redo-log信息等:
# 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_fast_checksum=false
innodb_page_size=16384
innodb_log_block_size=512
innodb_undo_directory=.
innodb_undo_tablespaces=0
② prepare:
第二步就是prepare,前文也提到,這個過程類似innodb的crash recovery
也可以理解為是“apply”的過程,這里是全備prepare的命令,十分簡單
innobackupex --apply-log $basedir
在--apply-log的時候,可以指定--use-memory,增大其值加快速度,若不指定,默認值為100MB。
③ 恢復到datadir:
恢復過程也十分簡單(全備和增備都是這一個恢復命令),只需要加上--copy-back參數即可
innobackupex --copy-back $basedir
這樣就可以將$basedir的東西恢復到datadir下了,datadir無需指定,將會讀取my.cnf獲得
默認是需要datadir內為空的(或者沒有創建),如果要強制寫,則需要加參數: --force-non-empty-directories
〇 增備
增量備份比起全備要復雜一點,本文也想主要介紹如何做增量備份。
用于有的場景,可能不需要每天對數據做全備。
比如有的場景是,每周做一次全備,每天對做一次增量備份,可以節約磁盤空間也可以減少備份時間。
增備的原理是通過對比LSN的信息,來找到被更變的數據,當有了修改操作時,LSN號會改變,和上一次全備的差異LSN號做對比,則可將差異數據備份出來。
整個過程還是分為三個步驟,備份 -> prepare -> 恢復
①增備方法與全備不一樣:
innobackupex --user= --password= --incremental $new_dir --incremental-basedir=$basedir
其中--incremental是本次增量備份存放目錄
$new_dir是表示將增量備份出來的東西放在哪個目錄
--incremental-basedir則表示,針對哪一次備份做增量備份
備份的差異在目錄的xtrabackup_checkpoints中查看:
比如:
$basedir中內容:
backup_type = full-prepared
from_lsn = 0
to_lsn = 304247338
last_lsn = 304247338
compact = 0
recover_binlog_info = 0
$new_bkdir中內容:
backup_type = incremental
from_lsn = 304247338
to_lsn = 304250267
last_lsn = 304250267
compact = 0
recover_binlog_info = 0
可以注意一下增備的from_lsn號
大于這個LSN號的頁都是被變更過的,這些偏移量,也就是需要被增量備份出去的
②prepare:
prepare過程:
從第一個備份開始(也就是全量)做prepare,再將往后的增量備份依次添加到全量備份中。
注意,此處多了一個參數即--redo-only,該參數是指將已提交的事務應用,未提交的事務回滾。
此外,--incremental-dir也是在之前沒有用到過的,這個參數代表需要被合并進去的增量備份目錄。
注意,此處多次的增量備份是指:針對上次的增量備份做的增量。
也就是可以理解為:
全備:500GB
第一次增量備份:2GB
第二次增量備份:1GB(針對第一次增量備份的增量數據)
……
第n次
按照備份順序做prepare,也就是prepare的順序為:
第一次全備 -> 增量備份1 -> 增量備份2 -> ... -> 增量備份n
第一次全備的prepare:innobackup --apply-log --redo-only $basedir
第二次prepare:innobackup --apply-log --redo-only $basedir --incremental-dir=$new_dir_1(此處的$new_dir_1也就是第一次增量備份)
......
第n次prepare:innobackup --apply-log $basedir --incremental-dir=$new_dir_n(此處的$new_dir_n也就是最近也就是最后一次的增量備份
最后一次增量備份的prepare,不需要指定--redo-only
最后將增量備份和全備進行合并,將未提交的事務回滾,這個操作和全量prepare無異:
innobackup --apply-log $basedir
看起來有點復雜,但沒關系,下面會有實驗和圖解。
③恢復到datadir:
和全量無異,直接copyback就行了
innobackupex --copy-back $basedir
增量備份的prepare有點蛋疼,還是小結一下:
① prepare完備(加上--redo-only)
② prepare每一次增量備份到完備中,需要加上--redo-only,最后一次增量備份的prepare不需要加--redo-only
③ 對生成的最終完備做--apply-log
〇 實驗
接下來就是實驗……
先建個備份用的用戶,給個權限。
mysql> CREATE USER xbackup@localhost IDENTIFIED BY 'back123';
mysql> GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO xbackup@localhost;
〇 完全備份&恢復
在test.tb里加入測試數據
mysql> CREATE TABLE test.tb(id int primary key, name varchar(16));
Query OK, 0 rows affected (0.07 sec)
mysql> INSERT INTO test.tb VALUES(1,'zhou'),(2,'430'),(3,'YYF'),(4,'ChuaN'),(5,'Faith');
Query OK, 5 rows affected (0.02 sec)
Records: 5 Duplicates: 0 Warnings: 0
創建備份存放目錄
$ mkdir -p /data/backup/
指定備份存放位置,開始備份
$ innobackupex -uxbackup -pbackup123 --no-timestamp /data/backup/backup
此處的/data/backup/backup就是全備的目錄了。
…………(省略刷屏輸出)
xtrabackup: Transaction log of lsn (304289583) to (304290858) was copied.
170321 16:06:11 completed OK!
看到completed OK,表明就真的ok了。
可以看一下這個目錄中的內容:
一部分是MySQL下datadir的內容,如庫目錄,redolog,系統表空間。
一部分是之前也有介紹過的,由備份工具生成的東西:
backup-my.cnf
ibdata1
ib_logfile0
ib_logfile1
mysql
performance_schema
test
xtrabackup_binlog_info
xtrabackup_binlog_pos_innodb
xtrabackup_checkpoints
xtrabackup_info
xtrabackup_logfile
進行prepare
$ innobackupex --apply-log /data/backup/backup
關閉mysqld
$ mysqladmin -uroot -p shutdown
Enter password:
$ ps -ef|grep mysql
root 2991 2438 1 11:08 pts/0 00:00:00 grep mysql
移除datadir:
$ mv /data/mysql_data /data/mysql_data.bk
恢復數據
$ innobackupex --copy-back /data/backup/backup/
修改新datadir的權限
$ chown mysql:mysql -R /data/mysql_data
啟動數據庫
$ mysqld &
$ ps -ef|grep mysql
root 2712 2438 86 16:35 pts/0 00:00:02 mysqld
root 2714 2438 0 16:35 pts/0 00:00:00 grep mysql
檢查test.tb中的內容
$ mysql -e "SELECT * FROM test.tb;"
+----+-------+
| id | name |
+----+-------+
| 1 | zhou |
| 2 | 430 |
| 3 | YYF |
| 4 | ChuaN |
| 5 | Faith |
+----+-------+
至此,完全備份&恢復完成
〇 增量備份&恢復
先來一次全備:
$ innobackupex -uxbackup -pbackup123 --no-timestamp /data/backup/all_backup
修改測試表及數據:(加個字段,改兩條數據)
mysql> ALTER TABLE test.tb ADD COLUMN picked varchar(16);
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> UPDATE test.tb SET picked='naga' WHERE id=1;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> UPDATE test.tb SET picked='TA' WHERE id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
執行第一次增量備份:
$ innobackupex -uxbackup -pbackup123 --no-timestamp --incremental /data/backup/incremental-dir-1 --incremental-basedir=/data/backup/all_backup/
可以再做一次增量備份:
此時有兩種增量備份方法:
第一種,總是針對basedir做增量,這個方式恢復起來就特別簡單了,只需要將最后一次的增量備份合并到全量備份里,就可以恢復了。
第二種,總是針對上一次的增量,做增量備份。這個方式的恢復,就要逐一合并了,也就是我上述所說看起來有點復雜的增備思路。
反正我是喜歡第一種的,感覺也可以適應絕大多數場景。
我拿word涂了兩張圖,幫助理解。
第一種:
總是將1月1日的全備作為basedir,所以FROM_LSN號總是5000。
第二種:
總是把上一次(最近一次)的備份作為basedir。
此處介紹第二種:
多次增量備份的方法依舊,只需要修改--incremental-basedir即可:
繼續對test.tb做一些修改:
mysql> UPDATE test.tb SET picked='DS' WHERE id=3;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM test.tb;
+----+-------+--------+
| id | name | picked |
+----+-------+--------+
| 1 | zhou | naga |
| 2 | 430 | TA |
| 3 | YYF | DS |
| 4 | ChuaN | NULL |
| 5 | Faith | NULL |
+----+-------+--------+
5 rows in set (0.01 sec)
針對第一次增量備份/data/backup/incremental-dir-1,做第二次增量備份,將第二次的增量備份放到/data/backup/incremental-dir-2/
$ innobackupex -uxbackup -pbackup123 --no-timestamp --incremental /data/backup/incremental-dir-2/ --incremental-basedir=/data/backup/incremental-dir-1
prepare過程,這個也是增量備份里最蛋疼的過程:
因為總共做了三次備份,所以先做三次prepare:
先對全備做prepare:
$ innobackupex --apply-log --redo-only /data/backup/all_backup/
然后接下來做第一次增量備份的prepare:
$ innobackupex --apply-log --redo-only /data/backup/all_backup/ --incremental-dir=/data/backup/incremental-dir-1
再對第二次的增量備份prepare,注意,第二次的增備是最后一次,所以不需要加上--redo-only參數:
$ innobackupex --apply-log /data/backup/all_backup/ --incremental-dir=/data/backup/incremental-dir-2
最后將兩次增量備份和全備做一次合并:
$ innobackupex --apply-log /data/backup/all_backup/
恢復過程,這個和全量恢復沒有區別:
停掉mysqld
$ mysqladmin -uroot -p shutdown
$ ps -ef|grep mysql
root 3533 3081 0 17:05 pts/1 00:00:00 grep mysql
移除datadir
$ mv /data/mysql_data /data/mysql_data.bk2
恢復數據
$ innobackupex --copy-back /data/backup/all_backup/
修改新datadir的權限
$ chown mysql:mysql -R /data/mysql_data
啟動
$ mysqld &
檢查一下,全備和兩次增備的內容都已經被恢復回來了,也就是最后一次數據的狀態:
$ mysql -uroot -p -e "SELECT * FROM test.tb;"
+----+-------+--------+
| id | name | picked |
+----+-------+--------+
| 1 | zhou | naga |
| 2 | 430 | TA |
| 3 | YYF | DS |
| 4 | ChuaN | NULL |
| 5 | Faith | NULL |
+----+-------+--------+
至此,增量備份&恢復完成
〇 總結一下xtrabackup備份及恢復全過程:
1、備份操作,需要提供具有足夠權限的MySQL用戶,并且mysqld啟動用戶需要對datadir有rwx的權限。
2、prepare,將未提交的事務回滾,將已提交的事務寫入數據文件。
3、停止mysqld服務
4、mv data/ data_bak_.../
5、copyback回去
6、修改權限新的datadir權限
7、啟動服務
當然,上述所有的備份對象,都是針對整個MySQL實例。
看完上述內容,你們掌握Percona XtraBackup怎樣實現全備及增量備份與恢復的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。