生產環境誤執行 DELETE、UPDATE、TRUNCATE 後,若開啟了 Row 格式 Binlog,利用淘寶彭立勳開發的 mysqlbinlog Flashback 功能,可將 Binlog 事件逆向重放:DELETE → INSERT、UPDATE → 反向 UPDATE、INSERT → DELETE,實現**無需全量備份、分鐘級精準恢復**。本文完整記錄編譯、定位、驗證、恢復全流程。
wget https://mysql.taobao.org/images/0/0f/5.5.18_flashback.diffpatch -p0 < 5.5.18_flashback.diffcmake . && make mysqlbinlog./mysqlbinlog --help | grep -B 出現 -B, --flashback 即成功。提示:二進制文件可直接從 GitHub 下載(Linux x86_64)。
mysql> SELECT COUNT(*) FROM pic_url; -- 786476
mysql> DELETE FROM pic_url; -- 22.81 秒刪除 78 萬行
mysql> SELECT COUNT(*) FROM pic_url; -- 0
mysql> SHOW BINARY LOGS;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000011 | 195001447 |
| mysql-bin.000012 | 106 |
+------------------+-----------+
最新文件極小(106 byte),說明誤刪在 mysql-bin.000011 末尾。
./mysqlbinlog -v --base64-output=decode-rows /u1/mysql/logs/mysql-bin.000011 > 11.sql
# 用編輯器搜表名 pic_url,定位 DELETE 事件的 start/stop position
# 假設發現:start-position=377, stop-position=195001377
# 生成帶逆向語句的文件
./mysqlbinlog -v --base64-output=decode-rows -B \
--start-position=377 --stop-position=195001377 \
/u1/mysql/logs/mysql-bin.000011 > B11.sql
# 檢查 B11.sql 開頭是否為 INSERT(原 DELETE 逆向),確認無誤
head -50 B11.sql
./mysqlbinlog -B --start-position=377 --stop-position=195001377 \
/u1/mysql/logs/mysql-bin.000011 | mysql test
大表恢復較慢,耐心等待。完成後驗證:
mysql> SELECT COUNT(*) FROM pic_url; -- 786476 ✓
ERROR 1153: Got a packet bigger than 'max_allowed_packet' bytes。SET GLOBAL max_allowed_packet = 1024*1024*1024; -- 1GBbinlog_format = ROW,Statement/Mixed 格式無法逆向行級變更。--start/stop-position 需精確到事務邊界,否則可能產生不完整逆向語句導致數據不一致。DROP TABLE、TRUNCATE、ALTER TABLE 等 DDL 無 Flashback 支持,需配合備份恢復。生產環境建議部署 pt-heartbeat 寫入心跳表,通過心跳時間戳快速定位誤操作發生的 Binlog 位點區間,避免全量解析大 Binlog 文件。
mysqlbinlog Flashback 是 **Row 模式 Binlog 下的「後悔藥」**:編譯帶 -B 參數的工具 → 解析定位位點 → 生成逆向 SQL 驗證 → 管道執行恢復。配合 max_allowed_packet 調大、備庫驗證、pt-heartbeat 定位,可將誤刪/誤更新恢復時間從「小時級(全量備份+增量)」壓縮至「分鐘級」,是 DBA 必備的核心應急技能。