MySQL 二进制日志格式深入理解

MySQL二制进日志用于记录数据库的变更记录,这里从结构上讨论一下日志的格式。

每个日志都包含4个字节的magic number 和event的描述包

日志有前四个字节是magic number: oxfe ox62 0×69 0x6e = 0xfe ‘b”i”n’ 转成整数:1852400382  用处就是读4个字节对比不是这个数,说明就不是二进制日志,就不用处理了。

 log_event.sh中可以查到

 /* 4 bytes which all binlogs should begin with */
    #define BINLOG_MAGIC        "\xfe\x62\x69\x6e"

每个event的header大概如下:

-每个event中包含:event的类型,什么时间,由哪版本的MySQL产生的
-从header头能找到该event的大小及一些变更信息

第一个event称为:format descriptor event(Event描述结构:FDE) 用于说明日志的格式

其它event就是依赖于描述结构不同,用不同的结构记录数据

最后一个event是: 日志切换事件(log-rotation event)用于指点定下个日志的文件名

每个event的结构大概如下:

+===================+
|event header      |
+===================+
|event data        |
+===================+

现在大多使用的V4结构,从MySQL 5.0起,具体如下:

+=====================================+
|event  |timestamp         0:4    |
|header+––––––––––––––+
|        |type_code         4:1    |
|        +––––––––––––––+
|        |server_id         5:4    |
|        +––––––––––––––+
|        |event_length      9:4    |
|        +––––––––––––––+
|        |next_position    13:4    |
|        +––––––––––––––+
|        |flags            17:2    |
|        +––––––––––––––+
|        |extra_headers    19:x-19|
+=====================================+
|event  |fixed part        x:y    |
|data   +––––––––––––––+
|        |variable part              |
+=====================================+
第一个event是FDE结构没有extra_headers部分,所以固定为19个字节。

FDE的event_data中定长部分为:

2字节的的日志格式版本,从MySQL 5.0后都是4

50字节 用于记录MySQL的版本号 如:5.6.16-64.2-rel64.2-log 不够50字节用0×00填充

4字节 日志产生的时间

1字节 header长度。一般是19,如果大于19,则下面的event都有extra_header字段
对于FDE变长部分一般为空

其它Event计算

header length = x byte

data length = (event_lenth -x )byte

数据区里定长部分长度

 fixed_part=ybyte
 variable_part=(event_length-(x+y))byte

补充:二进制操作

开启mysql二进制日志:
编辑my.cnf,添加
log-bin=/var/log/mysql/mysql-bin.log
开启日志后需要myssqladmin flush logs才能生效。
需要注意的是log-bin指定扩展名是无效的,当mysql创建二进制日志文件时,首先创建一个以“mysql_log_bin”为名称,以“.index”为后缀的文件;再创建一个以“mysql_log_bin”为名称,以 “.000001”为后缀的文件。当mysql服务重新启动一次以“.000001”为后缀的文件会增加一个,并且后缀名加1递增;如果日志长度超过了 max_binlog_size的上限(默认是1G)也会创建一个新的日志文件;使用flush logs(mysql命令符)或者执行mysqladmin –u –p flush-logs(windows命令提示符)也会创建一个新的日志文件。
查看:
由于日志是以二进制方式存储的,不能直接读取,需要使用mysql自带的mysqlbinlog工具来进行查看
mysqlbinlog mysql-bin.000002 -d test
mysqlbinlog有一些选项可以使用,简单说明常用选项:
-d,--database=name :指定数据库名称,只列出指定数据库的操作.
-D, --disable-log-bin :执行恢复的时候,禁止二进制日志.可以防止同一台MySQL加上-t时进入死循环
-o,--offset=n :忽略掉日志前n行命令
-r,--result-file=name :将输出日志到指定文件
-R, --read-from-remote-server :从一个MySQL服务器上读取二进制
-s,--short-form :显示简单格式,省略一些信息
-S, --socket=name  :socket文件连接path.
-t, --to-last-log  :和-R一起使用,在二进制日志结束的时候并不会停止,而是在MySQL服务器最后生成的binlog结束,如果输出和输入都在一台MySQL上可能会导致死循环.
--set-charset=char-name :在输出文本格式的时候,在第一行加上set names char-name.
--start-datetime=# --stop-datetime=# :指定输出起始日期的日志.
--start-position=# --stop-position=# :指定起始日志的位置.
清理:
删除全部二进制日志:
reset master
删除部分日志:
PURGE MASTER LOGS TO & PURGE MASTER LOGS BEFORE
PURGE MASTER LOGS TO 'mysql-bin.******'命令,是将'******'编号之前的所有日志进行删除
PURGE MASTER LOGS BEFORE 'yyyy-mm-dd hh:mm:ss'命令,是将在'yyyy-mm-dd hh:mm:ss'时间之前的所有日志进行删除
设置日志过期时间:
修改my.cnf
expire_log_day=5
这里设置保存5天的日志,超过5天的日志会被自动删除
恢复:
完全恢复:
mysqlbinlog mysql-bin.00001|mysql -uroot -p
基于时间点的恢复:
如果误删了一张表,使用完全恢复是没有用的,因为日志里同样也保留着删除的sql语句,所以我们需要恢复到误操作前的状态,然后跳过误操作的语句。
假如我在20:00误删了一张表,可以使用以下语句恢复:
mysqlbinlog --stop-date='2012-06-05 19:59:59' /var/log/mysql-bin.000001 | mysql -uroot -p
跳过误删除的时间点,再执行:
mysqlbinlog --start-date='2012-06-05 20:01:00' /var/log/mysql-bin.000001 | mysql -uroot -p
基于位置点的恢复:
基于位置点的恢复可以得到更为精确的数据。
binlog
如上图,drop table test这条语句的起始位置是889107,终止位置是889189,那么我们可以使用于以下语句进行恢复:
mysqlbinlog --stop-position='889107' /var/lib/mysql/mysql-bin.000001|mysql -uroot -p
mysqlbinlog --start-position='889189' /var/lib/mysql/mysql-bin.000001|mysql -uroot -p
有时有可能因为系统版本的问题,以上方法行不通,可以将二进制导出到一个sql文件中,再直接根据sql语句进行恢复
mysqlbinlog  mysqlbinlog.000001 >log.sql

时间: 2024-07-31 00:13:49

MySQL 二进制日志格式深入理解的相关文章

MySQL二进制日志(binary log)总结

原文:MySQL二进制日志(binary log)总结   本文出处:http://www.cnblogs.com/wy123/p/7182356.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误进行修正或补充,无他)    提示max_binlog_cache_size空间不足,因为开启了二进制日志,之前是默认设置没有大批量的事务性操作,没有遇到该问题,这一次一开始就遇到一个较大的事务性操作就失败了.之后修改binlog_cac

MySQL二进制日志总结

二进制日志简单介绍   MySQL的二进制日志(binary log)是一个二进制文件,主要用于记录修改数据或有可能引起数据变更的MySQL语句.二进制日志(binary log)中记录了对MySQL数据库执行更改的所有操作,并且记录了语句发生时间.执行时长.操作数据等其它额外信息,但是它不记录SELECT.SHOW等那些不修改数据的SQL语句.二进制日志(binary log)主要用于数据库恢复和主从复制,以及审计(audit)操作.   官方文档关于二进制日志(binary log)的介绍如

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

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

linux中关闭与删除mysql二进制日志的方法

1.删除mysql二进制日志 # mysql -uroot -p密码 -e"reset master;" 2.关闭二进制日志 编辑文件: vi /etc/my.cnf 注释如下代码: #log-bin=mysql-bin #binlog_format=mixed 3.重启mysql服务器 service mysql restart 友情提示,二进制日志文件可以非常方便的给我们数据进行备份哦,如果你系统出严重问题我们通常利用二进制文件进行数据恢复操作哦.

删除MySQL二进制日志具体方法

服务器上的120G SSD硬盘空间用了92%,检查后发现,原来是 MySQL的二进制日志没有及时清除,占用了大量的空间,于是直接用命令:reset master 一把删干净了.  代码如下 复制代码 reset master 如果MySQL服务器上的数据库做了replication,就不要使用该命令,而是应该用:purge binary logs 命令.purge 比较温和,通常有两种执行方式:  代码如下 复制代码 purge binary logs to     'mysql-bin.010

浅析MySQL二进制日志

一般情况下,二进制日志更多的用于数据库的同步,因为二进制日志记录了数据库的所有改变,可以使得SLAVE都可以执行同样的更新,其实二进制日志可以对数据库作一个写入回放,所以也可以用于统计或者即时恢复等其它的目的. 二进制日志仅仅包含可能改变数据库的语句,估计都很容易理解这个,但是那些还没有改变且有可能改变数据库的语句也会记录下来,比如drop table if exists或者是带有WHERE条件的UPDATE和DELETE语句. 一.二进制日志结构 二进制日志是一系列二进制日志事件(又称为bin

MySQL 二进制日志(Binary Log)

    同大多数关系型数据库一样,日志文件是MySQL数据库的重要组成部分.MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志,慢查询日志,等等.这些日志可以帮助我们定位mysqld内部发生的事件,数据库性能故障,记录数据的变更历史,用户恢复数据库等等.二进制日志,也叫binary log,是MySQL Server中最为重要的日志之一,本文主要描述二进制日志.   1.MySQL日志文件系统的组成   a.错误日志:记录启动.运行或停止mysqld时出现的问题.   b

删除MySQL二进制日志命令与例子详解

方法一,删除全部二进制日志: 在mysql上执行reset master命令,那么就清除了所有的mysql-bin.*日志,并且以后日志文件名从mysql-bin.000001开始 reset master 删除部分日志:  代码如下 复制代码 PURGE MASTER LOGS TO & PURGE MASTER LOGS BEFORE PURGE MASTER LOGS TO 'mysql-bin.******'命令,是将'******'编号之前的所有日志 进行删除 PURGE MASTER

删除MySQL二进制日志(log-bin)

查找当前有哪些二进制日志文件  代码如下 复制代码 mysql> show binary logs; +------------------+-----------+ | Log_name         | File_size | +------------------+-----------+ | mysql-bin.000001 |   1357315 | | mysql-bin.000002 |       117 | | mysql-bin.000003 |    404002 | |