视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
利用MySQL日志模拟恢复数据变化轨迹II
2020-11-09 13:14:38 责编:小采
文档


在上篇《利用MySQL日志模拟恢复数据变化轨迹》中,我们已经介绍了我们方案的大致思路,其原理就是某网友提到的捞日志方式。 通过mysqlbinlog解析binlog之后,我们可以发现对我们 有用的信息都是以###开头 ,通过正则表达式匹配,我们就可以得到。 在日志中有

在上篇《利用MySQL日志模拟恢复数据变化轨迹》中,我们已经介绍了我们方案的大致思路,其原理就是某网友提到的捞日志方式。

通过mysqlbinlog解析binlog之后,我们可以发现对我们有用的信息都是以###开头,通过正则表达式匹配,我们就可以得到。

在日志中有@1,@2等字符, 这是代表表结构的字段名,即@1表示表中第一个字段,@2表示表中第二个字段等。然后我们通过查询INFORMATION_SCHEMA.COLUMNS表可以找到表的所有字段,然后一一替换掉即可。对于INSERT 和 DELETE两种操作,其数据行只有一份,而UPDATE有两份数据行。对此,我们需要第二份。

例如:

表结构信息

binlog信息

我们需要将其翻译成完全可执行的sql:insert into a (id, num) values (1, 199);

在截取字段值时,我们遇到一下几个坑:

1、字段值为日期类型。在日志中保存的格式为 @1=2012-12-04 13:14:35,此时,必须将2012-12-04 13:14:35加上引号。

2、负数。负数在日志中保存的格式为 @1=-1 (4294967295), 此时,我们其实只需要‘-1’即可。

3、转义字符集。日志当中显示的字段值信息与数据库中字段值信息一致,但是mysql在插入数据库是做了转义,导致日志中的内容不能马上截取直接使用。对此,我们修改了mysqlbinlog这个工具,让其解析出来的文本是未被转义的。例举几个:

root@test 09:50:58>insert into tx values(‘a\’b');

root@test 09:56:47>insert into tx values(‘a\tb’);

root@test 10:06:01>insert into tx values(‘a\bb’);

root@test 10:06:04>insert into tx values(‘a\0b’);

——————————————————-

原版

### INSERT INTO test.tx
### SET
### @1=’a'b’
### INSERT INTO test.tx
### SET
### @1=’a\x09b’
### INSERT INTO test.tx
### SET
### @1=’a\x08b’
### INSERT INTO test.tx
### SET
### @1=’a\x00b’

——————————————————-

修改版

### INSERT INTO test.tx
### SET
### @1=’a\’b’
### INSERT INTO test.tx
### SET
### @1=’a\tb’
### INSERT INTO test.tx
### SET
### @1=’a\bb’
### INSERT INTO test.tx
### SET
### @1=’a\0b’

具体内容可以参照:https://bugs.launchpad.net/percona-server/+bug/949965

4、双字节字符问题。

碰到一次解析binlog得到

·······

### @1=’休闲女鞋白黄粉黒’

······

解析出来的sql是insert into a values (‘黒\’),插回到数据库报错。原因是多了一个转义字符,在回去查看binlog时,并没有这个多余的转义字符‘\’。仔细看后,发现这并不是那个‘黑’,前者的十六进制是(FC5C),后者的十六进制是(BADA)。查看ASCII码表后得知,5C对应的字符是‘\’,而在第三类问题上已经对转义字符集修改,导致在解析出来的时候变成了 @1=’黒\’。

5、未发现问题。这个就需要我们大家更多的测试实践才能发现了。

PS:稍后献上已经修改过的mysqlbinlog以及工具脚本的代码。

下载本文
显示全文
专题