一、演示環境說明:
系統CentOS Linux release 7.2.1511 (Core) X_86 64位最小化安裝
mysql版本是官方二進制版本5.7.22-22,mysql採用的是二進制安裝,單機上開啓2個mysql實例,mysql實例要開啓定時器event_scheduler=ON. 而且2個mysql實例都要開啓Gtid
xtrabackup 採用的是rpm包安裝,版本是version 2.4.13
MySQL備份方式採用每天一次全量備份和binlog增量備份
二、模擬刪除庫,進行數據恢復演示:
提示:當然此處只是演示,嚴禁生成環境刪庫,刪表模擬,後果你懂得
故障模擬:
線上誤刪除一個testdb庫下的test1_event表,利用當天的mysql的全量備份+當天生成的mysql的binlog文件來恢復數據到誤刪的表test1_event之前的數據
恢復方式介紹:
官方推薦採用利用mysql binlog方式恢復,生產實踐驗證官方的這個方式已經是不嚴謹的做法了(下面的方法是官方推薦的)
故障恢復過程如下:
2.1接收到誤刪除之前,第一時間確認大概誤操作時間
2.2 登錄主庫查看當前的binlog位置點(要記住此時的binlog文件,後面恢復時會用到)
(root@'mgr01':mysql3306.sock)[testdb]>show master status\G
*************************** 1. row ***************************
File: mysql-bin.000005
Position: 15211
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: bde7b592-b966-11e9-8c64-000c294f3e61:1-10445
1 row in set (0.00 sec)
2.3最好是flush logs下,讓接下來的sql寫入到新的binlog文件
2.4定位drop 表語句所在binglog文件的位置點:
[root@mgr01 binlog]# mysqlbinlog -v --base64-output=decode-rows /data/mysql/mysql3306/binlog/mysql-bin.000005|grep -i -C 15 drop
### @1=10422
### @2='tomcat'
### @3='xiaohuahua'
### @4='2019-08-08 14:22:18'
# at 14987
#190808 14:22:18 server id 63306 end_log_pos 15018 CRC32 0x873943dd Xid = 20695
COMMIT/*!*/;
#at15018###################################
#190808 14:22:19 server id 63306 end_log_pos 15083 CRC32 0xcc8773ce GTID last_committed=34 sequence_number=35 rbr_only=no
SET @@SESSION.GTID_NEXT= 'bde7b592-b966-11e9-8c64-000c294f3e61:10445'/*!*/;
#at 15083
#190808 14:22:19 server id 63306 end_log_pos 15211 CRC32 0x8d445019 Query thread_id=7213 exec_time=0 error_code=0
use `testdb`/*!*/;
SET TIMESTAMP=1565245339/*!*/;
SET @@session.sql_auto_is_null=0/*!*/;
DROP TABLE `test1_event` /* generated by server */
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
#End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
定位到15018 這個位置點就是利用binlog的文件恢復時的結束點
2.5恢復xtrabackup備份到 mysql3308 實例上:
提示:mysql 3308實例要開啓Gtid的
恢復備份的命令:
innobackupex --apply-log /data/backup/db_3306_20190808/
innobackupex --defaults-file=/data/mysql/mysql3308/my3308.cnf --copy-back /data/backup/db_3306_20190808/
給數據目錄data mysql 權限:
chown -R mysql.mysql /data/mysql/mysql3308/data/
啓動mysql3308 實例:
/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3308/my3308.cnf &
查看到恢復到3308實例的數據,但是在備份3306庫到刪除表test1_event 這時間段還存在很多缺失的數據未找回,要從增量的binlog文件中找回:
| 10273 | tomcat | xiaohuahua | 2019-08-08 14:17:16 |
| 10274 | tomcat | xiaohuahua | 2019-08-08 14:17:18 |
+-------+----------+------------+---------------------+
(root@'mgr01':mysql3308.sock)[testdb]>select count(*) from test1_event;
+----------+
| count(*) |
+----------+
| 10273 |
+----------+
1 row in set (0.00 sec)
xtrabackup 備份是開啓Gtid的,所以下面使用mysqlbinlog命令 進行增量binglog文件恢復數據時,要添加參數--skip-gtids 忽略掉binlog文件的中的Gtid信息,要是不加參數--skip-gtids 進行恢復的話,導致數據恢復不到3308庫
正確的恢復命令如下:
mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.000001 --skip-gtids |mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.000002 --skip-gtids |mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.000003 --skip-gtids |mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.000004 --skip-gtids |mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.000005 --stop-position="15018" --skip-gtids |mysql -f --binary-mode -S /tmp/mysql3308.sock
參數說明:
--skip-gtids 忽略binlog文件中的Gtid的信息
--binary-mode 主要是爲了解決中文亂碼或者是特殊字符串亂碼的問題
-f 強制恢復,忽略報錯
執行完以上命令,數據就恢復到刪除表test1_event之前的了
下面的恢復命令會導致數據恢復不到mysql 3308 實例上:(原因是my3308實例開啓了Gtid參數導致的)
mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.000001 |mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.000002 |mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.000003 |mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.000004 |mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog --stop-position="15018" /data/mysql/mysql3306/binlog/mysql-bin.000005|mysql -f --binary-mode -S /tmp/mysql3308.sock
2.6如果新的實例mysql3308 啓動前從my3308.cnf中關閉掉Gtid參數:
3.
這樣的話採用mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.00000* |mysql -f --binary-mode -S /tmp/mysql3308.sock 是可以將數據恢復到mysql 3308實例上的,但是恢復過程中報錯。這樣恢復到3308的數據,
生成的binlog文件是不記錄Gtid信息的
[root@mgr01 backup]# mysqlbinlog --stop-position="15018" /data/mysql/mysql3306/binlog/mysql-bin.000005|mysql -f --binary-mode -S /tmp/mysql3308.sock
ERROR 1781 (HY000) at line 17: @@SESSION.GTID_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID_MODE = OFF.
ERROR 1781 (HY000) at line 50: @@SESSION.GTID_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID_MODE = OFF.
ERROR 1781 (HY000) at line 74: @@SESSION.GTID_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID_MODE = OFF.
ERROR 1781 (HY000) at line 98: @@SESSION.GTID_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID_MODE = OFF.
當然也可以採用下面的方式來恢復,同樣3308的實例的binglog文件是不記錄Gtid信息的,這種方法在恢復的過程中可能會出現報錯,不能完全保證數據的完整性和正確性,所以生產上最好不要使用這種方法來恢復找回數據
[root@mgr01 backup]# mysqlbinlog --skip-gtids /data/mysql/mysql3306/binlog/mysql-bin.000001|mysql -f --binary-mode -S /tmp/mysql3308.sock
ERROR 1050 (42S01) at line 27: Table 'test1_event' already exists
ERROR 1062 (23000) at line 92: Duplicate entry '1' for key 'PRIMARY'
ERROR 1537 (HY000) at line 132: Event 'e_test' already exists
mysqlbinlog --skip-gtids /data/mysql/mysql3306/binlog/mysql-bin.000002|mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog --skip-gtids /data/mysql/mysql3306/binlog/mysql-bin.000003|mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog --skip-gtids /data/mysql/mysql3306/binlog/mysql-bin.000004|mysql -f --binary-mode -S /tmp/mysql3308.sock
mysqlbinlog --skip-gtids --stop-position="15018" /data/mysql/mysql3306/binlog/mysql-bin.000005|mysql -f --binary-mode -S /tmp/mysql3308.sock
友情提示:生產上還是最好開啓Gtid. 這樣在恢復數據和數據庫同步,以及解決同步錯誤是非常方便的
總結:
對於DDL語句像 drop database ,drop tables , drop tables , truncate table 這樣的語句就可以採用mysqlbinlog 來恢復。同時也可以採用binlog2sql工具來閃回
對於這樣的語句,不管binglog 格式爲row 格式,還是statement 格式,還是Mixed 格式,記錄的binlog格式都爲 statement 格式爲row
利用mysqlbinlog 只能支持到database級別的提取
全備+利用mysqlbinlog恢復到某個時間點
利用mysqlbinlog --skip-gtids 存在很大風險點