MySQL重做日志(redo log)总结

目录

一、redo log的概念

二、redo log的作用

三、redo log的组成

四、redo log的工作原理

五、redo log的相关参数

六、redo log与undo log比较

七、redo log与二进制日志比较

附录:参考资料


一、redo log的概念

redo log,重做日志,也叫重放日志。和undo log回滚日志一样,都是在数据库发生意外时用来进行数据恢复的,通过前面一篇文章对undo log的总结,我们都知道undo log记录的是数据更新前的样子,主要保证事务的原子性;而redo log则记录的是事务执行过程中的修改情况,redo log主要保证事务的持久性。

当数据库对数据做修改的时候,需要把数据页从磁盘读到buffer pool中,然后在buffer pool中进行修改,那么这个时候buffer pool中的数据页就与磁盘上的数据页内容不一致,称buffer pool的数据页为dirty page 脏数据,如果这个时候发生非正常的DB服务重启,那么这些数据还没在内存,并没有同步到磁盘文件中(注意,同步到磁盘文件是个随机IO),也就是会发生数据丢失,如果这个时候,能够在有一个文件,当buffer pool 中的数据页变更结束后,把相应修改记录记录到这个文件(注意,记录日志是顺序IO),那么当DB服务发生crash,进行恢复DB的时候,可以根据这个文件的记录内容,重新持久化刷新到磁盘文件,保持数据的一致性。

这个文件其实就是redo log ,用于记录数据修改后的记录,顺序记录,主要用于数据的持久化操作。

二、redo log的作用

  • 1、保证事务的持久性

如果buffer pool缓冲池中的脏页【脏数据】还没有进行刷盘的时候,此时数据库发生crash,重启服务后,我们可以通过redo log日志找到需要重放到磁盘文件的那些数据记录。

  • 2、提高事务提交的速度

buffer pool缓冲池中的数据直接刷新到磁盘,是一个随机IO,效率较差,而把buffer pool中的数据记录到redo log,是一个顺序IO,可以提高事务提交的速度。例如:

我们执行了一条更新语句:

update user set name = 'lisi' where id = 1   --更新前name = 'zhangsan'

此时redo log就会用来存在name = 'lisi'这条更新后的新纪录,如果在刷盘时发生异常,我们可以通过redo log找到这条记录,然后进行重放操作,以保证事务的持久性。

三、redo log的组成

redo log由两部分组成:

  • redo log buffer日志缓存

重做日志缓存(redo log buffer)存在于内存中,容易发生丢失。

  • redo log file日志文件

重做日志文件(redo log file)存在于磁盘中,不容易发生丢失。

从redo log buffer写日志到磁盘的redo log file中,过程如下: 

为了确保每次日志都能写入到事务日志文件中,在每次将log buffer中的日志写入日志文件的过程中都会调用一次操作系统的fsync操作(即fsync()系统调用)。因为MariaDB/MySQL是工作在用户空间的,MariaDB/MySQL的log buffer处于用户空间的内存中。要写入到磁盘上的log file中(redo:ib_logfileN文件,undo:share tablespace或.ibd文件),中间还要经过操作系统内核空间的os buffer,调用fsync()的作用就是将OS buffer中的日志刷到磁盘上的log file中

四、redo log的工作原理

和undo log相反,redo log记录的是新数据的备份。在事务提交前,只要将redo log持久化即可,

不需要将数据持久化,不需要将数据持久化,不需要将数据持久化,重要的事情说三遍!。当系统崩溃时,虽然数据没有持久化,但是redo log已经持久化到磁盘中,系统可以根据redo log的内容,将所有数据恢复到最新的状态。

同样,通过一张图来理解redo log的工作原理。

下面描述一下redo事务的简化过程。

 假设有A、B两个数据,值分别为1,2,开始一个事务,事务的操作内容为:把1修改为3,2修改为4,那么实际的记录如下(简化):

  •   A. 事务开始.
  •   B. 记录A=1到undo log.
  •   C. 修改A=3.
  •   D. 记录A=3到redo log.
  •   E. 记录B=2到undo log. -------记录undo log回滚日志
  •   F. 修改B=4. -------修改数据
  •   G. 记录B=4到redo log. -------记录redo log重做日志
  •   H. 将redo log写入磁盘。 -------redo log刷盘持久化
  •   I. 事务提交 -------提交事务

如上过程,我们可以总结出来undo + redo事务的特点:

  • A. 为了保证持久性,必须在事务提交前将redo log日志持久化。
  • B. 数据不需要在事务提交前写入磁盘,而是缓存在内存中。
  • C. redo log保证事务的持久性。
  • D. undo log保证事务的原子性。
  • E. 数据必须要晚于redo log写入持久存储。

五、redo log的相关参数

  • innodb_flush_log_at_trx_commit

控制commit动作是否刷新log buffer到磁盘。该变量有3种值:0、1、2,默认为1。

1、innodb_flush_log_at_trx_commit=0【延迟写】:事务提交时不会将log buffer中日志写入到os buffer,然后每秒调用fsync()写入到log file on disk磁盘文件中。

这种情况下如果系统崩溃,会丢失1秒钟的数据。

2、innodb_flush_log_at_trx_commit=1【实时写,实时刷】:事务每次提交,会保存到log buffer,接着保存到os buffer操作系统缓存,并调用fsync()刷到log file on disk磁盘文件中。

这种方式即使系统崩溃也不会丢失任何数据,但是因为每次提交都写入磁盘,IO的性能较差。

3、innodb_flush_log_at_trx_commit=2【实时写,延迟刷】:每次事务提交,数据不写到log buffer,仅写入到os buffer,然后是每秒调用fsync()将os buffer中的日志写入到log file on disk磁盘文件中。

如下图:

正常情况下,设置参数值为0或者2能提供插入的效率,但在故障的时候可能会丢失1秒钟数据。并且参数值为2和0的时候差距并不大,因为它们都是每秒从os buffer刷到磁盘,它们之间的时间差体现在log buffer刷到os buffer上。因为将log buffer中的日志刷新到os buffer只是内存数据的转移,并没有太大的开销,所以每次提交和每秒刷入差距并不大。但值为1的性能却会差很多。

  • innodb_log_buffer_size

指定 log buffer【redo log缓存区】的大小,默认8M。延迟事务日志写入磁盘,把redo log 放到该缓冲区,然后根据 innodb_flush_log_at_trx_commit参数的设置,再把日志从buffer 中flush 到磁盘中。

  • innodb_log_file_size

指定事务日志的大小,默认5M。

  • innodb_log_files_group =2

log group表示的是redo log group,一个组内由多个大小完全相同的redo log file组成。innodb_log_files_group指定事务日志组中的事务日志文件个数,默认2个,最大是100个。命名方式如:ib_logfile0,iblogfile1... iblogfilen。

在innodb将log buffer中的redo log block刷到这些log file中时,会以追加写入的方式循环轮训写入。即先在第一个log file(即ib_logfile0)的尾部追加写,直到满了之后向第二个log file(即ib_logfile1)写。当第二个log file满了会清空一部分第一个log file继续写入。

  • innodb_log_group_home_dir =./

指定事务日志组路径,当前目录表示数据目录。

六、redo log与undo log比较

  • 1、undo log和redo logo都是InnoDB的功能,都是事务日志。
  • 2、redo log通常是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样怎样,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。
  • 3、undo log用来回滚行记录到某个版本。undo log一般是逻辑日志,根据每行记录进行记录。
  • 4、undo log保证事务的原子性,而redo log则是保证事务的持久性。undo log在InnoDB中用来实现MVCC多版本控制,执行rollback操作时,undo log可以作为事务回滚的快照读参考,而redo log是备份的最新数据位置,系统冗机时,只要重启mysql服务,就可以将未持久保存的数据持久到磁盘。

七、redo log与二进制日志比较

  • 1、redo log是MySQL InnoDB存储引擎产生的,只记录该存储引擎中表的修改,而二进制日志是在数据库层面产生的,所有存储引擎对数据库进行修改都会产生二进制日志。
  • 2、二进制日志记录的是对应的SQL,比如记录的该行数据每一列的值是多少多少,而redo log记录的则是物理数据页的修改记录。
  • 3、redo log记录的是物理格式的日志,记录了对页的操作,而binlog记录的是逻辑日志,记录的是对应的SQL。
  • 4、redo log记录的是数据页的物理变化,因此恢复的时候速度比二进制日志要快很多。另外,redo log具有幂等性,所以多次操作得到同一结果的行为在日志中只记录一次。而二进制日志不具有幂等性,多次操作会全部记录下来,在恢复的时候会多次执行二进制日志中的记录,速度就慢得多。例如,某记录中id初始值为2,通过update将值设置为了3,后来又设置成了2,在事务日志中记录的将是无变化的页,根本无需恢复;而二进制会记录下两次update操作,恢复时也将执行这两次update操作,速度比事务日志恢复更慢。
  • 5、二进制日志在提交的时候一次性写入,一次提交对应一条记录,而redo log中是记录的物理页的修改,redo log文件中同一个事务可能多次记录,最后一个提交的事务记录会覆盖所有未提交的事务记录。举个例子,一个事务中插入10万条记录:
insert into user(name, age) values('zs', 20);
insert into user(name, age) values('ls', 30);
//.....插入十万条记录

在这个过程中,MySQL会一直不断的往redo log顺序记录,而binary log则不会记录,直到commit事务,才会一次性写入到bin log日志中。

附录:参考资料

https://www.cnblogs.com/f-ck-need-u/p/9010872.html#auto_id_11

https://www.cnblogs.com/wyy123/p/7880077.html

《MySQL技术内幕(第5版)》

MySQL中,binlogredolog是两种不同的日志文件,它们的作用和机制也不同: 1. Binlog(二进制日志): BinlogMySQL服务器的二进制日志,用于记录对MySQL数据库执行的所有修改操作,例如插入、更新和删除等操作。Binlog记录的是逻辑日志,它记录的是SQL语句的执行过程,而不是记录数据在磁盘上的物理位置。 Binlog的作用是: - 数据备份和恢复:通过binlog可以对数据库进行增量备份和恢复。 - 数据同步和复制:通过binlog可以将MySQL中的数据复制到其它MySQL实例中,实现数据同步。 - 数据恢复:通过binlog可以将数据库恢复到指定的时间点。 2. Redolog重做日志): Redolog是InnoDB存储引擎的日志,用于记录事务的修改操作,例如插入、更新和删除等操作。Redolog记录的是物理日志,它记录的是数据在磁盘上的物理位置,而不是记录执行的SQL语句。 Redolog的作用是: - 数据恢复:通过Redolog可以在发生宕机等异常情况时,恢复数据到事务提交前的状态。 - 保证事务的原子性:通过Redolog可以保证MySQL中的事务具有ACID特性中的原子性,即事务要么全部执行,要么全部回滚。 总的来说,BinlogRedolog都是MySQL中非常重要的日志文件,它们都具有保证数据的完整性、恢复数据等功能,但是它们记录的内容和机制不同,对MySQL的功能和性能也有着不同的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值