一般情况下,二进制日志更多的用于数据库的同步,因为二进制日志记录了数据库的所有改变,可以使得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在实际使用时,会有多个取值,但可以归纳为每个日志事件由三个部分组成:
- 通用头。这部分信息就是所有事件都具备的信息,包含一些基本的信息,比如事件类型以及事件的大小,以上面为例可以从Pos和End_log_pos计算出这条语句的大小。
- 提交头。这部分信息和特定的事件类型有关。
- 事件体。这部分信息存储事件的主要数据,因事件类型不同而不同,例如,事件是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执行时需要知道的隐式信息。如:
- 当前数据库。可以看到我执行insert时,并没有执行use db_info这条语句,但是也被日志事件记录下来。因为我在最初执行了,后面MYSQL都采用当前的数据库来执行语句。
- 用户自定义变量的值。如我执行下面两条语句之后
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
- RAND()函数的种子。在执行随机数时,不会记录其随机数,会记录其种子数。
- 当前时间。
- AUTO_INCREMENT字段的插入值,这个是一个上下文,因为它与前面的行有关。
- LAST_INSERT_ID函数。
- 线程ID,调用CORRENT_ID函数。
分享到:
相关推荐
这是一份腾讯内部的技术文档,详细讲述了 MySQL 数据库启用二进制日志 binlog 的细节,非常有参考价值。前言:日志是把数据库的每一个变化都记载到一个专用的文件里,这种文件就叫做日志文件。Mysql默认只打开出错...
二进制XML浅析[整理].pdf
数据迁移需要从mysql导入clickhouse, 总结方案如下,包括clickhouse自身支持的三种方式,第三方工具两种。 create table engin mysql CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] ( name1...
给大家介绍了ES6特性中的八进制和二进制整数字面量,介绍的挺不错的现在分享给大家,有需要的可以参考借鉴。
浅析MYSQL中的并发操作与锁定,主要介绍MYSQL的并发操作然后锁定
浅析MySQL数据库教程开设的意义.pdf
浅析MYSQL数据库的备份与恢复.pdf
浅析MYSQL数据库C/S浏览器设计.pdf
浅析MySQL数据库基于访问范围的外部安全性机制.pdf
浅析MySQL数据库在促进中小型企业发展中的应用.pdf
二进制日志 binary log 更新日志 update log 查询日志 query log 慢查询日志 slow query log innodb 的 redo 日志 2. 数据文件 >>>对于 myisam 来说: 表结构信息:.frm 数据信息:.myd 数据索引信息;.myi >>
主要介绍了Mysql联合索引最左匹配原则,使用联合索引的好处多多,具体内容详情大家跟随脚本之家小编一起学习吧
来自某知名IT公司的技术文档。做得很不错。
Redis架构下的MySQL数据库性能提升浅析.pdf
MySQL查询优化浅析
Mysql&分布式算法浅析, 一致性协议的作用就是保证各个Log副本数据的一致性,上图中的一致性模块就是用来保证一致性的。 再来看一个更具体的例子:在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都...
在MySQL的主从复制架构中,主库上经常会并发的执行很多SQL,只要这些SQL没有产生锁等待,那么同一时间并发好几个SQL线程是没有问题的。 我们知道,MySQL的从库是要通过IO_thread去拉取主库上的binlog的,然后...
MySQL JOIN 工作原理浅析1