0
点赞
收藏
分享

微信扫一扫

Stable Diffusion模型原理

科牛 2023-12-26 阅读 17

mysql 错误操作整个表全部数据后如何恢复?(百万行SQL,通过binlog日志恢复)

事件起因

在这里插入图片描述

找Binlog文件位置

我的是mysql 8,ubuntu,我的binlog文件在这个目录

/var/lib/mysql

在这里插入图片描述

聪明的你一眼就能看出这个binlog 27号文件只有六百多兆,序号也是最新的,证明这个是最近的一个文件,就是他了,冲

读取指定时间范围内的数据操作DML

mysqlbinlog --base64-output=DECODE-ROWS --verbose --start-datetime="2023-12-23 01:00:00" --stop-datetime="2023-12-23 01:10:00" /var/lib/mysql/binlog.000027 > restore.sql

把导出的SQL清理数据

导出的sql,我用IDEA打开的,随便你用哪个好用的文本处理工具,我们直接搜索set这个词,就能找到SQL的最开始位置如图


例如一条

### UPDATE `xx`.`t_xx`
### WHERE
###   @1=1
###   @2='xx'
###   @3=NULL
###   @4='默认'
###   @5='xx'
###   @6='xxxx'
###   @7='1'
###   @8=1
###   @9='2023-08-19 15:29:58'
###   @10='2023-08-19 18:41:06'
### SET
###   @1=1
###   @2='xx'
###   @3='xx'
###   @4='默认'
###   @5='xx'
###   @6='xx'
###   @7='1'
###   @8=1
###   @9='2023-08-19 15:29:58'
###   @10='2023-12-23 01:07:09'

这个数据的格式不难看出,记录了变更之前和之后的每个字段数据,xx为示意作用,在真实场景中就是你的真实数据,字段根据顺序@1一直到@10,证明我有10个字段,然后没个字段的值都记录了,整个结构为

update
where
每个字段的旧值
set
每个字段的新值

那么我们现在开始处理数据
IDEA 对于这个26MB的文件直接变仅读模式,不给我编辑,于是打开了subline text这个工具处理文本

处理数据

删除update语句以外的所有无关行

我们要的核心就是这个update语句,我们先掐头去尾,保留中间的update,我这个文件目前有100万行~
现在我这个文件只有那一个失误SQL执行的所有update语句,总共92万行~

去掉开头的###

/**
 * author: humorchen
 * date: 2023/12/23/023 1:57
 * desc:
 **/
public class RestoreData {
    /**
     * 移除头部标识
     *
     * @throws Exception
     */
    public static void removeHeadSignal() throws Exception {
        String file = "C:\\Users\\Administrator\\Desktop\\restore.sql";
        String newFile = "C:\\Users\\Administrator\\Desktop\\restore_1.sql";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(newFile));
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            if (line.startsWith("### ")) {
                line = line.substring(4);
            }
            bufferedWriter.write(line);
            bufferedWriter.write("\n");
        }
        bufferedWriter.flush();
        bufferedWriter.close();
        bufferedReader.close();
    }

    public static void main(String[] args) throws Exception {
        removeHeadSignal();
    }
}

在这里插入图片描述

set和where互换

    /**
     * where和set互换
     *
     * @throws Exception
     */
    public static void reverseWhereAndSet() throws Exception {
        String file = "C:\\Users\\Administrator\\Desktop\\restore_1.sql";
        String newFile = "C:\\Users\\Administrator\\Desktop\\restore_2.sql";
        final String SET = "SET";
        final String WHERE = "WHERE";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(newFile));
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            if (line.startsWith(WHERE)) {
                line = SET;
            } else if (line.startsWith(SET)) {
                line = WHERE;
            }
            bufferedWriter.write(line);
            bufferedWriter.write("\n");
        }
        bufferedWriter.flush();
        bufferedWriter.close();
        bufferedReader.close();
    }

    public static void main(String[] args) throws Exception {
//        removeHeadSignal();
        reverseWhereAndSet();
    }

在这里插入图片描述

字段替换

把字段数组作为参数数组传入函数,然后读取@多少,替换为对应下表的字段名



    /**
     * 替换字段名
     *
     * @param columnNames
     */
    public static void replaceColumns(String[] columnNames) throws Exception {
        String file = "C:\\Users\\Administrator\\Desktop\\restore_2.sql";
        String newFile = "C:\\Users\\Administrator\\Desktop\\restore_3.sql";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(newFile));
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        String line = null;
        final String PREFIX = "  @";
        final int PREFIX_LEN = PREFIX.length();
        while ((line = bufferedReader.readLine()) != null) {
            // line:  @1=1
            if (line.length() > PREFIX_LEN && line.startsWith(PREFIX)) {
                // 等于号位置
                int eqIndex = line.indexOf("=");
                String indexStr = line.substring(PREFIX_LEN, eqIndex);
                if (StrUtil.isNumeric(indexStr)) {
                    int index = Integer.parseInt(indexStr) - 1;
                    if (index >= 0 && index < columnNames.length) {
                        // 替换字段名
                        line = line.replace(PREFIX + indexStr, columnNames[index]);
                    }
                }
            }
            bufferedWriter.write(line);
            bufferedWriter.write("\n");
        }
        bufferedWriter.flush();
        bufferedWriter.close();
        bufferedReader.close();
    }

    public static void main(String[] args) throws Exception {
//        removeHeadSignal();
//        reverseWhereAndSet();
        replaceColumns(new String[]{"id", "title", "icon", "type", "email", "prompt", "temperature", "keep_context", "create_time", "update_time"});
    }

在这里插入图片描述

加,和and


    /**
     * 添加,和and和;
     *
     * @throws Exception
     */
    public static void addPrefix(String[] addPrefix) throws Exception {
        String file = "C:\\Users\\Administrator\\Desktop\\restore_3.sql";
        String newFile = "C:\\Users\\Administrator\\Desktop\\restore_4.sql";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(newFile));
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        String line = null;
        int index = -1;
        final String UPDATE = "UPDATE";
        while ((line = bufferedReader.readLine()) != null) {
            if (line.startsWith(UPDATE)) {
                index = 0;
                bufferedWriter.write("\n\n");
                ;
            }
            if (index >= 0) {
                line = line + addPrefix[index];
                index++;
            }
            bufferedWriter.write(line);
            bufferedWriter.write("\n");
        }
        bufferedWriter.flush();
        bufferedWriter.close();
        bufferedReader.close();
    }

    public static void main(String[] args) throws Exception {
//        removeHeadSignal();
//        reverseWhereAndSet();
//        replaceColumns(new String[]{"id", "title", "icon", "type", "email", "prompt", "temperature", "keep_context", "create_time", "update_time"});
        addPrefix(new String[]{" ", " ", ",", ",", ",", ",", ",", ",", ",", ",", ",", " ", " ", " and ", " and ", " and ", " and ", " and ", " and ", " and ", " and ", " and ", " ;"});
    }

在这里插入图片描述

大功告成,拿去执行即可!

举报

相关推荐

0 条评论