mysql对binlog的处理说明

然而这里不打算对某种存储引擎的实现细节进行描述,也不打算介绍各种存储引擎的优缺点,只是描述一下mysql如何处理binlog,并澄清几个容易混淆的问题。
Binlog对mysql而言是重要的,主要体现在它的功能上。Mysql官方文档明确指出,binlog的启动大概会为mysql增加1%的负载,因此在绝大多数情况下,binlog都不会成为mysql的性能瓶颈。
Binlog是mysql以二进制形式打印的日志,它默认不加密,不压缩。每个正常的binlog文件头部,有4个字节的标记,值为0xfe 0x62 0x69 0x6e。LOG_EVENT是binlog里的单位,即正常情况下binlog按照逐LOG_EVENT的形式增长。除去头部的标记,binlog就是一个LOG_EVENT的序列。每个LOG_EVENT都独立单元,没有互相引用的关系,它也有自己的二进制头部,主要是记录了时间戳、类型标记等描述信息。
Mysql把磁盘操作的实现封装在IO_CACHE结构里,这也方便了我们对binlog的研究和描述,后文如果没有特别说明,读写binlog与读写IO_CACHE的含义相同。
为了解mysql写入binlog的过程,可以找一个sql语句的处理过程进行跟踪。以update为例,在最简单的情况下,mysql会先调用为存储引擎开放的接口ha_update_row,然而执行binlog_query对binlog进行写操作。这样处理的原因是,在主从备份的场景下,如果主库先写入binlog成功、在执行update的过程中crash,从库有可能执行update成功,此时主库重启之后,与从库的数据不一致。如果update操作发生在事务性的表上,在写入binlog之后会执行开放接口ha_autocommit_or_rollback,由存储引擎判断操作结果。
在主从备份的场景下,主库相当于server,从库相当于client,双方采用tcp短连接。从库发出读取日志的请求,主库接收请求、读取本地binlog、然后发送给从库。从库接收日志,进行简单校验后写本地日志,称为relay log。此处从库的流程专门由一个线程负责,称为同步io线程。从库还有一个线程,称为同步sql线程。它的行为是,定期读取relay log,解析并执行同步过来的sql语句。

下面回答几个问题:

1. binlog的格式?
二进制顺序存储,不加密,不压缩

2.binlog使用WAL吗?

No
3.主库发送binlog,是使用内存里的copy吗?

无法确定,很有可能是先从磁盘上读一份,然后发送。

4. relaylog使用WAL吗?

Yes。从库接收到日志后,会先写relay log

5. binlog和relaylog的SQL是否一致?

在网络传输正确性可靠的前提下,yes

提一个问题:
既然binlog不使用WAL,那么在主从场景下,mysql异常之后,主库和从库是否会不一致呢?

之前有个问题一直没弄明白:
既然mysql是先做数据操作、再写binlog,如果写binlog的时候失败,mysql又crash,数据怎么办?
答案是由存储引擎决定数据。
可以把mysql和它的存储引擎分开看,因为mysql只是一个框架,而不是一个实现。
binlog是mysql自己的日志,而事务是由存储引擎本身保证的。
以update为例,mysql做的事情简单分为:
1. 修改数据update
2. 写binlog
3. 如果当前处理的表是一个事务性的表,则commit或rollback
注意此处的update和commit/rollback都由存储引擎实现,mysql只是站在逻辑的高度上理解这些操作。
对于事务型的引擎innodb,它本身有日志保证数据的一致性。在innodb的实现中,update修改数据之前,
会新建一个事务,并建立一个回滚点。而在innodb提供的commit/rollback接口会提交/回滚事务。
因此对innodb而言,每条SQL语句的事务,其实包含了binlog的写操作。然而即使是这样,innodb仍然无法保证
binlog和数据的一致性,因为innodb在写commit成功后crash,回滚操作不会回滚binlog。按照手册上的说法,
把--innodb-support-xa设置为1,同时保证sync_binlog=1,才能保证innodb的binlog和数据一致。

对于非事务型的引擎myisam,没有commit/rollback的机会,因此在异常情况下,数据会和binlog不一致。
那么新的问题出现了:myisam如何处理这个不一致呢?

(0)

相关推荐

  • [MySQL binlog]mysql如何彻底解析Mixed日志格式的binlog

    mysql binlog3种格式,row,mixed,statement. 解析工作 mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000144 |more --base64-output=DECODE-ROWS: 会显示出row模式带来的sql变更. -v :显示statement模式带来的sql语句 复制代码 代码如下: [mysql@002tmp]$ mysqlbinlog --base64-output=DECODE-ROWS

  • Linux上通过binlog文件恢复mysql数据库详细步骤

     一.binlog 介绍 服务器的二进制日志记录着该数据库的所有增删改的操作日志(前提是要在自己的服务器上开启binlog),还包括了这些操作的执行时间.为了显示这些二进制内容,我们可以使用mysqlbinlog命令来查看. 用途1:主从同步 用途2:恢复数据库(也是线上出现一次数据库文件丢失后,才对这个有所了解并学习的) mysqlbinlog命令用法:shell> mysqlbinlog [options] log_file ... <!--[if !supportLists]-->

  • MySQL binlog中的事件类型详解

    MySQL binlog记录的所有操作实际上都有对应的事件类型的,譬如STATEMENT格式中的DML操作对应的是QUERY_EVENT类型,ROW格式下的DML操作对应的是ROWS_EVENT类型. 首先,看看源码中定义的事件类型 源码位置:mysql-5.7.14/libbinlogevents/include/binlog_event.h enum Log_event_type { /** Every time you update this enum (when you add a ty

  • MySQL中的binlog相关命令和恢复技巧

    操作命令: 复制代码 代码如下: show binlog events in 'mysql-bin.000016' limit 10; reset master 删除所有的二进制日志flush logs  产生一个新的binlog日志文件 show master logs; 或者 show binary logs; 查看二进制文件列表和文件大小 复制代码 代码如下: ./mysqlbinlog --start-datetime="2012-05-21 15:30:00" --stop-

  • 教你自动恢复MySQL数据库的日志文件(binlog)

    如果MySQL服务器启用了二进制日志,你可以使用mysqlbinlog工具来恢复从指定的时间点开始 (例如,从你最后一次备份)直到现在或另一个指定的时间点的数据."mysqlbinlog:用于处理二进制日志文件的实用工具". 要想从二进制日志恢复数据,你需要知道当前二进制日志文件的路径和文件名.一般可以从选项文件(即my.cnf or my.ini,取决于你的系统)中找到路径.如果未包含在选项文件中,当服务器启动时,可以在命令行中以选项的形式给出.启用二进制日志的选项为 --log-b

  • Mysql Data目录和 Binlog 目录 搬迁的方法

    如果全过程使用的是Mysql用户,应该可以正常启动. 如果用的ROOT用户,可能不能正常启动,原因是新建的目录权限不对. 可能会这样的错误提示: /usr/local/mysql/libexec/mysqld: File '/home/mysql/mysqllog/binlog/mysql-bin.index' not found (Errcode: 2) 1. stop mysql service 一定要先停止,非常重要. # /etc/init.d/mysqld stop 2. 修改Mysq

  • 当mysqlbinlog版本与mysql不一致时可能导致出哪些问题

    首先要确定当前版本是不是mysqlbinlog版本,当不是mysqlbinlog版本时可能会导致出哪些问题,下面通过模拟场景的方法给大家做介绍,希望对大家有所帮助. 看当前mysqlbinlog版本的方法: mysqlbinlog --version mysqlbinlog Ver 3.3 for Linux at x86_64 场景1:mysql服务器为mysql 5.6,要求mysqlbinlog版本为3.4及以上,否则mysqlbinlog解析时会直接报错,之前已经碰到过很多次,但是没有记

  • mysql问题之slow log中出现大量的binlog dump记录的解决方法

    线上有个数据库,在slow log中,存在大量类似下面的记录: 复制代码 代码如下: # Time: 130823 13:56:08 # User@Host: repl[repl] @ slave [10.x.x.x] # Query_time: 9.000833 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1 SET timestamp=1377237368; # administrator command: Binlog Dump; 每完成

  • 在MySQL中使用mysqlbinlog flashback的简单教程

    简介: mysqlbinlog flashback功能是淘宝彭立勋(http://www.penglixun.com/)的一个很强劲的作品. 主要功能: 对rows格式的binlog可以进行逆向操作.delete反向生成insert, update生成反向的update,insert反向生成delete.让dba同学们也有机会简单的恢复数据.可恢复:insert, update,delete相关的操作. 演示一下使用过程: 生成带有flashback mysqlbinlog 工具: 项止主页:h

  • MySQL数据库恢复(使用mysqlbinlog命令)

    1:开启binlog日志记录 修改mysql配置文件mysql.ini,在[mysqld]节点下添加 复制代码 代码如下: # log-bin log-bin = E:/log/logbin.log 路径中不要包含中文和空格.重启mysql服务.通过命令行停止和启动mysql服务 复制代码 代码如下: c:\>net stop mysql; c:\>net start mysql; 进入命令行进入mysql并查看二进制日志是否已经启动 Sql代码 复制代码 代码如下: mysql>sho

  • MySQL binlog 远程备份方法详解

    以前备份binlog时,都是先在本地进行备份压缩,然后发送到远程服务器中.但是这其中还是有一定风险的,因为日志的备份都是周期性的,如果在某个周期中,服务器宕机了,硬盘损坏了,就可能导致这段时间的binlog就丢失了. 而且,以前用脚本对远程服务器进行备份的方式,有个缺点:无法对MySQL服务器当前正在写的二进制日志文件进行备份.所以,只能等到MySQL服务器全部写完才能进行备份.而写完一个binlog的时间并不固定,这就导致备份周期的不确定. 从MySQL5.6开始,mysqlbinlog支持将

随机推荐