背景
在進行開發的時候,本來是想刪除一張廢棄表,結果刪表的時候沒有進行對比,導致刪錯了數據 表,在此記錄一下恢復數據的過程
一、初識binlog
1、我們知道mysq有一個專門的日志記錄,叫binlog,mysql-binlog是MySQL數據庫的二進制日志,用於記錄用戶對數據庫操作的SQL語句,它記錄了所有的DDL和DML語句(除了數據查詢語句select),可以使用mysqlbin命令查看二進制日志的內容。運行服務器時若啟用二進制日志則性能大約慢1%。但是,二進制日志的好處,即用於恢復並允許設置復制超過了這個小小的性能損失。mysqld在每個二進制日志名后面添加一個數字擴展名。每次你啟動服務器或刷新日志時該數字則增加。如果當前的日志大小達到max_binlog_size,還會自動創建新的二進制日志。如果你正使用大的事務,二進制日志還會超過max_binlog_size:事務全寫入一個二進制日志中,絕對不要寫入不同的二進制日志中,為了能夠知道還使用了哪個不同的二進制日志文件,mysqld還創建一個二進制日志索引文件,包含所有使用的二進制日志文件的文件名。默認情況下與二進制日志文件的文件名相同,擴展名為'.index'。你可以用--log-bin-index[=file_name]選項更改二進制日志索引文件的文件名。當mysqld在運行時,不應手動編輯該文件;如果這樣做將會使mysqld變得混亂。
2、binlog使用場景
1、用於主從復制,master通過像從服務器發送binlog文件進行數據同步
2、恢復使能夠最大可能地更新數據庫
3、MySQL binlog格式
binlog的格式也有三種:STATEMENT、ROW、MIXED 。
1、STATMENT模式:基於SQL語句的復制(statement-based replication, SBR),每一條會修改數據的sql語句會記錄到binlog中。
優點:不需要記錄每一條SQL語句與每行的數據變化,這樣子binlog的日志也會比較少,減少了磁盤IO,提高性能。
缺點:在某些情況下會導致master-slave中的數據不一致(如sleep()函數, last_insert_id(),以及user-defined functions(udf)等會出現問題)
2、基於行的復制(row-based replication, RBR):不記錄每一條SQL語句的上下文信息,僅需記錄哪條數據被修改了,修改成了什么樣子了。
優點:不會出現某些特定情況下的存儲過程、或function、或trigger的調用和觸發無法被正確復制的問題。
缺點:會產生大量的日志,尤其是alter table的時候會讓日志暴漲。
3、混合模式復制(mixed-based replication, MBR):以上兩種模式的混合使用,一般的復制使用STATEMENT模式保存binlog,對於STATEMENT模式無法復制的操作使用ROW模式保存binlog,MySQL會根據執行的SQL語句選擇日志保存方式。
4、配置binlog
在MySQL配置文件my.cnf文件中的mysqld節中添加下面的配置文件:
[mysqld]
binlog_format = mixed #設置日志格式
log-bin = /data/mysql/logs/mysql-bin.log #設置日志路徑,注意路經需要mysql用戶有權限寫
expire_logs_days = 7#設置binlog清理時間
max_binlog_size = 100m#binlog每個日志文件大小
binlog_cache_size = 4m#binlog緩存大小
max_binlog_cache_size = 512m#最大binlog緩存大小
重啟MySQL生效。
mysqld-bin.index則記錄了所有的log的文件名稱
binlog日志以以mysqld-bin.00000X等作為名稱
5、首先進入mysql命令,查看binlog日志是否已經開啟。輸入命令show variables like 'log_bin';如下圖所示,如果沒有開啟binlog那么恭喜你,恢復數據就增加難度了。
1、show variables like 'log_bin' 查看日志是否開啟
2、show master logs; 查看日志列表
3、show master status;查看最后一個binlog日志的編號名稱,及其最后一個操作事件pos結束點(Position)值。
a、查詢第一個最早的binlog日志:
show binlog events\G;
b、指定查詢mysql-bin.000002這個文件
show binlog events in 'mysql-bin.000002'\G;
c、指定查詢mysql-bin.000002這個文件,從pos點:624開始查起:
show binlog events in 'mysql-bin.000002' from 624\G;
d、指定查詢mysql-bin.000002這個文件,從pos點:624開始查起,查詢10條(即10條語句)
show binlog events in 'mysql-bin.000002' from 624 limit 10\G;
e、指定查詢 mysql-bin.000002這個文件,從pos點:624開始查起,偏移2行(即中間跳過2個)查詢10條(即10條語句)。
show binlog events in 'mysql-bin.000002' from 624 limit 2,10\G;
6、恢復數據的方式
1、按時間點恢復
通過shell命令mysqlbinlog 查看binlog日志文件,找到需要的時間節點。然后通過以下命令
mysqlbinlog --start-datetime="2018-04-20 10:01:00" --stop-datetime="2005-04-21 10:01:00" mysql-bin.000001 | mysql -u root -pxxx database_name
--start-datetime=datetime
從二進制日志中第1個日期時間等於或晚於datetime參量的事件開始讀取。datetime值相對於運行mysqlbinlog的機器上的本地時區。該值格式應符合DATETIME或TIMESTAMP數據類型。

2、按位置號恢復
通過shell命令mysqlbinlog 查看binlog日志文件,找到需要的位置節點。然后通過以下命令
mysqlbinlog --stop-position="102" --start-position="367" mysql-bin.000001 | mysql -uroot -pxxx database_name

7、其實恢復數據有很多種方式,比如平時開啟備份,那么我們可以通過備份的數據進行數據庫恢復,然后在通過binlog日志進行恢復。