MySQL清空表后用binlog恢复数据

前提条件

首先保证开启了binlog二进制日志,在MySQL配置文件my.cnf中查看是否开启

log_bin=mysql-bin

找到日志文件

日志文件一般放在MySQL的data目录下,文件名类似mysql-bin.000001这种的就是,通过文件修改时间找到最新的那个日志文件

使用mysqlbinlog命令导出数据

1、把找到的日志文件复制到MySQL的bin目录下,一来拷贝一份以防万一,再一个方便后续命令中定位文件路径
2、在bin目录运行cmd,输入命令导出数据

mysqlbinlog --no-defaults --base64-output=decode-rows -vv  --start-datetime="2024-12-02 16:40:00" --stop-datetime="2024-12-02 16:55:00"  --database=your_database_name mysql-bin.000014 > truncate_recovery.sql

网上有些帖子这个命令中不带–base64-output=decode-rows这个参数,这会导致导出的数据还是二进制格式,没法查看。所以这个参数必须加上。
其他几个参数也好理解,开始时间和结束时间就是需要误删的那个时间点,时间范围可以稍微拉长一点。
–database=your_database_name 这里注意替换成你的数据库名字,注意不是连接名,是database的名字。
最后输出内容到truncate_recovery.sql这个文件中。

解析日志内容

清空表和删除数据,都可以在导出的文件中搜关键字DELETE
在这里插入图片描述
删除的数据都会在下面详细的列出来。
到这一步网上的帖子就会建议你用反写的工具去生成insert语句了,感兴趣可以搜一下myFlash工具。
咱作为Java开发看到这种文字处理还需要麻烦别人吗,直接手写一个函数就搞定了。
1、首先把数据相关的内容拷出来,单独放一个文件。
2、写一个main方法,io流读取文件内容,String Api处理文字内容,再将处理的内容写到另一个文件中。目的就是拼接成一个insert语句,代码如下:

public static void main(String[] args) {
        String filePath = "C:\\Users\\DogEgg\\Desktop\\revert.txt"; // 替换为你的文件路径
        
        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            // 把内容写到该文件中,我这里图省事没指定路径,后续用everything搜一下文件名就行。
            FileWriter writer = new FileWriter("example2.txt");
			// io流逐行读取文件内容
            while ((line = br.readLine()) != null) {
                if (line.contains("@")) {
                    if (line.contains("@1=")) {
                        writer.write("(");
                    }
                    if (line.contains("2024-")) {
                        writer.write("STR_TO_DATE(");
                    }
                    writer.write(line.substring(line.indexOf("=") + 1, line.indexOf("*") - 2));
                    if (line.contains("2024-")) {
                        writer.write(", '%Y-%m-%d %H:%i:%s')");
                    }
                    if (!line.contains("@30=")) {
                        writer.write(",");
                    }
                    if (line.contains("@30=")) {
                        writer.write("),");
                    }
                }
            }
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

内容处理的逻辑大家自由发挥,我这里因为着急恢复数据,写的很随意。
需要注意的就是日期格式要做转换,我这里用了STR_TO_DATE方法去转换格式,否则会报错类型不匹配。

找到输出的文件,打开看到内容就很眼熟了,都是(xx,xx,xx),(xx,xx,xx)这种格式的,只需要前面拼接insert into table_name(字段名1,字段名2…) values就够了,然后直接执行该sql文件。
完美结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值