本文介紹了怎樣用percona xtrabackup做全量備份及如何利用全量備份(不用增量備份)加binlog做完全恢復(將數據恢復到故障時刻)。
一 試驗步驟
1.1 備份
#對數據庫做備份
innobackupex --port=3307 --user=XtrabackupUser --password=123456 /download/bak/xtrbak/
備份完成後,會提示……completed OK!
備份完成後,會在備份路徑下生成一個以備份時間命名的子目錄,如:
[root@pc1 xtrbak]# pwd
/download/bak/xtrbak
[root@pc1 xtrbak]# ll
total 4
drwxr-x---. 5 root root 4096 Mar 17 15:44 2020-03-17_05-30-14
備份文件內容如下:
[root@pc1 xtrbak]# cd 2020-03-17_05-30-14
[root@pc1 2020-03-17_05-30-14]# ll
total 12340
-rw-r-----. 1 root root 426 Mar 17 05:30 backup-my.cnf
drwxr-x---. 2 root root 4096 Mar 17 05:30 dan_test
drwxr-x---. 2 root root 4096 Mar 17 05:30 dba
-rw-r-----. 1 root root 332 Mar 17 05:30 ib_buffer_pool
-rw-r-----. 1 root root 12582912 Mar 17 05:30 ibdata1
drwxr-x---. 2 root root 4096 Mar 17 05:30 mysql
drwxr-x---. 2 root root 4096 Mar 17 05:30 performance_schema
drwxr-x---. 2 root root 12288 Mar 17 05:30 sys
-rw-r-----. 1 root root 106 Mar 17 05:30 xtrabackup_binlog_info
-rw-r-----. 1 root root 113 Mar 17 05:30 xtrabackup_checkpoints
-rw-r-----. 1 root root 611 Mar 17 05:30 xtrabackup_info
-rw-r-----. 1 root root 2560 Mar 17 05:30 xtrabackup_logfile
1.2 故障模擬
刪除數據文件:
cd /data/server/mysql_3307/
mv data data_bak
重啓數據庫失敗:
Starting MySQL. ERROR! The server quit without updating PID file (/data/server/mysql_3307/data/pc1.pid)
1.3 恢復
1.3.1 prepare
在創建備份後,備份數據其實處於不可用狀態。因爲在redo log中可能存在未提交的事務和已經提交的事務,需要通過準備階段來使數據達到一致性的狀態。通過此階段,備份數據就可以用來恢復了。
在準備階段,需要指定選項--apply-log和備份路徑。
innobackupex --apply-log /download/bak/xtrbak/2020-03-17_05-30-14
如果最後輸出completed ok,則表明數據達到一致狀態。
1.3.2 使用innobackupex做恢復
在prepare階段後,如果需要用備份數據來恢復數據庫,則需要指定--copy-back和備份數據所在的目錄即可。
#如果數據庫沒被關閉,需要關閉數據庫:
service mysqld stop
#如果數據目錄不爲空,則將數據目錄設置爲空
cd /data/server/mysql_3307/
mv data data_bak
#在恢復機器上恢復數據:
innobackupex --copy-back /download/bak/xtrbak/2020-03-17_05-30-14
chown -R mysql:mysql data
此時,數據恢復到了備份時刻的狀態。
1.3.3 利用binlog做完全恢復
關閉相應的應用接口,阻止往數據庫裏寫入數據,防止數據錯亂。
service mysqld start
#查看應該從哪個binlog及position進行恢復
[root@pc1 2020-03-17_05-30-14]# cat xtrabackup_binlog_info
mysql-bin.000030 650 a4ac8cd2-e17c-11e9-a602-080027040516:1-86,
d4d2f1d2-66f2-11ea-972a-080027040516:1-17
#查看有哪些binlog需要恢復(上面陰影部分的binlog及其之後的binlog都需要恢復)
mysql> show binary logs;
……
| mysql-bin.000030 | 953 |
| mysql-bin.000031 | 537 |
| mysql-bin.000032 | 537 |
| mysql-bin.000033 | 234 |
| mysql-bin.000034 | 234 |
+------------------+-----------+
34 rows in set (0.00 sec)
#執行flush logs,以防止恢復最後一個binlog時,會重複複製,因爲恢復binlog本身的操作也會記錄到binlog裏。
#恢復
/usr/local/mysql/bin/mysqlbinlog --skip-gtids=true --start-position=650 mysql-bin.000030 | mysql -u root -p
/usr/local/mysql/bin/mysqlbinlog --skip-gtids=true mysql-bin.000031 mysql-bin.000032 mysql-bin.000033 mysql-bin.000034 | mysql -u root -p
--注意,必須得加上skip-gtid=true,否則雖然語句執行沒報錯,但是實際上卻未執行。
/*
如果我們是要恢復數據到源數據庫或者和源數據庫有相同 GTID 信息的實例,那麼就要使用該參數。因爲包含的 GTID 已經在源數據庫執行過了,根據 GTID 特性,一個 GTID 信息在一個數據庫只能執行一次,所以不會恢復成功。
如果是要恢復到其他實例的數據庫並且不包含源實例的 GTID 信息,那麼可以不使用該參數。
*/
--關於如何做增量備份,可以參考https://blog.csdn.net/yabingshi_tech/article/details/104953662