2019-05-11 MySQL物理備份工具Xtrabackup應(yīng)用實(shí)踐(2)

1. Xtrabackup工具安裝

1. 系統(tǒng)環(huán)境說明

實(shí)驗(yàn)環(huán)境為CentOS 6.8单默,與其它Linux系統(tǒng)大同小異

2. 安裝Xtrabackup

1)配置epel源:

[root@oldboy ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
---CentOS 7系統(tǒng)把epel源改成7的即可

2)安裝Xtrabackup軟件需要的基礎(chǔ)環(huán)境包:

[root@oldboy ~]# yum install -y perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL

3)下載Xtrabackup軟件并安裝:

[root@oldboy ~]# wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm
---如果地址無(wú)效次员,就去官網(wǎng)尋找合適的版本
[root@oldboy ~]# ll percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm 
-rw-r--r--. 1 root root 8534624 Jul 21  2016 percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm
[root@oldboy ~]# yum install -y percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm     ---自動(dòng)解決依賴包

4)查看安裝后的結(jié)果:

[root@oldboy ~]# ll `which xtrabackup innobackupex`
lrwxrwxrwx. 1 root root       10 Apr 27 12:27 /usr/bin/innobackupex -> xtrabackup
-rwxr-xr-x. 1 root root 22136096 Jul 21  2016 /usr/bin/xtrabackup

2. Xtrabackup應(yīng)用實(shí)踐

1. 用于Xtrabackup數(shù)據(jù)備份的用戶

用于Xtrabackup數(shù)據(jù)備份的用戶也是需要一定權(quán)限的,具體配置如下(backup用戶):

mysql> CREATE USER 'backup@localhost' IDENTIFIED BY 'backup123';
Query OK, 0 rows affected (0.03 sec)
mysql> GRANT RELOAD,LOCK TABLES,PROCESS,REPLICATION CLIENT ON *.* TO 'backup'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

此外谆吴,用于操作備份的Linux系統(tǒng)用戶有讀取和寫入相關(guān)的目錄的權(quán)限辆布,一般情況下,還是建議使用root管理員權(quán)限進(jìn)行備份,不管是MySQL還是Linux系統(tǒng)瞳脓。

2. 用于恢復(fù)的MySQL配置文件

先創(chuàng)建存放MySQL日志文件的目錄,將MySQL日志和數(shù)據(jù)文件分離到不同的目錄中澈侠,以便于Xtrabackup恢復(fù)正式數(shù)據(jù):

[root@oldboy ~]# mkdir /application/mysql/logs -p
[root@oldboy ~]# chown -R mysql.mysql /application/mysql/logs

然后劫侧,修改MySQL的配置文件,把二進(jìn)制日志、錯(cuò)誤日志烧栋、慢查詢?nèi)罩緩腗ySQL數(shù)據(jù)文件目錄中遷移出來写妥,并增加數(shù)據(jù)文件對(duì)應(yīng)得目錄。

[root@oldboy ~]# egrep -v "#|^$" /etc/my.cnf    ---修改后的配置文件
[client]
user = root
password = oldboy123
[mysqld]
basedir = /application/mysql/    ---增加MySQL根目錄
datadir = /application/mysql/data/    ---MySQL數(shù)據(jù)目錄审姓,Xtrabackup恢復(fù)數(shù)據(jù)時(shí)需要這個(gè)目錄
---以下為binlog相關(guān)配置---
log_bin = /application/mysql/logs/oldboy-bin
expire_logs_days = 7
---以下為慢查詢?nèi)罩鞠嚓P(guān)配置---
slow-query-log = ON
long_query_time = 2
log_queries_not_using_indexes = ON
slow-query-log-file = /application/mysql/logs/slow.log    ---慢查詢?nèi)罩韭窂秸{(diào)整
min_examined_row_limit = 800
[mysqld_safe]
log-error = /application/mysql/logs/oldboy.err    ---錯(cuò)誤日志路徑調(diào)整
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
調(diào)整完配置文件后重啟MySQL
[root@oldboy ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS! 
Starting MySQL.190427 13:03:52 mysqld_safe error: log-error set to '/application/mysql/logs/oldboy.err', however file don't exists. Create writable for user 'mysql'.
 ERROR! The server quit without updating PID file (/application/mysql/data//oldboy.pid).
 ---重啟時(shí)啟動(dòng)報(bào)錯(cuò)珍特,提示修改配置文件后沒有相關(guān)可寫的錯(cuò)誤日志文件,新建一個(gè)即可
[root@oldboy ~]# touch /application/mysql/logs/oldboy.err 
[root@oldboy ~]# chown mysql.mysql !$
chown mysql.mysql /application/mysql/logs/oldboy.err
[root@oldboy ~]# ll !$
ll /application/mysql/logs/oldboy.err
-rw-r--r--. 1 mysql mysql 0 Apr 27 13:04 /application/mysql/logs/oldboy.err
[root@oldboy ~]# /etc/init.d/mysqld start
Starting MySQL.... SUCCESS! 

上面調(diào)整MySQL配置文件魔吐,是為了后面直接使用Xtrabackup(--copy-back)將數(shù)據(jù)文件還原到數(shù)據(jù)文件的目錄中扎筒,如果使用mv等命令移動(dòng)還原數(shù)據(jù)文件,則可以不調(diào)整對(duì)應(yīng)配置文件參數(shù)酬姆。

3. Xtrabackup軟件附帶的備份工具說明

Xtrabackup軟件主要包含兩個(gè)常用的工具:
(1)Xtrabackup命令
Xtrabackup命令是專門用于對(duì)InnoDB和XtraDB等事務(wù)引擎得數(shù)據(jù)庫(kù)熱備份的工具嗜桌,不能用于備份MyISAM等其他類型的引擎數(shù)據(jù),其主要特點(diǎn)是備份數(shù)據(jù)時(shí)完全不用鎖表辞色。
(2)Innobackupex命令
Innobackupex命令是將上述Xtrabackup命令使用perl腳本進(jìn)行二次封裝的工具骨宠,除了可以用于InnoDB和XtraDB等引擎之外,還可以備份MyISAM及多種引擎混合使用的場(chǎng)景相满,該命令的主要特點(diǎn)是備份事務(wù)引擎數(shù)據(jù)而不用鎖表层亿,可以備份非事務(wù)引擎數(shù)據(jù),但要鎖表雳灵。
國(guó)內(nèi)運(yùn)維人員和DBA在企業(yè)里通常使用功能更多的Innobackupex命令來進(jìn)行備份和恢復(fù)棕所。

4. Innobackupex工具語(yǔ)法介紹

Innobackupex工具語(yǔ)法如下:

innobackupex [--user=name] [--host=name] [--password=WORD] [--port=PORT] [--socket=SOCKET] [--defaults-file=MY.CNF] PATH
Innobackupex工具參數(shù)說明

5. 全備與恢復(fù)全備實(shí)踐

5.1 數(shù)據(jù)準(zhǔn)備
mysql> use oldboy
Database changed
mysql> select * from test;
+----+----------+
| id | name     |
+----+----------+
|  1 | oldboy   |
|  2 | oldgirl  |
|  3 | inca     |
|  4 | zuma     |
|  5 | kaka     |
|  6 | bingbing |
|  7 | xiaoting |
+----+----------+
7 rows in set (0.00 sec)
5.2 開始全備

1)先創(chuàng)建一個(gè)規(guī)范的備份目錄:

[root@oldboy backup]# mkdir /server/backup -p

執(zhí)行備份時(shí),屏幕會(huì)有非常多的輸出信息悯辙,其實(shí)就是備份的工作流程細(xì)節(jié)琳省,全備份與增量備份每當(dāng)命令操作成功時(shí),都會(huì)在日志的結(jié)尾處打印“completed ok!”作為標(biāo)識(shí):

[root@oldboy backup]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp /server/backup/full
---省略若干行提醒信息及讀取數(shù)據(jù)庫(kù)的innodb參數(shù)配置等
190427 17:58:46 >> log scanned up to (2010527)    ---開始記錄并監(jiān)控redo日志
xtrabackup: Generating a list of tablespaces
InnoDB: Allocated tablespace ID 28 for oldboy/test, old maximum was 0
190427 17:58:47 [01] Copying ./ibdata1 to /server/backup/full/ibdata1
---開始復(fù)制innodb文件
190427 17:58:47 >> log scanned up to (2010527)
190427 17:58:48 [01]        ...done
---省略若干行
190427 17:58:48 [01] Copying ./mysql/slave_worker_info.ibd to /server/backup/full/mysql/slave_worker_info.ibd
190427 17:58:48 [01]        ...done
190427 17:58:48 Executing FLUSH NO_WRITE_TO_BINLOG TABLES...
190427 17:58:48 Executing FLUSH TABLES WITH READ LOCK...    ---開始鎖表備份非事務(wù)引擎表
190427 17:58:48 Starting to backup non-InnoDB tables and files
190427 17:58:48 [01] Copying ./oldboy/test.frm to /server/backup/full/oldboy/test.frm
190427 17:58:48 [01]        ...done
---省略若干復(fù)制MyISAM表的數(shù)據(jù)文件行
190427 17:58:49 Finished backing up non-InnoDB tables and files
---備份非事務(wù)引擎表完成
190427 17:58:49 [00] Writing xtrabackup_binlog_info    ---記錄binlog位置
190427 17:58:49 [00]        ...done
190427 17:58:49 Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS...
xtrabackup: The latest check point (for incremental): '2010527'
---記錄最新的checkpoint
xtrabackup: Stopping log copying thread.    ---停止日志監(jiān)控進(jìn)程
.190427 17:58:49 >> log scanned up to (2010527)
190427 17:58:49 Executing UNLOCK TABLES    ---停止鎖表
190427 17:58:49 All tables unlocked
---省略備份結(jié)果信息提示
190427 17:58:49 completed OK!    ---備份成功的標(biāo)識(shí)

最終的備份結(jié)果如下:

[root@oldboy ~]# ll /server/backup/full/
total 77860
-rw-r-----. 1 root root      418 Apr 27 17:58 backup-my.cnf    ---配置文件備份
-rw-r-----. 1 root root 79691776 Apr 27 17:58 ibdata1    ---共享表空間備份
drwxr-x---. 2 root root     4096 Apr 27 17:58 mysql    ---mysql庫(kù)的備份
drwxr-x---. 2 root root     4096 Apr 27 17:58 oldboy    ---oldboy庫(kù)的備份
drwxr-x---. 2 root root     4096 Apr 27 17:58 oldboy_utf8    ------oldboy_utf8庫(kù)的備份
drwxr-x---. 2 root root     4096 Apr 27 17:58 performance_schema    ---performance_schema庫(kù)的備份
-rw-r-----. 1 root root       22 Apr 27 17:58 xtrabackup_binlog_info    ---binlog的位置信息
-rw-r-----. 1 root root      113 Apr 27 17:58 xtrabackup_checkpoints    ---checkpoints信息
-rw-r-----. 1 root root      569 Apr 27 17:58 xtrabackup_info    ---xtrabackup信息
-rw-r-----. 1 root root     2560 Apr 27 17:58 xtrabackup_logfile    ---xtrabackup日志文件
[root@oldboy ~]# cd /server/backup/full/
[root@oldboy full]# cat xtrabackup_binlog_info 
oldboy-bin.000001   120    ---binlog位置信息
[root@oldboy full]# cat xtrabackup_checkpoints     ---存放備份的起始位置和結(jié)束位置
backup_type = full-backuped    ---備份類型
from_lsn = 0    ---checkpoints起始點(diǎn)
to_lsn = 2010527    ---checkpoints結(jié)束點(diǎn)
last_lsn = 2010527
compact = 0
recover_binlog_info = 0
5.3 利用全備恢復(fù)數(shù)據(jù)

使用Innobackupex備份的數(shù)據(jù)有可能會(huì)處于不一致的狀態(tài)躲撰,因此在恢復(fù)數(shù)據(jù)之前针贬,首先要將數(shù)據(jù)調(diào)成一致性的狀態(tài),即需要應(yīng)用備份過程中記錄變化的日志(xtrabackup_logfile)拢蛋,同時(shí)回滾未提交的事務(wù)日志數(shù)據(jù):

[root@oldboy full]# innobackupex --apply-log --use-memory=32M /server/backup/full/

提示
1)“--apply-log”用于記錄變化的日志桦他,并回滾未提交得事務(wù)日志數(shù)據(jù)
2)“use-memory=32M”是分配的使用內(nèi)存大小

執(zhí)行完此命令之后,備份的數(shù)據(jù)就可以用來恢復(fù)了谆棱。
使用Xtrabackup備份的本質(zhì)就是復(fù)制物理數(shù)據(jù)文件快压,因此,在進(jìn)行最終恢復(fù)時(shí)垃瞧,需要臨時(shí)關(guān)閉數(shù)據(jù)庫(kù)蔫劣,把物理文件復(fù)制回去進(jìn)行恢復(fù):

[root@oldboy ~]# /etc/init.d/mysqld stop    ---先停庫(kù)
Shutting down MySQL.. SUCCESS! 
[root@oldboy ~]# ss -lnt | grep 3306
[root@oldboy ~]# mv /application/mysql/data /application/mysql/data_ori    ---模擬刪除數(shù)據(jù)文件
[root@oldboy ~]# mkdir -p /application/mysql/data    ---創(chuàng)建原始數(shù)據(jù)目錄,目錄要為空
[root@oldboy ~]# mv /server/backup/full/* /application/mysql/data/    ---使用mv直接復(fù)制更舒服一些
---也可以使用下面的命令復(fù)制還原數(shù)據(jù)个从,和mv命令的功能是一樣的脉幢,下面的命令的缺點(diǎn)是要根據(jù)MySQL配置文件的路徑進(jìn)行回拷貝歪沃,因此
配置文件沒有指定數(shù)據(jù)文件路徑、數(shù)據(jù)文件目錄不為空等嫌松,都會(huì)導(dǎo)致無(wú)法回拷貝的問題沪曙。命令如下:
innobackupex --defaults-file=/etc/my.cnf --copy-back --rsync /server/backup/full/
[root@oldboy ~]# chown -R mysql.mysql /application/mysql/data
---如果權(quán)限不對(duì),啟動(dòng)數(shù)據(jù)庫(kù)可能會(huì)報(bào)“Starting MySQL. ERROR! The server quit without updating PID file”錯(cuò)誤
[root@oldboy ~]# /etc/init.d/mysqld start
Starting MySQL.. SUCCESS! 
[root@oldboy ~]# mysql -e "select * from oldboy.test;"    ---恢復(fù)成功
+----+----------+
| id | name     |
+----+----------+
|  1 | oldboy   |
|  2 | oldgirl  |
|  3 | inca     |
|  4 | zuma     |
|  5 | kaka     |
|  6 | bingbing |
|  7 | xiaoting |
+----+----------+

6. 增量備份與恢復(fù)增量數(shù)據(jù)實(shí)踐

使用Xtrabackup程序做增量備份之前萎羔,首先要進(jìn)行一次全備份液走,第一次增量備份是基于全備進(jìn)行的,之后的每一次增量備份都會(huì)基于上一次增量備份的數(shù)據(jù)來實(shí)現(xiàn)贾陷,操作如下:
(1)創(chuàng)建基礎(chǔ)全備份

[root@oldboy ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp /server/backup/base_full

(2)模擬增加數(shù)據(jù)育灸,然后做增量備份
增加如下數(shù)據(jù):

mysql> use oldboy
Database changed
mysql> insert into test values(8,'outman');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test values(9,'outgirl');
Query OK, 1 row affected (0.00 sec)
mysql> select * from test;
+----+----------+
| id | name     |
+----+----------+
|  1 | oldboy   |
|  2 | oldgirl  |
|  3 | inca     |
|  4 | zuma     |
|  5 | kaka     |
|  6 | bingbing |
|  7 | xiaoting |
|  8 | outman   |    ---全備后模擬增加了以下兩行數(shù)據(jù)
|  9 | outgirl  |
+----+----------+
9 rows in set (0.00 sec)

開始做第一次增量備份:

[root@oldboy ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp --incremental-basedir=/server/backup/base_full --incremental /server/backup/one_inc

注意,這里指定的全備路徑是--incremental-basedir=/server/backup/base_full昵宇。
增量備份的結(jié)果在/server/backup/one_inc下,其實(shí)就是從全備信息里最后得LSN開始讀取redo數(shù)據(jù)儿子,對(duì)改變的數(shù)據(jù)進(jìn)行增量備份瓦哎,所以我們剛剛增加的增量數(shù)據(jù)很少,InnoDB數(shù)據(jù)文件備份得也很少柔逼,增量備份的InnoDB數(shù)據(jù)備份的關(guān)鍵輸出如下:

xtrabackup: using the full scan for incremental backup
190427 21:55:43 [01] Copying ./ibdata1 to /server/backup/one_inc/ibdata1.delta
190427 21:55:43 [01]        ...done
190427 21:55:43 [01] Copying ./oldboy/test.ibd to /server/backup/one_inc/oldboy/test.ibd.delta
190427 21:55:43 [01]        ...done
190427 21:55:43 [01] Copying ./mysql/innodb_index_stats.ibd to /server/backup/one_inc/mysql/innodb_index_stats.ibd.delta
190427 21:55:43 [01]        ...done
190427 21:55:43 [01] Copying ./mysql/innodb_table_stats.ibd to /server/backup/one_inc/mysql/innodb_table_stats.ibd.delta
190427 21:55:43 [01]        ...done
190427 21:55:43 [01] Copying ./mysql/slave_master_info.ibd to /server/backup/one_inc/mysql/slave_master_info.ibd.delta
190427 21:55:43 [01]        ...done
190427 21:55:43 [01] Copying ./mysql/slave_relay_log_info.ibd to /server/backup/one_inc/mysql/slave_relay_log_info.ibd.delta
190427 21:55:43 [01]        ...done
190427 21:55:43 [01] Copying ./mysql/slave_worker_info.ibd to /server/backup/one_inc/mysql/slave_worker_info.ibd.delta
190427 21:55:43 [01]        ...done
190427 21:55:44 >> log scanned up to (2017505)
---省略無(wú)用行---
190427 21:55:45 [00] Writing xtrabackup_info
190427 21:55:45 [00]        ...done
xtrabackup: Transaction log of lsn (2017505) to (2017505) was copied.
190427 21:55:45 completed OK!

根據(jù)輸出蒋譬,我們也大概了解了插入數(shù)據(jù)到數(shù)據(jù)庫(kù)時(shí),對(duì)數(shù)據(jù)庫(kù)會(huì)有什么影響愉适,面對(duì)于非事務(wù)引擎的備份犯助,則仍是鎖表進(jìn)行全備。
(3)再模擬增加的數(shù)據(jù)维咸,然后做第二次增量備份
增加如下數(shù)據(jù):

mysql> use oldboy
Database changed
mysql> insert into test values(10,'two_inc1');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test values(11,'two_inc2');
Query OK, 1 row affected (0.00 sec)

開始做第二次增量備份剂买,注意,這里要用到第一次增量備份的目錄癌蓖,而不是全備目錄:

[root@oldboy ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp --parallel=3 --incremental-basedir=/server/backup/one_inc/ --incremental /server/backup/two_inc

到此為止瞬哼,已經(jīng)完成了1次全備,以及全備之后的兩次增量數(shù)據(jù)備份
(4)開始做增量數(shù)據(jù)恢復(fù)
增量恢復(fù)的步驟為先恢復(fù)全備(base_full目錄)數(shù)據(jù)租副,然后再恢復(fù)第一次增量(one_inc)的數(shù)據(jù)坐慰,以及第二次增量(two_inc)的數(shù)據(jù),如果有更多次增量備份就以此類推用僧。
1)應(yīng)用redo日志恢復(fù)全備數(shù)據(jù):

[root@oldboy ~]# innobackupex --apply-log --use-memory=32M --redo-only /server/backup/base_full/

注意:非最后一次合并增量數(shù)據(jù)一定要加--redo-only參數(shù)结胀,即只應(yīng)用redo日志恢復(fù)數(shù)據(jù),而不執(zhí)行undo回滾未提交的數(shù)據(jù)责循,等到最后一次增量備份合并完成后再進(jìn)行undo日志回滾數(shù)據(jù)糟港。
2)合并第一次的增量數(shù)據(jù)到全備數(shù)據(jù)目錄:

[root@oldboy ~]# innobackupex --apply-log --use-memory=32M --redo-only --incremental-dir=/server/backup/one_inc /server/backup/base_full/

3)合并第二次的增量數(shù)據(jù)到全備數(shù)據(jù)目錄:

[root@oldboy ~]# innobackupex --apply-log --use-memory=32M --incremental-dir=/server/backup/two_inc /server/backup/base_full/

需要強(qiáng)調(diào)的是,最后一次合并增量數(shù)據(jù)到全備時(shí)沼死,取消了“redo-only”參數(shù)着逐。
4)對(duì)最終的全量數(shù)據(jù)做redo日志應(yīng)用,并執(zhí)行undo回滾數(shù)據(jù):

[root@oldboy ~]# innobackupex --apply-log --use-memory=32M /server/backup/base_full/

提示:本命令取消了“--redo-only”參數(shù),目的是應(yīng)用undo日志回滾數(shù)據(jù)耸别,為最終的恢復(fù)數(shù)據(jù)做準(zhǔn)備健芭。
5)開始正式恢復(fù)數(shù)據(jù):

[root@oldboy ~]# /etc/init.d/mysqld stop
Shutting down MySQL.... SUCCESS! 
[root@oldboy ~]# ss -lnt | grep 3306
[root@oldboy ~]# mv /application/mysql/data /tmp/data_ori1
[root@oldboy ~]# mkdir -p /application/mysql/data    ---原始數(shù)據(jù)目錄要為空
[root@oldboy ~]# innobackupex --defaults-file=/etc/my.cnf --copy-back --rsync /server/backup/base_full/
---看看innobackupex效果和mv是不是一樣
[root@oldboy ~]# chown -R mysql.mysql /application/mysql/data
[root@oldboy ~]# /etc/init.d/mysqld start
Starting MySQL.. SUCCESS! 
[root@oldboy ~]# mysql -e "select * from oldboy.test;"
+----+----------+
| id | name     |
+----+----------+
|  1 | oldboy   |
|  2 | oldgirl  |
|  3 | inca     |
|  4 | zuma     |
|  5 | kaka     |
|  6 | bingbing |
|  7 | xiaoting |
|  8 | outman   |
|  9 | outgirl  |
| 10 | two_inc1 |
| 11 | two_inc2 |
+----+----------+

到此為止,全量和后增加的增量數(shù)據(jù)就都回來了秀姐,但上述恢復(fù)還未涉及binlog恢復(fù)的情況慈迈,因此,在實(shí)際生產(chǎn)中僅僅用上述方法來恢復(fù)數(shù)據(jù)省有,得到的數(shù)據(jù)將是不完整的痒留,還需要進(jìn)行binlog文件的恢復(fù)才行。

7. 中小企業(yè)MySQL Xtrabackup物理增量恢復(fù)案例實(shí)戰(zhàn)

什么樣的條件才能完整地物理恢復(fù)數(shù)據(jù)庫(kù)數(shù)據(jù)蠢沿?

  • 具備全量備份(Xtrabackup備份的全備)
  • 具備全量之后的所有增量備份(Xtrabackup備份的增量)
  • 具備最后一次增量備份以后的所有MySQL的binlog增量日志

假設(shè)當(dāng)前數(shù)據(jù)庫(kù)內(nèi)的數(shù)據(jù)如下:

mysql> use oldboy
Database changed
mysql> truncate table test;
Query OK, 0 rows affected (0.05 sec)
mysql> insert into test values(1,'full01');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test values(2,'full02');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test values(3,'full03');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test values(4,'full04');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test values(5,'full05');
Query OK, 1 row affected (0.00 sec)
mysql> select * from test;
+----+--------+
| id | name   |
+----+--------+
|  1 | full01 |
|  2 | full02 |
|  3 | full03 |
|  4 | full04 |
|  5 | full05 |
+----+--------+
5 rows in set (0.00 sec)

先模擬5月3日0點(diǎn)開始對(duì)數(shù)據(jù)庫(kù)oldboy數(shù)據(jù)進(jìn)行全備:

[root@oldboy ~]# date -s "2019/05/03"
Fri May  3 00:00:00 CST 2019
[root@oldboy ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp /server/backup/new_base_full

然后模擬5月3日0點(diǎn)全備之后(0:00-24:00點(diǎn))用戶繼續(xù)寫入數(shù)據(jù):

[root@oldboy ~]# mysql -e "use oldboy;insert into test values(6,'new_inc_one_1');"
[root@oldboy ~]# mysql -e "use oldboy;insert into test values(7,'new_inc_one_2');"
[root@oldboy ~]# mysql -e "select * from oldboy.test;"
+----+---------------+
| id | name          |
+----+---------------+
|  1 | full01        |
|  2 | full02        |
|  3 | full03        |
|  4 | full04        |
|  5 | full05        |
|  6 | new_inc_one_1 |
|  7 | new_inc_one_2 |
+----+---------------+

之后伸头,在5月4日0點(diǎn)做增量備份(沒做全備):

[root@oldboy ~]# date -s "2019/05/04"
Sat May  4 00:00:00 CST 2019
[root@oldboy ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp --incremental-basedir=/server/backup/new_base_full/ --incremental /server/backup/new_one_inc

在5月4日0點(diǎn)增備之后(0:00-24:00)用戶繼續(xù)寫入數(shù)據(jù):

[root@oldboy ~]# mysql -e "use oldboy;insert into test values(8,'binlog_data_1');"
[root@oldboy ~]# mysql -e "use oldboy;insert into test values(9,'binlog_data_2');"
[root@oldboy ~]# mysql -e "select * from oldboy.test;"
+----+---------------+
| id | name          |
+----+---------------+
|  1 | full01        |
|  2 | full02        |
|  3 | full03        |
|  4 | full04        |
|  5 | full05        |
|  6 | new_inc_one_1 |
|  7 | new_inc_one_2 |
|  8 | binlog_data_1 |
|  9 | binlog_data_2 |
+----+---------------+

假設(shè)5月4日上午10:00點(diǎn)管理人員誤刪除了oldboy數(shù)據(jù)庫(kù):

[root@oldboy ~]# date -s "2019/05/04 10:00"
Sat May  4 10:00:00 CST 2019
[root@oldboy ~]# mysql -e "drop database oldboy;show databases;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| oldboy_utf8        |
| performance_schema |
+--------------------+

數(shù)據(jù)庫(kù)出問題10分鐘后,公司的網(wǎng)站運(yùn)營(yíng)人員報(bào)網(wǎng)站故障舷蟀,聯(lián)系運(yùn)維人員恤磷、DBA解決。此時(shí)野宜,DBA或開發(fā)人員會(huì)查看網(wǎng)站報(bào)錯(cuò)(或者查看后臺(tái)日志)扫步,可以看到連不上oldboy數(shù)據(jù)庫(kù)的提示,然后登陸數(shù)據(jù)庫(kù)排查匈子,發(fā)現(xiàn)數(shù)據(jù)庫(kù)oldboy已經(jīng)不存在了河胎。登陸系統(tǒng)分析系統(tǒng)審計(jì)日志,以及分析數(shù)據(jù)庫(kù)binlog也可以發(fā)現(xiàn)庫(kù)丟失的原因虎敦;開發(fā)人員通過程序日志判斷應(yīng)該也可以查出來原因游岳。
開始進(jìn)行恢復(fù)前的準(zhǔn)備:
1)移走所有binlog增量文件,防止被二次破壞

[root@oldboy ~]# cp -a /application/mysql/logs /server/backup/binlog

2)開始恢復(fù)數(shù)據(jù)前的增量備份和全備合并
先合并全備數(shù)據(jù)到新全備目錄原茅,即恢復(fù)第一天0點(diǎn)前的所有數(shù)據(jù):

[root@oldboy ~]# innobackupex --apply-log --use-memory=32M --redo-only /server/backup/new_base_full/

再合并增量數(shù)據(jù)到新全備目錄吭历,即恢復(fù)第二天0點(diǎn)前的所有數(shù)據(jù):

[root@oldboy ~]# innobackupex --apply-log --use-memory=32M --incremental-dir=/server/backup/new_one_inc/ /server/backup/new_base_full/

最后應(yīng)用所有redo日志,并回滾未提交的數(shù)據(jù):

[root@oldboy ~]# innobackupex --apply-log --use-memory=32M /server/backup/new_base_full/

3)開始恢復(fù)binlog日志數(shù)據(jù)
由于5月4日0點(diǎn)之后的所有數(shù)據(jù)并不在全備里擂橘,也不在增量里晌区,而是在MySQL的binlog日志里,因此還要進(jìn)行如下操作來完成恢復(fù)通贞。
首先查看5月4日0點(diǎn)最后一次增量的binlog位置信息:

[root@oldboy ~]# cat /server/backup/new_one_inc/xtrabackup_binlog_info 
oldboy-bin.000003   1820

這個(gè)位置信息以后的binlog才是我們需要的朗若,以前的數(shù)據(jù)在Xtrabackup的全量和增量里已經(jīng)有了,然后查看問題出現(xiàn)后第一時(shí)間備份的binlog文件信息:

[root@oldboy ~]# ll /server/backup/binlog/oldboy-bin.*
-rw-rw----. 1 mysql mysql  143 Apr 27 21:16 /server/backup/binlog/oldboy-bin.000001
-rw-rw----. 1 mysql mysql 1951 Apr 27 23:17 /server/backup/binlog/oldboy-bin.000002
-rw-rw----. 1 mysql mysql 2386 May  4 10:00 /server/backup/binlog/oldboy-bin.000003
-rw-rw----. 1 mysql mysql  126 Apr 27 23:21 /server/backup/binlog/oldboy-bin.index

從上面的信息可知昌罩,需要使用的binlog文件為oldboy-bin.000003哭懈。(因?yàn)樽詈竺婢褪莖ldboy-bin.000003了)
現(xiàn)在從oldboy-bin.000003文件的1820位置點(diǎn)開始恢復(fù)增量數(shù)據(jù):

[root@oldboy binlog]# mysqlbinlog -d oldboy oldboy-bin.000003 --start-position=1820 -r bin.sql

這里要剔除誤刪除數(shù)據(jù)庫(kù)的drop語(yǔ)句,否則茎用,直接恢復(fù)就又進(jìn)入了刪庫(kù)故障的坑:

[root@oldboy binlog]# grep -w drop bin.sql     ---找出誤刪除數(shù)據(jù)庫(kù)的語(yǔ)句
drop database oldboy
[root@oldboy binlog]# sed -i '/drop database oldboy/d' bin.sql     ---剔除誤刪除數(shù)據(jù)庫(kù)的drop語(yǔ)句
[root@oldboy binlog]# grep -w drop bin.sql

需要注意的是遣总,本案例是刪除數(shù)據(jù)庫(kù)了睬罗,因此binlog日志就不再增長(zhǎng)了,所以可以利用上文第一時(shí)間備份的binlog恢復(fù)旭斥,如果是update操作誤改了數(shù)據(jù)又沒有停庫(kù)容达,那么,此時(shí)最好是在數(shù)據(jù)庫(kù)服務(wù)器上用Iptables控制應(yīng)用程序連接數(shù)據(jù)庫(kù)之后垂券,再?gòu)纳鲜鯾inlog位置點(diǎn)開始讀取正式日志目錄下的所有binlog日志花盐,一直將Iptables限制訪問時(shí)的所有binlog日志恢復(fù)完。
下面開始正式恢復(fù)數(shù)據(jù)庫(kù)數(shù)據(jù)菇爪。
1)停止數(shù)據(jù)庫(kù)對(duì)外訪問算芯。因?yàn)槭鞘褂胐rop命令刪除庫(kù),而且后面不會(huì)有寫入了凳宙,所以可以不用額外停止寫入熙揍,但如果是update導(dǎo)致的數(shù)據(jù)破壞,那么最好是在發(fā)現(xiàn)問題的第一時(shí)間就進(jìn)行停庫(kù)處理或?qū)ν馔V箤懭搿?/p>

[root@oldboy ~]# iptables -I INPUT -p tcp --dport 3306 ! -s 192.168.9.115 -j DROP    ---非192.168.9.115禁止訪問數(shù)據(jù)庫(kù)3306端口

2)恢復(fù)處理好的Xtrabackup備份的全量及增量數(shù)據(jù):

[root@oldboy ~]# /etc/init.d/mysqld stop    ---恢復(fù)時(shí)要停庫(kù)
Shutting down MySQL.. SUCCESS! 
[root@oldboy ~]# ss -lnt | grep 3306
[root@oldboy ~]# mv /application/mysql/data /tmp/data3    ---移走舊的數(shù)據(jù)
[root@oldboy ~]# mkdir -p /application/mysql/data    ---原始數(shù)據(jù)目錄要為空
[root@oldboy ~]# mv /server/backup/new_base_full/* /application/mysql/data/
---采用mv氏涩,而不是xtrabackup的--copy-back參數(shù)還原诈嘿,使用mv的時(shí)候,前文的MySQL配置就可以采用了
[root@oldboy ~]# chown -R mysql.mysql /application/mysql/data/    ---重新授權(quán)
[root@oldboy ~]# /etc/init.d/mysqld start
Starting MySQL.. SUCCESS! 
[root@oldboy ~]# mysql -e "select * from oldboy.test;"
+----+---------------+
| id | name          |
+----+---------------+
|  1 | full01        |
|  2 | full02        |
|  3 | full03        |
|  4 | full04        |
|  5 | full05        |
|  6 | new_inc_one_1 |
|  7 | new_inc_one_2 |
+----+---------------+

到此削葱,使用Xtrabackup備份的到5月3日的全備數(shù)據(jù)和5月4日0點(diǎn)之前增量備份的數(shù)據(jù)都回來了。
接下來開始恢復(fù)5月4日0點(diǎn)到10點(diǎn)的數(shù)據(jù)庫(kù)數(shù)據(jù)淳梦。
這時(shí)需要恢復(fù)binlog數(shù)據(jù)析砸,即從binlog解析出數(shù)據(jù)并且清理了drop語(yǔ)句的bin.sql文件:

[root@oldboy ~]# cd /server/backup/binlog/
[root@oldboy binlog]# mysql oldboy < bin.sql 
[root@oldboy binlog]# mysql -e "select * from oldboy.test;"
+----+---------------+
| id | name          |
+----+---------------+
|  1 | full01        |
|  2 | full02        |
|  3 | full03        |
|  4 | full04        |
|  5 | full05        |
|  6 | new_inc_one_1 |
|  7 | new_inc_one_2 |
|  8 | binlog_data_1 |    ---binlog里記錄的數(shù)據(jù)回來了
|  9 | binlog_data_2 |
+----+---------------+

到此,恢復(fù)完畢爆袍。

8. 使用Xtrabackup物理分庫(kù)分表備份

使用Xtrabackup物理分庫(kù)分表備份的前提是開啟獨(dú)立表空間模式首繁,即設(shè)置innodb_file_per_table=On,MySQL5.6默認(rèn)已經(jīng)開啟了此模式陨囊。
1)備份單個(gè)庫(kù)oldboy:

[root@oldboy binlog]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp --database="oldboy" /server/backup/oldboy_full
[root@oldboy binlog]# ll /server/backup/oldboy_full/
total 77860
-rw-r-----. 1 root root      418 May  4 12:52 backup-my.cnf
-rw-r-----. 1 root root 79691776 May  4 12:52 ibdata1
drwxr-x---. 2 root root     4096 May  4 12:52 mysql
drwxr-x---. 2 root root     4096 May  4 12:52 oldboy
drwxr-x---. 2 root root     4096 May  4 12:52 oldboy_utf8
drwxr-x---. 2 root root     4096 May  4 12:52 performance_schema
-rw-r-----. 1 root root       22 May  4 12:52 xtrabackup_binlog_info
-rw-r-----. 1 root root      113 May  4 12:52 xtrabackup_checkpoints
-rw-r-----. 1 root root      593 May  4 12:52 xtrabackup_info
-rw-r-----. 1 root root     2560 May  4 12:52 xtrabackup_logfile

2)備份多個(gè)庫(kù):

[root@oldboy binlog]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp --databases="oldboy oldgirl" /server/backup/oldboy_oldgirl
[root@oldboy binlog]# ll /server/backup/oldboy_oldgirl/
total 77848
-rw-r-----. 1 root root      418 May  4 12:55 backup-my.cnf
-rw-r-----. 1 root root 79691776 May  4 12:55 ibdata1
drwxr-x---. 2 root root     4096 May  4 12:55 oldboy
drwxr-x---. 2 root root     4096 May  4 12:55 oldgirl
-rw-r-----. 1 root root       22 May  4 12:55 xtrabackup_binlog_info
-rw-r-----. 1 root root      113 May  4 12:55 xtrabackup_checkpoints
-rw-r-----. 1 root root      606 May  4 12:55 xtrabackup_info
-rw-r-----. 1 root root     2560 May  4 12:55 xtrabackup_logfile

3)備份單個(gè)表:

[root@oldboy binlog]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp --databases="oldboy.test" /server/backup/oldboy_test

4)備份多個(gè)庫(kù)的多個(gè)表:

[root@oldboy binlog]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp --databases="oldboy.test oldboy.student" /server/backup/oldboy_test_student
[root@oldboy binlog]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.41/tmp/mysql.sock --no-timestamp --databases="oldboy.test oldboy.student mysql.user" /server/backup/all

9. 使用Xtrabackup物理分庫(kù)分表備份的恢復(fù)

在使用Xtrabackup物理分庫(kù)分表備份的恢復(fù)時(shí)弦疮,需要使用“--export”來做恢復(fù)準(zhǔn)備,最終恢復(fù)時(shí)蜘醋,不能使用常規(guī)的“--copy-back”選項(xiàng)胁塞,而是要初始化一個(gè)帶有mysql庫(kù)(“mysql_install_db --user=mysql”)的干凈的數(shù)據(jù)文件目錄。
1)恢復(fù)準(zhǔn)備

[root@oldboy binlog]# innobackupex --apply-log --export /server/backup/oldboy_test/    ---恢復(fù)oldboy的test表

2)初始化數(shù)據(jù)庫(kù)(這里為了方便压语,直接在當(dāng)前環(huán)境測(cè)試)

[root@oldboy binlog]# /etc/init.d/mysqld stop 
Shutting down MySQL.. SUCCESS! 
[root@oldboy binlog]# mv /application/mysql/data /tmp/data.ori    ---備份前面的數(shù)據(jù)
[root@oldboy binlog]# mkdir /application/mysql/data
[root@oldboy binlog]# /application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/application/mysql/data --user=mysql    ---初始化新的mysql數(shù)據(jù)文件
[root@oldboy binlog]# cp /server/backup/oldboy_test/* /application/mysql/data/
[root@oldboy binlog]# chown -R mysql.mysql /application/mysql/data
[root@oldboy binlog]# /etc/init.d/mysqld start
Starting MySQL. SUCCESS!
mysql> select * from oldboy.test;    ---查看還原的數(shù)據(jù)
+----+---------------+
| id | name          |
+----+---------------+
|  1 | full01        |
|  2 | full02        |
|  3 | full03        |
|  4 | full04        |
|  5 | full05        |
|  6 | new_inc_one_1 |
|  7 | new_inc_one_2 |
|  8 | binlog_data_1 |
|  9 | binlog_data_2 |
+----+---------------+
9 rows in set (0.00 sec)

如果有需要啸罢,可以通過mysqldump導(dǎo)出后恢復(fù)到正式庫(kù)
最后把當(dāng)前的環(huán)境恢復(fù)回來:

[root@oldboy binlog]# /etc/init.d/mysqld stop
Shutting down MySQL.. SUCCESS! 
[root@oldboy binlog]# mv /application/mysql/data /opt/data.new
[root@oldboy binlog]# mv /tmp/data.ori /application/mysql/data
[root@oldboy binlog]# chown -R mysql.mysql /application/mysql/data
[root@oldboy binlog]# /etc/init.d/mysqld start
Starting MySQL. SUCCESS! 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市胎食,隨后出現(xiàn)的幾起案子扰才,更是在濱河造成了極大的恐慌,老刑警劉巖厕怜,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衩匣,死亡現(xiàn)場(chǎng)離奇詭異蕾总,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)琅捏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門生百,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人午绳,你說我怎么就攤上這事置侍。” “怎么了拦焚?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵蜡坊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我赎败,道長(zhǎng)秕衙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任僵刮,我火速辦了婚禮据忘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搞糕。我一直安慰自己勇吊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布窍仰。 她就那樣靜靜地躺著汉规,像睡著了一般。 火紅的嫁衣襯著肌膚如雪驹吮。 梳的紋絲不亂的頭發(fā)上针史,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音碟狞,去河邊找鬼啄枕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛族沃,可吹牛的內(nèi)容都是我干的频祝。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼脆淹,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼智润!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起未辆,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤窟绷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后咐柜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兼蜈,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡攘残,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了为狸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歼郭。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖辐棒,靈堂內(nèi)的尸體忽然破棺而出病曾,到底是詐尸還是另有隱情,我是刑警寧澤漾根,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布泰涂,位于F島的核電站,受9級(jí)特大地震影響辐怕,放射性物質(zhì)發(fā)生泄漏逼蒙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一寄疏、第九天 我趴在偏房一處隱蔽的房頂上張望是牢。 院中可真熱鬧,春花似錦陕截、人聲如沸驳棱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蹈胡。三九已至,卻和暖如春朋蔫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背却汉。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工驯妄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人合砂。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓青扔,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親翩伪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子微猖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容