1. 直接导入数据库

mysqlbinlog --database=testdb mysql-bin. | mysql -uroot -f

2. 导出成SQL文

(1) 从binlog输出为SQL

mysqlbinlog -vv --database=testdb --base64-output=decode-rows mysql-bin. > .sql
grep "###" .sql > 0001_#.sql

导出的SQL文如下格式:

### UPDATE `test`.`test_data1`
### WHERE
### @1='2002001809730903086' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
### @2='2001001959581442003' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
### @3='0661594' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### @4='758686' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### @5=1449174648065 /* LONGINT meta=0 nullable=1 is_null=0 */
### @6=0 /* LONGINT meta=0 nullable=1 is_null=0 */
### @7=0 /* LONGINT meta=0 nullable=1 is_null=0 */
### @8=0 /* LONGINT meta=0 nullable=1 is_null=0 */
### @9=1458787027688 /* LONGINT meta=0 nullable=1 is_null=0 */
### @10=0 /* LONGINT meta=0 nullable=1 is_null=0 */
### @11=1458787027688 /* LONGINT meta=0 nullable=1 is_null=0 */
### @12=300 /* INT meta=0 nullable=1 is_null=0 */
### SET
### @1='2002001809730903086' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
### @2='2001001959581442003' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
### @3='0661594' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### @4='758686' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### @5=1449174648065 /* LONGINT meta=0 nullable=1 is_null=0 */
### @6=0 /* LONGINT meta=0 nullable=1 is_null=0 */
### @7=0 /* LONGINT meta=0 nullable=1 is_null=0 */
### @8=0 /* LONGINT meta=0 nullable=1 is_null=0 */
### @9=1458787027688 /* LONGINT meta=0 nullable=1 is_null=0 */
### @10=1458787191658 /* LONGINT meta=0 nullable=1 is_null=0 */
### @11=1458787191658 /* LONGINT meta=0 nullable=1 is_null=0 */
### @12=400 /* INT meta=0 nullable=1 is_null=0 */
### INSERT INTO `test`.`test_data2`
### SET
### @1='00020017b4c3418b' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
### @2='2002001809730903086' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
### @3='00003997' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### @4='0661594' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### @5=1458787191658 /* LONGINT meta=0 nullable=1 is_null=0 */
### @6=0 /* INT meta=0 nullable=1 is_null=0 */

(2) 需要将其转换可以在mysql客户端执行的SQL。我写了一个小程序处理这个格式,代码如下:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Set; /**
*
* @author Beef Liu
*
**/
public class BinLogSQLConverter {
public final static String RTN_LINE = "\r\n"; private final static String SQL_WORD_INSERT_INTO = "INSERT INTO";
private final static String SQL_WORD_UPDATE = "UPDATE";
private final static String SQL_WORD_DELETE = "DELETE"; private final static String SQL_WORD_SET = "SET";
private final static String SQL_WORD_WHERE = "WHERE"; private final static String LINE_COMMENT = "###";
private final static String REGEX_BLOCK_COMMENT = "/\\*[^\\n']*/"; public static class TableDesc {
private String _tableName;
private String[] _colNames; public TableDesc() {
} public TableDesc(String tableName, String[] colNames) {
_tableName = tableName;
_colNames = colNames;
} public String getTableName() {
return _tableName;
}
public void setTableName(String tableName) {
_tableName = tableName;
}
public String[] getColNames() {
return _colNames;
}
public void setColNames(String[] colNames) {
_colNames = colNames;
}
} public static void convertToSQL(
File inputBinSQL, File outputSQL,
Charset charset,
TableDesc[] tableDescs
) throws IOException {
BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(inputBinSQL), charset)); try {
OutputStreamWriter writer = new OutputStreamWriter(
new BufferedOutputStream(new FileOutputStream(outputSQL)),
charset);
try {
List<String> lines = new ArrayList<String>(); while(true) {
String line = reader.readLine();
if(line == null) {
break;
} //trim '###'
if(line.startsWith(LINE_COMMENT)) {
line = line.substring(LINE_COMMENT.length());
} //trim block comment
line = line.replaceAll(REGEX_BLOCK_COMMENT, ""); if(startsWithAndIgnoreSpace(line, SQL_WORD_INSERT_INTO)
|| startsWithAndIgnoreSpace(line, SQL_WORD_UPDATE)
|| startsWithAndIgnoreSpace(line, SQL_WORD_DELETE)
) {
//format previous statement
if(lines.size() > 0) {
String formatedStmt = formatStatement(tableDescs, lines);
if(formatedStmt != null && formatedStmt.length() > 0) {
writer.append(formatedStmt).append(RTN_LINE);
}
} //new statement
lines.clear();
} lines.add(line);
} if(lines.size() > 0) {
String formatedStmt = formatStatement(tableDescs, lines);
if(formatedStmt != null && formatedStmt.length() > 0) {
writer.append(formatedStmt).append(RTN_LINE);
}
}
} finally {
writer.close();
}
} finally {
reader.close();
}
} private final static String formatStatement(TableDesc[] tableDescs, List<String> lines) {
String line; line = lines.get(0);
if(startsWithAndIgnoreSpace(line, SQL_WORD_INSERT_INTO)) {
return formatStatementOfInsert(tableDescs, lines);
} else if (startsWithAndIgnoreSpace(line, SQL_WORD_UPDATE)) {
return formatStatementOfUpdate(tableDescs, lines);
} else {
System.out.println("Not supported yet. statement type:" + line);
return "";
}
} private final static String formatStatementOfInsert(TableDesc[] tableDescs, List<String> lines) {
/*
INSERT INTO `test`.`test_data1`
SET
@1='00020017bae7830b'
@2='2002001280299806243'
@3='00004407'
@4='0661601'
@5=1458889871654
@6=0
*/ String tableName = findTableNameInLine(lines.get(0));
TableDesc tblDesc = getTableDesc(tableDescs, tableName);
if(tblDesc == null) {
return null;
} StringBuilder sql = new StringBuilder();
//INSERT INTO
sql.append(lines.get(0)).append(RTN_LINE);
//SET
sql.append(lines.get(1)).append(RTN_LINE); //@1=xxxx
for(int i = 2; i < lines.size(); i++) {
if (i > 2) {
sql.append(", ");
}
sql.append(substituteColName(tblDesc, lines.get(i))).append(RTN_LINE);
} sql.append(";").append(RTN_LINE); return sql.toString();
} private final static String formatStatementOfUpdate(TableDesc[] tableDescs, List<String> lines) {
/*
UPDATE `test`.`test_data2`
WHERE
@1='2002001280299806243'
@2='2001001394921721184'
@3='0661601'
@4='758029'
@5=1450922125360
@6=0
@7=1458889670699
@8=0
@9=1458889682247
@10=0
@11=1458889682247
@12=300
SET
@1='2002001280299806243'
@2='2001001394921721184'
@3='0661601'
@4='758029'
@5=1450922125360
@6=0
@7=1458889670699
@8=0
@9=1458889682247
@10=1458889871654
@11=1458889871654
@12=400
*/ String tableName = findTableNameInLine(lines.get(0));
TableDesc tblDesc = getTableDesc(tableDescs, tableName);
if(tblDesc == null) {
return null;
} StringBuilder sql = new StringBuilder();
//UPDATE
sql.append(lines.get(0)).append(RTN_LINE); List<String> blockOfWhere = new ArrayList<String>();
List<String> blockOfSet = new ArrayList<String>(); //@1=xxxx
List<String> blockRef = blockOfWhere;
for(int i = 1; i < lines.size(); i++) {
String line = lines.get(i); if(startsWithAndIgnoreSpace(line, SQL_WORD_SET)) {
blockRef = blockOfSet;
} line = substituteColName(tblDesc, line);
blockRef.add(line);
} //output SET block
sql.append(blockOfSet.get(0)).append(RTN_LINE);
for(int i = 1; i < blockOfSet.size(); i++) {
if(i > 1) {
sql.append(", ");
}
sql.append(blockOfSet.get(i)).append(RTN_LINE);
} sql.append(blockOfWhere.get(0)).append(RTN_LINE);
for(int i = 1; i < blockOfWhere.size(); i++) {
if (i > 1) {
sql.append("AND ");
}
sql.append(blockOfSet.get(i)).append(RTN_LINE);
} sql.append(";").append(RTN_LINE); return sql.toString();
} private final static String substituteColName(
TableDesc tblDesc, String line) {
int index0 = line.indexOf('@');
if(index0 < 0) {
return line;
} int index1 = line.indexOf('=', index0);
if(index1 < 0) {
return line;
} int colNum = Integer.parseInt(line.substring(index0 + 1, index1));
return line.substring(0, index0)
.concat("`").concat(tblDesc.getColNames()[colNum - 1]).concat("`")
.concat(line.substring(index1))
;
} private final static String findTableNameInLine(String line) {
int index1 = line.lastIndexOf('`');
int index0 = line.lastIndexOf('`', index1 - 1); return line.substring(index0 + 1, index1);
} private final static TableDesc getTableDesc(TableDesc[] tableDescs, String tableName) {
for(TableDesc desc : tableDescs) {
if(desc.getTableName().equalsIgnoreCase(tableName)) {
return desc;
}
} return null;
} private final static boolean startsWithAndIgnoreSpace(String str, String prefix) {
int begin;
for(begin = 0; begin < str.length(); begin++) {
char c = str.charAt(begin);
if(c != ' ') {
break;
}
} return str.startsWith(prefix, begin);
} }

调用的例子:

    @Test
public void test1() {
try {
File input = new File("test/restore001_#.sql");
File output = new File("test/restore001_#formated.sql"); BinLogSQLConverter.convertToSQL(
input, output,
Charset.forName("utf-8"),
new BinLogSQLConverter.TableDesc[] {
new BinLogSQLConverter.TableDesc(
"test_data1",
new String[] {"code","name","col3","col4"}
),
new BinLogSQLConverter.TableDesc(
"test_data2",
new String[] {"code","name","col3","col4"}
),
}
);
} catch (Throwable e) {
e.printStackTrace();
}
}

MySql binlog恢复数据的更多相关文章

  1. mysql binlog恢复数据实战

    在前面,我们了解了mysql binlog日志的作用以及使用方法:  http://www.php20.cn/article/237 在后面讲到了,可以通过binlog进行恢复数据,那么,具体步骤是怎 ...

  2. MySQL 5.7 - 通过 BINLOG 恢复数据

    日常开发,运维中,经常会出现误删数据的情况.误删数据的类型大致可分为以下几类: 使用 delete 误删行 使用 drop table 或 truncate table 误删表 使用 drop dat ...

  3. Mysql binlog备份数据及恢复数据,学会这个,我在也不怕删库跑路啦~

    导读 我一直都主张,技多不压身(没有学不会的技术,只有不学习的人),多学一项技能,未来就少求人一次.网上经常听到xxx删库跑路,万一真的遇到了,相信通过今天的学习,也能将数据再恢复回来~~~ 当然啦, ...

  4. 不小心删除数据--利用MySQL的binlog恢复数据

    MySQL Binary Log也就是常说的bin-log, ,是mysql执行改动产生的二进制日志文件,其主要作用有两个: * 数据回复 * 主从数据库.用于slave端执行增删改,保持与maste ...

  5. Mysql使用binlog恢复数据解决误操作问题的两种方法

    为保证没有其他参数配置影响,重新安装配置了一台最小化安装的CentOS7虚拟机 1. 基础知识
 安装mysql5.6数据库Mysql binlog初步理解 2. 配置mysql 开启binlog.修 ...

  6. 利用mysql的binlog恢复数据

    MySQL Binary Log也就是常说的bin-log, ,是mysql执行改动产生的二进制日志文件,其主要作用有两个: * 数据回复 * 主从数据库.用于slave端执行增删改,保持与maste ...

  7. mysql利用binlog恢复数据详细例子

    模拟数据恢复的案例 有些时候脑瓜就会短路,难免会出错 场景:在生产环境中,我们搭建了mysql主从,备份操作都是在从备份数据库上 前提:有最近一天或者最近的全备 或者最近一天相关数据库的备份 最重要的 ...

  8. mysql利用binlog恢复数据

    需求:需要给开发提供一个2018年9月30号的数据,按照我们公司正常备份策略来说,直接找到对应时间的备份数据,解压导入即可,恰好这个时间节点的数据没有,只备份到2018年9月25号的,糟糕了吧 咋办呢 ...

  9. mysql binlog恢复

    MySQL Binary Log也就是常说的bin-log, ,是mysql执行改动产生的二进制日志文件,其主要作用有两个: * 数据回复 * 主从数据库.用于slave端执行增删改,保持与maste ...

随机推荐

  1. docker-freebsd-20150625

    http://www.docker.org.cn/book/docker/prepare-docker-1.html https://wiki.freebsd.org/Docker pkg insta ...

  2. git clone时,报403错误,完美解决方案

    首先命令行操作结果如下: root@zhiren-PowerEdge-T110-II:/zrun# git clone https://git.coding.net/xxxxxxxx/xxxx.git ...

  3. tar命令实用介绍

    tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...

  4. 临时存存储页面上的数据---Web存储

    HTML5 Web存储的两种方法使用 localStorage和sessionStorage 参考: http://www.cnblogs.com/taoweiji/archive/2012/12/0 ...

  5. 基于Python的TestAgent实现

    问题: 1.本人工作主要做自动化,经常要去Linux后台进行一些脚本操作,有时要去后台执行命令,如果逐个登陆比较费事,效率会大打折扣 2.虽然有可以直接去后台执行命令的AW,但是该AW存在很多问题,而 ...

  6. JAVASE02-Unit06: 文件操作——File 、 文件操作—— RandomAccessFile

    Unit06: 文件操作--File . 文件操作-- RandomAccessFile java.io.FileFile的每一个实例是用来表示文件系统中的一个文件或目录 package day06; ...

  7. HP ALM 使用经验

    使用HP ALM(Application Lifecycle Management)软件有一个多月的时间了,我是从安装,部署,建项,配置,使用,再到问题收集,这个过程过来的.发现ALM是一个功能确实强 ...

  8. inotify监控目录变化重启服务器tornado项目

    pycharm 配置了提交服务器项目每次pycharm修改后,虽然保存到服务器但是项目还得自己去服务器kill再启动.就花几分钟写了shell脚本用于监控项目目录变化并重启tornado项目的脚本 如 ...

  9. Docker应用程序容器技术_转

    转自:百度百科 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相 ...

  10. 分析App应用市场, App应用有哪些类型

    随着移动互联网的流行,APP应用也是异常火爆,App应用市场就如破冰的泉水在我们的生活中到处渗透,对于App开发的的状况来分析,企业在寻找技术人员开发一款专业的App软件的时候,必须先了解用户的需求与 ...