mysql通過binlog來恢復被刪除的資料庫
阿新 • • 發佈:2020-10-12
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表。