bin log、redo log、undo log区别

本文详细介绍了MySQL中的Binlog、Redolog和Undolog,包括它们的定义、功能、日志格式、刷盘时机以及在数据库恢复和一致性保障中的作用,帮助读者理解这三种机制在数据库管理中的重要性。
摘要由CSDN通过智能技术生成

1. Bin log

   1.1 bin log 是什么:        

        binlog是MySQL数据库中的二进制日志(Binary Log)的简称。它是MySQL服务器用来记录对数据库进行的修改操作的一种日志文件。当对数据库进行了INSERT、UPDATE、DELETE等写操作时,MySQL会将这些操作以二进制的形式记录到binlog中,而不是记录对应的SQL语句。这个binlog文件可以用于数据恢复、主从复制、以及数据库的备份等操作。

   1.2 bin log的三种日志格式:

 binlog 有三种记录格式,分别是ROW、STATEMENT、MIXED。

1、ROW: 基于行的复制模式,基于变更的数据行进行记录,如果一个update语句修改一百行数据,那么这种模式下就会记录100行对应的记录日志。

2、STATEMENT(mysql默认的日志格式):基于语句的复制模式。基于SQL语句级别的记录日志,相对于ROW模式,STATEMENT模式下只会记录这个update 的语句。所以此模式下会非常节省日志空间,也避免着大量的IO操作。

3、MIXED: 混合模式,此模式是ROW模式和STATEMENT模式的混合体,一般的语句修改使用statment格式保存binlog,如一些函数的日志;对于statement无法完成主从复制的操作,则采用row格式保存binlog。

   1.3 bin log的刷盘时机
binlog 写入策略在进行事务的过程中,首先会把binlog 写入到binlog cache中(因为写入到cache中会比较快,一个事务通常会有多个操作,避免每个操作都直接写磁盘导致性能降低),事务最终提交的时候再吧binlog 写入到磁盘中。当然事务在最终commit的时候binlog是否马上写入到磁盘中是由参数 sync_binlog 配置来决定的。

1、sync_binlog=0 的时候,表示每次提交事务binlog不会马上写入到磁盘,而是先写到page cache,相对于磁盘写入来说写page cache要快得多,不过在Mysql 崩溃的时候会有丢失日志的风险。

2、sync_binlog=1 的时候,表示每次提交事务都会执行 fsync 写入到磁盘(mysql默认的机制);

3、 sync_binlog的值大于1 的时候,表示每次提交事务都 先写到page cach,只有等到积累了N个事务之后才fsync 写入到磁盘,同样在此设置下Mysql 崩溃的时候会有丢失N个事务日志的风险。很显然三种模式下,sync_binlog=1 是强一致的选择,选择0或者N的情况下在极端情况下就会有丢失日志的风险,具体选择什么模式还是得看系统对于一致性的要求。

2. Redo log

   2.1 redo log是什么 
redo log是innodb引擎级别,用来记录innodb存储引擎的事务日志,不管事务是否提交都会记录下来,用于数据恢复。当数据库发生故障,innoDB存储引擎会使用redo log恢复到发生故障前的时刻,以此来保证数据的完整性。将参数innodb_flush_log_at_tx_commit设置为1,那么在执行commit时会将redo log同步写到磁盘。

redo log 的设计目标是支持innodb的“事务”的特性,事务ACID特性分别是原子性、一致性、隔离性、持久性, 一致性是事务的最终追求的目标,隔离性、原子性、持久性是达成一致性目标的手段,根据的文章我们已经知道隔离性是通过锁机制来实现的。 而事务的原子性和持久性则是分别通过undo log和redo log 来保障的。

   2.2 redo log刷盘时机

  1. redo log占用的空间是一定的,并不会无线增大(可以通过参数设置),写入的时候是进顺序写的,所以写入的性能比较高。当redo log空间满了之后又会从头开始以循环的方式进行覆盖式的写入。
  2. 在写入redo log的时候也有一个redo log buffer,日志什么时候会刷到磁盘是通过innodb_flush_log_at_trx_commit 参数决定。
  • innodb_flush_log_at_trx_commit=0 ,表示每次事务提交时都只是把 redo log 留在 redo log buffer 中,只有当buffer中存储了多个事务日志才会刷入磁盘中;
  • innodb_flush_log_at_trx_commit=1,表示每次事务提交时都将 redo log 直接持久化到磁盘;
  • innodb_flush_log_at_trx_commit=2,表示每次事务提交时都只是把 redo log 写到 page cache(内核缓冲区)。

     3. 除了上面几种机制外,还有其它两种情况会把redo log buffer中的日志刷到磁盘。

  • 定时处理:有线程会定时(每隔 1 秒)把redo log buffer中的数据刷盘。
  • 根据空间处理:redo log buffer 占用到了一定程度( innodb_log_buffer_size 设置的值一半)占,这个时候也会把redo log buffer中的数据刷盘。

3. Undo log

Undo log 以逻辑方式记录数据库事务的修改操作,它记录了事务执行过程中旧值的备份,以便在事务回滚或并发控制需要时能够恢复数据。

例如:当我们执行一条 insert 语句时,Undo Log 就会记录一条相反的 delete 语句。

   3.1 Undo log 的作用:

  • 事务回滚:在事务执行过程中,如果出现错误或需要回滚操作,Undo log 可以恢复事务执行之前的数据状态,实现事务的回滚操作。

  • 并发控制:通过 Undo log 的使用,数据库可以实现并发事务的隔离性和一致性,避免数据读取和写入的冲突。

   3.2 隐藏字段以及Undo Log版本链:

对于使用 InnoDB 存储引擎的表来说,它的聚簇索引记录中都包含两个必 要的隐藏列。

1、trx_id :每次一个事务对某条聚簇索引记录进行改动时,都会把该事务的 事务id 赋值给 trx_id 隐藏列。

2、roll_pointer :每次对某条聚簇索引记录进行改动时,都会把旧的版本写入到 undo日志 中,然 后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。

insert undo只在事务回滚时起作用,当事务提交后,该类型的undo日志就没用了,它占用的Undo Log Segment也会被系统回收(也就是该undo日志占用的Undo页面链表要么被重用,要么被释放)。

假设 id = 100 的事务 A 插入一条行记录(id = 1, username = "Jack", age = 18),那么,这行记录的两个隐藏字段 trx_id = 100 和 roll_pointer指向一个空的 undo log,因为在这之前并没有事务操作 id = 1 的这行记录。如图所示:

然后,id = 200 的事务 B 修改了这条行记录,把 age 从 18 修改成了 20,于是,这条行记录的 trx_id就变成了 200,roll_pointer就指向事务 A 生成的 undo log :

接着,id = 300 的事务 C 再次修改了这条行记录,把 age 从 20 修改成了 30,如下图:

可以看到,每次修改行记录都会更新 trx_id 和 roll_pointer 这两个隐藏字段,之前的多个数据快照对应的 undo log 会通过 roll_pointer 指针串联起来,从而形成一个版本链。MVCC 这个机制,其实就是靠 update undo log 实现的。

   3.3 在使用 Undo log 时,需要注意:

  • Undo log 的管理和清理:由于 Undo log 会占用存储空间,需要定期清理不再需要的 Undo log,以释放存储空间。

  • 配置 Undo log 的大小:根据数据库的并发事务量和数据修改量,合理配置 Undo log 的大小,以确保足够的空间来存储 Undo log 信息。

  • 定期备份 Undo log:为了避免数据丢失,定期备份 Undo log 文件,以便在需要恢复数据时使用。

4. bin log和redo log :


   4.1 有什么区别?

  1. bin log会记录所有日志记录,包括InnoDB、MyISAM等存储引擎的日志;redo log只记录innoDB自身的事务日志。
  2. bin log主要用于数据库的 主从复制 以及数据恢复工作(比如恢复到数据库的某一个历史版本),redo log 主要用于发生故障后,让所有数据恢复到发生故障之前的状态
  3. bin log是逻辑日志,记录的是SQL语句;redo log是物理日志,记录的数据格式是 “在某个数据页上做了什么修改”。
  4. bin log的日志空间是二进制流式的缓冲区,写完一个缓冲区后,不会覆盖之前的内容,而是重开一个缓冲区,继续写入日志;而redo log的日志空间大小是固定的,通过循环写入的方式将日志写入磁盘,一旦没有空闲空间,则会采用覆盖的方式,覆盖的之前的内容
  5. bin log只在事务提交前被写入一次磁盘(MySQL 5.7.7之后版本的默认保存方式),一个事务只写一次;而对于redo log,在事务开始时会写入一次磁盘,提交redo log为prepare状态,事务提交后又会写入一次磁盘,提交redo log 为commit状态

   4.2 bin log日志恢复和redo log日志恢复的区别

binlog(二进制日志)恢复和redo log(重做日志)恢复是数据库恢复机制中的两个不同方面,它们的主要区别在于目标和内容:

  1. 目标不同

    1.1 binlog恢复的主要目标是用于数据库的逻辑恢复和复制。通过分析binlog中记录的SQL语句,可以还原数据库中的数据和操作,以实现数据恢复、主从复制等目标。binlog是用于逻辑恢复和数据同步的工具。
    1.2 redo log恢复的主要目标是用于数据库的物理恢复。redo log包含了InnoDB存储引擎中发生的物理更改(如页的修改),它的主要作用是在数据库发生崩溃或故障时,确保数据的一致性和完整性,以防止数据损坏。redo log是用于物理恢复的工具。

  2. 内容不同

    2.1 binlog内容:binlog记录的是实际执行的SQL语句,这些语句包括数据的插入、更新、删除,以及数据库结构的变更(DDL语句)。binlog中的内容是逻辑操作的记录。
    2.2 redo log内容:redo log记录的是InnoDB存储引擎所执行的物理更改。这包括数据页的修改,而不是SQL语句本身。redo log中的内容是物理操作的记录。

  3. 使用场景不同

    3.1 binlog的使用场景:binlog主要用于实现数据库的逻辑备份和还原,以及主从复制。它适用于恢复到特定时间点、误操作恢复和数据复制等场景。
    3.2 redo log的使用场景:redo log主要用于数据库的物理恢复。它用于保证在数据库崩溃或发生故障时,数据库可以恢复到崩溃前的状态,以确保数据的一致性和完整性。

总之,binlog和redo log在数据库中扮演着不同的角色。binlog主要用于逻辑恢复和复制,记录的是SQL语句的逻辑操作。而redo log主要用于物理恢复,记录的是InnoDB存储引擎的物理操作,以确保数据的一致性和持久性。这两者在数据库备份、恢复和复制方面起到了关键作用,但它们的内容和目标不同。

5. redo log 和 undo log的区别

  1. 目的不同:redo log主要是用于发生故障时的数据恢复操作,将数据恢复到故障发生前的状态,而undo log主要用于事务的回滚,将数据恢复为事务发生前的状态
  2. redo log 和 undo log 都是MySQL用于实现事务和保证数据一致性的机制,但它们的作用不同:

         2.1 Redo Log(重做日志): 主要用于保证事务的持久性(Durability)。当事务执行时,首先会把修改记录到redo log中,然后再慢慢地更新到磁盘的数据页中。这样即使系统突然宕机,也可以通过redo log来恢复数据。在MySQL的InnoDB存储引擎中,redo log是固定大小的,采用循环写入的方式,可以保证在系统宕机的情况下,最近的一段时间内的修改都不会丢失。

         2.2 Undo Log(回滚日志): 主要用于实现事务的原子性(Atomicity)和一致性(Consistency)。当事务需要回滚或者其他事务需要读取旧的数据版本时,就需要使用undo log。undo log记录了事务执行过程中对数据的修改,如果事务失败需要回滚,或者其他事务需要读取数据修改前的版本,就会使用undo log中的信息来还原数据。

  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值