使用mysqlbinlog恢復指定表


從整庫備份的sql文件中導出某個表的sql語句時,vim查找到表的第一條INSERT語句后,按上下換行鍵計數INSERT語句的條數,然后按n yy復制,退出vim后,
再新建一個文件,按p粘貼剛才的n條INSERT語句,再進行source導入。

----------------------------------------------------------------

一、登錄數據庫刷新binlog

1.1)查看當前的binlog
MySQL> show master status;
+---------------------+----------+--------------+------------------+-------------------+
| File                | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------------+----------+--------------+------------------+-------------------+
| test-150-bin.000003 |  2895377 |              |                  |                   |
+---------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

1.2)刷新binlog
mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)

1.3)確認刷新binlog成功
mysql> show master status;
+---------------------+----------+--------------+------------------+-------------------+
| File                | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------------+----------+--------------+------------------+-------------------+
| test-150-bin.000004 |      120 |              |                  |                   |
+---------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
用show master status 命令查看當前的binlog已經由test-150-bin.000003變為test-150-bin.000004,
證明binlog已經刷新成功。

二、查詢二進制日志位置
mysql> show variables like'log_bin%';
+---------------------------------+------------------------------------------+
| Variable_name                   | Value                                    |
+---------------------------------+------------------------------------------+
| log_bin                             | ON                                       |
| log_bin_basename             | /db/mysql5.6/data/test-150-bin       |
| log_bin_index                    | /db/mysql5.6/data/test-150-bin.index |
| log_bin_trust_function_creators  | ON                                       |
| log_bin_use_v1_row_events       | OFF                                      |
+---------------------------------+------------------------------------------+

三、從二進制日志中獲取表被刪除的時間
$ mysqlbinlog test-150-bin.000003 | grep -i DROP  -A3 -B4
COMMIT/*!*/;
# at 122869
#140126 17:03:35 server id 150  end_log_pos 122989 CRC32 0x8707c4c4     Query   thread_id=12519 exec_time=0     error_code=0
SET TIMESTAMP=1390727015/*!*/;
DROP TABLE `test` /* generated by server */
/*!*/;
# at 122989
#140126 17:04:06 server id 150  end_log_pos 123039 CRC32 0x43476aad     Rotate to test-150-bin.000004  pos: 4

drop語句的前兩行表名drop語句的執行時間是在 17:03:35
mysql> SELECT from_unixtime('1390727015');
+-----------------------------+
| from_unixtime('1390727015')  |
+-----------------------------+
| 2014-01-26 17:03:35.000000 |
+-----------------------------+
1 row in set

 

四、從binlog中獲取指定數據庫的改變數據
用mysqlbinlog 恢復ivr數據庫在二進制日志test-150-bin.000003中的數據
假設從上一次mysql備份后,只有一個binlog產生,即登錄數據庫時查詢到binlog test-150-bin.000003

mysqlbinlog -d ivr --stop-datetime='2014-01-26 17:03:35' test-150-bin.000003 > recover_ivr.sql

如果從上次備份刷新binlog,到發現表被刪掉的過程中產生了多個binlog。則要按照binlog產生的順序進行恢復,那
么恢復的次序應該是按照binglog的產生的序號,從小到大依次恢復。
假如從上次備份,到發現表被刪除,共有兩個binlog文件,分別是test-150-bin.000002,test-150-bin.000003 ,
則按照binlog序號從小到大的排列,恢復的順序應該是:

mysqlbinlog -d ivr  test-150-bin.000002  > recover_ivr.sql

mysqlbinlog -d ivr --stop-datetime='2014-01-26 17:03:35' test-150-bin.000003  >> recover_ivr.sql

由於恢復的文件recover_ivr.sql中包含了整個ivr數據庫的所有表,我們只要恢復指定的表mytable,還要對恢復出來的sql進行過濾

cat recover_ivr.sql | grep  -A1 -B3 -i -E '^insert|^update|^delete|^replace|^alter' | grep -A1 -B3 mytable  > mytable.sql

可以先使用more確認一下
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
--
# at 122721
#140126 17:03:28 server id 150  end_log_pos 122721 CRC32 0xe0f851bb     Intvar
SET INSERT_ID=4/*!*/;
#140126 17:03:28 server id 150  end_log_pos 122838 CRC32 0x9efcc7b2     Query   thread_id=12578 exec_time=0     error_code=0
use `ivr`/*!*/;
SET TIMESTAMP=1390727008/*!*/;
INSERT INTO `testtuo` (`name`) VALUES ('d')
/*!*/;
# at 122838

將過濾后的結果保存為sql腳本,恢復到數據庫即可。


恢復之前為了避免產生沒有用的二進制日志,可以關閉二進制日志的記錄
SET SESSION sql_log_bin=0;

恢復完成,啟用記錄二進制日志
SET SESSION sql_log_bin=1;

 

 

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM