当前位置: 首页 > news >正文

基于binlog恢复误删除MySQL数据

AI 提示词

[root@appdb-01 qding]# ls
mysqld-bin.054733  mysqld-bin.054736  mysqld-bin.054739  mysqld-bin.054742  mysqld-bin.054745  relay.000101  relay.000104  relay.index
mysqld-bin.054734  mysqld-bin.054737  mysqld-bin.054740  mysqld-bin.054743  mysqld-bin.index   relay.000102  relay.000105
mysqld-bin.054735  mysqld-bin.054738  mysqld-bin.054741  mysqld-bin.054744  relay.000100       relay.000103  relay.000106
[root@appdb-01 qding]#这是我的binlog文件, 我刚刚执行的delete语句误删除了部分数据,我想恢复我删除的数据。涉及的数据库是db_iam 数据表是 t_iam_func_auth

进入binlog目录

在这里插入图片描述

确认最新binlog文件‌

根据文件列表,最新的是mysqld-bin.054745(数字最大的文件)6。

解析binlog内容‌

使用mysqlbinlog工具解析,注意添加--database--base64-output参数:

mysqlbinlog --base64-output=decode-rows -v --database=db_iam mysqld-bin.054745 > parsed_binlog.sql

定位DELETE语句‌

在生成的parsed_binlog.sql中搜索以下内容:
表名t_iam_func_auth
操作类型### DELETE FROM,这是其中部分数据:

###   @17='XZ'
###   @18='增加问卷配置人员权限'
###   @19=NULL
# at 154852463
#250610 16:50:29 server id 453309  end_log_pos 154852494 CRC32 0x70183b1f 	Xid = 635330624
COMMIT/*!*/;
# at 154852494
#250610 16:50:29 server id 453309  end_log_pos 154852559 CRC32 0x36be420c 	Anonymous_GTID	last_committed=5320	sequence_number=16105	rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 154852559
#250610 16:50:29 server id 453309  end_log_pos 154852635 CRC32 0xfd531c3d 	Query	thread_id=6117380	exec_time=0	error_code=0
SET TIMESTAMP=1749545429/*!*/;
BEGIN
/*!*/;
# at 154852635
# at 154852753
#250610 16:50:29 server id 453309  end_log_pos 154852866 CRC32 0xe6a38df5 	Table_map: `db_iam`.`t_iam_func_auth` mapped to number 56488
# at 154852866
#250610 16:50:29 server id 453309  end_log_pos 154853264 CRC32 0x448e2624 	Delete_rows: table id 56488 flags: STMT_END_F
### DELETE FROM `db_iam`.`t_iam_func_auth`
### WHERE
###   @1='00c5383a-d564-47e8-b905-7335e740ea31'
###   @2='FP.XZ.QUESTION.7858636'
###   @3='9ea88e7d-b92e-4c8b-a394-cb7fc6b93d9b'
###   @4='edd8239e-a049-4bdc-954f-41fa60c6894c'
###   @5='U'
###   @6=1
###   @7=0
###   @8='605aeca6-01a8-4172-959f-34fff0cf0e67'
###   @9=1742459189
###   @10='605aeca6-01a8-4172-959f-34fff0cf0e67'
###   @11=1743040916
###   @12='984ff0e4-68ad-4ca1-a1bf-d38d4f785ae5'
###   @13='88c514fd-7c1f-4696-8a2c-cfa49ae1e2c2'
###   @14=NULL
###   @15=NULL
###   @16='984ff0e4-68ad-4ca1-a1bf-d38d4f785ae5'
###   @17='XZ'
###   @18='系统初始化'
###   @19=NULL
# at 154853264
#250610 16:50:29 server id 453309  end_log_pos 154853295 CRC32 0x5bd6c7f8 	Xid = 635330630
COMMIT/*!*/;
# at 154853295
#250610 16:50:29 server id 453309  end_log_pos 154853360 CRC32 0x3354fd33 	Anonymous_GTID	last_committed=5320	sequence_number=16106	rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 154853360
#250610 16:50:29 server id 453309  end_log_pos 154853436 CRC32 0x64d6f71e 	Query	thread_id=6117380	exec_time=0	error_code=0
SET TIMESTAMP=1749545429/*!*/;
BEGIN
/*!*/;
# at 154853436
# at 154853554
#250610 16:50:29 server id 453309  end_log_pos 154853667 CRC32 0x1fb2c80b 	Table_map: `db_iam`.`t_iam_func_auth` mapped to number 56488
# at 154853667
#250610 16:50:29 server id 453309  end_log_pos 154854080 CRC32 0x2a7b4493 	Delete_rows: table id 56488 flags: STMT_END_F
### DELETE FROM `db_iam`.`t_iam_func_auth`
### WHERE
###   @1='027c0a0c-9c1c-4fca-ab18-4ebfdafe3ab2'
###   @2='FP.XZ.QUESTION.7858778'
###   @3='9cd3db3c-75a0-48bf-a047-9e30deb57c33'
###   @4='edd8239e-a049-4bdc-954f-41fa60c6894c'
###   @5='R'
###   @6=1
###   @7=0
###   @8='1a7a3bb3-eeb9-454e-b458-d2da75c9539f'
###   @9=1747275151
###   @10='1a7a3bb3-eeb9-454e-b458-d2da75c9539f'
###   @11=1747275343
###   @12='984ff0e4-68ad-4ca1-a1bf-d38d4f785ae5'
###   @13='88c514fd-7c1f-4696-8a2c-cfa49ae1e2c2'
###   @14=NULL
###   @15=NULL
###   @16='984ff0e4-68ad-4ca1-a1bf-d38d4f785ae5'
###   @17='XZ'
###   @18='增加问卷配置人员权限'
###   @19=NULL
# at 154854080
#250610 16:50:29 server id 453309  end_log_pos 154854111 CRC32 0x3d46f972 	Xid = 635330631
COMMIT/*!*/;
# at 154854111
#250610 16:50:29 server id 453309  end_log_pos 154854176 CRC32 0xc755be74 	Anonymous_GTID	last_committed=5320	sequence_number=16107	rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 154854176
#250610 16:50:29 server id 453309  end_log_pos 154854252 CRC32 0x103fa6aa 	Query	thread_id=6117380	exec_time=0	error_code=0
SET TIMESTAMP=1749545429/*!*/;
BEGIN
/*!*/;

通过JAVA代码还原SQL语句


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class BinlogToInsertConverter {private static final Pattern DELETE_PATTERN = Pattern.compile("### DELETE FROM `([^`]+)`\\.`([^`]+)`.*?### WHERE(.*?)(?=# at|COMMIT)",Pattern.DOTALL);private static final Pattern FIELD_PATTERN = Pattern.compile("###\\s+@(\\d+)='?(.*?)'?(?:\\s|$|NULL)",Pattern.DOTALL);private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public static void main(String[] args) {String filePath = "/Users/admin/Downloads/parsed_binlog.txt";try {List<String> insertStatements = convertDeleteToInsert(filePath);for (String insert : insertStatements) {System.out.println(insert+";");}} catch (IOException e) {e.printStackTrace();}}public static List<String> convertDeleteToInsert(String filePath) throws IOException {List<String> result = new ArrayList<>();StringBuilder fileContent = new StringBuilder();try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {String line;while ((line = reader.readLine()) != null) {fileContent.append(line).append("\n");}}Matcher deleteMatcher = DELETE_PATTERN.matcher(fileContent.toString());while (deleteMatcher.find()) {String database = deleteMatcher.group(1);String table = deleteMatcher.group(2);String whereClause = deleteMatcher.group(3);List<String> values = new ArrayList<>();Matcher fieldMatcher = FIELD_PATTERN.matcher(whereClause);while (fieldMatcher.find()) {String fieldNum = fieldMatcher.group(1);String value = fieldMatcher.group(2);if ("NULL".equals(value)) {values.add("NULL");} else if ("9".equals(fieldNum) || "11".equals(fieldNum)) {// 处理时间戳字段try {long timestamp = Long.parseLong(value);String formattedDate = DATE_FORMAT.format(new Date(timestamp * 1000L));values.add("'" + formattedDate + "'");} catch (NumberFormatException e) {values.add("'" + value.replace("'", "''") + "'");}} else {values.add("'" + value.replace("'", "''") + "'");}}if (!values.isEmpty()) {String insert = String.format("INSERT INTO `%s`.`%s` VALUES (%s)",database, table, String.join(", ", values));result.add(insert);}}return result;}
}

这里注意时间搓转为年月日格式。else if ("9".equals(fieldNum) || "11".equals(fieldNum))这段代码需要修改。
最后生成类似的代码:

INSERT INTO `db_iam`.`t_iam_func_auth` VALUES ('feaa322a-c7de-4c76-a07f-1d2c6d58ee37', 'FP.XZ.QUESTION.7858767', '9cd3db3c-75a0-48bf-a047-9e30deb57c33', '005f1c8a-7b9b-435d-b0cd-cc636d19f617', '9e57750d-2b2d-453b-a500-5c9e3bff2e75', '1', '0', '1a7a3bb3-eeb9-454e-b458-d2da75c9539f', '2025-05-15 10:12:31', '1a7a3bb3-eeb9-454e-b458-d2da75c9539f', '2025-05-15 10:15:34', '984ff0e4-68ad-4ca1-a1bf-d38d4f785ae5', '88c514fd-7c1f-4696-8a2c-cfa49ae1e2c2', '', '', '984ff0e4-68ad-4ca1-a1bf-d38d4f785ae5', 'XZ', '增加问卷配置人员权限', '');
INSERT INTO `db_iam`.`t_iam_func_auth` VALUES ('ff61bac9-ebb4-4fa7-bcda-016e7cb0d4bf', 'FP.XZ.QUESTION.7858656', '9ea88e7d-b92e-4c8b-a394-cb7fc6b93d9b', '39bbf469-c86b-4321-9f1c-2e7ac512bbcb', '043351b6-6ea1-4242-9085-7c4e7f9d9483', '1', '0', '605aeca6-01a8-4172-959f-34fff0cf0e67', '2025-03-26 11:32:18', '605aeca6-01a8-4172-959f-34fff0cf0e67', '2025-03-27 10:01:56', '984ff0e4-68ad-4ca1-a1bf-d38d4f785ae5', '88c514fd-7c1f-4696-8a2c-cfa49ae1e2c2', '', '', '984ff0e4-68ad-4ca1-a1bf-d38d4f785ae5', 'XZ', '系统初始化', '');

最后核对数据还原数据库数据

相关文章:

  • 利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
  • 系统设计 --- MongoDB亿级数据查询优化策略
  • Python 爬虫工具全解析及实战指南
  • 将两个变量a,b的值进行交换,不使用任何中间变量
  • 【持续更新】linux网络编程试题
  • leetcode240-搜索二维矩阵
  • ps去掉画板
  • Appium 安装指南
  • word的目录和正文之间存在一张空白纸,目录后面的分节符为什么调不上去?
  • MVVM 模式,以及 Angular、React、Vue 和 jQuery 的区别与关系
  • 【无标题】装箱问题的拓扑动力学解法:几何凝聚与量子坍缩模型
  • LeetCode - 394. 字符串解码
  • Java多线程实现之Callable接口深度解析
  • 蓝桥杯 2024 15届国赛 A组 儿童节快乐
  • 清新文艺手绘学习教育培训竞标汇报PPT模版分享
  • error: Sandbox: rsync(17136) deny(1) file-write-create
  • 【论文解读】ReSearch:让LLM自主学习搜索
  • C++ 手写实现 unordered_map 和 unordered_set:深入解析与源码实战
  • C# 中常用的 字符串截取方法
  • ASP4644电源芯片FB引脚:从原理到实战
  • 做网站一定要域名嘛/重庆seo代理计费
  • 厦门微信网站/代做百度首页排名
  • 佛山顺德网站建设/东莞最新疫情
  • 5种有效增加网站流量/推推蛙seo顾问
  • wordpress美女图片站源码/江小白网络营销案例
  • 创业网站开发/站长之家seo工具包