undo log 和 binlog
本文最后更新于:2021年11月2日 晚上
基本概念
数据库中数据存放的文件称为
data file
,日志文件称为log file
数据库中数据都是有缓存的,如果没有缓存,每次都得读或者写磁盘,性能非常差劲;
- 数据的缓存称为
data buffer
,日志的缓存称为log buffer
- 数据的缓存称为
内存缓冲池
buffer pool
:- buffer pool是 物理页 的缓存,对 InnoDB 的任何修改操作都会首先在 bp 的 page 上进行,然后这样的页面将被标记为 dirty 并被放到专门的flush list 上,后续将由专门的刷脏线程阶段性的将这些页面写入磁盘。
- 这样的好处是避免每次写操作都操作磁盘导致大量的随机 IO,阶段性的刷脏可以将多次对页面的修改 merge 成一次IO 操作,同时异步写入也降低了访问的时延。
- 然而,如果在 dirty page 还未刷入磁盘时,server非正常关闭,这些修改操作将会丢失,如果写入操作正在进行,甚至会由于损坏数据文件导致数据库不可用。为了避免上述问题的发生,Innodb 将所有对页面的修改操作写入一个专门的文件,并
在数据库启动时从此文件进行恢复操作
,这个文件就是redo log file
。这样的技术推迟了 bp 页面的刷新,从而提升了数据库的吞吐,有效的降低了访问时延。带来的问题是额外的写 redo log 操作的开销(顺序 IO,比随机 IO 快很多),以及数据库启动时恢复操作所需的时间。
redo/undo log
redo log
是物理日志,记录物理页的修改,用来恢复已经commit的数据,保持持久性。数据库启动时,再做一遍,以恢复数据状态
undo log
用来回滚记录到某个版本,保证事务的原子性。撤销某些操作,以恢复数据状态
- 在innodb引擎中,MVCC的实现也借助于undo log
在系统恢复时,
通过
redo log
恢复所有已经在存储引擎内部commit的事务;而有些事务还未提交,但数据已被修改过了,即
redo log
处于prepare
状态,但没有commit,为保证原子性,需借助undo log
进行回滚。
为什么只用redo log 或者 undo log不行?
- 只有undo log,没有redo log:如果脏数据尚未刷入磁盘,服务器宕机了,会丢失保存在缓存中的已经提交的数据,无法保证持久性。必须保证在提交事务前完成刷脏,但这样会损害性能。(一般在空闲时刷脏,实时刷脏io开销较大)
- 只有redo log,没有undo log:无法随心所欲地在事务提交前刷脏,即:如果刷脏完成后尚未commit时,服务器崩了;redo log未commit,需要回滚数据,但这部分数据是无法完成回滚的
redo/undo log 和bin log
- 层次不同:redo/undo log是innodb引擎层的日志,而binlog是server层的日志,所有引擎共享binlog
- 记录内容不同:redo/undo log 记录的是每个数据页的修改情况,binlog的Statement格式下记录 SQL语句、Row格式记录每一行改动情况、Mixed格式混合记录;
- 记录时机不同:redo/undo log在事务执行过程中记录,而binlog在事务最终提交前写入;binlog 什么时候刷新到磁盘和参数
sync_binlog
有关
参考文件
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!