一文搞懂MySQL日志区别-binlog/redo log/undo log
一、前言
- MySQL 整体来看,其实就有两块:一块是Server层,它主要做的是MySQL功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜。
- redo log 是 InnoDB 引擎特有的日志,而 Server 层也有自己的日志,称为 binlog(归档日志)。
二、Redo log
WAL技术的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘。
- 当有一条记录需要更新的时候,InnoDB引擎就会先把记录写到redo log里面,并更新内存,这个时候更新就算完成了。同时,InnoDB引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做。
- InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是1GB,那么redo log总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写。
- write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到0号文件开头。checkpoint是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。
- write pos和checkpoint之间的是“粉板”上还空着的部分,可以用来记录新的操作。如果write pos追上checkpoint,表示“粉板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。
- 有了 redo log,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe。
三、Binlog
3.1 为什要有binlog还需要redo log呢?
因为最开始 MySQL 里并没有 InnoDB 引擎。MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe 的能力,binlog 日志只能用于归档。而 InnoDB 是另一个公司以插件形式引入 MySQL 的,既然只依靠 binlog 是没有 crash-safe 能力的,所以 InnoDB 使用另外一套日志系统,也就是 redo log 来实现 crash-safe 能力。
3.2 Binlog和Redo log区别?
- redo log 是InnoDB 引擎特有的;binlog是MySQL的Server 层实现的,所有引擎都可以使用。
- redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2这一行的 c 字段加 1 ”。
- redo log 是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
四、Undo log
4.1 什么是多版本并发控制(MVCC)?
可重复读为例:在 MySQL 中,实际上每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值,通过回滚操作,都可以得到前一个状态的值。
假设一个值从1被按顺序改成了2、3、4,在回滚日志里面就会有类似下面的记录。
- 当前值是 4,但是在查询这条记录的时候,不同时刻启动的事务会有不同的read-view。如图中看到的,在视图A、B、C里面,这一个记录的值分别是1、2、4,同一条记录在系统中可以存在多个版本,就是数据库的多版本并发控制(MVCC)。对于 read-view A,要得到1,就必须将当前值依次执行图中所有的回滚操作得到。
- 同时你会发现,即使现在有另外一个事务正在将 4 改成 5,这个事务跟 read-viewA、B、C对应的事务是不会冲突的。
- 系统会判断,当没有事务再需要用到这些回滚日志时,回滚日志会被删除。即系统里没有比这个回滚日志更早的read-view 的时候。
4.2 什么是undo log?
- InnoDB 里面每个事务有一个唯一的事务 ID,叫作 transaction id。它是在事务开始的时候向 InnoDB 的事务系统申请的,是按申请顺序严格递增的。
- 而每行数据也都是有多个版本的。每次事务更新数据的时候,都会生成一个新的数据版本,并且把 transaction id 赋值给这个数据版本的事务 ID,记为 row trx_id。同时,旧的数据版本要保留,并且在新的数据版本中,能够有信息可以直接拿到它。
- 也就是说,数据表中的一行记录,其实可能有多个版本 (row),每个版本有自己的 row trx_id。
如图 所示,就是一个记录被多个事务连续更新后的状态:
图中虚线框里是同一行数据的 4 个版本,当前最新版本是 V4,k 的值是 22,它是被 transaction id 为 25 的事务更新的,因此它的 row trx_id 也是 25。
你可能会问,前面的文章不是说,语句更新会生成 undo log(回滚日志)吗?那么,undo log 在哪呢?
实际上,上图中的三个虚线箭头,就是 undo log;而 V1、V2、V3 并不是物理上真实存在的,而是每次需要的时候根据当前版本和undo log 计算出来的。比如,需要 V2 的时候,就是通过 V4 依次执行 U3、U2 算出来。
作者:UStarGao
链接:https://www.starcto.com/mysql/298.html
来源:STARCTO
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
UCloud云平台推荐
随便看看
- 2021-03-18Linux入侵检测AIDE-检查文件的完整性
- 2022-05-16MySQL sql_mode参数详解
- 2022-03-31MongoDB分片集群安装部署教程
- 2021-04-23Linux进程带宽占用查看—NetHogs工具
- 2021-05-16MongoDB 用户权限管理