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. ubuntu与登录有关的log配置信息

    1. 所有sudo, sshd, sftp登录的信息都在auth.log中. 2. pam的配置是在/etc/pam.conf与/etc/pam.d中,在文件夹pam.d对cron, sudo,ssh ...

  2. Android pop3与imap方式接收邮件(javamail)

    需要下载3个jar包:mail.jar/    activation.jar/    additionnal.jar 1.pop3 /** * 以pop3方式读取邮件,此方法不能读取邮件是否为已读,已 ...

  3. 在 shell 脚本获取 ip、数字转换等网络操作

    在 shell 脚本获取 ip.数字转换等网络操作 ip 和数字的相互转换 ip转换为数字 :: function ip2num() { local ip=$1 local a=$(echo $ip ...

  4. 百度富文本编辑器UEDITOR

    前言 http://jingyan.baidu.com/article/a948d65108d7fa0a2dcd2e8d.html 配置<a>测试啊</a>.net mvc4项 ...

  5. AngularJS Best Practices: ng-include vs directive

    For building an HTML template with reusable widgets like header, sidebar, footer, etc. Basically the ...

  6. Eclipse中配置svn

    1.打开eclipse,help--> Eclipse MarketPlace...,搜索输入“subclipse”,点击安装,一路按向导安装: 2.安装成功后,在Window --> S ...

  7. win8.1 Framework3.5安装不上的问题

    问题症状:安装的WIN8系统无法安装Framework,SQL等都有问题 解决误区:直接安装或者更新后在线安装(结果一样各种错误) 解决方法: 1.先gpedit.msc进入本地组策略管理,目录:计算 ...

  8. 【C# 小窍门】WeakEventManager 无法识别!ErrorCS0246The type or namespace name 'WeakEventManager' could not be found

    WeakEventManager 想用一下这个,在学习C# 事件的时候,结果添加了Using System.Windows, WeakEventManager却一直是红色的,无法识别,报这个错哦~ 好 ...

  9. java List<Item> its=new ArrayList<Item>(); Map按value中的某字段排序

    public List<Item> getAllItem(){ Map<Long, Item> itemDic = new HashMap<Long, Item>( ...

  10. 打开QQ会话

    Android:String url="mqqwpa://im/chat?chat_type=wpa&uin=123456";startActivity(new Inten ...