Mysql/Mariadb備份(xtrabackup)還原實戰
之前的文章說到mysql的安裝與mysql的基本使用;本文是後續補充,主要說明針對mysql或mariadb的備份與還原;眾所周知,數據是重中之重,因此平時對企業數據需要做備份,當數據系統崩潰,數據丟失異常時,才能依據備份文件進行恢復!
本次的環境:
CentOS7.4_x64 , mysql5.7.21, xtrabackup
mysql的安裝配置可參考之前系列文章;只補充相關配置項的開啟;以及xtrabackup安裝使用;
用到的演示數據導入mysql數據庫
[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 | +-----------------+
測試數據庫及數據表準備完成,在進行數據的備份與恢復前,我們先簡單了解下數據庫備份與恢復的相關概念原理;
關於數據庫的備份與還原
為什麽備份?
主要是為了災難恢復如:硬件故障(冗余)、軟件故障(bug)、自然災害、黑客攻擊、誤操作、以及測試需要導出數據等;
還原或叫恢復時即基於以往的備份文件;
備份類型
全量備份、增量備份、差異備份:
完全備份: 備份數據的副本(某時間點);
增量備份:僅備份自上一次完全備份或 增量備份以來變量的那部數據;
差異備份:僅備份自上一次完全備份以來變量的那部數據;
物理備份、邏輯備份:
物理備份:復制數據文件進行的備份;
邏輯備份:從數據庫導出數據另存在一個或多個文件中;
根據數據服務是否在線:
溫備:可讀但不可寫狀態下進行的備份;
冷備:讀寫操作均不可進行的狀態下所做的備份
以上的各備份類型備份執行時只能備份數據在備份時的狀態,如想要恢復數據庫崩潰那一刻的狀態,需要打開binary log功能,需要基於備份的數據+binary log來恢復到數據崩潰前一刻的狀態;
備份的工具有mysqldump(溫備,不適合大型數據的在線備份),xtrabackup(支持對InnoDB熱備,開源專業的備份數據,支持mysql/mariadb)本文將通過mysqldump與xtrabackup來說明數據的備份與恢復(異地);
無論那種工具備份,在恢復時均要binary log才能恢復到崩潰前的狀態;因此需要配置數據庫開啟binary log功能;以下能mysql5.7.21
#cat /usr/local/mysql/etc/my.cnf
server-id = 1
log_bin = /data1/mysqldb/mysql-bin.log
二、mysqldump備份與恢復
mysqldump使用說明
單進程邏輯備份、完全備份、部分備份;
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數據庫
熱備,備份存儲過程和存儲函數,事件,並記得下事件位置;(便於從binlog中的位置開始恢復到故障前)
#mysqldump -uroot -predhat --single-transaction -R -E --triggers --master-data=2 --databases study >/home/san/studydb.sql
說明:
less studydb.sql
會看到以下內容
-- CHANGE MASTER TO MASTER_LOG_FILE=‘mysql-bin.000005‘, MASTER_LOG_POS=154;
這就是--master-data=2 選項作用,註釋了,binary log 點在154
模擬備份後數據修改操作
修改前的:
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轉移到新機器上恢復;前提數據配置參數需要一樣;
三、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所在目錄不要放在同一塊物理磁盤;同時需要計劃備份並實現異地備份;這樣出現刪庫跑或崩潰數據丟失時就不怕了!本文很多步驟,可能存在遺漏之處,如有錯誤之處,歡迎指點;
Mysql/Mariadb備份(xtrabackup)還原實戰