MySQL使用二进制日志来恢复数据二种方法

MySQL使用二进制日志来恢复数据二种方法

如果MySQL服务器启用了二进制日志,你可以使用mysql教程binlog工具来恢复从指定的时间点开始 (例如,从你最后一次备份)直到现在或另一个指定的时间点的数据。关于启用二进制日志的信息,参见5.11.3节,“二进制日志”。对于 mysqlbinlog的详细信息,“mysqlbinlog:用于处理二进制日志文件的实用工具”。

  要想从二进制日志恢复数据,你需要知道当前二进制日志文件的路径和文件名。一般可以从选项文件(即my.cnf or my.ini,取决于你的系统)中找到路径。如果未包含在选项文件中。

mysqlbinlog工具的使用,大家可以看MySQL的帮助手册。里面有详细的用,

在这个例子中,重点是--start-position参数和--stop-position参数的使用。

 

·--start-position=N

 

从二进制日志中第个位置等于N参量时的事件开始读。

 

·--stop-position=N

 

从二进制日志中第个位置等于和大于N参量时的事件起停止读。

 

 

 

OK,现在开始,要启动二进制日志记录,要先在my.cnf / my.ini文件的mysqld里添加

 

log-bin=日志名

 

在这里,偶是的设置是log-bin=liangck

 

然后再启动mysql服务,因为偶是用windows系统,所以执行net start mysql命令即可。

 

 

 

然后在一测试数据库教程里,创建一个表,并添加记录。

 

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 4 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)

 

mysql> drop table test;       --删除表

 

Query OK, 0 row affected (0.05 sec)

 

??????????????????????????????????

 

OK,现在测试数据已经建好了,要求是什么呢?

 

就是将test表的数据全部恢复出来。

 

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

 

F:/Program Files/MySQL_Data/data/log>mysqlbinlog liangck.000001 > G:/001.txt

 

F:/Program Files/MySQL_Data/data/log>mysqlbinlog liangck.000002 > G:/002.txt

 

F:/Program Files/MySQL_Data/data/log>mysqlbinlog liangck.000003 > G:/003.txt

 

通过这三个命令,可以在G盘下生成个文件,里面分别记录了日志文件的内容,也就是用户操作的步骤。

 

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

 

F:/Program Files/MySQL_Data/data/log>mysqlbinlog liangck.000001 | mysql -uroot –p

 

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

 

我们先打开.txt文件来分析一下。

 

/*

 

 

/*!40019 SET @@session.max_insert_delayed_threads=0*/;

 

/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

 

DELIMITER /*!*/;

 

# at 4

 

#090427 15:27:56 server id 1  end_log_pos 106 Start: binlog v 4, server v 5.1.32-community-log created 090427 15:27:56

 

BINLOG '

 

fF71SQ8BAAAAZgAAAGoAAAAAAAQANS4xLjMyLWNvbW11bml0eS1sb2cAAAAAAAAAAAAAAAAAAAAA

 

AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC

 

'/*!*/;

 

# at 106

 

#090427 15:28:37 server id 1  end_log_pos 176 Query  thread_id=1   exec_time=0   error_code=0

 

use mytest/*!*/;

 

SET TIMESTAMP=1240817317/*!*/;

 

SET @@session.ps教程eudo_thread_id=1/*!*/;

 

SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;

 

SET @@session.sql_mode=1344274432/*!*/;

 

SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;

 

/*!/C gbk *//*!*/;

 

SET @@session.character_set_client=28,@@session.collation_connection=28,@@session.collation_server=28/*!*/;

 

SET @@session.lc_time_names=0/*!*/;

 

SET @@session.collation_database=DEFAULT/*!*/;

 

BEGIN

 

/*!*/;

 

# at 176

 

#090427 15:28:37 server id 1  end_log_pos 204 Intvar

 

SET INSERT_ID=4/*!*/;

 

# at 204

 

#090427 15:28:37 server id 1  end_log_pos 312 Query  thread_id=1   exec_time=0   error_code=0

 

SET TIMESTAMP=1240817317/*!*/;

 

insert into test(val,data) values(40,'aaa')

 

/*!*/;

 

# at 312

 

#090427 15:28:37 server id 1  end_log_pos 339 Xid = 12

 

COMMIT/*!*/;

 

# at 339

 

#090427 15:28:46 server id 1  end_log_pos 409 Query  thread_id=1   exec_time=0   error_code=0

 

SET TIMESTAMP=1240817326/*!*/;

 

BEGIN

 

/*!*/;

 

# at 409

 

#090427 15:28:46 server id 1  end_log_pos 437 Intvar

 

SET INSERT_ID=5/*!*/;

 

# at 437

 

#090427 15:28:46 server id 1  end_log_pos 545 Query  thread_id=1   exec_time=0   error_code=0

 

SET TIMESTAMP=1240817326/*!*/;

 

insert into test(val,data) values(50,'bbb')

 

/*!*/;

 

# at 545

 

#090427 15:28:46 server id 1  end_log_pos 572 Xid = 13

 

COMMIT/*!*/;

 

# at 572

 

#090427 15:29:35 server id 1  end_log_pos 642 Query  thread_id=1   exec_time=0   error_code=0

 

SET TIMESTAMP=1240817375/*!*/;

 

BEGIN

 

/*!*/;

 

# at 642

 

#090427 15:29:35 server id 1  end_log_pos 670 Intvar

 

SET INSERT_ID=6/*!*/;

 

# at 670

 

#090427 15:29:35 server id 1  end_log_pos 778 Query  thread_id=1   exec_time=0   error_code=0

 

SET TIMESTAMP=1240817375/*!*/;

 

insert into test(val,data) values(60,'ccc')

 

/*!*/;

 

# at 778

 

#090427 15:29:35 server id 1  end_log_pos 805 Xid = 14

 

COMMIT/*!*/;

 

# at 805

 

#090427 15:30:21 server id 1  end_log_pos 875 Query  thread_id=1   exec_time=0   error_code=0

 

SET TIMESTAMP=1240817421/*!*/;

 

BEGIN

 

/*!*/;

 

# at 875

 

#090427 15:30:21 server id 1  end_log_pos 981 Query  thread_id=1   exec_time=0   error_code=0

 

SET TIMESTAMP=1240817421/*!*/;

 

delete from test where id between 4 and 5

 

/*!*/;

 

# at 981

 

#090427 15:30:21 server id 1  end_log_pos 1008    Xid = 15

 

COMMIT/*!*/;

 

# at 1008

 

#090427 15:30:34 server id 1  end_log_pos 1078    Query  thread_id=1   exec_time=0    error_code=0

 

SET TIMESTAMP=1240817434/*!*/;

 

BEGIN

 

/*!*/;

 

# at 1078

 

#090427 15:30:34 server id 1  end_log_pos 1106    Intvar

 

SET INSERT_ID=7/*!*/;

 

# at 1106

 

#090427 15:30:34 server id 1  end_log_pos 1214    Query  thread_id=1   exec_time=0    error_code=0

 

SET TIMESTAMP=1240817434/*!*/;

 

insert into test(val,data) values(70,'ddd')

 

/*!*/;

 

# at 1214

 

#090427 15:30:34 server id 1  end_log_pos 1241    Xid = 16

 

COMMIT/*!*/;

 

# at 1241

 

#090427 15:30:41 server id 1  end_log_pos 1282    Rotate to liangck.000003  pos: 4

 

DELIMITER ;

 

# End of log file

 

ROLLBACK /* added by mysqlbinlog */;

 

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

 

 

 

?????????????????????????????????????

 

*/

 

 

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

 

F:/Program Files/MySQL_Data/data/log>mysqlbinlog liangck.000002 --stop-pos=875 | mysql -uroot -p

 

 

 

F:/Program Files/MySQL_Data/data/log>mysqlbinlog liangck.000002 --start-pos=1008 | mysql -uroot -p mytest

 

 

 

OK,现在第二个日志文件的数据了。

 

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

 

F:/Program Files/MySQL_Data/data/log>mysqlbinlog liangck.000003 --stop-pos=574 | mysql -uroot –p

 

 

 

现在我们再查一下数据看看:

 

mysql> select * from test;

 

+----+------+-------+

 

| id | val  | data  |

 

+----+------+-------+

 

|  1 |   10 | liang |

 

|  2 |   20 | jia   |

 

|  3 |   30 | hui   |

 

|  4 |   40 | aaa   |

 

|  5 |   50 | bbb   |

 

|  6 |   60 | ccc   |

 

|  7 |   70 | ddd   |

 

|  8 |   80 | dddd  |

 

|  9 |   90 | eeee  |

 

+----+------+-------+

 

9 rows in set (0.00 sec)

方法二

要想从二进制日志恢复数据,你需要知道当前二进制日志文件的路径和文件名。一般可以从选项文件(即my.cnf or my.ini,取决于你的系统)中找到路径。如果未包含在选项文件中,当服务器启动时,可以在命令行中以选项的形式给出。启用二进制日志的选项为-- log-bin。要想确定当前的二进制日志文件的文件名,输入下面的MySQL语句:

SHOW BINLOG EVENTS G

你还可以从命令行输入下面的内容:

mysql --user=root -pmy_pwd -e 'SHOW BINLOG EVENTS G'

将密码my_pwd替换为服务器的root密码。

1. 指定恢复时间

对于MySQL 4.1.4,可以在mysqlbinlog语句中通过--start-date和--stop-date选项指定DATETIME格式的起止时间。举例说明,假设在今天上午10:00(今天是2006年4月20日),执行SQL语句来删除一个大表。要想恢复表和数据,你可以恢复前晚上的备份,并输入:

mysqlbinlog --stop-date="2005-04-20 9:59:59" /var/log/mysql/bin.123456

  mysql -u root -pmypwd

该命令将恢复截止到在--stop-date选项中以DATETIME格式给出的日期和时间的所有数据。如果你没有检测到几个小时后输入的错误的SQL语句,可能你想要恢复后面发生的活动。根据这些,你可以用起使日期和时间再次运行mysqlbinlog:

mysqlbinlog --start-date="2005-04-20 10:01:00" /var/log/mysql/bin.123456

  mysql -u root -pmypwd

在该行中,从上午10:01登录的SQL语句将运行。组合执行前夜的转储文件和mysqlbinlog的两行可以将所有数据恢复到上午10:00前一秒钟。你应检查日志以确保时间确切。下一节介绍如何实现。

2. 指定恢复位置

也可以不指定日期和时间,而使用mysqlbinlog的选项--start-position和--stop-position来指定日志位置。它们的作用与起止日选项相同,不同的是给出了从日志起的位置号。使用日志位置是更准确的恢复方法,特别是当由于破坏性SQL语句同时发生许多事务的时候。要想确定位置号,可以运行mysqlbinlog寻找执行了不期望的事务的时间范围,但应将结果重新指向文本文件以便进行检查。操作方法为:

mysqlbinlog --start-date="2005-04-20 9:55:00" --stop-date="2005-04-20 10:05:00"

/var/log/mysql/bin.123456 > /tmp/mysql_restore.sql

该命令将在/tmp目录创建小的文本文件,将显示执行了错误的SQL语句时的SQL语句。你可以用文本编辑器打开该文件,寻找你不要想重复的语句。如果二进制日志中的位置号用于停止和继续恢复操作,应进行注释。用log_pos加一个数字来标记位置。使用位置号恢复了以前的备份文件后,你应从命令行输入下面内容:

mysqlbinlog --stop-position="368312" /var/log/mysql/bin.123456

  mysql -u root -pmypwd

mysqlbinlog --start-position="368315" /var/log/mysql/bin.123456

  mysql -u root -pmypwd

上面的第1行将恢复到停止位置为止的所有事务。下一行将恢复从给定的起始位置直到二进制日志结束的所有事务。因为mysqlbinlog的输出包括每个SQL语句记录之前的SET TIMESTAMP语句,恢复的数据和相关MySQL日志将反应事务执行的原时间

 

时间: 2024-11-08 08:03:32

MySQL使用二进制日志来恢复数据二种方法的相关文章

MySQL数据库二进制日志备份和恢复步骤

基本概念 定义: 二进制日志包含了所有更新了数据或者已经潜在更新了数据(例如,没有匹配任何行的一个DELETE)的所有语句. 作用: 1.二进制日志的主要目的是在恢复使能够最大可能地更新数据库,因为二进制日志包含备份后进行的所有更新. 2.二进制日志还用于在主复制服务器上记录所有将发送给从服务器的语句. 不良影响: 运行服务器时若启用二进制日志则性能大约慢1%. MySQL默认二进制日志是关闭状态,先手动改动配置文件打开二进制日志 在my.cnf(windows下是my.ini)中的mysqld

mysql二进制日志文件恢复数据库_Mysql

二进制日志的文件的作用     mysql二进制日志文件用来记录所有用户对数据库操作,即记录用户对数据库操作的sql语句.如果有此文件,当数据库发生意外时,可以通过此文件查看到用户在此文件记录的时间段内用户所做的操作,再和数据库备份配合使用,即可再现用户操作,使数据库恢复. 二进制日志文件的弊端 二进制日志文件开启后,所有对数据库操作的记录均会被记录到此文件, 所以,当长时间开启之后,日志文件会变得很大,占用磁盘空间. 使用二进制日志文件恢复数据库 开启日志文件 mysql默认是不开启日志文件的

excel数据导入mysql数据库二种方法

下面我们要讲二种excel数据导入mysql教程数据库教程方法了,这二种方法比较简单,也是很方便的,以前我把excel数据导入到mysql数据库都是用php教程程序来实例,现在我们不需要程序,用现有的工具就行了. 方法一,利用phpmyadmin把excel数据导入mysql数据库方法如下 这是excel的,必须是这种样子的. 在phpmyadmin导入文件的格式应该如上图配置.(注意一点,导入的excel表的结构必须与mysql数据表的结构,数据类型等一致就ok了.否则会导入失败的. 方法二,

php 列出MySQL数据库中所有表二种方法

php教程 列出MySQL数据库教程中所有表二种方法 PHP代码如下: function list_tables($database) {     $rs = mysql教程_list_tables($database);     $tables = array();     while ($row = mysql_fetch_row($rs)) {         $tables[] = $row[0];     }     mysql_free_result($rs);     return

c#连接mysql数据库的二种方法

c#连接mysql教程数据库教程的二种方法 mysql提供的是一个dll文件--"mysql.data.dll",目前我用的就是这个dll文件,将这个文件(见附件)放到网站的bin目录下,就可以使用了.而且和sql server的用法并没有太大的出入,只是应用的名称不一样而已. 代码如下: 1.default.asp教程x: <%@ page language="c#" autoeventwireup="true"  codefile=&q

java发送url请求获取返回值的二种方法_java

下面提供二种方法会使用java发送url请求,并获取服务器返回的值 第一种方法: 复制代码 代码如下: import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.HttpClient;import org.apache.http.client.entity.UrlEncodedFor

asp.net C# 数据库备份和还原二种方法(sql server )

asp教程.net c# 数据库教程备份和还原二种方法(sql server ) 下面主要是讲一下关于利用c#来备份mssql server数据库了.下面看代码, ///备份方法 /// sqlconnection   conn   =   new   sqlconnection( "server=.;database=master;user   id=sa;password=sa; "); sqlcommand   cmdbk   =   new   sqlcommand(); cm

java解析xml二种方法

java解析xml二种方法 配置文件为: <?xml version="1.0" encoding="utf-8"?> <config>     <point name="test1">         <name>zhang3</name>         <address>abcdefg</address>         <email>a@b.c

asp 连接access数据库二种方法

连接access数据库教程二种方法 这里提供了access数据库的dsn-less连接方法与access ole db连接方法哦. dim db ="db.mdb"; access数据库的dsn-less连接方法: set adocon=server.createobject("adodb.connection") adoconn.open"driver={microsoft access driver(*.mdb)};dbq="& _