MySQL基礎(十三):備份與恢復

一、備份類型

1. 熱備
	在數據庫正常業務時,備份數據,並且能夠一致性恢復(只能是innodb)對業務影響非常小
2. 溫備
鎖表備份,只能查詢不能修改(myisam)影響到寫入操作
3. 冷備
關閉數據庫業務,數據庫沒有任何變更的情況下,進行備份數據.業務停止

二、備份方式及工具介紹

不管哪種備份方式,都需要開啓binlog日誌!開啓方式見:
https://blog.csdn.net/weixin_44571270/article/details/103148755

1、備份工具

1. 邏輯備份工具
		基於SQL語句進行備份
		mysqldump
		mysqlbinlog
2. 物理備份工具
		基於磁盤數據文件備份
		xtrabackup(XBK) :percona 第三方
		MySQL Enterprise Backup(MEB)

下面講解我們主要學習,邏輯備份工具mysqldump、物理備份工具xtrabackup以及無論那個必用的mysqlbinlog增量恢復

2、邏輯備份和物理備份的比較

(1)mysqldump (MDP)
優點:
	(1)不需要下載安裝
	(2)備份出來的是SQL,文本格式,可讀性高,便於備份處理
	(3)壓縮比較高,節省備份的磁盤空間
缺點:
	依賴於數據庫引擎,需要從磁盤把數據讀出,然後轉換成SQL進行轉儲,比較耗費資源,數據量大的話效率較低
建議:
	(1)100G以內的數據量級,可以使用mysqldump
	(2)超過TB以上,我們也可能選擇的是mysqldump,配合分佈式的系統
	1EB  =1024 PB =1000000 TB
(2)xtrabackup(XBK)
優點:
	(1)類似於直接cp數據文件,不需要管邏輯結構,相對來說性能較高
缺點:
	(2)可讀性差
	(3)壓縮比低,需要更多磁盤空間
建議:
	>100G<TB

3、備份策略

備份方式:
	全備:全庫備份,備份所有數據
	增量:備份變化的數據,只在物理備份中有
備份週期:
	根據數據量設計備份週期
	比如:週日全備,周1-6增量
邏輯備份=mysqldump+mysqlbinlog
物理備份=xtrabackup_full+xtrabackup_incr+binlog 或者 xtrabackup_full+binlog

三、mysqldump的使用

首先學一個命令,我們先要研究它參數的意義!mysqldump命令分爲連接參數與備份專用參數兩部分!

1、連接參數

-u  -p   -S   -h  -P    
本地備份: mysqldump -uroot -p  -S /tmp/mysql.sock
遠程備份: mysqldump -uroot -p  -h 10.0.0.51 -P3306 -S /tmp/mysql.sock

2、備份專用參數

(1)-A 全備參數

注:備份所有庫!

mysqldump -uroot -p -A >/data/backup/full.sql
# 補充:
# 1.常規備份是要加 --set-gtid-purged=OFF,解決備份時的警告
# [root@db01 ~]# mysqldump -uroot -p123 -A  --set-gtid-purged=OFF  >/backup/full.sql
# 2.構建主從時,做的備份,不需要加這個參數
# [root@db01 ~]# mysqldump -uroot -p123 -A    --set-gtid-purged=ON >/backup/full.sql
(2)-B 備份多個單庫
2 備份db01、db02兩個庫:
mysqldump -uroot -pmysql -B db01 db02>/data/backup/db.sql 
(3)備份一個庫下多個表
3 world數據庫下的city,country表
mysqldump -uroot -p world city country >/backup/bak1.sql
以上備份恢復時:必須庫事先存在,並且use才能source恢復

3、高級參數應用

(1)–master-data=2
以註釋的形式,保存備份開始時間點的binlog的狀態信息

mysqldump -uroot -p  -A  -R --triggers --master-data=2   >/back/world.sql
[root@db01 ~]# grep 'CHANGE' /backup/world.sql 
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000035', MASTER_LOG_POS=194;

功能:
(1)在備份時,會自動記錄,二進制日誌文件名和位置號
0 默認值
1  以change master to命令形式,可以用作主從複製
2  以註釋的形式記錄,備份時刻的文件名+postion號
(2) 自動鎖表
(3)如果配合--single-transaction,只對非InnoDB表進行鎖表備份,InnoDB表進行“熱“”備,實際上是實現快照備份。
(2)–single-transaction
innodb 存儲引擎開啓熱備(快照備份)功能       
master-data可以自動加鎖
(1)在不加--single-transaction ,啓動所有表的溫備份,所有表都鎖定
(1)加上--single-transaction ,對innodb進行快照備份,對非innodb表可以實現自動鎖表功能
例子6: 備份必加參數
mysqldump -uroot -p -A -R -E --triggers --master-data=2  --single-transaction --set-gtid-purged=OFF >/data/backup/full.sql
(3)-R、-E、–triggers
-R            備份存儲過程及函數
--triggers  備份觸發器
-E             備份事件

例子4:
[root@db01 backup]# mysqldump -uroot -p -A -R -E --triggers >/data/backup/full.sql
(4)–max-allowed-packet
mysqldump -uroot -p -A -R -E --triggers --master-data=2  --single-transaction --set-gtid-purged=OFF --max-allowed-packet=256M >/data/backup/full.sql
(5)–set-gtid-purged=auto
auto , on
off 
使用場景:
1. --set-gtid-purged=OFF,可以使用在日常備份參數中.
mysqldump -uroot -p -A -R -E --triggers --master-data=2  --single-transaction --set-gtid-purged=OFF >/data/backup/full.sql
2. auto , on:在構建主從複製環境時需要的參數配置
mysqldump -uroot -p -A -R -E --triggers --master-data=2  --single-transaction --set-gtid-purged=ON >/data/backup/full.sql

4、模擬故障案例並恢復

1)每天全備
(2)binlog日誌是完整
(3)模擬白天的數據變化
(4)模擬誤刪除數據庫

需求: 利用全備+binlog回覆數據庫誤刪除之前。
故障模擬及恢復:
1. 模擬週一23:00的全備
mysqldump -uroot -p -A --master-data=2 --single-transaction -R -E --triggers --set-gtid-purged=OFF >/data/backup/full.sql
2. 模擬白天的數據變化
Master [(none)]>create database day1 charset utf8;
Master [(none)]>use day1
Master [day1]>create table t1(id int);
Master [day1]>insert into t1 values(1),(2),(3);
Master [world]>update city set countrycode='CHN';
3.模擬磁盤損壞:
rm -rf /data/mysql/data/*
4. 恢復思路
	(1)檢查備份可用性
	(2)從備份中獲取二進制日誌位置
	(3)根據日誌pos開始結束位置截取需要的二進制日誌 # 詳細使用請見bin-log日誌恢復
	(4)初始化數據庫,並啓動
	(5)恢復全備
	(6)恢復二進制日誌

四、xtrabackup的使用

1、xtrabackup的安裝

(1)安裝依賴包
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL libev
(2)下載軟件並安裝
wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm

or

yum -y install percona-xtrabackup-24-2.4.4-1.el7.x86_64.rpm

2、備份方式——物理備份

1)對於非Innodb表(比如 myisam),鎖表後,再cp數據文件,屬於一種溫備份。
(2)對於Innodb的表(支持事務的),不鎖表,拷貝數據頁,最終以數據文件的方式保存下來,把一部分redo和undo一併備走,屬於熱備方式。

3、面試題:XBK在innodb表備份恢復的流程

0、xbk備份執行的瞬間,立即觸發ckpt,已提交的數據髒頁,從內存刷寫到磁盤,並記錄此時的LSN號
1、備份時,拷貝磁盤數據頁,並且記錄備份過程中產生的redo和undo一起拷貝走,也就是checkpoint LSN之後的日誌
2、在恢復之前,模擬Innodb“自動故障恢復”的過程,將redo(前滾)與undo(回滾)進行應用
3、恢復過程是cp 備份到原來數據目錄下

4、innobackupex使用–全備

注意:xtrabackup只是一個軟件名,真正工作的是命令innobackupex!
全備的恢復:上次全備+binlog日誌

(1)如何做全備?
# 兩句話做全備
mkdir -pv /data/backup # 創建物理備份的數據存放目錄
innobackupex --user=root --password=123 --no-timestamp /data/backup/full

# 其他連接參數
1. 當然如果你mysql的sock文件不在默認位置,也需要指定其--socket=
2. 如果是遠程備份到本地,你需要指定--host=
3. 如果你數據庫不是默認的3306端口,則需要指定--port=

下面是對全備的一些介紹,和一些理論知識!

innobackupex --user=root --password=123  /data/backup
# 注意:這條命令生成的存儲備份數據的文件夾的名稱是以當前時間來命名的,例:2020-07-02_13-24-41

# 上面這樣不好看,因此我們一般採用下面這條命令,指定文件夾名稱:
innobackupex --user=root --password=123 --no-timestamp /data/backup/full
-rw-r----- 1 root root       24 Jun 29 09:59 xtrabackup_binlog_info
-rw-r----- 1 root root      119 Jun 29 09:59 xtrabackup_checkpoints
-rw-r----- 1 root root      489 Jun 29 09:59 xtrabackup_info
-rw-r----- 1 root root     2560 Jun 29 09:59 xtrabackup_logfile

1. xtrabackup_binlog_info :(備份時刻的binlog位置)
	[root@db01 full]# cat xtrabackup_binlog_info 
	mysql-bin.000003    536749
	79de40d3-5ff3-11e9-804a-000c2928f5dd:1-7
	記錄的是備份時刻,binlog的文件名字和當時的結束的position,可以用來作爲截取binlog時的起點。

2. xtrabackup_checkpoints :
	backup_type = full-backuped
	from_lsn = 0            上次所到達的LSN號(對於全備就是從0開始,對於增量有別的顯示方法)
	to_lsn = 160683027      備份開始時間(ckpt)點數據頁的LSN    
	last_lsn = 160683036    備份結束後,redo日誌最終的LSN
	compact = 0
	recover_binlog_info = 01)備份時刻,立即將已經commit過的,內存中的數據頁刷新到磁盤(CKPT).開始備份數據,數據文件的LSN會停留在to_lsn位置。
	(2)備份時刻有可能會有其他的數據寫入,已備走的數據文件就不會再發生變化了。
	(3)在備份過程中,備份軟件會一直監控着redo的undo,如果一旦有變化會將日誌也一併備走,並記錄LSN到last_lsn。
	從to_lsn  ----》last_lsn 就是,備份過程中產生的數據變化.

# 注意其他兩個參數不需要了解

在這裏插入圖片描述注:如果沒有binlog_info文件,說明你沒開啓binlog日誌!

(2)全備的恢復
  • 準備備份
# 將redo進行重做,已提交的寫到數據文件,未提交的使用undo回滾掉。模擬了CSR的過程
innobackupex --apply-log  /backup/full
  • 恢復備份
前提:
1、被恢復的目錄是空
2、被恢復的數據庫的實例是關閉
systemctl stop mysqld
  • 創建新目錄
mkdir /data/mysql1
  • 恢復備份
cp -a /backup/full/* /data/mysql1/
  • 啓動數據庫
vim /etc/my.cnf
datadir=/data/mysql1

chown -R mysql.mysql /data/mysql1
systemctl start mysqld

好!現在全備已經恢復了,還需要恢復binlog日誌!

(3)binlog日誌恢復
  • 確定全備時binlog的pos點
cat /data/backup/full_2020-07-02/xtrabackup_binlog_info

在這裏插入圖片描述pos點爲245!

  • 確定刪庫前的pos點

原來刪庫的binlog文件在/var/lib/mysql/下:

mysqlbinlog /var/lib/mysql/mysql-bin.000001 

在這裏插入圖片描述pos點爲807

  • mysqlbinlog進行恢復

首先說,binlog日誌無法改變其位置,因此,我們在恢復時需要避免恢復的sql語句再次寫入原來的bin-log日誌文件中:

set sql_log_bin=0;

'不改也可以',因爲全備時,連你當時的binlog也會備份
指定datadir,啓動mysql之後,你會生成一個mysql-bin就在/data/mysql/下,你可以指定logbin文件的位置爲它的路徑
然後通過恢復的操作,把binlog日誌也一起同步了!
mysqlbinlog --start-position=245 --stop-position=807 /var/lib/mysql/mysql-bin.000001 |mysql -uroot -pmysql

5、innobackupex使用–增量備份

一般一週做一次全備,每天凌晨進行增量備份!
增量的恢復:上週的全備+每天增量+binlog

(1)增量備份須知
1. 增量備份的方式,是基於上一次備份進行增量。
2. 增量備份無法單獨恢復。必須基於全備進行恢復。
3. 所有增量必須要按順序合併到全備中。
(2)增量備份命令
1. 刪掉原來備份
略.
2. 全備(週日)
innobackupex --user=root --password --no-timestamp /backup/full >&/tmp/xbk_full.log

3. 模擬週一數據變化
db01 [(none)]>create database cs charset utf8;
db01 [(none)]>use cs
db01 [cs]>create table t1 (id int);
db01 [cs]>insert into t1 values(1),(2),(3);
db01 [cs]>commit;
4. 第一次增量備份(週一)
innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/full  /backup/inc1 &>/tmp/inc1.log

5. 模擬週二數據
db01 [cs]>create table t2 (id int);
db01 [cs]>insert into t2 values(1),(2),(3);
db01 [cs]>commit;
6. 週二增量
 innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/inc1  /backup/inc2  &>/tmp/inc2.log
 
7. 模擬週三數據變化
db01 [cs]>create table t3 (id int);
db01 [cs]>insert into t3 values(1),(2),(3);
db01 [cs]>commit;
db01 [cs]>drop database cs;

現在我們要恢復到週三誤drop之前的數據狀態!

(3)數據恢復
恢復思路:
1. 掛出維護頁,停止當天的自動備份腳本
2. 檢查備份:週日full+週一inc1+週二inc2,週三的完整二進制日誌
3. 進行備份整理(細節),截取關鍵的二進制日誌(從備份——誤刪除之前)
4. 測試庫進行備份恢復及日誌恢復
5. 應用進行測試無誤,開啓業務
6. 此次工作的總結

恢復過程

1. 備份整理(apply-log)+合併備份(full+inc1+inc2)
	(1) 全備的整理
		innobackupex --apply-log --redo-only /data/backup/full
	(2) 合併inc1到full中
		innobackupex --apply-log --redo-only --incremental-dir=/data/backup/inc1 /data/backup/full
	(3) 合併inc2到full中
		innobackupex --apply-log  --incremental-dir=/data/backup/inc2 /data/backup/full
		# 注意:最後一次合併不要加--redo-only!
	(4) 最後一次整理全備
		innobackupex --apply-log  /data/backup/full
2. 截取週二 23:00 到drop 之前的 binlog 
	mysqlbinlog --start-position=807 --stop-position=1500 /data/binlog/mysql-bin.000009 >/data/backup/binlog.sql
3. 進行恢復
	mkdir /data/mysql/data2 -p
	cp -a * /data/mysql/data2
	chown -R mysql.  /data/*
	systemctl stop mysqld
	vim /etc/my.cnf
		datadir=/data/mysql/data2
	systemctl start mysqld
	Master [(none)]>set sql_log_bin=0;
	Master [(none)]>source /data/backup/binlog.sql

五、作業訓練

1、腳本實現數據庫自動備份

#!/bin/bash
CONN_USER=root
CONN_PWD=mysql
CONN_SERVER_IP=127.0.0.1
CONN_PORT=3306
CONN_SOCK=/var/lib/mysql/mysql.sock

#-------------- 全備 --------------
MDB_DUMP(){
    echo -e '\033[31m ----------------- 開始進行數據庫全備... ----------------- \033[0m'
    mysqldump -u${CONN_USER} -p${CONN_PWD} -h${CONN_SERVER_IP} -P${CONN_PORT} -S${CONN_SOCK} -A --master-data=2 --single-transaction -R -E --triggers --max-allowed-packet=64M > /data/MDB_backup/full_`date +%F`.sql
    ls /data/MDB_backup/|grep "full_`date +%F`.log"
    if [ $? -ne 0 ];then
        echo '`date '+%F %T %p'` 數據庫全備出錯!' >>/var/log/MDB_back.log
        exit 1
    fi
    BACK_NUM = ls /data/MDB_backup/|wc -l
    # /data/MDB_backup/中的全備文件不能超過五個,一旦超過,便刪除最舊的那個全備文件
    if [ ${BACK_NUM} -g 5 ];then
        DELETE_FILE=find /data/MDB_backup/ -type f -print0|xargs -0 ls -lt -c|tail -1|awk -F' ' '{print $9}'
        rm -f DELETE_FILE
        if [ $? -ne 0 ];then
            echo '`date '+%F %T %p'` 刪除全備文件出錯!' >>/var/log/MDB_back.log
            exit 2
        fi
    fi
}
MDB_DUMP

2、從mysqldump 全備中獲取單庫或單表的備份

1、獲取單表備份
	(1)獲得表結構
		sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE 'city'/!d;q'  full.sql>createtable.sql
	(2)獲得INSERT INTO 語句,用於數據的恢復
		grep -i 'INSERT INTO 'city''  full.sql >data.sql &
	# 注意:恢復的時候需要先恢復表表結構再恢復表數據

3.獲取單庫的備份
	sed -n '/^-- Current Database: 'world'/,/^-- Current Database: /p' all.sql >world.sql
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章