mysqlbinlog恢复数据

BINLOG就是一个记录SQL语句的过程,和普通的LOG一样。只是它是二进制存储,普通的是十进制存储。

==============================================================================

1.启动二进制日志记录,默认mysql关闭binlog。
# vim /etc/my.cnf,修改或添加

#log-bin = mysql-bin (此处等号后边名字可以自定义)

重启mysql

bin-log日志的存储位置:

如果log-bin配置项没指定绝对路径,则在配置的datadir目录下,不指定的话默认和数据在一起,不方便管理。

可以自己指定如log-bin=/var/lib/mysql/binlog/mysql-bin

我的datadir=/var/lib/mysql,指定上边的目录就是在mysql下建立个binlog文件夹,注意要先建立此文件件,并且注意权限,之后才可以指定成上边的存贮位置。

查看bin-log是否开启:

Show variables like "%log_bin%";

查看bin-log日志文件名:

show binary logs;

+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       149 |
| mysql-bin.000002 |       106 |
+------------------+-----------+

新生成一个bin-log日志(即再发生的sql操作将会写入这个bin-log里):

flush logs;

查看当前bin-log日志:

show master status;

清空bin-log日志: 

reset master; (一般在数据库进行完一次完整的备份时就清空一次bin-log日志)

查看某个日志:

mysqlbinlog --no-defaults mysql-bin.000001 [ | more]      此命令在命令行下执行报错可以到 /usr/local/mysql/bin/下执行。

--no-defaults 作用:

如果my.cnf中设置了default-character-set选项,不加--np-defaults  会报错  mysqlbinlog: unknown variable 'default-character-set=utf8'

这是mysql使用mysqlbinlog的bug:

使用mysqlbinlog工具查看二进制日志时会重新读取的mysql的配置文件my.cnf(windows下是my.ini),而不是服务器已经加 载进内存的配置文件。也就是说只要修改并保存了my.cnf文件,而不需要重起mysql服务器,则使用mysqlbinlog查看时修改后的 my.cnf配置文件对mysqlbinlog而言已经生效。所以这里可以使用此方法:把client选项组中default-character- set=utf8选项屏蔽掉,然后运行mysqlbinlog工具,则不会产生任何问题了。当然记得在不使用mysqlbinlog工具时把选项恢复。

使用--no-defaults 就不用修改上边的配置了,所以还是使用这个选项比较方便。

以下是mysqlbinlog后跟的主要参数:

--stop-position="100"

--start-position="50"

--stop-date="2012-01-04 21:17:50"

--start-date="2012-01-04 19:10:10"

binlog日志删除:

binlog日志会使文件增长非常快,很快会占满磁盘空间,所以要定期删除。

mysql>show variables like ‘%expire_logs_days%’;   #默认是0,既不过期

mysql>set global expire_logs_days=7;   #保存7天,设置全局参数(set global)是方便不重启mysql使之生效,想要重启后生效要配置到my.cnf。

2.测试

SQL code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
mysql> create table test(id int auto_increment not null primary key,
             val int,data varchar(20));
 
mysql> insert into test(val,data) values(10,'liang');
Query OK, 1 row affected (0.03 sec)
 
mysql> insert into test(val,data) values(20,'jia');
Query OK, 1 row affected (0.08 sec)
 
mysql> insert into test(val,data) values(30,'hui');
Query OK, 1 row affected (0.03 sec)
 
mysql> flush logs;   --产生第二个日志文件
Query OK, 0 rows affected (0.09 sec)
 
mysql> insert into test(val,data) values(40,'aaa');
Query OK, 1 row affected (0.05 sec)
 
mysql> insert into test(val,data) values(50,'bbb');
Query OK, 1 row affected (0.03 sec)
 
mysql> insert into test(val,data) values(60,'ccc');
Query OK, 1 row affected (0.03 sec)
 
mysql> delete from test where id between and 5;  --删除记录
Query OK, 2 rows affected (0.05 sec)
 
mysql> insert into test(val,data) values(70,'ddd');
Query OK, 1 row affected (0.03 sec)
 
mysql> flush logs;          --产生第三个文件文件
Query OK, 0 rows affected (0.11 sec)
 
mysql> insert into test(val,data) values(80,'dddd');
Query OK, 1 row affected (0.05 sec)
 
mysql> insert into test(val,data) values(90,'eeee');
Query OK, 1 row affected (0.03 sec)
 drop table test;       --删除表
Query OK, 0 row affected (0.05 sec)

OK,现在测试数据已经建好了,要的就是将test表的数据全部恢复出来。


先用mysqlbinlog工具将日志文件生成txt文件出来分析。

#mysqlbinlog mysql-bin. > .txt
#mysqlbinlog mysql-bin. > .txt
#mysqlbinlog mysql-bin.. > .txt

注:如果报mysqlbinlog命令不存在,需要进入到/usr/local/mysql/bin下执行,

[bin]  mysqlbinlog ../var/bin-log.000001 > /tmp/log1.txt   //指定bin-log的相对路径

因为我们需要重做第一个日志文件的所有操作,所以这里只需要将第一个日志文件全恢复就行了。

mysqlbinlog mysql-bin. | mysql -uroot –p123  [databasename]  //可以指定数据库

Ok,接着,我们需要分析的是第二个日志文件。为什么要分析它呢,
因为它中途执行了一个操作是DELETE,因为我们要做的是恢复全部数据,
也就是我们不希望去重做这个语句。所以在这里我们要想办法去绕开它。
我们先打开002.txt文件来分析一下。

# at
# :: server id end_log_pos Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
delete from gl_whos_online where full_name=
/*!*/;

在这个文件中,我们可以看到DELETE的操作的起始位置是546,终止位置是654.
那么我们只要重做第二个日志文件的开头到546的操作,然后再从654到末尾的操作,
我们就可以把数据给恢复回来,而不会DELETE数据。所以执行两个命令:

#mysqlbinlog mysql-bin. --stop-pos= | mysql -uroot -p123
#mysqlbinlog mysql-bin. --start-pos= | mysql -uroot -p

OK,现在第二个日志文件的数据了。
第三个日志文件也是同理,只要找到DROP TABLE的位置,就可以了。

#mysqlbinlog mysql-bin. --stop-pos= | mysql -uroot –p123

最终,全部数据都回来了。

总结:bin-log日志就是记录了操作数据库的语句,用bin-log恢复数据就是把曾执行的语句有选择的再执行一遍,执行需要的,像delete什么的就跳过。

我第一次按操作把表drop后执行binlog恢复总是报错:指定的表不存在,

因为我恢复的日志中没有创建表的语句,汗!

2014-08-20号添加内容

=====================================================================================

今天把数据库中的前三天的数据不小心删了,想要通过binlog日志恢复,这个表的数据时通过每天的定时任务插入的。

我删除了17,18,19号的数据,想通过上边的方法恢复,但是不可行,因为binlog文件太大了,要从这个表的建表语句恢复到我执行的delete语句,要执行几个binlog,文件很大不说,关键的问题是里边不光是这一个表的语句,还包含了其他表的语句。

关键时刻,帆哥出马:

思路:

1,先从binlog日志中找出17,18,19号的插入语句,因为表的数据通过每天的crontab(每天9:00执行)插入的,可以根据crontab的执行时间剔除掉binlog中的不需要的数据。

mysqlbinlog  --no-defaults  --start-date="2014-08-17 09:00:00" --stop-date="2014-08-17 09:01:00"  mysql-bin. >> mylog.txt

mysqlbinlog  --no-defaults  --start-date="2014-08-18 09:00:00" --stop-date="2014-08-18 09:01:00"  mysql-bin. >> mylog.txt

mysqlbinlog  --no-defaults  --start-date="2014-08-19 09:00:00" --stop-date="2014-08-19 09:01:00"  mysql-bin. >> mylog.txt

查看crontab执行时间:最好执行的脚本在结束后echo开始时间和结束时间到指定log,以便查看每天执行情况。

2,通过上边的三条语句把17,18,19三天的插入语句都放入到了mylog.txt中,然后过滤掉操作的不是当前表名的行,不是insert into的行。

  cat mylog.txt | grep 'INSERT INTO' | grep 'tablename' > newlog.sql

3, 导入newlog.sql到当前的表中,

导入时报错:导入的文件太大了,要设置配置项max_allowed_packet,方法参看http://www.cnblogs.com/leezhxing/p/3925332.html

搞定,数据回来了。

mysqlbinlog恢复数据-update20140820的更多相关文章

  1. mysqlbinlog恢复数据注意事项【转】

    mysqlbinlog 恢复数据注意事项 前言: 上次有个有个朋友恢复 MySQL 数据,一直恢复不成功,也没有报错信息,使用的环境是 MySQL 5.7 使用了 GTID 以及 binlog 格式为 ...

  2. mysql数据安全之利用二进制日志mysqlbinlog恢复数据

    mysql数据安全之利用二进制日志mysqlbinlog恢复数据 简介:如何利用二进制日志来恢复数据 查看二进制日志文件的内容报错: [root@xdclass-public log_bin]# my ...

  3. 通过mysqlbinlog 恢复数据

    前提数据库开启了bin_log记录日志. 查看日志 刷新日志 flush logs; 再次查看 show binary logs; 向表中插入一条数据 现在执行delete误操作,删除所有的数据. d ...

  4. 使用mysqlbinlog恢复数据

    前提:mysql数据库开启了binlog日志,并且有对应的日志文件 起因:今天由于同事对数据库的误操作不小心删除了一条数据 方法一:通过binlog日志文件恢复数据 通过mysqlbinlog恢复My ...

  5. mysqlbinlog 恢复数据到任意时间点

    创建表,插入数据. ``` mysql> create database binlog; mysql> create table bt(id int); mysql> insert ...

  6. mysqlbinlog恢复数据

    操作命令: 复制代码代码如下: show binlog events in 'mysql-bin.000016' limit 10; reset master 删除所有的二进制日志flush logs ...

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

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

  8. [转] 使用 MYSQLBINLOG 来恢复数据

     使用 MYSQLBINLOG 来恢复数据 2009-04-05 12:47:05 标签:mysql mysqlbinlog 恢复 数据库 数据 原创作品,允许转载,转载时请务必以超链接形式标明文章 ...

  9. 从binlog恢复数据及Mysqlbinlog文件删除

    做了mysql主从也有一段时间了,这两天检查磁盘空间情况,发现放数据库的分区磁盘激增了40多G,一路查看下来,发现配置好主从复制以来到现在的binlog就有40多G,原来根源出在这里,查看了一下my. ...

随机推荐

  1. 【51NOD 1478】括号序列的最长合法子段

    很恶心啊,一道水题改了半天,主要是各种细节没有注意到,包括左括号剩余时有可能会出错的情况,需要从后往前扫 贡献一组测试数据: ((()))())(())(( 答案:8 1 #include<cs ...

  2. HoG

    实现步骤 先计算每一个像素点位置上x和y方向上的梯度. 这样在每一个像素点位置上得到一个二维向量, 计算它的方向和模长 将图片分为一个个的cell, 如\(8\times 8\). 计算它的HOG: ...

  3. quartz介绍

    Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度.本 ...

  4. dede使用方法----如何自定义字段

    我们在用dede做东西的时候,有时候需要添加一些dede里面没有的字段,有dede后台里面可以添加相关的自段,下面我就以如何给产品添加一个价格的字段来讲述一下如何给dede添加字段,并且调用它. 1. ...

  5. 匿名内部类为什么访问外部类局部变量必须是final的?

    1.内部类里面使用外部类的局部变量时,其实就是内部类的对象在使用它,内部类对象生命周期中都可能调用它,而内部类试图访问外部方法中的局部变量时,外部方法的局部变量很可能已经不存在了,那么就得延续其生命, ...

  6. css后代选择器(div.class中间不带空格)

    如果我要查找<div>上用了.class的元素,查找方法:div.class:中间是不空格的. 以上这种形式为css后代选择器 参考:http://www.w3school.com.cn/ ...

  7. TYVJ1982 武器分配

    描述     后勤部队运来一批武器(机枪和盔甲).你要把这些武器分配给手下的marine们(每人一部机枪,一套盔甲).可是问题来了...    这些武器的型号不相同(武器是由出价最低的承包商制造的), ...

  8. dedecms /member/myfriend_group.php SQL Injection Vul

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Dedecms会员中心注入漏洞 Relevant Link http:/ ...

  9. C#点击按钮关闭当前窗体 打开另一个窗体。

    网上有很多是隐藏当前窗体,但是这样占用资源,效果不好,因此改进方法如下: private void button1_Click(object sender,EventArgs e) { this.hi ...

  10. resultset 对象获取行字段数据时报:java.sql.SQLException: Column 'id' not found.

    resultset 对象获取行字段数据时报:java.sql.SQLException: Column 'id' not found. 代码: String sql="SELECT d.co ...