Mysql/Mariadb備份(xtrabackup)還原實戰

1、概述

以前的文章說到mysql的安裝與mysql的基本使用;本文是後續補充,主要說明針對mysql或mariadb的備份與還原;衆所周知,數據是重中之重,所以平時對企業數據須要作備份,當數據系統崩潰,數據丟失異常時,才能依據備份文件進行恢復!
本次的環境:
CentOS7.4_x64 , mysql5.7.21, xtrabackup
mysql的安裝配置可參考以前系列文章;只補充相關配置項的開啓;以及xtrabackup安裝使用;
用到的演示數據導入mysql數據庫html

[root@db ~]# mysql -uroot -predhat < testdb.sql
或
mysql> source   testdb.sql
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| example            |
| mysql              |
| performance_schema |
| study              |
| sys                |
以上study即爲測試數據庫包含如下測試表

mysql> show tables;
+-----------------+
| Tables_in_study |
+-----------------+
| class           |
| course          |
| part            |
| score           |
| student         |
| tb31            |
| tb32            |
| teacher         |
| test1           |
| test2           |
| user_info       |
+-----------------+

測試數據庫及數據表準備完成,在進行數據的備份與恢復前,咱們先簡單瞭解下數據庫備份與恢復的相關概念原理;mysql

關於數據庫的備份與還原
爲何備份?
主要是爲了災難恢復如:硬件故障(冗餘)、軟件故障(bug)、天然災害、******、誤操做、以及測試須要導出數據等;
還原或叫恢復時即基於以往的備份文件;
備份類型
全量備份、增量備份、差別備份:
徹底備份: 備份數據的副本(某時間點);
增量備份:僅備份自上一次徹底備份或 增量備份以來變量的那部數據;
差別備份:僅備份自上一次徹底備份以來變量的那部數據;sql

物理備份、邏輯備份:
物理備份:複製數據文件進行的備份;
邏輯備份:從數據庫導出數據另存在一個或多個文件中;數據庫

根據數據服務是否在線:
熱備:讀寫操做都可進行的狀態下所作的備份;
溫備:可讀但不可寫狀態下進行的備份;
冷備:讀寫操做均不可進行的狀態下所作的備份
以上的各備份類型備份執行時只能備份數據在備份時的狀態,如想要恢復數據庫崩潰那一刻的狀態,須要打開binary log功能,須要基於備份的數據+binary log來恢復到數據崩潰前一刻的狀態;
備份的工具備mysqldump(溫備,不適合大型數據的在線備份),xtrabackup(支持對InnoDB熱備,開源專業的備份數據,支持mysql/mariadb)本文將經過mysqldump與xtrabackup來講明數據的備份與恢復(異地);centos

不管那種工具有份,在恢復時均要binary log才能恢復到崩潰前的狀態;所以須要配置數據庫開啓binary log功能;如下能mysql5.7.21服務器

#cat /usr/local/mysql/etc/my.cnf
server-id       = 1
log_bin         = /data1/mysqldb/mysql-bin.log

2、mysqldump備份與恢復

mysqldump使用說明
單進程邏輯備份、徹底備份、部分備份;session

Usage: 
mysqldump [OPTIONS] database [tables]
         OR     mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
         OR     mysqldump [OPTIONS] --all-databases [OPTIONS]

mysqldump mydb:表級別備份(還原時庫須要存在)
mysqldump --databases mydb:庫級別備份(庫不在會自行建立庫)

MyISAM存儲引擎:支持溫備,備份時要鎖定表;
         -x, --lock-all-tables:鎖定全部庫的全部表,讀鎖;
         -l, --lock-tables:鎖定指定庫全部表;

InnoDB存儲引擎:支持溫備和熱備;
         -x, --lock-all-tables:鎖定全部庫的全部表,讀鎖;
         -l, --lock-tables:鎖定指定庫全部表;
        --single-transaction:建立一個事務,基於此快照執行備份;
                -R, --routines:存儲過程和存儲函數;
                --triggers      觸發器
                -E, --events      事件

                 --master-data[=#]
                        1:記錄爲CHANGE MASTER TO語句,此語句不被註釋;
                        2:記錄爲CHANGE MASTER TO語句,此語句被註釋;

                --flush-logs:鎖定表完成後,即進行日誌刷新操做(從新生成binlog日誌);

基於mysqldump備份study數據庫app

熱備,備份存儲過程和存儲函數,事件,並記得下事件位置;(便於從binlog中的位置開始恢復到故障前)
#mysqldump -uroot -predhat --single-transaction  -R -E --triggers --master-data=2 --databases study >/home/san/studydb.sql

說明:
less studydb.sql
會看到如下內容less

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=154;

這就是--master-data=2 選項做用,註釋了,binary log 點在154
模擬備份後數據修改操做ide

修改前的:
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   1 | san   |   20 | 男     |        1 |
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  10 | e     |   22 | 男     |        3 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
+-----+-------+------+--------+----------+
11 rows in set (0.00 sec)
增長一條:
mysql> insert into user_info values(13,'hi',18,'男',4);
Query OK, 1 row affected (0.03 sec)
刪除一條:
mysql> delete  from user_info where nid=1;
Query OK, 1 row affected (0.01 sec)
最終在上次備份後user_info數據以下:
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  10 | e     |   22 | 男     |        3 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
|  13 | hi    |   18 | 男     |        4 |
+-----+-------+------+--------+----------+
11 rows in set (0.00 sec)
能夠看出少了一條,加了一條;

模擬數據庫損壞並恢復study數據庫
關閉mysql併到數據目錄刪除study數據庫;

假設發現study數據已經丟失了;
數據庫運行正常;查看binlog位置
mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       815 |
| mysql-bin.000002 |       177 |
| mysql-bin.000003 |       177 |
| mysql-bin.000004 |   1890875 |
| mysql-bin.000005 |       725 |
+------------------+-----------+
記住這裏最後一個binlog文件及位置是mysql-bin.000005   725
結合上面備份文件中的-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=154; 能夠分析出備份時位置是154而數據庫丟失前是725
所以咱們恢復study數據庫裏須要恢復上次的全備+加mysql-bin.000005中的154-725內容;

模擬study丟失過程(傳說潰的刪庫路)
[root@db mysqldb]# service stop mysqld
[root@db mysqldb]# pwd
/data1/mysqldb
[root@db mysqldb]# rm -rf  study/
啓動數據庫
[root@db mysqldb]# service stop mysqld
登陸數據庫並查看發現study數據庫已經丟失了

還原數據庫

mysql -uroot -predhat < studydb.sql
mysql> show databases;
可發現已經恢復;可是以前完整備份的到崩潰前的修改不見了;以下:
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   1 | san   |   20 | 男     |        1 |
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  10 | e     |   22 | 男     |        3 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
+-----+-------+------+--------+----------+
11 rows in set (0.00 sec)

結合binlog恢復:

從binlog上導出sql文件
[root@db mysqldb]# mysqlbinlog mysql-bin.000005 >/root/binlog.sql
登陸mysql恢復
恢復過程當中臨時關閉binlog記錄
mysql> set @@session.sql_log_bin=OFF;
mysql> source binlog.sql;
Query OK, 0 rows affected (0.00 sec

mysql> set @@session.sql_log_bin=ON;
mysql> use study; 
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  10 | e     |   22 | 男     |        3 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
|  13 | hi    |   18 | 男     |        4 |
+-----+-------+------+--------+----------+
11 rows in set (0.00 sec)

能夠看出study數據庫已經恢復到崩潰損壞前的狀態;另外徹底 能夠新準備一臺數據庫服務器;把sql轉移到新機器上恢復;前提數據配置參數須要同樣;

3、xtrabackup備份與恢復

xtrabackup簡介
xtrabackup是Percona一款開源工具,支持innodb,Xtradb(mariadb)引擎數據庫的熱備;
對MyISAM:溫備,不支持增量備份;InnoDB:熱備,增量;
物理備份,速率快、可靠;備份完成後自動校驗備份結果集是否可用;還原速度快
功能介紹與Innobackup(mysql企業版收費)對比參考官網
所數據庫引擎請使用innodb引擎

xtrabackup安裝與使用說明

安裝
[官方下載地址](https://www.percona.com/downloads/XtraBackup/LATEST/)
本次使用percona-xtrabackup-24-2.4.8-1
[root@db ~]# wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.8/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.8-1.el7.x86_64.rpm
[root@db ~]# yum install ./percona-xtrabackup-24-2.4.8-1.el7.x86_64.rpm -y

**獲取幫助與使用:**
能夠經過man  xtrabackup 獲取詳細使用說明與實例
Usage: 
 innobackupex [--defaults-file=#] --backup | innobackupex [--defaults-file=#] --prepare] [OPTIONS]
 備份用到的主要選項:
    --defaults-file=     #mysql或mariadb配置文件
        --user=                  #備份時使用的用戶(對備份的數據庫有備份權限)
        --password=         #備份用戶密碼
        -H | --host=            #localhost或遠程主機

**恢復時到的主要選項:**
        --apply-log         #分析獲取binary log文件生成backup_binlog_info文件
        ---copy-back      #基於backup_binlog_info等文件恢復
注:innobackupex是xtrabackup的軟件連接;

xtrabackup全備與恢復:
注意:備份時數據庫是在線狀態;恢復時須要離線而且mysql數據目錄爲空;
備份:

建立備份目錄 
mkdir -pv /data/backup
建立備份受權帳號root(能夠是其餘用戶最小權限)
mysql> GRANT ALL ON *.* TO 'root'@'127.0.0.1' identified by "redhat";
Query OK, 0 rows affected, 1 warning (0.00 sec)

[root@db mysqldb]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --user=root --password=redhat  --host=127.0.0.1 /data/backup
看到相似以下信息表示備份成功:
xtrabackup: Transaction log of lsn (7701576) to (7701585) was copied.
180401 11:52:35 completed OK!
同時在/data/backup目錄中產生以時間爲目錄的備份目錄
[root@db backup]# ll /data/backup/
drwxr-x--- 14 root root 4096 4月   1 11:52 2018-04-01_11-52-29

備份後對數據庫study 中的表進行修改

刪除student表
mysql> drop table student;
Query OK, 0 rows affected (0.04 sec)
往user_info表中插入兩行
mysql> insert into user_info values(1,"san",18,"男",4),(14,"Hello",28,"女",2);
Query OK, 1 row affected (0.00 sec)

模擬數據庫崩潰

注意binlog文件備份好;若是binglog和數據目錄在一塊兒
[root@db backup]# service mysqld stop
[root@db backup]# rm -rf /data1/mysqldb/*

恢復數據:

切換到備份數據目錄
[root@db backup]# cd /data/backup/2018-04-01_11-52-29
事務回滾不提交
[root@db 2018-04-01_11-52-29]# innobackupex  --defaults-file=/usr/local/mysql/etc/my.cnf --apply-log ./
相似如下提示表示完成:
InnoDB: Shutdown completed; log sequence number 7702056
180401 12:13:40 completed OK!

數據還原

因爲centos7默認有/etc/my.cnf文件
所以須要重命名my.cnf或移除以避免影響恢復;
[root@db 2018-04-01_11-52-29]# innobackupex  --defaults-file=/usr/local/mysql/etc/my.cnf --copy-back ./
相似如下提示表示恢復完成:
180401 12:16:15 [01]        ...done
180401 12:16:15 completed OK!

恢復binlog中信息
查看全備中的binlog信息(文件和位置)

[root@db backup]# cat /data/backup/2018-04-01_11-52-29/xtrabackup_binlog_info
mysql-bin.000008        14775
由引可知在上次全備時的binglog文件是mysql-bin.000008位置爲14775
獲取binlog信息
[root@db backup]# mysqlbinlog -j 14775 mysql-bin.000008 >/data/backup/binlog.sql
還原binlog中的內容(全備後的修改數據內容)
切換到mysql數據目錄(/data1/mysqldb)並修改權限
[root@db mysqldb]# cd /data1/mysqldb
[root@db mysqldb]# chown mysql.mysql *  -R
啓動mysql
[root@db mysqldb]# service mysqld start

登陸數據庫並導入binlog.sql

mysql> source /data/backup/binlog.sql
Query OK, 0 rows affected (0.00 sec)

mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   1 | san   |   18 | 男     |        4 |
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  10 | e     |   22 | 男     |        3 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
|  13 | hi    |   18 | 男     |        4 |
|  14 | Hello |   28 | 女     |        2 |
+-----+-------+------+--------+----------+
13 rows in set (0.00 sec)

xtrabackup 增量備份與恢復
備份流程:
首次增量備份是基於完整備份後作的增量備份 ,後面的增量備份將基於前一次增量備份;
恢復流程:
合併完整備份事務 -->再合併第一次增量的事務-->....最後一次增量備份 +binlog日誌

完整備份:

[root@db ~# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --user=root --password=redhat  --host=127.0.0.1 /data/backup
提示相似以下信息完成 :
xtrabackup: Transaction log of lsn (7802468) to (7802477) was copied.
180401 13:13:13 completed OK!
[root@db ~# ll /data/backup
2018-04-01_13-13-10    ######完整備份目錄

模擬數據庫的修改操做

刪除第10行並新增一行
mysql> delete from user_info where nid=10;
Query OK, 1 row affected (0.01 sec)

mysql> insert into user_info value(15,'hehe',22,'男',1);
Query OK, 1 row affected (0.01 sec)

第一次增量備份

[root@db ~# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --incremental --user=root --password=redhat  --host=127.0.0.1 /data/backup/ --incremental-basedir=/data/backup/2018-04-01_13-13-10/
提示相似以下信息完成 :
xtrabackup: Transaction log of lsn (7803424) to (7803433) was copied.
180401 13:17:26 completed OK!

再次模擬數據庫的修改操做

mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   1 | san   |   18 | 男     |        4 |
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
|  13 | hi    |   18 | 男     |        4 |
|  14 | Hello |   28 | 女     |        2 |
|  15 | hehe  |   22 | 男     |        1 |
+-----+-------+------+--------+----------+
13 rows in set (0.01 sec)
插入一行再刪除一行
mysql> insert into user_info value(16,'haha',21,'女',3);
Query OK, 1 row affected (0.01 sec)

mysql> delete from user_info where nid=2;
Query OK, 1 row affected (0.01 sec)
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   1 | san   |   18 | 男     |        4 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
|  13 | hi    |   18 | 男     |        4 |
|  14 | Hello |   28 | 女     |        2 |
|  15 | hehe  |   22 | 男     |        1 |
|  16 | haha  |   21 | 女     |        3 |
+-----+-------+------+--------+----------+
13 rows in set (0.00 sec)

第二次增量備份:

[root@db backup]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --incremental --user=root --password=redhat  --host=127.0.0.1 /data/backup/ --incremental-basedir=/data/backup/2018-04-01_13-17-21/
注意:這裏的 --incremental-basedir=/data/backup/2018-04-01_13-17-21/ 是上一次增量備份 產生的備份 目錄 
若是基於第一次完整備份 則成爲差別備份

找出最近一次增量備份的binlog文件及信息

cd /data/backup/2018-04-01_13-21-56
[root@db 2018-04-01_13-21-56]# cat xtrabackup_binlog_info 
mysql-bin.000001    17452
備份 mysql-bin.000001 到/data/backup中
[root@db backup]# cd /data/backup
[root@db backup]# cp /data1/mysqldb/mysql-bin.000001 .
[root@db backup]# mysqlbinlog mysql-bin.000001 >binlog.sql

模擬數據庫崩潰數據丟失

[root@db backup]# service mysqld stop
[root@db backup]# rm -rf /data1/mysqldb/*

數據恢復

[root@n1 backup]# ls
2018-04-01_13-13-10     2018-04-01_13-17-21    2018-04-01_13-21-56     binlog.sql    mysql-bin.000001

依次是徹底整備份 ,第一次和第二次增量備份 目錄 ,以及備份出來的binlog文件與binlog.sql
恢復過程:
首先對第1個(完整備份)合併只提交事務不回滾 再把第2個目錄合併提交事務不回滾到第一個,再把第3個合併到第1箇中;最後作一次回滾,再作統一事務提交;最後再加binlog恢復

完整備份 的事務合併
[root@db backup]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --apply-log --redo-only 2018-04-01_13-13-10/
合併第一次增量事務
[root@db backup]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --apply-log --redo-only 2018-04-01_13-13-10/ --incremental-dir=2018-04-01_13-17-21/
合併第二次增量事務
[root@db backup]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --apply-log --redo-only 2018-04-01_13-13-10/ --incremental-dir=2018-04-01_13-21-56/
合併全部的事務
[root@db backup]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf  --apply-log 2018-04-01_13-13-10/
提交還原事務
[root@db backup] innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf  --copy-back 2018-04-01_13-13-10/

修改還原數據權限與啓動數據庫:

[root@db backup]chown mysq.mysql /data1/mysqldb -R
[root@db backup] systemctl start mysqld

binlog事務恢復
mysql> source /data/backup/binlog.sql
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name | age | gender | part_nid |
+-----+-------+------+--------+----------+
| 1 | san | 18 | 男 | 4 |
| 4 | Ling | 28 | 男 | 4 |
| 5 | ling | 28 | 男 | 3 |
| 6 | dong | 30 | 男 | 1 |
| 7 | b | 11 | 女 | 1 |
| 8 | c | 12 | 女 | 1 |
| 9 | d | 18 | 女 | 4 |
| 11 | f | 23 | 男 | 2 |
| 12 | dongy | 22 | 男 | 1 |
| 13 | hi | 18 | 男 | 4 |
| 14 | Hello | 28 | 女 | 2 |
| 15 | hehe | 22 | 男 | 1 |
| 16 | haha | 21 | 女 | 3 |
+-----+-------+------+--------+----------+
13 rows in set (0.00 sec)

到此增量備份 與恢復 已經 完成!

總結:

平常數據庫的備份是十分有必要的,並且無論用什麼方法恢復,開啓binary log十分重要,不然恢復不完整;binary log最好不要和數據目錄一塊兒,另外建議數據目錄和binary log所在目錄不要放在同一塊物理磁盤;同時須要計劃備份並實現異地備份;這樣出現刪庫跑或崩潰數據丟失時就不怕了!本文不少步驟,可能存在遺漏之處,若有錯誤之處,歡迎指點;

相關文章
相關標籤/搜索