mysqlbinlog+binlog日志文件+数据恢复

一、binlog介绍

1)该日志记录着数据库的所有增、删、改的操作日志,还包括这些操作的执行时间。

Binlog功能默认是关闭的,没有开启。

查看binlog,用mysqlbinlog -v mysql-bin.000001

Binlog的用途:1:主从同步 2:恢复数据库

开启binary log功能:通过编辑my.cnf中的log-bin选项可以开启二进制日志;形式如右:log-bin[=DIR/[filename]] ,注释:每次重启mysql服务或运行mysql> flush logs;都会生成一个新的二进制日志文件,这些日志文件的number会不断地递增,除了生成上述的文件外还会生成一个名为filename.index的文件。这个文件中存储所有二进制日志文件的清单又称为二进制文件的索引。

mysql > show variables like 'log_bin';

二、演示mysqlbinlog方式提取binlog

a、提取指定的binlog日志

# mysqlbinlog /opt/data/APP01bin.000001

# mysqlbinlog /opt/data/APP01bin.000001|grep insert

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

insert into tb values(2,'jack')

b、提取指定position位置的binlog日志

# mysqlbinlog --start-position="120" --stop-position="332" /opt/data/APP01bin.000001

c、提取指定position位置的binlog日志并输出到压缩文件

# mysqlbinlog --start-position="120" --stop-position="332" /opt/data/APP01bin.000001 |gzip >extra_01.sql.gz

d、提取指定position位置的binlog日志导入数据库

# mysqlbinlog --start-position="120" --stop-position="332" /opt/data/APP01bin.000001 | mysql -uroot -p

e、提取指定开始时间的binlog并输出到日志文件

# mysqlbinlog --start-datetime="2014-12-15 20:15:23" /opt/data/APP01bin.000002 --result-file=extra02.sql

f、提取指定位置的多个binlog日志文件

# mysqlbinlog --start-position="120" --stop-position="332" /opt/data/APP01bin.000001 /opt/data/APP01bin.000002|more

g、提取指定数据库binlog并转换字符集到UTF8

# mysqlbinlog --database=test --set-charset=utf8 /opt/data/APP01bin.000001 /opt/data/APP01bin.000002 >test.sql

h、远程提取日志,指定结束时间

# mysqlbinlog -urobin -p -h192.168.1.116 -P3306 --stop-datetime="2014-12-15 20:30:23" --read-from-remote-server mysql-bin.000033 |more

i、远程提取使用row格式的binlog日志并输出到本地文件

# mysqlbinlog -urobin -p -P3606 -h192.168.1.177 --read-from-remote-server -vv inst3606bin.000005 >row.sql

一些binlog的查看命令,及基础知识

mysql> show binary logs;

mysql> show master status;

mysql > show binlog events;

默认显示可找到的第一个二进制日志文件中的事件,包含了日志文件名,事件的开始位置,事件类型,结束位置,信息等内容。

Format_desc:是格式描述事件

query: 是查询事件

query(begin): 是查询事件、事物开始。

table map:是表映射事件。

write rows: 执行的insert事件。

xid: 该事件是自动提交事物的动作。 该事件记录了事务的ID,在MySQL进行崩溃恢复时,根据事务在binlog中的提交情况来决定是否提交存储引擎中状态为prepared的事务。

rotate:为日志轮换事件,是我们执行flush logs开启新日志文件引起的。

注意:执行完一个语句,会产生四个事务时间,这四个事件加一起才是一个执行语句%完整事件

query(begin)+ table map + write rows + rotate

GTID_LOG_EVENT:

在启用GTID模式后,MySQL实际上为每个事务都分配了个GTID

PREVIOUS_GTIDS_LOG_EVENT

开启GTID模式后,每个binlog开头都会有一个PREVIOUS_GTIDS_LOG_EVENT事件,它的值是上一个binlog的PREVIOUS_GTIDS_LOG_EVENT+GTID_LOG_EVENT,实际上,在数据库重启的时候,需要重新填充gtid_executed的值,该值即是最新一个binlog的PREVIOUS_GTIDS_LOG_EVENT+GTID_LOG_EVENT。

STOP_EVENT

当MySQL数据库停止时,会在当前的binlog末尾添加一个STOP_EVENT事件表示数据库停止

查看指定的二进制日志中的事件:

mysql > show binlog events in 'binlog.000002';

该命令还包含其他选项以便灵活查看:

mysql > show binlog events in 'binlog.000002' from 255 limit 1,3;

从255开始,偏移一个事件后取出3个事件

总结:上述方式可以查看到服务器上存在的二进制日志文件及文件中的事件,但是想查看到文件中具体的内容并应于恢复场景还得借助mysqlbinlog这个工具。

语法格式:mysqlbinlog [options] log_file ...

输出内容会因日志文件的格式以及mysqlbinlog工具使用的选项不同而略不同。

mysqlbinlog的可用选项可参考man手册。

二进制日志文件的格式包含行模式、语句模式和混合模式(有服务器决定在什么情况下记录什么类型的日志),基于语句的日志中事件信息包含执行的语句等,基于行的日志中事件信息包含的是行的变化信息等。混合模式的日志中两种类型的事件信息都会记录。未来便于查看记录了行变化信息的事件在当时具体执行了什么样的sql语句,,可以使用mysqlbinlog 工具的 -v (--verbose)选项,该选项会将行事件重构成被注释掉的伪sql语句,如果想看更详细的信息可以将该选项给两次如 -vv ,这样可以包含一些数据类型和元信息的注。例如:

先切换到binlog所在的目录下

#mysqlbinlog mysql-bin.000001

#mysqlbinlog -v mysql-bin.000001

#mysqlbinlog -vv mysql-bin.000001

另外mysqlbinlog和可以通过 --read-from-remote-server 选项从远程服务器读取二进制日志文件,这是需要一些额外的连接参数,如-h,-P, -p, -u等,这些参数仅在指定了--read-from-remote-server后有效。

说明:无论是本地二进制日志文件还是远程服务器上的二进制日志文件,无论是行模式、语句模式还是混合模式的二进制日志文件,被mysqlbinlog工具解析后都可直接应用与MySQL Server进行基于时间点、位置或数据库的恢复。

注意:在实际生产环境中,如果遇到需要恢复数据库的情况,不要让用户能访问到数据库,以避免新的数据插入进来,以及在主从的环境下,关闭主从。

mysqlbinlog选项详解:

--start-datetime    #从二进制日志中读取指定时间戳或者本地计算机时间之后的日志事件

--stop-datetime    #从二进制日志中读取指定时间戳或者本地计算机时间之前的日志事件

--start-position       #从二进制日志中读取指定position事件位置作为开始。

--stop-position       #从二进制日志中读取指定position事件位置作为事件截止。

三、实例,利用binlog文件恢复删除语句

说明:bin-log是二进制文件,不能通过文件内容查看命令直接打开查看,mysql提供两种方式查看方式。

1、对数据库进行一下增删改的操作,记录到binlog里

mysql > reset master;    #清空二进制文件,然后重新开始从00001记录

#由于上一步清空了binlog文件,所以下边的操作都会记录到mysql-bin.000001中

mysql > create database test;

mysql > use test;

mysql > create table M(id int,name varchar(10))engine=myisam;

mysql > insert into M values(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');

2、重新开始一个新的日志文件( flush logs;---强制产生新的二进制文件)

mysql > flush logs;    #重新开始一个日志

#一下操作会记录到mysql-bin。000002中

mysql > delete from M where id=4;模拟误操作,删除数据

mysql > create table I(id int,name varchar(10))engine=innodb;

mysql > insert into I values(11,'A'),(22,'B'),(33,'C'),(44,'D'),(55,'E');    #插入数据

mysql > select * from I;

3、查看MySQL Server上的二进制日志

mysql > show  binary logs;

4、查看binlog文件,从中找出delete from M where id=4

# cd /var/lib/mysql/

# mysqlbinlog -v mysql-bin.000002

显示结果如下:

# at 219

#170316 21:52:28 server id 1 end_log_pos 287 CRC32 0xff83a85b Query thread_id=2 exec_time=0 error_code=0

SET TIMESTAMP=1489672348/*!*/;

SET @@session.pseudo_thread_id=2/*!*/;

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

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

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

/*!\C utf8 *//*!*/;

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

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

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

BEGIN

/*!*/;

# at 287

#170316 21:52:28 server id 1 end_log_pos 337 CRC32 0x343e7343 Table_map: `bdqn`.`test` mapped to number 108

# at 337

#170316 21:52:28 server id 1 end_log_pos 382 CRC32 0xa3d1ce0d Delete_rows: table id 108 flags: STMT_END_F

BINLOG '

nJjKWBMBAAAAMgAAAFEBAAAAAGwAAAAAAAEABGJkcW4ABHRlc3QAAgMPAjwAAkNzPjQ=

nJjKWCABAAAALQAAAH4BAAAAAGwAAAAAAAEAAgAC//wCAAAABGxpc2kNztGj

'/*!*/;

### DELETE FROM `test`.`M`

### WHERE

### @1=4

### @2='d'

# at 382

#170316 21:52:28 server id 1 end_log_pos 413 CRC32 0x257e7073 Xid = 10

COMMIT/*!*/;

说明:可以从上图可以看出来delete时间发生position是287,事件结束position是413

5、恢复流程:直接用bin-log日志将数据库恢复到删除位置287前,然后跳过故障点,再进行恢复下面所有的操作,命令如下。由于之前没有做过全库备份,所以要使用所有binlog日志恢复,所以生产环境中需要很长时间恢复,导出相关binlog文件。

mysqlbinlog /var/lib/mysql/mysql-bin.000001 > mysql-bin.sql

mysqlbinlog /var/lib/mysql/mysql-bin.000002 --stop-position=287 > 287.sql

mysqlbinlog /var/lib/mysql/mysql-bin.000002 --sart-position=413 > 413.sql

6、删除test数据库)

mysql > drop database test;

7、利用binlog恢复数据

#mysql -uroot -p@123456 < mysql-bin.sql

#mysql -uroot -p@123456 < 287.sql

#mysql -uroot -p@123456 < 413.sql

8、恢复完成后,表的数据是否完整。

OK

猜你喜欢

转载自blog.csdn.net/LiuHuan_study/article/details/81413080