淘寶彭立勳開發的 mysqlbinlog 擴展補丁,針對 ROW 格式 binlog 生成逆向 SQL:
DELETE → INSERTUPDATE → 反向 UPDATE(舊值換新值)INSERT → DELETE讓 DBA 具備「時光機」能力,無需完整 PITR 即可精準撤銷誤操作。
# 1. 獲取源碼(以 Percona 5.5.18 為例)
wget https://www.percona.com/downloads/Percona-Server-5.5/Percona-Server-5.5.18/source/Percona-Server-5.5.18.tar.gz
tar xzf Percona-Server-5.5.18.tar.gz
cd Percona-Server-5.5.18
# 2. 下載並應用補丁
wget https://mysql.taobao.org/images/0/0f/5.5.18_flashback.diff
patch -p0 < 5.5.18_flashback.diff
# 3. 僅編譯 mysqlbinlog(無需完整編譯 MySQL)
cmake . -DBUILD_CONFIG=mysql_release -DWITHOUT_SERVER=ON
make mysqlbinlog
# 4. 驗證
./mysqlbinlog --help | grep -B2 -A2 flashback
# 應出現 -B, --flashback 選項
備選:作者提供預編譯 64 位 Linux 二進制:GitHub 下載。
mysql> SELECT COUNT(*) FROM pic_url; -- 786476
mysql> DELETE FROM pic_url; -- 22.81s 刪光
mysql> SELECT COUNT(*) FROM pic_url; -- 0
mysql> SHOW BINARY LOGS;
-- 當前文件較小,目標在上一個文件 mysql-bin.000011
# 解碼查看(調試用)
./mysqlbinlog -v --base64-output=decode-rows mysql-bin.000011 > 11.sql
# 搜索 'pic_url' 定位 DELETE 事件的 start/stop position
# 假設:start=377, stop=195001377
./mysqlbinlog -v --base64-output=decode-rows -B \
--start-position=377 --stop-position=195001377 \
mysql-bin.000011 > B11.sql
# 檢查 B11.sql 尾部是否為大量 INSERT INTO pic_url ...
# 關鍵:調大 max_allowed_packet 防止大包報錯
mysql> SET GLOBAL max_allowed_packet = 1024*1024*1024;
# 管道直連執行
./mysqlbinlog -B --start-position=377 --stop-position=195001377 \
mysql-bin.000011 | mysql test
mysql> SELECT COUNT(*) FROM pic_url; -- 786476 ✅
| 參數 | 說明 |
|---|---|
-B, --flashback | 啟用逆向生成 |
-v --base64-output=decode-rows | ROW 事件解碼為可讀 SQL(調試必加) |
--start-position / --stop-position | 精確截取誤操作事務區間 |
--rewrite-db='src->dst' | 庫名重映射(恢復至測試庫驗證) |
max_allowed_packet:否則報 ERROR 1153: Got a packet bigger than 'max_allowed_packet' bytes。TRUNCATE、DROP、ALTER)無逆向邏輯。--include-gtids 定位事務集。結語:mysqlbinlog flashback 是 ROW 格式 binlog 的「後悔藥」,將誤 DELETE/UPDATE 恢復從「小時級 PITR」壓縮至「分鐘級管道執行」。建議所有核心業務庫強制 ROW 格式,並預先編譯部署帶 Flashback 的 mysqlbinlog 到跳板機,做到有備無患。