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 空间管理 ...
随机推荐
- Android Studio2.0 教程从入门到精通Windows版 - 提高篇
第二篇我们开发了一个Hello World应用,并介绍Android Sutdio的界面和如何调试应用,接下来将介绍一些常用的快捷键和必备插件. 常用快捷键 代码跳转 描述:跳转是为了方便代码位置的定 ...
- [C语言]进阶|指针与字符串
------------------------------------------------------------------------------------ 回顾:[C语言]指针与字符串 ...
- jQuery自定义alert,confirm方法及样式
学过JavaScript的都知道,alert().confirm()都是window对象特有的方法,而这两个方法我们平时使用的频率也很高,但是比较扎心的就是他自带的样式太... 因此,我整理了一个比较 ...
- cdnbest常见http状态码解释
cdnbest的常见状态码提示界面: 400状态码:语义有误,当前请求无法被服务器理解 网站访问报这个提示:host not found(找不到主机),这是没有同步站点信息到这个节点上,检查节点连接主 ...
- [leetcode]254. Factor Combinations因式组合
Numbers can be regarded as product of its factors. For example, 8 = 2 x 2 x 2; = 2 x 4. Write a func ...
- [leetcode]37. Sudoku Solver 解数独
Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy ...
- pythone函数基础(9)操作数据库连接
#操作数据库连接import pymysqlconn = pymysql.connect(host='118.24.3.40',user='jxz', password='123456',port=3 ...
- 《C#从现象到本质》读书笔记(五)第5章字符串第6章垃圾回收第7章异常与异常处理
<C#从现象到本质>读书笔记(五)第5章字符串 字符串是引用类型,但如果在某方法中,将字符串传入另一方法,在另一方法内部修改,执行完之后,字符串的只并不会改变,而引用类型无论是按值传递还是 ...
- Django 载入静态文件地址
1,Django框架中有专门存放静态文件的目录. 项目中的CSS.图片.js都是静态文件 配置静态文件 在settings 文件中定义静态内容 2,这些静态文件,他们统一存放在项目目录,templat ...
- 2019.02.11 bzoj3165: [Heoi2013]Segment(线段树)
传送门 题意简述:要求支持两种操作: 插入一条线段. 询问与直线x=kx=kx=k相交的线段中,交点最靠上的线段的编号. 思路: 直接上李超线段树即可. 代码: #include<bits/st ...