MySQL:binlog 和 redo log
【参考文章】:MySQL中Redo与Binlog顺序一致性问题?
【参考文章】:极客时间
1. 数据更新时的日志处理流程

1.1 redo log(prepare状态)
此时SQL已经成功执行了,已经产生了语句的redo和undo内存日志,已经进入了事务commit步骤。然后告诉引擎做Prepare完成第一阶段,Prepare阶段就是写Prepare Log(Prepare Log也是Redo Log),将事务状态设为TRX_PREPARED,写Prepare XID(事务ID号)到Redo Log。写XID到Redo Log的时候会一并把Redo Log刷新到磁盘,这个时候Redo Log的日志量大小取决于执行SQL语句时产生的Redo是否被刷盘,这个刷盘是随机的,后台Master线程每秒钟都会刷新一次。
1.2 binlog
如果事务涉及的所有存储引擎的Prepare(即Redo Log写入磁盘之后)都执行成功,则调用TC_LOG_BINLOG::log_xid方法将SQL语句写到Binlog(write()将binary log内存日志数据写入文件系统缓存,fsync()将binary log文件系统缓存日志数据永久写入磁盘),同时也会把XID写入到Binlog。此时,事务已经铁定要提交了。否则,调用ha_rollback_trans方法回滚事务,而SQL语句实际上也不会写到binlog。
Binlog是事务commit时才刷新到磁盘,如果binlog太大则commit时会慢。
1.3 redo log(commit状态)
最后,调用引擎的Commit完成事务的提交。并且会对事务的undo log从prepare状态设置为提交状态(可清理状态),刷新Commit Log到Redo Log,释放锁,释放mvcc相关的read view等等;将事务设为TRX_NOT_STARTED状态。
1.4 两阶段提交
由上面的二阶段提交流程可以看出,通过两阶段提交方式保证了无论在任何情况下,事务要么同时存在于存储引擎和binlog中,要么两个里面都不存在,可以保证事务的binlog和redo log顺序一致性。一旦阶段2中持久化Binlog完成,就确保了事务的提交。
此外需要注意的是,每个阶段都需要进行一次fsync操作才能保证上下两层数据的一致性。
阶段1的fsync由参数innodb_flush_log_at_trx_commit=1控制,阶段2的fsync由参数sync_binlog=1控制,俗称“双1”,是保证CrashSafe的根本。
1.5 CrashSafe
CrashSafe指MySQL服务器宕机重启后,能够保证:
– 所有已经提交的事务的数据仍然存在。
– 所有没有提交的事务的数据自动回滚。
2. binlog
二进制日志是server层的,主要用来做主从复制和即时点恢复时使用的。
2.1 日志记录的三种模式
基于SQL语句的复制(statement-based replication,SBR):记录执行的SQL语句
基于行的复制(row-based replication,RBR):记录更新的每一条记录的变化情况
混合模式复制(mixed-based replication,MBR):根据具体的更新语句选择上述两种中的一种方式记录
2.2 设置 binlog 日志模式
静态设置,配置文件形式
vi my.cnf
binlog_format="STATEMENT"
动态设置,命令形式
mysql> SET GLOBAL binlog_format = 'STATEMENT';
3. redo log
事务日志(redo log)是InnoDB存储引擎层的,用来保证事务安全的。
3.1 redo log 文件
redo log 是固定大小的,从头开始写,写到末尾又回到开头循环写;
redo log 有两个指针:
一个为 write pos:表示当前记录的位置,一边写一边后移;
一个为 checkpoint:表示当前要擦除的位置,一边擦除一边后移,擦除之前要将记录写到磁盘文件中;
4. 区别
binlog 属于MySQL的 sever 层,所有引擎都可以使用;redo log 属于 InnoDB引擎特有。
binlog 是逻辑日志,记录的是SQL语句的原始逻辑;redo log 是物理日志,记录的是在某个数据页上做了什么修改。
binlog 是追加写,一个文件写满之后就写到下一个文件,不会覆盖之前的文件;redo log 是循环写,写到文件末尾之后又从文件起始位置开始写,会覆盖之前的日志。
5. 故障恢复
开启Binary log的MySQL在crash recovery时:MySQL在prepare阶段会生成xid,然后会在commit阶段写入到binlog中。在进行恢复时事务要提交还是回滚,是由Binlog来决定的。
– 事务的Xid_log_event存在,就要提交。
– 事务的Xid_log_event不存在,就要回滚。
恢复的过程非常简单:
– 扫描最后一个Binlog文件(进行rotate binlog文件时,确保老的binlog文件对应的事务已经提交),提取其中的Xid_log_event
– 重做检查点以后的redo日志,读取事务的undo段信息,搜集处于prepare阶段的事务链表,将事务的xid与binlog中的xid对比,若存在,则提交,否则就回滚
总结一下,基本顶多会出现下面是几种情况:
- 当事务在prepare阶段crash,数据库recovery的时候该事务未写入Binary log并且存储引擎未提交,将该事务rollback。
- 当事务在binlog阶段crash,此时日志还没有成功写入到磁盘中,启动时会rollback此事务。
- 当事务在binlog日志已经fsync()到磁盘后crash,但是InnoDB没有来得及commit,此时MySQL数据库recovery的时候将会读出二进制日志的Xid_log_event,然后告诉InnoDB提交这些XID的事务,InnoDB提交完这些事务后会回滚其它的事务,使存储引擎和二进制日志始终保持一致。
总结起来说就是如果一个事务在prepare阶段中落盘成功,并在MySQL Server层中的binlog也写入成功,那这个事务必定commit成功。
MySQL:binlog 和 redo log的更多相关文章
- 必须了解的mysql三大日志-binlog、redo log和undo log
日志是 mysql 数据库的重要组成部分,记录着数据库运行期间各种状态信息.mysql日志主要包括错误日志.查询日志.慢查询日志.事务日志.二进制日志几大类.作为开发,我们重点需要关注的是二进制日志( ...
- 3000帧动画图解MySQL为什么需要binlog、redo log和undo log
全文建立在MySQL的存储引擎为InnoDB的基础上 先看一条SQL如何入库的: 这是一条很简单的更新SQL,从MySQL服务端接收到SQL到落盘,先后经过了MySQL Server层和InnoDB存 ...
- binlog和redo log日志提交
组提交(group commit)是MYSQL处理日志的一种优化方式,主要为了解决写日志时频繁刷磁盘的问题.组提交伴随着MYSQL的发展不断优化,从最初只支持redo log 组提交,到目前5.6官方 ...
- 技术分析 | 通过DML语句浅谈binlog和redo log
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 1 ...
- MySQL中的redo log和undo log
MySQL中的redo log和undo log MySQL日志系统中最重要的日志为重做日志redo log和归档日志bin log,后者为MySQL Server层的日志,前者为InnoDB存储引擎 ...
- 深入理解MySQL系列之redo log、undo log和binlog
事务的实现 redo log保证事务的持久性,undo log用来帮助事务回滚及MVCC的功能. InnoDB存储引擎体系结构 redo log Write Ahead Log策略 事务提交时,先写重 ...
- 说说MySQL中的Redo log Undo log都在干啥
在数据库系统中,既有存放数据的文件,也有存放日志的文件.日志在内存中也是有缓存Log buffer,也有磁盘文件log file,本文主要描述存放日志的文件. MySQL中的日志文件, ...
- 详细分析MySQL事务日志(redo log和undo log)
innodb事务日志包括redo log和undo log.redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作. undo log不是redo log的逆向过程,其实它 ...
- 【转】说说MySQL中的Redo log Undo log都在干啥
阅读目录(Content) 1 undo 1.1 undo是啥 1.2 undo参数 1.3 undo空间管理 2 redo 2.1 redo是啥 2.2 redo 参数 2.3 redo 空间管理 ...
随机推荐
- java 8 日期函数
1.Timestamp(long)转成日期 Timestamp timestamp = new Timestamp(System.currentTimeMillis()); LocalDate ...
- Blob分析--粘连颗粒检测 基于距离变换的分水岭区域分割 盆地与原连通域求交集
文章转自微信公众号:机器视觉那些事 *******************************************************************公众号:机器视觉那些事儿*** ...
- Django项目vue前端依赖框架过大,工程打开太卡的问题
前景提要:利用vue开发项目,由于依赖框架太大,导致pyCharm内存不够,项目打开太慢.步骤一:修改pyCharm的占用内存大小,按照下图操作.1.在应用程序中找到pyCharm,点击"显 ...
- 判断JS的数据类型
typeof.instanceof. constructor. prototype方法比较 (摘自如何判断JS中的数据类型) 1. 使用typeof操作符. 对一个值使用 typeof 操作符可能返回 ...
- Zabbix告警脚本-短信
[root@iot-svndata02 bin]# cat zbsms.sh #!/bin/sh #curl http://221.179.180.137:8080/smsaServer/lkSend ...
- Python自动化测试用例设计--测试类型
1.前言 WEB自动化测试时候测试哪些类型,下面将介绍一下: 2. 测试类型 2.1 测试静态内容 静态内容测试是最简单的测试,用于验证静态的.不变化的UI 元素的存在性.例如: 每个页面都有其预期的 ...
- NSLog无法使用
iOS/macos 中 #import<foundation/foundation.h> nslog不能用 如果项目中包含c/c++程序代码 将其后缀修改成.m .mm 将项目的build ...
- 在java项目中使用umeditor
之前有介绍了ueditor的用法,可看这篇:https://www.cnblogs.com/roy-blog/p/7250668.html umeditor是ueditor的简化版,不仅在功能,容量上 ...
- onload、onpageshow、onpagehide、onbeforeunload、onunload的谣言纠正及特点介绍
谣言一.chrome不支持unload.onbeforeunload 为什么说不支持呢?因为你使用alert,confirm,promot用来测试是否可用了!在unload和onbeforeunloa ...
- js string to date
Date.prototype.pattern=function(fmt) { //alert(this.getFullYear()); fmt=fmt.toUpperCase(); var o = { ...