浅析MySQL二进制日志

一般情况下,二进制日志更多的用于数据库的同步,因为二进制日志记录了数据库的所有改变,可以使得SLAVE都可以执行同样的更新,其实二进制日志可以对数据库作一个写入回放,所以也可以用于统计或者即时恢复等其它的目的。

  二进制日志仅仅包含可能改变数据库的语句,估计都很容易理解这个,但是那些还没有改变且有可能改变数据库的语句也会记录下来,比如drop table if exists或者是带有WHERE条件的UPDATE和DELETE语句。

  一、二进制日志结构

  二进制日志是一系列二进制日志事件(又称为binlog事件),其实就是很多文件【包括系列日志文件和一个日志索引文件】共同组成二进制日志,这里每个日志文件称为binlog文件,每个日志文件由很多个日志事件组成,每个日志文件都是以Format_description事件开头并且以日志轮换事件Rotate作为文件结束,如:

  mysql> show binlog events in 'master-bin.000003';
+-------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name          | Pos | Event_type  | Server_id | End_log_pos | Info                                  |
+-------------------+-----+-------------+-----------+-------------+---------------------------------------+
| master-bin.000003 |   4 | Format_desc |         1 |         106 | Server ver: 5.1.34-log, Binlog ver: 4 |
| master-bin.000003 | 106 | Rotate      |         1 |         150 | master-bin.000004;pos=4               |
+-------------------+-----+-------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)

  Format_description事件包含写日志文件的服务器信息以及日志文件格式,而Rotate事件包含下一个日志文件的文件名及其开始读取的位置。

  除了这两个事件以外,日志文件中的其他事件都被分成一个组一个组的形式,在事务存储引擎中,每个组会对应一个事务,而其它有可能是一个语句,总之,日志文件中的事件要么是单个语句,要么是由多条语句组成的事务。

  事件类型是有很多种,就是上面的Event_type在实际使用时,会有多个取值,但可以归纳为每个日志事件由三个部分组成:

  1、通用头。这部分信息就是所有事件都具备的信息,包含一些基本的信息,比如事件类型以及事件的大小,以上面为例可以从Pos和End_log_pos计算出这条语句的大小。

  2、提交头。这部分信息和特定的事件类型有关。

  3、事件体。这部分信息存储事件的主要数据,因事件类型不同而不同,例如,事件是Query的时候,存储查询语句。如下:

| master-bin.000004 | 180 | Query       |         1 |         297 | use `db_info`; insert into i_node(name,value) values("sql",@value)      

  二、记录语句

  传统的MySQL采用基于语句的复制,将实际执行的语句及某些和执行相关的信息一起写入二进制日志,然后在从库上重新执行这些语句。由于二进制日志是多个线程往里写入数据,避免两个线程同时更新对于同步来说是很重要的,为此,在事件写入二进制日志之前,需要获得一个互斥锁,然后在事件写完后释放该锁。下面讨论一下哪些数据会被写入二进制日志

  2.1 数据操作语言

  这通常就是DELETE,INSERT,UPDATE语句。在执行这些语句时,通常是执行语句拥有写锁期间写二进制日志,然后在日志写操作完成之后释放锁,这样保证二进制日志和语句导致的更新信息是一致的。

  2.2 数据定义语言

  如一些CREATE TABLE 和ALTER TABLE之类的语句。

 2.3 查询语句

  查询语句的类型是Query事件,这也是最常见的事件,用来存储主库上执行的语句,其实除了实际执行的语句外,这个事件还要包含一些附加的信息。如在写入一行数据中含有AUTO_INCREMENT的字段,我们执行一下写入,然后可以看到日志事件中多了哪些事件:

  执行下面语句:

insert into i_node(name,value) values("sql","copy");

  可以得到多了两条日志事件

| master-bin.000004 | 451 | Intvar      |         1 |         479 | INSERT_ID=12                                                                | 
| master-bin.000004 | 479 | Query       |         1 |         596 | use `db_info`; insert into i_node(name,value) values("sql","copy")          | 
+-------------------+-----+-------------+-----------+-------------+-----------------------------------------------------------------------------+

  其实除此以外,还有其它的一些上下文信息会给当前的执行带来结果的影响,这些都是MySQL执行时需要知道的隐式信息。如:

  1、当前数据库。可以看到我执行insert时,并没有执行use db_info这条语句,但是也被日志事件记录下来。因为我在最初执行了,后面MYSQL都采用当前的数据库来执行语句。

  2、用户自定义变量的值。如我执行下面两条语句之后


mysql> set @value = 'copy-on-write';
Query OK, 0 rows affected (0.00 sec)

mysql> insert into i_node(name,value) values("sql",@value);
Query OK, 1 row affected (0.00 sec)

  可以看到此时的日志事件如下:

| master-bin.000004 | 596 | Intvar      |         1 |         624 | INSERT_ID=13                                                                | 
| master-bin.000004 | 624 | User var    |         1 |         675 | @`value`=_latin1 0x636F70792D6F6E2D7772697465 COLLATE latin1_swedish_ci     | 
| master-bin.000004 | 675 | Query       |         1 |         792 | use `db_info`; insert into i_node(name,value) values("sql",@value)          |

  多了一个变量的赋值操作,类型是User var

  3、RAND()函数的种子。在执行随机数时,不会记录其随机数,会记录其种子数。

  4、当前时间。

  5、AUTO_INCREMENT字段的插入值,这个是一个上下文,因为它与前面的行有关。

  6、LAST_INSERT_ID函数。

  7、线程ID,调用CORRENT_ID函数。

====================================分割线================================

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-10-28 12:16:19

浅析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二制进日志用于记录数据库的变更记录,这里从结构上讨论一下日志的格式. 每个日志都包含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 be

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 二进制日志(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 | |