Flashback闪回工具-java版本
之前博主介绍的闪回;发现使用后还是有瑕疵啊,闪回后sql语句没办法正常使用,而且是必须安装python 我也觉得有点麻烦,毕竟我是一个小java开发。
之后博主又在网上浏览到另一种方法 sed 去替换文件,但是sed 替换语句复杂起来是真的复杂!
事发过程
小A突然把现网数据定时库不加条件全部update 了一边
案例1 sed 方法
mysql> select * from t1;
+----+-----------+-----+-----------------------+
| id | name | sex | address |
+----+-----------+-----+-----------------------+
| 1 | 范冰冰 | f | 北京市朝阳区 |
| 2 | 赵四 | m | 河北省石家庄市 |
| 3 | daiiy | m | guangzhou |
| 4 | tom | f | shanghai |
| 5 | liany | m | beijing |
| 6 | lilu | m | zhuhai |
+----+-----------+-----+-----------------------+
1. 根据位置查找到修改的内容
mysqlbinlog --start-position='669112226' --stop-position='669213941' --base64-output=decode-rows -vv binlog.000009 > t1.txt
2. 过滤该txt内容
sed '/WHERE/{:a;N;/SET/!ba;s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}' t1.txt | sed -r '/WHERE/{:a;N;/@4/!ba;s/### @2.*//g}' | sed 's/### //g;s/\/\*.*/,/g' | sed '/WHERE/{:a;N;/@1/!ba;s/,/;/g};s/#.*//g;s/COMMIT,//g' | sed '/^$/d' > recover.sql
3.替换字段
sed -i 's/@1/id/g;s/@2/name/g;s/@3/sex/g;s/@4/address/g' recover.sql
其实对于这种sed 的Linux 命令过于复杂的博主其实看的就有点头疼了,尤其是 2过滤 方法的正则
对于这种情况我自己写了个java 版本的工具 基础mysql-8.0 版本
java update闪回
大家可以直接拿去用,不过需要 t1.txt。要查找出之前更新的日志节点,从哪里更新使用
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @author zhoumo
* @create 2022/6/9 18:29
* @Description:
*/
public class flushsSql1 {
public static void main(String[] args) throws Exception {
String sqlcomment = gettablecolumn();
updateflashback(sqlcomment);
}
static String updateflashback ( String sqlstr) throws Exception {
String[] sqlcomment = sqlstr.split(" ");
FileInputStream fileInputStream = new FileInputStream("D:\\t1.txt");
// 02.将 fileInputStream(字节流) 流作为参数,转为InputStreamReader(字符流)
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
// 03.将 字符流(参数)转为字符串流,带缓冲的流读取,默认缓冲区8k
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String tempString;
List<String > lsit=new ArrayList<>();
String str="";
String wherestr="";
String setstr="";
// 直接返回读取的字符串
while ((tempString = bufferedReader.readLine()) != null) {
if (tempString.contains("UPDATE") && str.length() != 0 ) {
wherestr= wherestr.substring(0,wherestr.length()-3);
setstr= setstr.substring(0,setstr.length()-1);
lsit.add(String.format(str,setstr,wherestr)+" ; ");
str="";
wherestr="";
setstr="";
}
if (tempString.contains("###") && !tempString.contains("/* ")) {
String comment= tempString.replace("###", "");
if(comment.contains("WHERE")){
comment=" SET %s";
} else if (comment.contains("SET")) {
comment=" WHERE %s";
}
str += comment;
}
if (tempString.contains("###") && tempString.contains("/* ")){
String replace = tempString.replace("###", "");
// 获取列名转换
String[] split = replace.split("=");
String columns="";
if(split[0].contains("@")){
String trim = split[0].replace("@", "").trim();
columns=sqlcomment[ Integer.valueOf(trim) -1];
}
String[] split1 = split[1].split("/\\*");
if(str.endsWith("WHERE %s")){
wherestr+= " "+columns +" = "+ split1[0]+" and";
}else {
setstr+= " "+columns +" = "+ split1[0]+" ,";
}
}
}
if( str.length() != 0 ){
wherestr= wherestr.substring(0,wherestr.length()-3);
setstr= setstr.substring(0,setstr.length()-1);
lsit.add(String.format(str,setstr,wherestr)+" ; ");
}
System.out.println("---------------------- "+lsit.size()+" --------------------------- ");
lsit.forEach((s)-> System.out.println(s+"\t"));
bufferedReader.close();
return "";
}
static String gettablecolumn(){
String s=" (\n" +
" `id` varchar(50) NOT NULL,\n" +
" `job_name` varchar(255) DEFAULT NULL COMMENT '任务名',\n" +
" `description` varchar(255) DEFAULT NULL COMMENT '任务描述',\n" +
" `cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron表达式',\n" +
" `bean_class` varchar(255) DEFAULT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名',\n" +
" `job_status` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '任务状态1、运行0、停止',\n" +
" `job_group` varchar(255) DEFAULT NULL COMMENT '任务分组',\n" +
" `create_user` varchar(64) DEFAULT NULL COMMENT '创建者',\n"
int num=0;
String str="";
String[] split = s.split(" ");
for (int i = 0; i <split.length; i++) {
if (split[i].contains("`")){
num++;
String b=split[i];
b=b.replace("`","");
str += b+ " ";
}
}
System.out.println(str);
return str;
}
}