天天看點

第七章 備份恢複第七章 備份恢複1. 備份的作用2. 備份工具3. 作為DBA在備份恢複工作職責4. mysqldump 應用5. 實體備份工具使用-Percona Xtrabackup(PXB)

第七章 備份恢複

1. 備份的作用

處理資料庫損壞。

損壞?

實體 :磁盤、檔案系統、資料檔案。處理方案:主從、高可用、備份+日志。

邏輯 :drop truncate delete update 。 處理方案: 備份+日志、延時從。

2. 備份工具

邏輯備份 : mysqldump (MDP)、binlog 、主從 …

實體備份 : Percona Xtrabackup (PXB\XBK\Xbakcup)

擴充: 8.0 Clone plugin

3. 作為DBA在備份恢複工作職責

a. 設計備份政策 : 備份周期、備份工具、備份方式(全備、增量…)

b. 定期備份檢查。

c. 定期恢複演練。

d. 資料恢複。

e. 資料的遷移更新。

4. mysqldump 應用

4.1 介紹

邏輯備份工具。文本形式儲存備份,可讀性較強。

備份邏輯: 将建庫、建表、資料插入語句導出,包存至一個sql檔案中。

比較适合于:資料量較小的場景,單表資料行千萬級别以内。百G以内的小型資料庫.跨版本、跨平台遷移。

可以本地、可以遠端備份。

注意: 一般情況下,恢複需要耗費的時間是備份耗費時間的3-5倍。

4.2 使用

4.2.1 連接配接參數

mysqldump -u -p -S -h -P 
           

4.2.2 備份基礎參數

-A 全備
[[email protected] ~]# mysqldump -uroot -p123 -A >/data/backup/full.sql
           
-B 單庫或多庫備份
[[email protected] ~]# mysqldump -uroot -p123 -B test world >/data/backup/db.sql
           
單表或多表備份
[[email protected] ~]# mysqldump -uroot -p123  world city country >/data/backup/tb.sql
           

注意:

-A 和 -B 都帶有了 create database 和use 語句,直接恢複即可

單表或多表備份方式, 沒有 create database 和use 語句,是以要手工進行建庫和use,再恢複資料。

4.2.3 進階功能參數

參數一: --master-data=2
a. 自動記錄binlog位置點 b. 自動加GRL鎖(FTWRL ,flush tables with read lock) c. 配合--single-transaction ,減少鎖的時間。
           
參數二: single-transaction

a. 對于InnoDB表,利用MVCC中一緻性快照進行備份。備份資料時,不加鎖 b. 備份期間如果出現DDL操作,導緻備份資料不一緻 問題: mysqldump是嚴格意義上的熱備嗎? 8.0 之後 master-data和single-transaction,對于InnoDB資料備份時是快照備份的. 備份表結構等資料時,還是FTWRL過程備份. --single-transaction 隻是針對InnoDB表資料進行一緻性快照備份。 問題: mysqldump備份需要鎖表嗎? 是有的。global read lock

參數三: -R -E --triggers 備份特殊對象

存儲過程 函數 觸發器 事件

參數四: --max_allowed_packet=64M

最大允許資料包的大小。

4.2.4 标準化備份

[root@db01 backup]# mysqldump -uroot -p -A --master-data=2 --single-transaction -R -E --triggers --max_allowed_packet=64M >/data/backup/full_`date +%F`.sql
Enter password: 
           

4.2.5 案例:通過mysqldump全備+binlog實作PIT資料恢複

環境背景: 小型的業務資料庫,50G,每天23:00全備,定期binlog異地備份。

故障場景: 周三下午2點,開發Navicat連接配接資料庫執行個體錯誤,導緻生産資料被誤删除(DROP)

恢複思路:

\1. 挂維護頁。

\2. 檢查備份、日志可用。

\3. 如果隻是部分損壞,建議找一個應急庫進行恢複

a. 全備恢複

b. 日志截取并恢複

\4. 恢複後資料校驗 (業務測試部門驗證)

\5. 立即備份(停機冷備)

\6. 恢複架構系統

\7. 撤維護頁,恢複業務

> 模拟環境:
mysql> create database mdb;
Query OK, 1 row affected (0.01 sec)

mysql> use mdb
Database changed
mysql> create table t1 (id int);
Query OK, 0 rows affected (0.03 sec)

mysql> create table t2 (id int);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t1 values(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t2 values(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)


[root@db01 backup]# mysqldump -uroot -p -A --master-data=2 --single-transaction -R -E --triggers --max_allowed_packet=64M >/data/backup/full_`date +%F`.sql

mysql> create table t3 (id int);
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t3 values(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> drop database mdb;
           
> 恢複過程:  
a. 檢視備份,擷取二進制日志位置點

-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POS=1274;

思考一個問題: binlog位置點是備份開始時,還是備份結束時的位置點?

b.  恢複全備
mysql> source /data/backup/full_2020-09-18.sql

c.  binlog 截取并恢複 
| binlog.000001 | 1711 | Xid            |         1 |        1742 | COMMIT /* xid=2278 */    

[root@db01 backup]# mysqlbinlog --skip-gtids --start-position=1274 --stop-position=1742 /data/3306/data/binlog.000001 >/tmp/bin.sql


mysql> set sql_log_bin=0;
mysql> source /tmp/bin.sql
           

4.2.6 擴充 (課後作業)

100G mysqldump全備恢複時間很長,誤删除的表10M大小 ,有什麼思路可以快速恢複?
思路:  
a. 從全備中,将單表 建表語句和insert語句提取出來 ,進行恢複

# sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `oldguo`/!d;q'  /data/backup/mdp/full.sql>/data/createtable.sql
# grep -i 'INSERT INTO `oldguo`'   /data/backup/mdp/full.sql >/data/data.sql 

b. 從binlog中單獨截取單表的所有binlog,進行恢複。 
binlog2sql 截取單表binlog,恢複。
           

5. 實體備份工具使用-Percona Xtrabackup(PXB)

5.0 介紹

實體備份工具,支援全備和增量備份。

備份邏輯:

a. 資料庫運作期間,拷貝資料表空間.

b. 拷貝的同時,會将備份期間的redo進行備份

恢複邏輯 :

模拟了InnoDB Crash Recovery 功能,需要要将備份進行處理(前滾和復原)後才能恢複

5.1 安裝

yum install percona-xtrabackup*.rpm
           

注意:

對于MySQL 8.0.20版本,需要使用PXB 8.0.12+以上版本,MysQL:8.0.11 ~ 8.0.19 使用PXB 8.0正式版本。

MySQL 8.0 之前(5.6,5.7 )的版本: PXB 2.4

5.2 全量備份

1.全量備份
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=123   --backup --target-dir=/data/backup/full
           
2.資料恢複:
[[email protected] ~]# pkill mysqld
[[email protected] ~]# rm -rf /data/3306/data/*
[[email protected] ~]# rm -rf /data/3306/logs/*
[[email protected] ~]# rm -rf /data/3306/binlog/*

           
2.1 準備:(CR)
xtrabackup   --prepare --target-dir=/data/backup/full
           
說明: 模拟CR過程,将redo前滾,undo復原,讓備份資料是一緻狀态
2.2 拷回資料:
xtrabackup  --copy-back --target-dir=/data/backup/full
           
2.3 修改權限并啟動資料庫
[root@db01 data]# chown -R mysql.mysql /data/*
[[email protected] data]# /etc/init.d/mysqld start

           

5.3 增量備份

5.3.1 介紹

增量備份,是基于上一次備份LSN變化過的資料頁進行備份,在備份同時産生的新變更,會将redo備份。

第一次增量是依賴于全備的。将來的恢複也要合并到全備中,再進行統一恢複。

5.3.2 增量備份演練

全量備份的目錄為: mkdir -p /data/backup/full

增量備份的目錄為: mkdir -p /data/backup/inc

1.備份過程
1. 全量備份:
xtrabackup --defaults-file=/etc/my.cnf  --user=root --password=123  --backup --parallel=4 --target-dir=/data/backup/full

mysql> create database pxb;
mysql> use pxb
mysql> create table t1 (id int);
mysql> insert into t1 values(1),(2),(3);
mysql> commit;

1.2.增量備份:
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=123  --backup --parallel=4 --target-dir=/data/backup/inc  --incremental-basedir=/data/backup/full
 
1.3. 模拟損壞  
[[email protected] ~]# pkill mysqld
[[email protected] ~]# rm -rf /data/3306/data/*

2. 恢複操作:
2.1 準備全備份的日志:
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/full


2.2 準備增量備份的日志:
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/full  --incremental-dir=/data/backup/inc


2.3 全備份準備:
# xtrabackup --prepare --target-dir=/data/backup/full


2.4 拷回資料:
xtrabackup    --copy-back --target-dir=/data/backup/full
 
2.5 修改資料目錄的權限和屬性:
chown -R mysql:mysql /data/*

課後思考: 
500G資料, 每周日全備,其他時間段增量,周三下午誤删除了一個表(10M)資料。
如何快速恢複。

           

2.8 MySQL 8.0(8.0.17+) Clone-plugin

2.8.1 Clone Plugin介紹

本地克隆

啟動克隆操作的MySQL伺服器執行個體中的資料,克隆到同伺服器或同節點上的一個目錄裡

遠端克隆

預設情況下,遠端克隆操作會删除接受者(recipient)資料目錄中的資料,并将其替換為捐贈者(donor)的克隆資料。您也可以将資料克隆到接受者的其他目錄,以避免删除現有資料。(可選)

2.8.2 原理

PAGE COPY

開啟redo archiving功能,從目前點開始存儲新增的redo log,這樣從目前點開始所有的增量修改都不會丢失。同時上一步在page track的page被發送到目标端。確定目前點之前所做的變更一定發送到目标端。

關于redo archiving,實際上這是官方早就存在的功能,主要用于官方的企業級備份工具,但這裡clone利用了該特性來維持增量修改産生的redo。

在開始前會做一次checkpoint, 開啟一個背景線程log_archiver_thread()來做日志歸檔。當有新的寫入時(notify_about_advanced_write_lsn)也會通知他去archive。當arch_log_sys處于活躍狀态時,他會控制日志寫入以避免未歸檔的日志被覆寫(log_writer_wait_on_archiver), 注意如果log_writer等待時間過長的話, archive任務會被中斷掉.

Redo Copy

停止Redo Archiving,所有歸檔的日志被發送到目标端,這些日志包含了從page copy階段開始到現在的所有日志,另外可能還需要記下目前的複制點,例如最後一個事務送出時的binlog位點或者gtid資訊,在系統頁中可以找到。

Done

目标端重新開機執行個體,通過crash recovery将redo log應用上去。

2.8.3 限制

官方文檔列出的一些限制:

The clone plugin is subject to these limitations:

* DDL, is not permitted during a cloning operation. This limitation should be considered when selecting data sources. A workaround is to use dedicated donor instances, which can accommodate DDL operations being blocked while data is cloned. Concurrent DML is permitted.

* An instance cannot be cloned from a different MySQL server version. The donor and recipient must have the same MySQL server version. For example, you cannot clone between MySQL 5.7 and MySQL 8.0\. The clone plugin is only supported in MySQL 8.0.17 and higher.

* Only a single MySQL instance can be cloned at a time. Cloning multiple MySQL instances in a single cloning operation is not supported.

* The X Protocol port specified byis not supported for remote cloning operations

* The clone plugin does not support cloning of MySQL server configurations.

* The clone plugin does not support cloning of binary logs.

* The clone plugin only clones data stored in

InnoDB

. Other storage engine data is not cloned.

* Connecting to the donor MySQL server instance through MySQL Router is not supported.

* Local cloning operations do not support cloning of general tablespaces that were created with an absolute path. A cloned tablespace file with the same path as the source tablespace file would cause a conflict.

2.8.4. 應用

a. 本地

# 1. 加載插件
INSTALL PLUGIN clone SONAME 'mysql_clone.so';
或
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT

SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE 'clone';

# 2 建立克隆專用使用者
CREATE USER clone_user@'%' IDENTIFIED by 'password'; 
GRANT BACKUP_ADMIN ON *.* TO 'clone_user'; 

注意:BACKUP_ADMIN是MySQL8.0 才有的備份鎖的權限

# 3 本地克隆
[root@db01 3306]# mkdir -p /data/test/
[root@db01 3306]# chown -R mysql.mysql /data/
mysql -uclone_user -ppassword
CLONE LOCAL DATA DIRECTORY = '/data/test/clonedir';

# 4 觀測狀态
db01 [(none)]> SELECT STAGE, STATE, END_TIME FROM performance_schema.clone_progress;
+-----------+-------------+----------------------------+
| STAGE     | STATE       | END_TIME                   |
+-----------+-------------+----------------------------+
| DROP DATA | Completed   | 2020-04-20 21:13:19.264003 |
| FILE COPY | Completed   | 2020-04-20 21:13:20.025444 |
| PAGE COPY | Completed   | 2020-04-20 21:13:20.028552 |
| REDO COPY | Completed   | 2020-04-20 21:13:20.030042 |
| FILE SYNC | Completed   | 2020-04-20 21:13:20.439444 |
| RESTART   | Not Started | NULL                       |
| RECOVERY  | Not Started | NULL                       |
+-----------+-------------+----------------------------+
7 rows in set (0.00 sec)

# 日志觀測: 
set global log_error_verbosity=3;
tail -f db01.err
CLONE LOCAL DATA DIRECTORY = '/data/test/3308';

# 啟動新執行個體
[root@db01 clonedir]# mysqld_safe  --datadir=/data/test/clonedir --port=3333 --socket=/tmp/mysql3333.sock --user=mysql --mysqlx=OFF &
           

2.8.5 遠端clone

# 各個節點加載插件
INSTALL PLUGIN clone SONAME 'mysql_clone.so';
或
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT

SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE 'clone';

# 建立遠端clone使用者
# 捐贈者(source)授權
create user test_s@'%' identified by '123';
grant backup_admin on *.* to test_s@'%';

# 接受者(target)授權
create user test_t@'%' identified by '123';
grant clone_admin on *.* to test_t@'%';

# 遠端clone(目标端)
# 開始克隆
SET GLOBAL clone_valid_donor_list='10.0.0.51:3306';
mysql -utest_t -p123 -h10.0.0.52  -P3306
CLONE INSTANCE FROM test_s@'10.0.0.51':3306 IDENTIFIED BY '123';
           

繼續閱讀