MySQL誤刪數據急救指南:基于Binlog日志的實戰恢復詳解

背景

數據誤刪是一個比較嚴重的場景

1.典型誤操作場景

場景1:DELETE FROM orders WHERE status=0 → 漏寫AND create_time>=‘2025-06-20’
場景2:DROP TABLE customer → 誤執行于生產環境

認識 binlog

1.binlog 的核心作用

  • 記錄所有 DDL/DML 操作(不含 SELECT)
  • ROW格式binlog記錄數據行的完整鏡像(例:DELETE操作保存被刪行的所有字段值)

2.三種格式對比

  • ROW格式:可解析具體數據變更(如DELETE的行數據),是數據恢復的前提。
  • STATEMENT格式:僅記錄SQL語句(如DELETE FROM user),無法還原誤刪的具體數據。
  • MIXED格式:混合模式,可能無法保證所有操作記錄完整數據3。

3.binlog恢復原理與前提條件

binlog為什么能恢復數據?

  • ROW格式記錄物理變更:保存每行數據的修改前/后鏡像(DELETE記錄完整被刪行數據)。
  • 事務連續性:通過start position和end position精準定位事務邊界。
  • 與Undo Log的區別:binlog持久化到磁盤,不受事務提交影響。

4.無法恢復的場景

  • binlog未開啟或格式為STATEMENT(僅記錄SQL語句,無原始數據)
  • TRUNCATE TABLE操作(直接清空物理文件,不記錄行數據)
  • binlog已被自動清理(expire_logs_days過期)或手動PURGE
  • 大事務未提交時服務器崩潰(事務不完整)

5.如何開啟 binlog

  • 修改 my.cnf 配置(代碼示例):
[mysqld]
server_id=1 
log_bin=mysql-bin 
binlog_format=ROW  # 必須為ROW格式才能解析具體數據 
expire_logs_days=7  # 自動清理周期 
  • 驗證是否開啟:SHOW VARIABLES LIKE '%log_bin%';

恢復步驟

1. 確定操作時間與特征

  • 通過業務日志/監控系統確認誤刪時間(如 2025-06-16 18:30:00)

  • 提取SQL特征(如 delete from employee_performance where department = ‘研發’)

  • 查看最近執行的刪除語句(需開啟general_log

SELECT * FROM mysql.general_log  
WHERE argument LIKE '%DELETE FROM your_table%' 
ORDER BY event_time DESC LIMIT 1;

2. 列出時間范圍內的所有binlog文件

# Linux/Mac(需替換實際路徑)
ls -l /var/lib/mysql/mysql-bin.0*
# 解析binlog索引文件(通常為mysql-bin.index )
cat /var/lib/mysql/mysql-bin.index # Windows(PowerShell)
dir
# 解析binlog索引文件(通常為mysql-bin.index )
cat .\mysql-binlog.index# mysql
SHOW BINARY LOGS;  -- 列出所有binlog文件

3. 解析binlog找到誤操作事件

舉例

  • 誤刪表:employee_performance
  • 誤刪表所屬庫:test_demo
  • 誤刪大致時間段:2025-06-17 23:00:00-2025-06-17 23:30:00
  • 誤刪數據所屬binlog文件名稱:mysql-binlog.000002 (根據誤刪時間段推導)
  • 誤刪數據量:124514行(根據delete sql執行結果得出)

從binlog提取SQL
使用mysqlbinlog解析binlog:

# 查找2025-06-18 23:00:00-2025-06-18 23:30:00間的binlog
#并輸出到delete_sql.sql
mysqlbinlog --no-defaults --user=root -p -d test_demo --start-datetime="2025-06-17 23:00:00" --stop-datetime="2025-06-17 23:30:00" --base64-output=decode-rows -vv ../data/mysql-binlog.000002 > delete_sql.sql

輸出文件內容示例
在這里插入圖片描述
注意事項:

  • –start/stop-datetime(時間范圍)依賴系統時鐘同步),受服務器時間漂移影響。
  • 導出的文件并不一定是一個完整的事務(可能漏掉邊界事務
    ) 觀察此批delete from 末尾是否含有commit標志
    在這里插入圖片描述

數據恢復

在上一步我們已經導出了delete_sql.sql文件,接下來需要根據這個文件內容進行
過濾并重建數據

1.數據轉換(java)

反轉操作邏輯(將DELETE轉為INSERT)
轉換代碼如下:

        Path outputPath = Paths.get(outputFilePath);// 步驟一: 讀取輸入文件的所有行,使用 UTF-8 編碼,并替換無法解析的字符。List<String> lines;try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputFilePath),StandardCharsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE)))) {lines = reader.lines().collect(Collectors.toList());}// 步驟二、三、四: 過濾并處理有效的 binlog 行記錄。List<String> processedLines = lines.stream()// 僅保留以 "### " 開頭的行,這些是我們要處理的 binlog DML 語句。.filter(line -> line.startsWith("### "))// 去掉行首的 "### " 標識。.map(line -> line.substring(4))// 使用正則表達式移除從 "/*" 開始到行尾的注釋。.map(line -> line.replaceAll("(?s)/\\*.*", ""))// 將 "DELETE FROM" 替換為 "INSERT INTO",為逆向生成 INSERT 語句做準備。.map(line -> line.replace("DELETE FROM", "INSERT INTO")).collect(Collectors.toList());// 步驟五: 將所有處理過的行用換行符連接成一個單獨的字符串,并將 "WHERE" 替換為 " VALUES ("。String text = String.join("\n", processedLines);text = text.replace("\nWHERE", " VALUES (");// 步驟六: 移除 binlog 中的字段位置標識,例如 "@1=", "@2=" 等。text = text.replaceAll("@[0-9]+=", "");// 步驟七: 對每一行進行整理,并在行尾添加逗號,為構建 VALUES 子句做準備。text = Stream.of(text.split("\n"))// 移除每行首尾的空白字符。.map(String::trim)// 過濾掉處理后可能產生的空行。.filter(line -> !line.isEmpty())// 如果行尾沒有逗號,則添加一個,確保 VALUES 子句中的值都以逗號分隔。.map(line -> line.endsWith(",") ? line : line + ",").collect(Collectors.joining("\n"));// 步驟八: 修正由于前面步驟可能產生的 "VALUES (," 寫法,將其規范為 "VALUES ("。text = text.replace("VALUES (,", "VALUES (");// 步驟九: 將多個 INSERT 語句正確地分隔開。將前一個 INSERT 的值與后一個 INSERT 語句用 ");" 連接。text = text.replace(",\nINSERT", ");\nINSERT");// 步驟十: 閉合最后一個 INSERT 語句。如果字符串以逗號結尾,則將其替換為 ");"。if (text.endsWith(",")) {text = text.substring(0, text.length() - 1) + ");";}// 將最終處理好的字符串以 UTF-8 編碼寫入到指定的輸出文件中。Files.write(outputPath, text.getBytes(StandardCharsets.UTF_8));

詳細轉換代碼見此項目(含測試用例)

mysql-binlog2sql


2.數據校驗

運行完成后可以看到輸入文件已經轉換完成
在這里插入圖片描述
條數也是對的 一條數據10行 1245140/10 = 1245410行和上面的模擬數據一致。

3.數據導入

重新執行轉換的sql文件導入即可

SOURCE /tmp/restore.sql; 

番外

binlog 文件分割機制

當通過 binlog 恢復誤刪數據時,binlog 文件的大小限制和跨文件存儲問題是影響恢復完整性的關鍵因素。

文件大小限制
MySQL 默認通過 max_binlog_size 控制單個 binlog 文件大小(默認 1GB)

大事務跨文件存儲
若單個事務(如大表 DELETE)產生的日志量超過當前要落入的binlog文件 的max_binlog_size,該事務會跨多個 binlog 文件存儲。

示例:一個 5GB 的事務可能分布在 mysql-bin.000001~mysql-bin.000005 中。

文件命名規則
Binlog 按順序生成:mysql-bin.000001 → mysql-bin.000002 → …

新文件在以下情況創建:

  • 當前文件 ≥ max_binlog_size
  • 執行 FLUSH LOGS 或重啟 MySQL。

確認binlog是否開啟(Value=ON)

SHOW VARIABLES LIKE 'log_bin';  

在這里插入圖片描述
查看MySQL的binlog模式是否為ROW

show global variables like "binlog%";

在這里插入圖片描述

查詢ROW格式需為FULL(記錄完整行數據)


SHOW VARIABLES LIKE 'binlog_row_image'; 

在這里插入圖片描述

檢查binlog過期時間(確保日志未被自動清理)MySQL 8.0+默認30天

SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';

常用解析binlog文件參數詳解

-no-defaults:

–start-datetime:指定開始時間(過濾早于該時間的日志) 示例: --start-datetime=“2025-06-15 14:00:00”

–stop-datetime: 指定結束時間(過濾晚于該時間的日志) 示例: --stop-datetime=“2025-06-15 15:00:00”

–read-from-remote-server: 從遠程MySQL服務器讀取binlog(需配合–host)
示例:–read-from-remote-server --host=192.168.1.100

–user --password :指定連接MySQL的用戶名和密碼(遠程解析時必填)示例: --user=root --password=your_password

-base64-output=decode-rows:解析ROW格式數據

-d :指定庫

注意事項

時間格式必須精確
日期時間需用引號包裹,格式為 “YYYY-MM-DD HH:MM:SS”(如 “2025-06-15 14:00:00”)。
權限要求
本地解析:需操作系統用戶有binlog文件讀取權限。
遠程解析:MySQL用戶需有REPLICATION CLIENT權限[]。
大事務處理
若事務過大導致mysqlbinlog內存溢出,可分段解析

-start/stop-position --start/stop-datetime 區別詳解

1. --start/stop-position(物理位置)

原理
直接指向binlog事件的物理存儲位置(如 # at 54321),通過解析binlog文件的固定偏移量定位。
特點
? 100%精確到具體事務
? 不受時間同步問題影響
? 需先通過其他方式獲取位置號

2. --start/stop-datetime(時間范圍)

原理
根據binlog事件頭的時間戳字段過濾(如 #250618 10:00:00),依賴系統時鐘同步。
特點
? 無需提前知道位置號
? 最大可能有1秒誤差(可能漏掉邊界事務)
? 受服務器時間漂移影響

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86489.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86489.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86489.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

高效數據采集方案:快速部署與應用 AnyCrawl 網頁爬蟲工具實操指南

以下是對 AnyCrawl 的簡單介紹&#xff1a; AnyCrawl 提供高性能網頁數據爬取&#xff0c;其功能專為 LLM 集成和數據處理而設計支持利用搜索引擎直接查詢獲取結果內容&#xff0c;類似 searxng提供開發者友好的API&#xff0c;支持動態內容抓取&#xff0c;并輸出結構化數據&…

vue3可以分頁、搜索的select

下載 npm i v-selectpage基本使用 import { SelectPageList } from v-selectpage;<SelectPageListlanguage"zh-chs"key-prop"id"label-prop"name"fetch-data"fetchData" />const fetchData (data,callback) > {const { sea…

C# 入門學習教程 (一)

文章目錄 一、解決方案與項目1. Solution 與 project 二、類與名稱空間1.類與名稱空間2.類庫的引用1. DLL引用&#xff08;黑盒引用&#xff0c;無源代碼&#xff09;2. Nuget 引用3. 項目引用&#xff08;白盒引用&#xff0c;有源代碼&#xff09; 3.依賴關系 三、類&#xf…

76、單元測試-參數化測試

76、單元測試-參數化測試 參數化測試是一種單元測試技術&#xff0c;通過將測試數據與測試邏輯分離&#xff0c;使用不同的輸入參數多次運行相同的測試用例&#xff0c;從而提高測試效率和代碼復用性。 #### 基本原理 - **數據驅動測試**&#xff1a;將測試數據參數化&#xf…

SQL學習筆記3

SQL常用函數 1、字符串函數 函數調用的語法&#xff1a;select 函數&#xff08;參數); 常用的字符串函數有&#xff1a; 拼接字符串&#xff0c;將幾個字符串拼到一起&#xff1a;concat (s1,s2,……); select concat(你好,hello); update mytable set wherefo concat(中…

Golang 面向對象編程,如何實現 封裝、繼承、多態

Go語言雖然不是純粹的面向對象語言&#xff0c;但它通過結構體(struct)、接口(interface)和方法(method)提供了面向對象編程的能力。下面我將通過具體示例展示Go中如何實現類、封裝、繼承、多態以及構造函數等概念。 1. 類與封裝 在Go中&#xff0c;使用結構體(struct)來定義…

為什么android要使用Binder機制

1.linux中大多數標準 IPC 場景&#xff08;如管道、消息隊列、ioctl 等&#xff09;的進程間通信機制 ------------------ ------------------ ------------------ | 用戶進程 A | | 內核空間 | | 用戶進程 B | | (User Spa…

OpenCV CUDA模塊設備層-----雙曲余弦函數cosh()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 該函數用于計算四維浮點向量&#xff08;float4類型&#xff09;的雙曲余弦值&#xff0c;作用于CUDA設備端。雙曲余弦函數定義為cosh(x) (e? …

48頁PPT | 企業數字化轉型關鍵方法論:實踐路徑、案例和落地評估框架

目錄 一、什么是企業數據化轉型&#xff1f; 二、為什么要進行數據化轉型&#xff1f; 1. 市場復雜性與不確定性上升 2. 內部流程效率與協同難題突出 3. 數字資產沉淀不足&#xff0c;智能化基礎薄弱 三、數據化流程管理&#xff1a;從“業務流程”到“數據流程”的對齊 …

VTK中的形態學處理

VTK圖像處理代碼解析:閾值化與形態學開閉運算 這段代碼展示了使用VTK進行醫學圖像處理的兩個關鍵步驟:閾值分割和形態學開閉運算。下面我將詳細解析每個部分的功能和實現原理。 處理前 處理后 1. 閾值分割部分 (vtkImageThreshold) vtkSmartPointer<vtkImageThresho…

xlsx.utils.sheet_to_json() 方法詳解

sheet_to_json() 是 SheetJS/xlsx 庫中最常用的方法之一&#xff0c;用于將 Excel 工作表&#xff08;Worksheet&#xff09;轉換為 JSON 格式數據。下面我將全面講解它的用法、參數配置和實際應用場景。 基本語法 javascript 復制 下載 const jsonData XLSX.utils.sheet…

〔從零搭建〕BI可視化平臺部署指南

&#x1f525;&#x1f525; AllData大數據產品是可定義數據中臺&#xff0c;以數據平臺為底座&#xff0c;以數據中臺為橋梁&#xff0c;以機器學習平臺為中層框架&#xff0c;以大模型應用為上游產品&#xff0c;提供全鏈路數字化解決方案。 ?杭州奧零數據科技官網&#xf…

合規型區塊鏈RWA系統解決方案報告——機構資產數字化的終極武器

&#xff08;跨境金融科技解決方案白皮書&#xff09; 一、直擊機構客戶四大痛點 痛點傳統方案缺陷我們的破局點?? 跨境資產流動性差結算周期30天&#xff0c;摩擦成本超8%?? 724h全球實時交易&#xff08;速度提升90%&#xff09;?? 合規成本飆升KYC/AML人工審核占成本…

探索阿里云容器:解鎖云原生應用的無限可能

引言&#xff1a;容器時代的開啟 在數字化浪潮洶涌澎湃的當下&#xff0c;云計算已成為企業創新與發展的關鍵驅動力。從早期的基礎設施即服務&#xff08;IaaS&#xff09;&#xff0c;到如今蓬勃發展的平臺即服務&#xff08;PaaS&#xff09;和軟件即服務&#xff08;SaaS&a…

spring-ai 1.0.0 (1)模型調用能力

聽說1.0是一個非常好用的版本&#xff0c;最后還是扛不住聽說的壓力&#xff0c;為了落實自己懸浮心理&#xff0c;自己還是著手實踐一下了。 第一步pom集成&#xff1a; 參考spring-projects/spring-ai | DeepWiki維基以及官方文檔入門 &#xff1a;&#xff1a; Spring AI …

數據分享:汽車行業-汽車屬性數據集

說明&#xff1a;如需數據可以直接到文章最后關注獲取。 1.數據背景 Automobile數據集源自于對汽車市場深入研究的需求&#xff0c;旨在為汽車行業提供一個全面且詳細的資源&#xff0c;以便更好地理解影響汽車價格及性能的各種因素。該數據集最初由卡內基梅隆大學&#x…

C++ 第三階段:語言改進 - 第四節:nullptr vs NULL

目錄 一、背景與概述 二、NULL 的定義與問題 1. NULL 的定義 2. NULL 的問題 三、nullptr 的定義與優勢 1. nullptr 的定義 2. nullptr 的優勢 四、nullptr 與 NULL 的對比 五、實際應用場景 1. 初始化指針 2. 函數調用與重載 3. 條件判斷 4. 模板與泛型編程 六、…

計算機存儲器容量擴展設計實例解析

存儲器容量擴充是《計算機組成原理》課程的重要知識點。講解一個例題&#xff0c;以說明進行存儲器容量擴充設計的方法。 題目&#xff1a;在32位計算機系統中&#xff0c;用8K16位的SRAM芯片組成一個64KB的存儲器&#xff0c;已知起始地址為&#xff1a;6000 0000H。已知&…

轉載-秒殺系統—1.架構設計和方案簡介

轉載&#xff1a; https://mp.weixin.qq.com/s?__bizMzg5MzY5NDM3MQ&mid2247490866&idx1&sn0081517454680c85e0ed23eda4e82df5&chksmc02ba5fef75c2ce8b0c7f54182f3bda539230c75d2d75ed2b514b93decc0ff0c5de548a35dc3&cur_album_id3548464749150224391&…

Kubernetes中的容器生命周期回調

在介紹Kubernetes容器生命周期回調前&#xff0c;展示一個案例。 有個私有化部署的項目需要跑一個redis用作緩存&#xff0c;因redis中的數據不需要持久化&#xff0c;選擇在Kubernetes中通過deployment的方式部署&#xff0c;下面是deployment的代碼片段&#xff0c; ......…