1. 程式人生 > 其它 >MySQL 誤刪資料應該怎麼處理?

MySQL 誤刪資料應該怎麼處理?

如此處理各種情況下的誤刪資料

delete 語句刪除

用 delete 語句誤刪了資料行,可以用 Flashback 工具通過閃回把資料恢復回來。Flashback 恢復資料的原理,是修改 binlog 的內容,拿回原庫重放。而能夠使用這個方案的前提是,需要確保
binlog_format=row 和 binlog_row_image=FULL。

具體恢復資料時,對單個事務做如下處理:

  • 對於 insert 語句,對應的 binlog event 型別是 Write_rows event,把它改成 Delete_rows event 即可;
  • 同理,對於 delete 語句,也是將 Delete_rows event 改為 Write_rows event;而如果是 Update_rows 的話,binlog 裡面記錄了資料行修改前和修改後的值,對調這兩行的位置即可。

如果要恢復多個事務,需要順序反過來執行。

Flashback 解析到的日誌需要反過來執行,並且最好找一個臨時庫恢復出一個備份,確認沒問題再恢復到主庫。

預防誤刪的策略:
1、將sql_safe_updates引數設定為on, 這樣delete或者update語句沒有寫where條件的話,就會報錯。
2、程式碼上線前要求SQL審計

drop table 或者 truncate table

使用drop table或者truncate table刪除資料,即使binlog_format=row,記錄的binlog還是statement格式。

這時候只有使用全量備份 + 增量備份,這個方案要求線上有定期的全量備份,並且實時備份binlog。

方法是:

  1. 取最近一次全量備份;
  2. 用備份恢復出一個臨時庫;
  3. 將全量備份後產生的增量日誌應用到臨時庫,增量日誌需要剔除掉誤操作的記錄。

mysqlbinlog 支援 --database 同步某個資料庫,但不支援指定資料表。

怎麼跳過誤刪除的那個記錄?

  1. 無gtid。--stop-position 應用誤操作之前的日誌,--start-position從誤操作之後的日誌繼續執行
  2. 有gtid。假設誤操作的gtid是gtid1,那麼只需要執行
    set gtid_next=gtid1;begin;commit;加到臨時例項的gtid集合,之後按順序執行binlog,自動跳過誤操作的語句。

延遲複製備庫


如果有非常核心的業務,不允許太長的恢復時間,我們可以考慮搭建延遲複製的備庫。這個功能是 MySQL 5.6 版本引入的。

延時複製的備庫是一種特殊的備庫,通過 CHANGE MASTER TO MASTER_DELAY = N 命令,可以指定這個備庫持續保持跟主庫有 N 秒的延遲。

drop database

預防為主,賬號分離,日常只使用只讀賬號。製作規範,比如刪除表前重命名錶為xxx_to_deleted, 觀察沒問題後通過管理系統刪除。

rm命令刪除這個MySQL例項

對於一個有高可用機制的 MySQL 叢集來說,最不怕的就是 rm 刪除資料了。只要不是惡意地把整個叢集刪除,而只是刪掉了其中某一個節點的資料的話,HA 系統就會開始工作,選出一個新的主庫,從而保證整個叢集的正常工作。這時,你要做的就是在這個節點上把資料恢復回來,再接入整個叢集。