目录
参考文档:浅析MySQL事务中的redo与undo - 简书 (jianshu.com)
参考文档:浅析MySQL事务中的redo与undo - 简书 (jianshu.com)
事务有4种特性:原子性、一致性、隔离性和持久性,在事务中的操作,要么全部执行,要么全部不做,这就是事务的目的。事务的隔离性由锁机制实现,原子性、一致性和持久性由事务的redo 日志和undo 日志来保证。
什么是Redo和Undo日志,他们是怎样产生的呢?
redo日志和undo日志是数据库管理系统中的两种重要的日志类型。他们与InnoDB存储引擎有十分重要的联系
redo日志(又称重做日志)大部分情况下 Redo是物理日志,记录的是数据页的物理变化,是一种持久化的日志记录,用于记录数据库中所做的修改操作。当数据库发生故障时,通过redo日志可以对故障前的状态进行恢复。在实现上,redo日志是由数据库引擎在执行事务提交时生成的,主要用于记录所有已经提交的数据更改操作,保证数据的一致性。
undo日志(又称撤销日志)undo是一种逻辑日志,也是一种持久化的日志记录,主要用于保证事务的原子性和隔离性。当事务发生回滚操作时,通过undo日志可以将事务中所做的修改操作全部回滚。在实现上,undo日志记录了事务中每个操作的反向操作,以便在回滚事务时能够正确还原数据。
这两种日志产生的方式不同。redo日志是在事务提交时产生的,而undo日志是在事务执行阶段就开始产生的。在执行一个事务时,数据库引擎InnoDB会根据事务的操作生成相应的undo日志记录,记录所有必要的信息,以保证在事务回滚时能够还原数据。
总之,redo日志和undo日志是保证数据库数据一致性和可靠性的重要手段。redo日志记录已提交的事务更改,以防止数据丢失。undo日志记录事务执行的反向操作,以确保事务原子性和隔离性。
Redo log:
Redo的作用:
Redo log的主要作用是用于数据库的崩溃恢复
什么时候写Redo?
- 第一步:先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝
- 第二步:生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值
- 第三步:当事务commit时,将redo log buffer中的内容刷新到 redo log file,对 redo log file采用追加写的方式
- 第四步:定期将内存中修改的数据刷新到磁盘中
在数据库中,Redo是用于保证事务的持久性和数据完整性的重要日志。Redo日志记录了已经提交的事务对数据库所做的修改操作,以便数据库在发生故障后能够通过Redo日志进行恢复。
Redo日志主要在以下情况下进行写入:
在事务提交时:当一个事务成功提交之后,数据库引擎将会生成一个Redo日志记录,记录本次事务提交产生的所有修改操作。这是Redo日志最常见的情况。
在定期或不定期的时间点进行刷盘:为了保证Redo日志的持久性,数据库引擎在某些情况下需要将Redo日志刷写到磁盘上。这样可以确保即使发生机器宕机等故障,Redo日志也不会丢失。刷盘的策略可以根据实际需求进行配置,有可能每次在事务提交时都会刷盘,也有可能通过异步方式进行刷盘。
在发生故障后进行恢复:当数据库发生故障导致无法正常向磁盘写入数据时,Redo日志就成为了恢复数据库的关键手段。通过读取Redo日志记录,数据库可以重新执行已经提交的事务对数据所做的修改操作,以恢复数据库中的数据。
因此,Redo日志主要在事务提交、刷盘和故障恢复时进行写入,通过记录数据的修改操作帮助保证事务的持久性和数据完整性。
Redo如何保证 事务的持久性?
在数据库中,Redo日志是用于保证事务的持久性和数据完整性的重要手段。持久性是指当事务提交后,其对数据库的修改操作能够永久保存下来,即使发生系统故障或崩溃也能够保持不变。
Redo日志通过记录已经提交的事务对数据库进行的修改操作,可以实现事务的持久性保证。当事务完成提交时,数据库引擎会将该事务所做的修改操作以Redo日志的形式记录下来,并将其写入到磁盘上;这样即使数据库在此后发生故障或崩溃,数据库引擎可以通过读取Redo日志来重新执行已经提交的事务对数据库所做的修改操作,以保证数据的一致性。
Redo在InnoDB中是如何实现的?
在InnoDB存储引擎中,Redo日志采用固定大小的循环缓冲区实现,被称为“重做日志缓冲(redo log buffer)”。当事务提交时,该事务所对应的Redo日志记录会先写入到重做日志缓冲区中,随后异步地将缓冲区中的Redo日志记录刷新到磁盘的Redo日志文件中。
InnoDB的Redo日志实现过程大致如下:
重做日志缓冲:InnoDB引擎会为每个线程分配一个私有的重做日志缓冲区,用于缓存事务提交时产生的Redo日志记录。重做日志缓冲区是循环缓冲区结构,其大小由参数innodb_log_buffer_size指定。
Redo日志文件:InnoDB引擎会在数据库目录下创建至少一个Redo日志文件,并在需要时动态添加新的日志文件。Redo日志文件的大小由参数innodb_log_file_size指定,默认值为48MB。
后台进程:InnoDB引擎会启动一个后台线程,将重做日志缓冲区中的Redo日志记录异步地刷新到磁盘的Redo日志文件中。
持久化:InnoDB引擎在将Redo日志记录刷新到磁盘时,会使用一种称为“group commit”的机制,将多个事务的Redo日志记录合并在一起,减少磁盘I/O次数和增加I/O容量。当某个事务提交后,在Redo日志缓冲区中生成的所有Redo日志记录都会被异步地刷新到Redo日志文件中。
Checkpoint:为了避免Redo日志文件无限制地增长,InnoDB引擎会定期执行Checkpoint操作,将所有已经提交的事务对应的Redo日志记录写入磁盘,并标记这些日志记录已经不再需要。这样就可以释放Redo日志文件中已经不再需要的空间,同时缩短系统崩溃恢复时的恢复时间。
总之,在InnoDB引擎中,Redo日志是通过固定大小的循环缓冲区实现的,并且采用异步写入磁盘、group commit以及Checkpoint等机制来提高性能和可靠性。
Undo log:
Undo log的定义
undo log主要记录的是数据的逻辑变化,为了在发生错误时回滚之前的操作,需要将之前的操作都记录下来,然后在发生错误时才可以回滚。
Undo log的作用:
undo是一种逻辑日志,有两个作用:
-
实现事务的原子性:事务的原子性是指事务内的所有操作必须作为一个不可分割的单元执行。当发生错误或回滚时,Undo日志可以用来恢复到事务开始前的状态,确保数据不会因为错误而发生混乱。
-
实现事务的一致性:事务的一致性是指事务执行前和执行后都必须满足一定的约束条件。例如,一个银行转账操作中,不仅要扣除转出账户的余额,还要增加转入账户的余额。Undo日志可以用来回滚操作,确保在事务执行过程中不会破坏数据的完整性。
-
支持多版本并发控制(MVCC):在数据库中,多版本并发控制(MVCC)是常见的一种事务处理机制。它允许多个事务同时访问同一数据项,但每个事务只能读取已提交的版本,从而避免了读-写冲突。在实现MVCC时,Undo日志扮演了重要的角色,用于支持回滚操作。
-
支持数据库的备份和恢复:在进行数据库备份和恢复时,Undo日志可以帮助恢复到备份前的状态。
undo日志,只将数据库逻辑地恢复到原来的样子,在回滚的时候,它实际上是做的相反的工作,比如一条INSERT ,对应一条 DELETE,对于每个UPDATE,对应一条相反的 UPDATE,将修改前的行放回去。undo日志用于事务的回滚操作进而保障了事务的原子性。Undo日志记录了当事务进行数据修改时所执行的原子操作的反向操作,以便在发生错误或回滚时撤消或撤销对数据库的修改操作。
Undo log的写入时机:
在数据库中,Undo日志的写入时机通常分为两种情况:
在事务执行期间,当数据被修改时,相关的Undo日志将被立即写入磁盘中。这种写入方式被称为“紧凑型写入(eager writing)”,它可以确保在事务提交前,相关的Undo日志已经写入磁盘中,可以保证事务的原子性和一致性。
在事务提交时,所有尚未写入磁盘的Undo日志都将被批量写入磁盘中。这种写入方式被称为“延迟写入(lazy writing)”,它通常会以批量方式对大量Undo日志进行写入,从而提高写入效率和性能。但是,如果在延迟写入时发生系统故障或崩溃,则可能会导致某些事务的数据修改被丢失,并且不能恢复到原来的状态,因此需要谨慎使用。
综上所述,Undo日志的写入时机取决于实际应用场景和系统需求。在保证数据一致性和可靠性的同时,还需要考虑系统的性能和效率,权衡各种因素并选择合适的写入策略。需要注意的是,undo页面的修改,同样需要记录redo日志。
Undo的存储位置
在InnoDB存储引擎中,undo存储在回滚段(Rollback Segment)中,每个回滚段记录了1024个undo log segment,而在每个undo log segment段中进行undo 页的申请,在5.6以前,Rollback Segment是在共享表空间里的,5.6.3之后,可通过 innodb_undo_tablespace设置undo存储的位置。
Undo log 是否是Redo log的逆过程?
在数据库中,Undo日志(回滚日志)和Redo日志(重做日志)是两种不同的日志文件,它们之间有一定的联系和区别。
Undo日志记录了对数据进行修改的操作的反向操作,用于撤销或回滚事务对数据库的修改。例如,如果一个事务删除了某个数据行,那么Undo日志就会记录该数据行的插入操作,以便在需要时可以恢复该数据行。
而Redo日志则记录了对数据进行修改的操作本身,用于在发生崩溃或系统故障时重新执行已经提交的事务,从而保证数据的一致性和完整性。例如,如果一个事务将某个数据列的值从A改为B,那么Redo日志就会记录这个修改操作,以便在需要时可以重新执行该操作以恢复数据的状态。
因此,undo log 是否是redo log的逆过程?其实从前文就可以得出答案了,undo log是逻辑日志,对事务回滚时,只是将数据库逻辑地恢复到原来的样子,而redo log是物理日志,记录的是数据页的物理变化,显然undo log不是redo log的逆过程。
Redo & Undo总结
下面是redo log + undo log的简化过程,便于理解两种日志的过程:
假设有A、B两个数据,值分别为1,2. 1. 事务开始 2. 记录A=1到undo log 3. 修改A=3 4. 记录A=3到 redo log 5. 记录B=2到 undo log 6. 修改B=4 7. 记录B=4到redo log 8. 将redo log写入磁盘 9. 事务提交