1. 程式人生 > 實用技巧 >mysql通過binlog來恢復被刪除的資料庫

mysql通過binlog來恢復被刪除的資料庫

binlog日誌

查詢:
MariaDB [(none)]> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

MariaDB [(none)]> show variables like 'binlog_format';
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
1 row in set (0.01 sec)


設定:
log_bin/data/mysql/mysql-bin
binlog_format=row


詳細:
[mysqld]
basedir=/application/mysql
datadir=/application/mysql/data
socket=/tmp/mysql.sock
log-error=/var/log/mysql.log
log-bin=/data/mysql/mysql-bin
server-id=1
port=3306

log_bin=/data/mysql/mysql-bin
binlog_format=row
[client]
socket=/tmp/mysql.sock


設定完成後檢查:
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |     <------ binlog日誌開啟
+---------------+-------+
1 row in set (0.00 sec)

mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |   <------ binlog日誌開啟 
+---------------+-------+
1 row in set (0.00 sec)



mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       177 |
| mysql-bin.000002 |       177 |
| mysql-bin.000003 |     97002 |
| mysql-bin.000004 |     97002 |
| mysql-bin.000005 |     97002 |
| mysql-bin.000006 |       143 |
| mysql-bin.000007 |       120 |
+------------------+-----------+
7 rows in set (0.01 sec)


binlog開啟後,可以通過命令檢視到哪些日誌是正在使用的
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
#這裡的日誌 只有一個是在被使用的


檢視一個binlog日誌詳情:
mysql> show binlog events in 'mysql-bin.000004' limit 5;
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000004 |   4 | Format_desc    |         6 |         123 | Server ver: 5.7.20-log, Binlog ver: 4 |
| mysql-bin.000004 | 123 | Previous_gtids |         6 |         154 |                                       |
| mysql-bin.000004 | 154 | Anonymous_Gtid |         6 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000004 | 219 | Query          |         6 |         317 | CREATE DATABASE mysql;                |
| mysql-bin.000004 | 317 | Anonymous_Gtid |         6 |         382 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
5 rows in set (0.00 sec)
這是檢視這個binlog日誌的前五個事件。

記住: 在binlog最小的記錄單元叫event,一個事務會被拆分為多個event。
event特性: 每個event都有一個開始位置[start-position]和一個結束位置[stop-position]

所謂的位置就是: event對於整個二進位制檔案的相對位置
在一個二進位制日誌中,前120個 position是檔案格式資訊的預留空間
也就是mysql第一個記錄的時間,都是從120開始的

--row模式下的二進位制日誌分析案例:
1. 檢視日誌量
mysql> show master status;  
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

2. 檢視日誌量
mysql> create database binlog;
Query OK, 1 row affected (0.00 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |      220 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)   ## 說並已經記錄了二進位制日誌了

再新增資料:
mysql> use binlog;
Database changed
mysql> create table bt(id int);
Query OK, 0 rows affected (0.01 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |      321 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)



插入一個ddl內容:
mysql> insert into bt values(1);
Query OK, 1 row affected (0.00 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |      513 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

[自動提交,如果沒有變化可以使用 commit 提交一次]
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |      705 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)




主要命令:
mysql> show master status;
mysql> create database binlog;
mysql> show master status;
mysql> use binlog;




#更新資料
mysql> update bt set id=2 where id=2;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |     1862 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


此時感覺錯了,想恢復到delete之前的操作發現不會,所以我果斷直接刪了:
mysql> select * from bt;
+------+
| id   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

mysql> drop table bt;
Query OK, 0 rows affected (0.00 sec)

此時通過binlog檢視資料:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |     1981 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

此時。。連庫也直接刪了:
mysql> drop database binlog;
Query OK, 0 rows affected (0.01 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| world              |
+--------------------+
5 rows in set (0.00 sec)
這時候,整個binlog庫都被刪除了。


此時來了個大神需要恢復資料:
此時需要用二進位制日誌進行恢復

恢復思路:
二進位制日誌是以時間進記錄的.
1. 通過show master status; 檢視到記錄的日誌檔案。
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |     2070 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

2. 檢視這個日誌:
mysql> show binlog events in 'mysql-bin.000007';
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------+
| Log_name         | Pos  | Event_type  | Server_id | End_log_pos | Info                                                    |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------+
| mysql-bin.000007 |    4 | Format_desc |         1 |         120 | Server ver: 5.6.38-log, Binlog ver: 4                   |
| mysql-bin.000007 |  120 | Query       |         1 |         220 | create database binlog                                  |
| mysql-bin.000007 |  220 | Query       |         1 |         321 | use `binlog`; create table bt(id int)                   |
| mysql-bin.000007 |  321 | Query       |         1 |         395 | BEGIN                                                   |
| mysql-bin.000007 |  395 | Table_map   |         1 |         442 | table_id: 70 (binlog.bt)                                |
| mysql-bin.000007 |  442 | Write_rows  |         1 |         482 | table_id: 70 flags: STMT_END_F                          |
| mysql-bin.000007 |  482 | Xid         |         1 |         513 | COMMIT /* xid=46 */                                     |
| mysql-bin.000007 |  513 | Query       |         1 |         587 | BEGIN                                                   |
| mysql-bin.000007 |  587 | Table_map   |         1 |         634 | table_id: 70 (binlog.bt)                                |
| mysql-bin.000007 |  634 | Write_rows  |         1 |         674 | table_id: 70 flags: STMT_END_F                          |
| mysql-bin.000007 |  674 | Xid         |         1 |         705 | COMMIT /* xid=48 */                                     |
| mysql-bin.000007 |  705 | Query       |         1 |         779 | BEGIN                                                   |
| mysql-bin.000007 |  779 | Table_map   |         1 |         826 | table_id: 70 (binlog.bt)                                |
| mysql-bin.000007 |  826 | Write_rows  |         1 |         866 | table_id: 70 flags: STMT_END_F                          |
| mysql-bin.000007 |  866 | Xid         |         1 |         897 | COMMIT /* xid=79 */                                     |
| mysql-bin.000007 |  897 | Query       |         1 |         971 | BEGIN                                                   |
| mysql-bin.000007 |  971 | Table_map   |         1 |        1018 | table_id: 70 (binlog.bt)                                |
| mysql-bin.000007 | 1018 | Write_rows  |         1 |        1058 | table_id: 70 flags: STMT_END_F                          |
| mysql-bin.000007 | 1058 | Xid         |         1 |        1089 | COMMIT /* xid=81 */                                     |
| mysql-bin.000007 | 1089 | Query       |         1 |        1163 | BEGIN                                                   |
| mysql-bin.000007 | 1163 | Table_map   |         1 |        1210 | table_id: 70 (binlog.bt)                                |
| mysql-bin.000007 | 1210 | Write_rows  |         1 |        1250 | table_id: 70 flags: STMT_END_F                          |
| mysql-bin.000007 | 1250 | Xid         |         1 |        1281 | COMMIT /* xid=87 */                                     |
| mysql-bin.000007 | 1281 | Query       |         1 |        1355 | BEGIN                                                   |
| mysql-bin.000007 | 1355 | Table_map   |         1 |        1402 | table_id: 70 (binlog.bt)                                |
| mysql-bin.000007 | 1402 | Delete_rows |         1 |        1442 | table_id: 70 flags: STMT_END_F                          |
| mysql-bin.000007 | 1442 | Xid         |         1 |        1473 | COMMIT /* xid=89 */                                     |
| mysql-bin.000007 | 1473 | Query       |         1 |        1547 | BEGIN                                                   |
| mysql-bin.000007 | 1547 | Table_map   |         1 |        1594 | table_id: 70 (binlog.bt)                                |
| mysql-bin.000007 | 1594 | Delete_rows |         1 |        1634 | table_id: 70 flags: STMT_END_F                          |
| mysql-bin.000007 | 1634 | Xid         |         1 |        1665 | COMMIT /* xid=91 */                                     |
| mysql-bin.000007 | 1665 | Query       |         1 |        1739 | BEGIN                                                   |
| mysql-bin.000007 | 1739 | Table_map   |         1 |        1786 | table_id: 70 (binlog.bt)                                |
| mysql-bin.000007 | 1786 | Delete_rows |         1 |        1831 | table_id: 70 flags: STMT_END_F                          |
| mysql-bin.000007 | 1831 | Xid         |         1 |        1862 | COMMIT /* xid=93 */                                     |
| mysql-bin.000007 | 1862 | Query       |         1 |        1981 | use `binlog`; DROP TABLE `bt` /* generated by server */ |
| mysql-bin.000007 | 1981 | Query       |         1 |        2070 | drop database binlog                                    |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------+
37 rows in set (0.00 sec)

發現binlog也記錄了刪除資料的操作。但是又很多看不懂,此時需要使用binlog的專門工具進行檢視
檢視:
mysqlbinlog --base64-output=decode-rows  -vvv /data/mysql/mysql-bin.000007


擷取刪除之前的日誌:
mysqlbinlog --start-position=120 --stop-position=1402 /data/mysql/mysql-bin.000007 >bin.sql


在資料庫中暫時關閉日誌記錄:
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.01 sec)


開始恢復資料:
mysql> source /root/bin.sql

驗證資料:
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| binlog             |
| mysql              |
| performance_schema |
| test               |
| world              |
+--------------------+
6 rows in set (0.00 sec)

已經恢復了 被刪除的  binlog  資料庫

mysql> show tables;
+------------------+
| Tables_in_binlog |
+------------------+
| bt               |
+------------------+
1 row in set (0.00 sec)
經過檢查 也恢復了被刪除的BT表。