以前的文章說到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
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轉移到新機器上恢復;前提數據配置參數須要同樣;
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所在目錄不要放在同一塊物理磁盤;同時須要計劃備份並實現異地備份;這樣出現刪庫跑或崩潰數據丟失時就不怕了!本文不少步驟,可能存在遺漏之處,若有錯誤之處,歡迎指點;