1. 程式人生 > 實用技巧 >十二、mysql備份與恢復 、mysqldump邏輯備份、xtrabackup物理備份

十二、mysql備份與恢復 、mysqldump邏輯備份、xtrabackup物理備份

一、資料的備份

1.備份的原因

1.資料重要
2.備份就是為了恢復
3.減少公司的損失

2.備份的型別

1.冷備份:先停止資料庫的訪問,然後備份

這些備份在使用者不能訪問資料時進行,因此無法讀取或修改資料。這些離線備份會阻止執行任何使用資料的活動。這些型別的備份不會干擾正常執行的系統的效能。但是,對於某些應用程式,會無法接受必須在一段較長的時間裡鎖定或完全阻止使用者訪問資料。

2.溫備份:不停止資料庫的訪問,不阻止資料的讀取,阻止資料修改的同時然後備份

這些備份在讀取資料時進行,但在多數情況下,在進行備份時不能修改資料本身。這種中途備份型別的優點是不必完全鎖定終端使用者。但是,其不足之處在於無法在進行備份時修改資料集,這可能使這種型別的備份不適用於某些應用程式。在備份過程中無法修改資料可能產生效能問題。

3.熱備份:不停止資料庫的訪問,不鎖表,不阻止資料的讀取和寫入的同時進行備份

這些動態備份在讀取或修改資料的過程中進行,很少中斷或者不中斷傳輸或處理資料的功能。使用熱備份時,系統仍可供讀取和修改資料的操作訪問

3.備份的形式

1)邏輯備份

#把資料匯出成sql檔案的形式進行備份
1.binlog 的方式
2.into outfile
1)配置資料庫
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
secure-file-priv=/tmp
2)資料庫執行
mysql> select * from world.city into outfile '/tmp/world_city.data';
3)檢視匯出檔案
3.mysqldump
4.replication (資料庫主從,屬於邏輯備份,並沒有是真正的做到備份)

2)物理備份

1.直接備份data目錄
1)將資料目錄data打包
2)將data打包檔案推送到另一臺資料庫伺服器(兩臺機器必須使用相同安裝方式)
3)到新機器解壓data目錄到資料庫的資料目錄進行替換
4)登入資料庫檢視

2.Xtrabackup

3)備份的型別

1.全備:全部資料都進行備份
1)比較浪費磁碟空間
2)恢復資料方便

2.增備:對新增加的資料進行備份
1)相對於全備比較節省磁碟空間
2)恢復資料需要合併多次資料

3.差異備份:針對上一次全備進行備份
1)也會出現資料的重複,比較浪費磁碟空間
2)恢復資料,只需要與全備合併進行恢復即可

二、mysqldump 備份命令

1.mysql客戶端

1.mysql
2.mysqladmin
3.mysqldump

2.mysqldump命令引數

0)語法

Usage: mysqldump [OPTIONS] database [tables]
OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR mysqldump [OPTIONS] --all-databases [OPTIONS]
For more options, use mysqldump --help

1)不使用任何引數的時候

1.匯出指定庫
[root@db01 ~]# mysqldump -uroot -p world > /tmp/world.sql

2.匯出指定庫下面的指定表
[root@db01 ~]# mysqldump -uroot -p world city > /tmp/city.sql

3.匯出指定庫下面的多個表(第一個引數必須是庫,後面的其他引數都只能是表名)
[root@db01 ~]# mysqldump -uroot -p world city country > /tmp/city2.sql

2) 加引數

1. -A 等於 --all-databases,匯出所有庫
[root@db01 ~]# mysqldump -uroot -p -A > /tmp/full.sql

2. -B 指定庫備份,只能指定庫的名字
[root@db01 ~]# mysqldump -uroot -p -B world row events > /tmp/1.sql

3. -F 備份資料的同時重新整理binlog
[root@db01 ~]# mysqldump -uroot -p -F world city > /tmp/city2.sql

4. --master-data=2 備份時進行打點,記錄備份時的binlog位置點(必須開啟binlog才能使用)
[root@db01 ~]# mysqldump -uroot -p123 -B world --master-data=2 > /tmp/world.sql
--master-data=0 不打點不記錄位置
--master-data=2 打點並註釋(單純的進行備份時)
--master-data=1 打點不註釋(主從資料庫擴充套件從庫時)

5. --single-transaction 快照備份

6. -d 僅表結構
7. -t 僅資料
8. -R --routines 備份儲存過程和函式資料
9. --triggers 備份觸發器資料

#備份的完整命令
[root@db01 ~]# mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql

3)擴充套件

1. gzip 壓縮備份
[root@db01 ~]# mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction | gzip > /tmp/full.tar.gz
#壓縮恢復資料時
[root@db01 ~]# zcat /tmp/full.tar.gz | mysql -uroot -p

2. 備份同時加上時間戳
[root@db01 ~]# mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full$(date +%F).sql

三、企業故障恢復案例

1.背景

1.正在執行的網站系統,MySQL資料庫,資料量25G,日業務增量10-15M。

2.備份策略:每天23:00,計劃任務呼叫mysqldump執行全備指令碼

3.故障時間點:上午10點開發人員誤刪除一個核心業務表,如何恢復

2.資料庫恢復思路

1.停止業務,避免資料的二次傷害
2.找一個臨時的庫,恢復前一天的全備
3.擷取前一天23:00到第二天10點誤刪除之間的binlog,恢復到臨時庫
4.測試可用性和完整性
5.開啟業務前的兩種方式
1)直接使用臨時庫頂替原生產庫,前端應用割接到新庫(核心業務表資料量多的時候)
2)將誤刪除的表單獨匯出,然後匯入到原生產環境(核心業務表資料量少的時候)
6.開啟業務

3.故障模擬

1)準備資料

#建庫
mysql> create database backup;
#切換庫
mysql> use backup;
#建表
mysql> create table back111(id int);
#建表
mysql> create table back222 select * from world.city;

2)進行23:00全備

#定時任務備份
[root@db01 ~]# mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/backup$(date +%F).sql

3)模擬23:00備份後到早上10點的操作

#切換庫
mysql> use backup
#建表
mysql> create table back333 select * from world.city;
#修改資料
mysql> update back222 set countrycode='CHN' where 1=1;

4)模擬10:00開發人員刪除核心表

#刪除核心表
mysql> drop table back111;

4.恢復資料

1)停止業務

[root@db01 ~]# systemctl stop mysqld

2)準備新的資料庫

3)找出binlog對應23:00到10點的位置點

1.找到起始位置點
[root@db01 ~]# less /tmp/backup2020-11-04.sql
#第22行
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000013', MASTER_LOG_POS=959935;

2.找到結束位置點
[root@db01 ~]# mysqlbinlog --base64-output=decode-rows -vvv --start-position=959935 /usr/local/mysql/data/mysql-bin.000013 > 1.txt
[root@db01 ~]# vim 1.txt
# at 1339403
... ...
DROP TABLE `back111` /* generated by server */

3.擷取binlog
[root@db01 ~]# mysqlbinlog --start-position=959935 --stop-position=1339403 /usr/local/mysql/data/mysql-bin.000013 > /tmp/huifu.sql

4)將全備和恢復的sql推送到新庫

[root@db01 ~]# scp /tmp/backup2020-11-04.sql 172.16.1.52:/tmp
[root@db01 ~]# scp /tmp/huifu.sql 172.16.1.52:/tmp

5)將sql匯入新的資料庫

[root@db02 ~]# mysql < /tmp/backup2020-11-04.sql 
[root@db02 ~]# mysql < /tmp/huifu.sql
#儘量使用source的方式恢復

6)確認資料

mysql> use backup
mysql> select * from back333;

四、Xtrabackup 物理備份

1.上傳或者下載Xtrabackup工具

1.上傳
[root@db01 ~]# rz percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm

#或者

2.下載
#下載epel源
wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-6.repo
#安裝依賴
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL
#下載Xtrabackup
wget httpss://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

2.安裝

[root@db01 ~]# yum localinstall -y percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm

[root@db01 ~]# xtrabackup #舊版本的命令
[root@db01 ~]# innobackupex #新版本的命令

3.xtrabackup特性

1.對於非innodb表(比如myisam)是直接鎖表cp資料檔案,屬於一種溫備。
2.對於innodb的表(支援事務),不鎖表,cp資料頁最終以資料檔案方式儲存下來,並且把redo和undo一併備走,屬於熱備方式。
3.備份時讀取配置檔案/etc/my.cnf

4.xtrabackup全量備份

1.建立備份的目錄
[root@db01 ~]# mkdir /backup

2.全備
[root@db01 ~]# innobackupex --user=root --password=123 /backup/full/

3.檢視全備的檔案
[root@db01 ~]# ll /backup/full/
總用量 0
drwxr-x--- 9 root root 271 11月 4 17:50 2020-11-04_17-50-18
drwxr-x--- 9 root root 271 11月 4 17:51 2020-11-04_17-51-34

4.去除時間戳進行備份
[root@db01 ~]# innobackupex --user=root --password=123 --no-timestamp /backup/full/

5.再次檢視備份檔案
[root@db01 ~]# ll /backup/full/
[root@db01 /backup/full]# vim xtrabackup_checkpoints #備份的資訊
backup_type = full-backuped
from_lsn = 0
to_lsn = 2330991066

xtrabackup_binlog_info #binlog的資訊
xtrabackup_info #備份工具的資訊
xtrabackup_logfile #binlog

5.使用xtrabackup進行資料恢復

1.刪庫
mysql> drop database test;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
+--------------------+
2 rows in set (0.00 sec)

2.停止資料庫
[root@db01 ~]# systemctl stop mysqld

3.將redo進行重做,已提交的寫到資料檔案,未提交的使用undo回滾,模擬CSR的過程
[root@db01 ~]# innobackupex --user=root --password=123 --apply-log /backup/full

4.恢復資料
[root@db01 ~]# cd /usr/local/mysql
[root@db01 /usr/local/mysql]# mv data databack
#方式一:
[root@db01 /usr/local/mysql]# cp -r /backup/full ./data
[root@db01 /usr/local/mysql]# chown -R mysql.mysql data
#方式二:
[root@db01 /usr/local/mysql]# innobackupex --copy-back /backup/full/
[root@db01 /usr/local/mysql]# chown -R mysql.mysql data

5.xtrabackup增量備份

1.基於上一次備份進行增量
2.增量備份無法單獨恢復,必須基於全備進行恢復
3.所有增量必須要按順序合併到全備當中

6.xtrabackup增量備份實踐

1.首先進行全備
[root@db01 ~]# innobackupex --user=root --password=123 --no-timestamp /backup/full$(date +%F)

2.模擬新增資料
mysql> create database xtra;
mysql> use xtra
mysql> create table xtrabackup(id int);
mysql> insert xtrabackup values(1),(2),(3);

3.進行增量備份
[root@db01 ~]# innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/full2020-11-05 /backup/firstadd
引數說明:
--incremental:
--incremental-basedir:上一次備份的路徑

4.確認增量備份是否準確
[root@db01 /backup]# cat full2020-11-05/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 2327894806

[root@db01 /backup]# cat firstadd/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 2327894806 #第一次增備的起始位置點是全備的結束位置點
to_lsn = 2327902069

5.再次新增資料
mysql> use xtra
mysql> insert xtrabackup values(4),(5),(6);

6.再次增備
[root@db01 ~]# innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/firstadd /backup/twoadd

7.再次檢視是否銜接
[root@db01 /backup]# cat full2020-11-05/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 2327894806

[root@db01 /backup]# cat firstadd/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 2327894806 #全備的結束點
to_lsn = 2327902069

[root@db01 /backup]# cat twoadd/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 2327902069 #第一次增備的結束點
to_lsn = 2327903988

7.xtrabackup增量備份恢復實踐

1.準備恢復
1)full + firstadd + twoadd
2)需要將 firstadd 和 twoadd 按順序合併到full中
3)分步驟進行 --apply-log

2.第一步:在全備中apply-log時,只應用redo,不應用undo
[root@db01 ~]# innobackupex --apply-log --redo-only /backup/full2020-11-05

3.第二步:將 firstadd 合併到 full 中,並且apply-log,只應用redo,不應用undo
[root@db01 ~]# innobackupex --apply-log --redo-only --incremental-dir=/backup/firstadd/ /backup/full2020-11-05

4.確認合併
[root@db01 ~]# cat /backup/full2020-11-05/xtrabackup_checkpoints
backup_type = log-applied
from_lsn = 0
to_lsn = 2327902069 #全備的值等於第一次增備的值

5.第三步:將 twoadd 合併到 full 中,redo和undo都應用
[root@db01 ~]# innobackupex --apply-log --incremental-dir=/backup/twoadd/ /backup/full2020-11-05

6.再次確認合併
[root@db01 ~]# cat /backup/full2020-11-05/xtrabackup_checkpoints
backup_type = full-prepared
from_lsn = 0
to_lsn = 2327903988

7.第四步:整體full執行apply-log,redo和undo都應用
[root@db01 mysql]# innobackupex --apply-log /backup/full2020-11-05
[root@db01 ~]# systemctl stop mysqld
[root@db01 ~]# mv /usr/local/mysql/data /usr/local/mysql/databack
[root@db01 ~]# innobackupex --copy-back /backup/full2020-11-05
[root@db01 ~]# chown -R mysql.mysql /usr/local/mysql/data
[root@db01 ~]# systemctl start mysqld