1. 程式人生 > >mysql通過binlog二進位制日誌恢復資料

mysql通過binlog二進位制日誌恢復資料

有些萌新做事的時候經常大大咧咧,有一天萌新心血來潮寫了個sql delete from tablename 然後小手指一點,糟了沒加where條件。萌新的mysql還沒入門就到了刪庫跑路這一步。 資料都沒了,怎麼辦?沒關係我們可以使用乾坤大挪移,讓時間倒流打死這個萌新。
一般情況下如果我們有備份的時候,會通過備份來恢復資料庫。那麼沒有備份的時候呢,你最好祈禱開了二進位制日誌binlog。神馬?二進位制日誌也沒開,OK OK 沒關係 我們先打死萌新祭資料庫,然後以死謝罪。
話不多說,操作起來。
一般情況下我們安裝mysql之後二進位制日誌並沒有開啟,需要我們自行開啟。
開啟方法如下:

1.開啟bin-log
(1)在/etc/my.cnf配置檔案裡面
[mysqld] #選項新增
log-bin=mysql-bin #日誌檔名稱,未指定位置,預設資料檔案位置
重啟mysql服務
log_bin是生成的bin-log的檔名,字尾則是6位數字的編碼,從000001開始,按照上面的配置,生成的檔案則為: 
      mysql_bin.000001 
      mysql_bin.000002 
      ...... 
基本操作
2.基本操作
(1)檢視所有日誌檔案:
mysql> show binary logs;   或show master logs;
+------------------+-----------+
| Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 120 | +------------------+-----------+ (2)檢視正在寫入的日誌檔案: mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 120 | | | | +------------------+----------+--------------+------------------+-------------------+ (3)檢視當前binlog檔案內容: mysql> show binlog events; #可以格式化輸出 show binlog events\G; 或指定日誌檔案檢視show binlog events in 'mysql-bin.000001'; +------------------+-----+-------------+-----------+-------------+---------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+-------------+-----------+-------------+---------------------------------------+ | mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.25-log, Binlog ver: 4 | +------------------+-----+-------------+-----------+-------------+-------------------- 注: Log_name:此條log存在哪個檔案中 Pos:log在bin-log中的開始位置 Event_type:log的型別資訊 Server_id:可以檢視配置中的server_id,表示log是哪個伺服器產生 End_log_pos:log在bin-log中的結束位置 Info:log的一些備註資訊,可以直觀的看出進行了什麼操作 (4)手動啟用新的日誌檔案,一般備份完資料庫後執行 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 120 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> flush logs; #結束正在寫入日誌檔案 Query OK, 0 rows affected (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000002 | 120 | | | | +------------------+----------+--------------+------------------+-------------------+ (5)刪除所有二進位制日誌,並從新開始記錄 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000002 | 120 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> reset master; #重新開始 Query OK, 0 rows affected (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 120 | | | | +------------------+----------+--------------+------------------+-------------------+ 還有: mysql> purge master logs to 'mysql-bin.000002'; #是將'mysql-bin.000002'編號之前的所有日誌進行刪除 mysql> purge master logs before 'yyyy-mm-dd hh:mm:ss' #是將在'yyyy-mm-dd hh:mm:ss'時間之前 3.二進位制日誌檔案匯出 # mysqlbinlog binlog.000001 >1.sql #到處成sql格式 # mysqlbinlog --start-datetime="2018-03-20 11:25:56" --stop-datetime="2018-03-20 14:20:10" mysql-bin.000001 > /data/test01.log #按時間點匯出 # mysqlbinlog --start-position=203 --stop-position=203 mysql-bin.000001 > /data/test02.log #按事件位置匯出 4.恢復資料 強烈建議:做任何恢復之前都給資料庫做一個完整備份,新建庫進行恢復。 恢復 bin-log是記錄著mysql所有事件的操作,可以通過bin-log做完整恢復,基於時間點的恢復,和基於位置的恢復 (1)完整恢復,先執行上次完整備份恢復,再執行自上次備份後產生的二進位制日誌檔案恢復 # mysql localhost mysql-bin.000001 | mysql -uroot -p 這樣資料庫就可以完全的恢復到崩潰前的完全狀態 (2)基於時間點的恢復,如果確認誤操作時間點為2018-03-20 10:00:00執行如下 # mysqlbinlog --stop-date='2018-03-02 9:59:59' mysql-bin.000001 | mysql -uroot -p 然後跳過誤操作的時間點,繼續執行後面的binlog # mysqlbinlog --start-date='2018-03-20 10:01:00' mysql-bin.000001 | mysql -uroot -p 其中--stop-date='2018-03-20 9:59:59' 和 --start-date='2018-03-20 10:01:00' 取兩時間點 # mysqlbinlog --start-datetime="2018-03-20 11:25:56" --stop-datetime="2018-03-20 14:20:10" mysql-bin.000001 | mysql -u root -p #注:其中的時間是你誤操作的時間,而且這個時間點還可能涉及到的不只是誤操作,也有可能有正確的操作也被跳過去了。那麼執行位置恢復 基於位置恢復,通過檢視日誌檔案資訊,確認6259-6362為誤操作點 # mysqlbinlog --stop-position=6259 mysql-bin.000001 | mysql -uroot -p #從1開始至6259的事件讀,不包括6259事件 # mysqlbinlog --start-position=6363 mysql-bin.000001 | mysql -uroot -p #從6259的事件開始讀 # 取兩事件點 mysqlbinlog --start-position=5786 --stop-position=6254 mysql-bin.000001 | mysql -uroot -p 到此為止基本就可以恢復被誤刪的資料了。 當然我們平時還是要管理好資料庫許可權,避免萌新們誤刪資料帶來不必要的麻煩。當我們操作生產環境上的正式資料庫時候一點要在操作之前先備份,提前做好準備。避免給正式資料庫造成不必要的資料汙染。