MySQL使用binlog日志回滾操作失誤的數(shù)據(jù)的操作教程
一、背景
在日常開發(fā)運維中,我們可能會出現(xiàn)一些操作失誤的情況,比如使用了錯誤的 sql 語句對 mysql 數(shù)據(jù)進行了 update、delete 等操作,失誤操作導致數(shù)據(jù)出現(xiàn)問題,又或者架構(gòu)設(shè)計上沒有使用軟刪除機制,用戶誤刪除了數(shù)據(jù)需要恢復。
那么如果出現(xiàn)這種情況,應(yīng)該如何恢復失誤/mysql 誤刪數(shù)據(jù)時,本文將使用幾種常用方法一步一步帶你回滾誤刪/誤操的數(shù)據(jù)
二、準備測試數(shù)據(jù)
1. 創(chuàng)建測試表
create table jxy_pms.test_model ( create_time bigint unsigned default 0 null, update_time bigint unsigned default 0 null, delete_time bigint unsigned default 0 null, test_model_id varchar(255) not null primary key, name varchar(255) null, remark varchar(255) null ) collate = utf8mb4_unicode_ci;
2. 創(chuàng)建測試數(shù)據(jù)
insert into test_model (test_model_id, name, remark) values ('1','test1','test-1'), ('2','test2','test-2'), ('3','test3','test-3'); select * from test_model test_model_id name remark 1 test1 test-1 2 test2 test-2 3 test3 test-3
三、模擬誤操作
delete from test_model
四、數(shù)據(jù)回滾
(一)方案一:云數(shù)據(jù)庫恢復
如果你的 mysql 使用的時云數(shù)據(jù)庫,比如阿里云、騰訊云,那么你可以到云數(shù)據(jù)庫的控制臺操作面板進行一鍵數(shù)據(jù)回滾,一般都可以選擇對應(yīng)的恢復區(qū)間,具體可以咨詢對應(yīng)的云數(shù)據(jù)庫提供商,一般都會提供技術(shù)支持
優(yōu)點:
- 低風險
- 操作簡單
- 有云供應(yīng)商提供技術(shù)支持
缺點:
- 恢復精度較低,沒辦法恢復指定的數(shù)據(jù)
- 有可能恢復不全,云數(shù)據(jù)庫是定期備份,可能還沒來得及備份就被刪了
(二)方案二:手動恢復
通過解讀 binlog 日志內(nèi)容,進行解析然后回放數(shù)據(jù)
binlog 日志:大白話:記錄數(shù)據(jù)庫的每個修改操作 sql
所以我們只需要找到對應(yīng)的 binlog 日志中我們誤操作的 sql 數(shù)據(jù),然后編寫對應(yīng)的回放sql,就可以回滾數(shù)據(jù)
實操如下:
1. 查詢 binlog 日志
show binary logs; 或 SHOW MASTER STATUS; mysql-bin.000014 80019706 No mysql-bin.000015 1326884 No mysql-bin.000016 3650781 No mysql-bin.000017 81424072 No mysql-bin.000018 46681992 No mysql-bin.000019 1075 No mysql-bin.000020 207322979 No
可以看到最新的日志為:mysql-bin.000020
2. 找到刪除語句,手動還原為插入語句
mysqlbinlog --no-defaults --verbose --base64-output=DECODE-ROWS --start-datetime='2025-01-16 15:12:00' --stop-datetime='2025-01-16 15:15:00' /var/lib/mysql/mysql-bin.000027 > /home/DataVolume/rec.sql
- --base64-output=DECODE-ROWS 生成不加密的 sql 文件
- --start-datetime 、stop-datetime 數(shù)據(jù)操作的時間區(qū)間
從 rec.sql 中找到對應(yīng)的表 test_model 的刪除操作,如果找不到,調(diào)整下--start-datetime 和 stop-datetime
找到刪除的 sql 語句如下:
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; ........ /*!*/; # at 207319108 #240919 10:58:30 server id 1 end_log_pos 207319202 CRC32 0xe7b80345 Table_map: `jxy_pms`.`asynccron_cron_task` mapped to number 306 #240919 10:59:04 server id 1 end_log_pos 207321626 CRC32 0x6b3323a9 Table_map: `jxy_pms`.`test_model` mapped to number 315 # at 207321626 #240919 10:59:04 server id 1 end_log_pos 207321718 CRC32 0xb004dad7 Delete_rows: table id 315 flags: STMT_END_F ### DELETE FROM `jxy_pms`.`test_model` ### WHERE ### @1='1' ### @2='test1' ### @3='test-1' ### DELETE FROM `jxy_pms`.`test_model` ### WHERE ### @1='2' ### @2='test2' ### @3='test-2' ### DELETE FROM `jxy_pms`.`test_model` ### WHERE ### @1='3' ### @2='test3' ### @3='test-3' # at 207321718 #240919 10:59:04 server id 1 end_log_pos 207321749 CRC32 0x90b858f7 Xid = 7486642 COMMIT/*!*/;
然后寫個腳本,解析這塊 sql,重新翻譯為 insert 語句即可
優(yōu)點:
- 適合一些少量數(shù)據(jù)的還原
- 能準確還原指定的數(shù)據(jù),操作簡單
- 重新執(zhí)行的 sql,不會對已有的數(shù)據(jù)造成其他損壞
缺點:
- 不適合一些大量數(shù)據(jù)的還原
- 比較復雜,需要解讀 binlog 日志,并且需要編寫腳本
(三)方案三: 導入還原的 sql(未測試,慎用)
如果你的數(shù)據(jù)庫不是用的云數(shù)據(jù)庫,沒有一鍵恢復功能,然后你又不想用方案二,覺得太復雜,你可以直接將 binlog 日志直接全部還原
先導出 binlog 日志
mysqlbinlog --no-defaults --verbose --base64-output=DECODE-ROWS --start-datetime='2025-01-16 15:12:00' --stop-datetime='2025-01-16 15:15:00' /var/lib/mysql/mysql-bin.000027 > /home/DataVolume/rec.sql
這里會導出 rec.sql 文件
導入 sql
mysql -u root -p test < rec.sql
優(yōu)點:
- 相比較方案二簡單一些
- 適合范圍恢復
缺點:
- 恢復精度較低,比如你可能只需要恢復 2025-01-16 15:12:00 這個點的某條錯誤sql,但是這個點可能還有其他操作sql也會被一起恢復,
- 恢復期間的操作數(shù)據(jù)可能存在丟失
??:本方案沒有實際驗證過,請自行測試
總結(jié)
如果你用的是云數(shù)據(jù)庫,并且恢復的數(shù)據(jù)量比較大,推薦【方案一】使用云數(shù)據(jù)庫提供的恢復功能(非常適用那么刪庫跑路的恢復,哈哈哈哈)
如果你只是想要恢復某個個點、某些錯誤sql,那么可以使用【方案二】
以上就是MySQL使用binlog日志回滾操作失誤的數(shù)據(jù)的操作教程的詳細內(nèi)容,更多關(guān)于MySQL binlog回滾數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決MySQL錯誤碼:1054 Unknown column ‘**‘ in&n
這篇文章主要介紹了解決MySQL錯誤碼:1054 Unknown column ‘**‘ in ‘field list‘的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05mysql的語句查詢順序、耗時分析以及查詢調(diào)優(yōu)技巧分享
文章詳細介紹了MySQL中SQL查詢語句的執(zhí)行順序、耗時分析及查詢調(diào)優(yōu)方法,包括使用EXPLAIN、SHOW PROFILE和慢查詢?nèi)罩镜裙ぞ哌M行耗時分析,以及使用索引、避免全表掃描、優(yōu)化查詢語句、分區(qū)表和調(diào)整服務(wù)器配置等技巧進行性能優(yōu)化2025-02-02MySQL中g(shù)roup by與max()一起使用的坑
最近在做一個項目,發(fā)現(xiàn)用之前SQL語句導出的余額與客戶人員最近消費記錄所顯示的余額不一致,本文就來了解一下這個錯誤,感興趣的可以了解一下2023-08-08