数据库redo日志和undo日志
- 1、redo日志
- 1.1 redo日志的作用
- 1.1.1 不使用redo日志的问题
- 1.1.2 使用redo日志的好处
- 1.2 redo日志刷盘策略
- 2、undo日志
- 2.1 undo日志的作用
- 2.2 undo日志的简要生成过程
1、redo日志
事务的4大特性(ACID):原子性、一致性、隔离性、持久性,是基于什么机制实现的?
- 隔离性:由
锁机制
实现。 - 原子性、一致性、持久性:由redo日志和undo日志来保证。
1)redo日志:提供再写入能力,恢复提交事物修改的页操作,保证事务的持久性。
2)undo日志:提供回滚能力,可以恢复到某个特定的版本,保证事务的原子性、一致性。
3)注意:redo日志和undo日志不是正向和反向的关系,他们都属于数据库事务的一种恢复操作,只是解决的问题不同而已。redo日志针对的是事务写过程中,在保证数据持久性的基础上,提升了事务提交的速度。undo日志针对的是事务需要回滚时,能保证数据一致性。
1.1 redo日志的作用
1.1.1 不使用redo日志的问题
InnoDb存储引擎是以页为单位
来管理存储空间的。由于cpu和磁盘处理速率差距非常大,因此所有变更都必须先更新内存中的缓冲池(Buffer Pool)
,然后再以一定的频率被刷入磁盘。
这样的话会存在一些问题:
1、修改量与刷新磁盘工作量严重不成正比
:有时候仅仅更新了数据库中某一行的某一列的一个字段,但是事务提交的时候需要刷新一个完整页(16KB)到磁盘上。效率上和速度上都不高。
2、随机IO刷新较慢
:一个事务可能包含很多语句,对应的数据不一定在磁盘相邻的页上,当把数据从buffer pool刷入到磁盘上时,需要进行很多的随机IO
,而随机IO比顺序IO要慢很多,因此这个事务的耗时会非常久。
1.1.2 使用redo日志的好处
使用redo日志,即数据从缓冲池(buffer pool)刷入到redo日志中,该事务就算提交成功了。即使此时数据库系统崩溃了,数据库重启的时候,系统也能从redo日志中将刚刚那次事务的变更刷入到磁盘中。
同时由于redo日志时顺序写入,因此速度要比随机IO快很多。
这种策略叫Write Ahead Log(预先日志持久化)
,即先写入到顺序IO的redo日志上,再写入到数据磁盘上。
1.2 redo日志刷盘策略
使用redo日志后也存在一个问题,即什么时候将redo log buffer刷入到redo日志上呢?
Innodb提供了3种策略,通过innodb_flush_log_at_trx_commit参数进行选择:
- 设置为0:每次事务提交时不进行刷盘操作。(系统默认master thread每隔1s进行一个redo日志的同步)。
- 设置为1:每次事务提交时都进行刷盘动作(
系统默认值
)。 - 设置为2:每次事务提交时都只把redo log buffer内容写入page cache,不进行同步,由系统决定什么时候刷入到磁盘。
2、undo日志
2.1 undo日志的作用
作用1:回滚数据
回滚数据时逻辑上地将数据回滚到事务开始前,实际磁盘页上的数据是进行了变更的。
比如执行insert之前,会写一条delete的语句到undo日志中,一旦事务回滚,则会执行这条delete语句。
作用2:MVCC
InnoDb存储引擎中的MVCC是通过undo日志实现的。当用户读取一行记录时,若该记录已被其他未提交事务占用,当前事务可以通过undo日志读取改行记录之前版本的信息,从而实现了非锁定的读取。
2.2 undo日志的简要生成过程
以update操作举例,简要过程如下
- 开启事务,执行update操作
- 缓存中不存在待update数据,则从磁盘中查询并加载
- 记录可以回滚语句到undo log中
- 执行update操作语句
- 将操作结果写入到redo log buffer中
- 将redo log buffer结果以一定的频率写入到redo log种
- 提交事务后,将结果写入到bin log文件