数据库日志——binlog、redo log、undo log扫盲
日志是数据库中比较重要的组成部分,很多核心的功能必须依靠日志才能完成。
该篇文章简要介绍了binlog、redo log与undo log,能够在一定程度上拓宽对mysql日志的整体认识。
binlog
又称归档日志,由Server层实现与记录,因此对任何引擎都有效。
binlog是一种只记录对表中数据以及对表结构产生更改操作的二进制文件,比如有insert、update、delete、create table、alter table等操作,不记录select、show,因为这些操作不会产生任何更改。不过就算一个update未产生数据变化,也是会被记录进去的。
你可以理解binlog是直接记录sql语句,或者说记录原始sql逻辑,因此binlog属于逻辑日志。
binlog是追加写入的,一个文件写满,会重新创建一个文件继续写,文件名称是mysql-bin.xxxxxx,例如myql-bin.000001,序号部分会递增。
binlog的格式
binlog有三种格式,可以通过binlog-format来设定
STATEMENT
直接记录操作的sql语句,例如update student set name='tom' where id=1;
优点:
这种格式的binlog,可以直接进行阅读。
不记录具体的行数据,日志量不会很大,性能较优。
缺点:
当binlog用于主从之间的复制时,如果当前的sql语句为随机函数rand()、当前日期now()等,在重现之后具有不同的值,具有歧义性,可能会造成复制后数据不一致。
ROW
对于update student set name='tom' where id=1操作,会记录id=1这条数据中name字段在修改前与修改后的数据。
优点:
准确性强
缺点:
可读性差,需要借助mysqlbinlog解析。
如果经常修改一些字段比较长的数据,会造成生成的binlog日志量变多,性能稍弱。
当然,alter table等直接改变表结构的语句,也会快速增加日志量与磁盘IO。
MIXED
其实就是一种对STATEMENT与ROW的混合使用方式
对不会造成歧义的操作使用STATEMENT格式进行记录,否则使用ROW格式记录。
对表结构的修改操作,也使用ROW格式进行记录。
不过,比较推荐的是ROW格式,特别是在SSD、云端存储、大带宽普及的今天,这点儿的存储空间与磁盘IO还是吃得消的,滴滴基于Binlog的采集架构就是直接使用的ROW格式。
binlog的使用场景
主从复制
当我们使用主从结构的mysql时,从库需要同步主库的数据。
这个时候主库会将自己的binlog异步发送给从库,从库在本地完成sql回放,来达到主从数据一致的目的。
主从复制之间可能会存在延迟,当主库只负责写,从库只负责读时,写完主库之后的立马读从库,可能会出现问题。
关于主从复制原理及主从延迟的解决方案,会另开篇幅。

数据恢复
当误删生产数据时,可以通过binlog来恢复。
找到生产库最近的一次全量备份,首先由全量备份恢复到临时库中。
接着从全量备份的时间点开始,重放binlog一直到mysql不产生新的binlog为止,另外要注意删除binlog中误操作的语句,最后切换临时库为生产库。
值得注意的一点是,binlog默认是不开启的。
redo log
又称重做日志,是Innodb引擎中特有的日志。如果当前使用的引擎是Myisam或者Memory,那就无从谈起redo log。
和binlog的内容不同,redo log记录了“在某个数据页上做了哪些修改”,属于物理日志。
为什么要有redo log?
Innodb引擎是以页为单位来和磁盘交互的,一般来说,如果一个事务提交后,需要将修改后的数据页写回到磁盘中。
如果本次事务只修改当前数据页中的几个Byte,直接将当前数据页的所有内容刷到磁盘后,涉及到大量的随机写,IO成本很高,性能比较低。
如果事务提交后,先将“对哪个数据页做了哪些修改”顺序写入redo log,之后会在合适的时机写回到buffer pool(你可以把buffer pool理解为缓冲池,如果查询到一条记录时,会将记录所在的数据页加载进缓冲池中。之后再进行查找时,先查询缓冲池,查不到再查磁盘,查到了就再放入到缓冲池中。这样做,在一定程度上可以减少IO成本,提升性能)中,最后将buffer pool中的数据页刷盘,在一定程度上可以减少IO成本。
此外,binlog是不支持crash-safe,即崩溃恢复的,只是支持误删数据恢复。当redo log与binlog结合在一起的时候,光芒就出现了,此处应该有迪迦。redo log中较实际数据页中多出来的那部分日志,就是崩溃后用于恢复的日志。
redo log的记录方式
和binlog追加写不同,redo log采用的是循环写。之所以用循环写,是因为之前恢复的数据再保存在redo log中就没有任何意义了。
假设redo log最终会写入到4个文件中,每个文件的大小都是1GB,则此时能够记录的最大日志量为4GB。
比如先从1号文件中写入,写满之后,就换到2号文件中。4个文件全部写满后,再回到1号文件从头继续写。

这里还有两个指针,write position与check point
write position
指向redo log的记录进度,write position指针走过的区域,代表着redo log的日志量逐渐增长。
check point
指向数据页刷盘后的恢复进度,check point指针走过的区域,会将区域内redo log数据用于恢复,接着将redo log擦除。

两个指针的运动方向,都是顺时针方向。
因此,从write position顺时针到check point之间的区域,都是空着的部分。
当redo log记录过快时,write position可能会追赶上check point。此时就需要停止redo log记录,并将所有文件中的redo log恢复。
在这里,有必要总结一下binlog与redo log的区别。
binlog与redo log的区别
| binlog | redo log | |
|---|---|---|
| 日志归属 | 由Server层实现,所有的引擎都可以使用 | Innodb引擎中特有的日志 |
| 日志类型 | 逻辑日志,记录原始的sql逻辑或数据变更的前后内容 | 物理日志,记录在哪个数据页上进行了哪些更改 |
| 写入方式 | 追加写,写满则创建一个新文件继续写 | 循环写,全部写满就从头开始 |
| 适用场景 | 主从同步与误删恢复 | 崩溃恢复 |
在一条类型为update的sql语句的执行背后,涉及到binglog与redo log的两阶段提交,这个也会另开篇幅。
Undo log
undo log主要用于事务回滚时恢复原来的数据
mysql在执行sql语句时,会将一条逻辑相反的日志保存到undo log中。因此,undo log中记录的也是逻辑日志。
当sql语句为insert时,会在undo log中记录本次插入的主键id。等事务回滚时,delete此id即可。
当sql语句为update时,会在undo log中记录修改前的数据。等事务回滚时,再执行一次update,得到原来的数据。
当sql语句为delete时,会在undo log中记录删除前的数据。等事务回滚时,insert原来的数据即可。
数据库事务四大特性中的原子性,即事务具有不可分割性,要么全部成功,要么全部失败,其底层就靠undo log实现。在某一步执行失败时,会对之前事务的语句进行回滚。
另外,undo log与ReadView合作可以实现多版本并发控制MVCC(Mutil-Version Concurrency Control)。
MVCC
对于MVCC,简单来讲,就是mysql保存了一行数据在多个时间点的快照,是一种使用空间换取时间的策略,能做到读(快照读,可以理解就是普通的select语句)写不加锁。
你可以暂时理解为,每一份快照包含了一行undo log日志,各个版本的快照通过指针连接起来,这样可以顺着指针快速找到上一份快照。

(图片来源于互联网,联系侵删)
关于MVCC实现原理,也会另开篇幅。
数据库日志——binlog、redo log、undo log扫盲的更多相关文章
- 【msql】关于redo 和 undo log
InnoDB 有两块非常重要的日志,一个是undo log,另外一个是redo log,前者用来保证事务的原子性以及InnoDB的MVCC,后者用来保证事务的持久性.和大多数关系型数据库一样,Inno ...
- 深入学习MySQL 02 日志系统:bin log,redo log,undo log
上一篇文章中,我们了解了一条查询语句的执行过程,按理说这篇应该讲一条更新语句的执行过程,但这个过程比较复杂,涉及到了好几个日志与事物,所以先梳理一下3个重要的日志,bin log(归档日志).redo ...
- 说说MySQL中的Redo log Undo log都在干啥
在数据库系统中,既有存放数据的文件,也有存放日志的文件.日志在内存中也是有缓存Log buffer,也有磁盘文件log file,本文主要描述存放日志的文件. MySQL中的日志文件, ...
- 【转】说说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 空间管理 ...
- binlog、redo log、undo log区别
root@(none) 04:17:18>show variables like 'innodb_log_group_home_dir';+--------------------------- ...
- 深入理解MySQL系列之redo log、undo log和binlog
事务的实现 redo log保证事务的持久性,undo log用来帮助事务回滚及MVCC的功能. InnoDB存储引擎体系结构 redo log Write Ahead Log策略 事务提交时,先写重 ...
- 【Mysql】三大日志 redo log、bin log、undo log
@ 目录 redo log(物理日志\重做日志) binlog(逻辑日志/归档日志) update语句执行流程 Uodolog(回滚日志/重做日志) undo log+redo log保证持久性 re ...
- InnoDB事务日志(redo log 和 undo log)详解
数据库通常借助日志来实现事务,常见的有undo log.redo log,undo/redo log都能保证事务特性,undolog实现事务原子性,redolog实现事务的持久性. 为了最大程度避免数 ...
- mysql事务(一)——redo log与undo log
数据事务 即支持ACID四大特性. A:atomicity 原子性——事务中所有操作要么全部执行成功,要么全部执行失败,回滚到初始状态 C:consistency 一致性—— ...
- 基于Redo Log和Undo Log的MySQL崩溃恢复流程
在之前的文章「简单了解InnoDB底层原理」聊了一下MySQL的Buffer Pool.这里再简单提一嘴,Buffer Pool是MySQL内存结构中十分核心的一个组成,你可以先把它想象成一个黑盒子. ...
随机推荐
- A-卷积网络压缩方法总结
卷积网络的压缩方法 一,低秩近似 二,剪枝与稀疏约束 三,参数量化 四,二值化网络 五,知识蒸馏 六,浅层网络 我们知道,在一定程度上,网络越深,参数越多,模型越复杂,其最终效果越好.神经网络的压缩算 ...
- Python生成10个八位随机密码
#生成10个八位随机密码 import random lst1=[ chr(i) for i in range(97,123) ] #生成26为字母列表 lst2=[i for i in range( ...
- 某OA系统需要提供一个假条审批的模块,如果员工请假天数小于3天,主任可以审批该请假条;如果员工请假天数大于等于3天,小于10天,经理可以审批;如果员工请假天数大于等于10天,小于30天,总经理可以审批
某OA系统需要提供一个假条审批的模块,如果员工请假天数小于3天,主任可以审批该请假条:如果员工请假天数大于等于3天,小于10天,经理可以审批:如果员工请假天数大于等于10天,小于30天,总经理可以审批 ...
- java实现双向链表的增删改查
双向链表的增删改查 和单链表的操作很像:https://blog.csdn.net/weixin_43304253/article/details/119758276 基本结构 1.增加操作 1.链接 ...
- 《吐血整理》高级系列教程-吃透Fiddler抓包教程(30)-Fiddler如何抓取Android7.0以上的Https包-番外篇
1.简介 通过宏哥前边几篇文章的讲解和介绍想必大家都知道android7.0以上,有android的机制不在信任用户证书,导致https协议无法抓包.除非把证书装在系统信任的证书里,此时手机需要roo ...
- Xpath 高级用法
xpath 高级用法 1. 匹配当前节点下的所有: .// . 表示当前 // 表示当前标签下的所有标签 注: 要配合使用 2. 匹配某标签的属性值: /@属性名称 这里以input里的value值为 ...
- KMP算法,匹配字符串模板(返回下标)
//KMP算法,匹配字符串模板 void getNext(int[] next, String t) { int n = next.length; for (int i = 1, j = 0; i & ...
- 嵌入式-C语言基础:数组得初始化
#include<stdio.h> int main() { int a[10]; int size=sizeof(a)/sizeof(a[0]);//计算数组得大小 for(int i= ...
- Web浏览器Linux Shell(shellinabox解决通用区服务器Linux Shell访问很麻烦的问题)
问题背景 通用区服务器的Linux Shell访问,比较麻烦 需要动态密码(手机上装Token)连跳板机,再用跳板机上的终端工具连Linux Shell 改进方法 使用shellinabox,就能直接 ...
- 【云原生 · Docker】Docker虚拟化技术
1.Docker入门简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化. 容器是完全使用沙箱 ...