吃透MySQL(十一):undolog redolog binlog详细介绍

在这里插入图片描述

一,Undo log

Undo:意为取消,以撤销操作为目的,返回指定某个状态的操作。

Undo Log:数据库事务提交之前,会将事务修改数据的镜像(即修改前的旧版本)存放到 undo 日志里,当事务回滚时,或者数据库奔溃时,可以利用 undo 日志,即旧版本数据,撤销未提交事务对数据库产生的影响。。

  • 对于 insert 操作,undo 日志记录新数据的 PK(ROW_ID),回滚时直接删除;

  • 对于 delete/update 操作,undo 日志记录旧数据 row,回滚时直接恢复;

  • 他们分别存放在不同的buffer里。

Undo Log 是为了实现事务的原子性而出现的产物。

Undo Log 实现事务原子性:事务处理过程中,如果出现了错误或者用户执行了 ROLLBACK 语句,MySQL 可以利用 Undo Log 中的备份将数据恢复到事务开始之前的状态。

InnoDB 发现可以基于 Undo Log 来实现多版本并发控制。

Undo Log 在 MySQL InnoDB 存储引擎中用来实现多版本并发控制。

Undo Log 实现多版本并发控制:事务未提交之前,Undo Log 保存了未提交之前的版本数据,Undo Log 中的数据可作为数据旧版本快照供其他并发事务进行快照读。

关于Undo log是怎么实现MVCC的,请参考上篇文章:吃透MySQL(九):MVCC多版本并发控制

二,Redo log

Redo:顾名思义就是重做。以恢复操作为目的,重现操作。

Redo Log:指事务中操作的任何数据,将最新的数据备份到一个地方(Redo Log)。

Redo Log 的持久化:不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入 Redo Log 中,具体的落盘策略可以进行配置。

Redo Log 是为了实现事务的持久性而出现的产物。

Redo Log 实现事务持久性:防止在发生故障的时间点,缓冲池(buffer pool)尚有脏页未写入表的 IBD 文件中,在重启 MySQL 服务的时候,根据 Redo Log 进行重做,从而达到事务的未入磁盘数据进行持久化这一特性。

一旦事务成功提交且数据从缓冲池(buffer pool)持久化到表的 IBD 文件中之后,此时 Redo Log 中的对应事务数据记录就失去了意义,所 以 Redo Log 的写入是日志文件循环写入的过程,也就是覆盖写的过程。

Redo Log 的持久化配置

指定 Redo Log 记录在 {datadir}/ib_logfile1 和 ib_logfile2 两个文件中,可以通过 innodb_log_group_home_dir配置指定目录存储。

Redo Buffer 持久化到 Redo Log 的策略,通过设置 Innodb_flush_log_at_trx_commit 的值:

  • 取值0:每秒提交 Redo buffer -> Redo Log OS cache -> flush cache to disk,可能丢失一秒内的事务数据。

  • 取值1(默认值):每次事务提交执行 Redo Buffer -> Redo Log OS cache -> flush cache to disk,最安全,性能最差的方式

  • 取值2:每次事务提交执行 Redo Buffer -> Redo log OS cache 再每一秒执行 -> flush cache to disk 操作

三,binlog

binlog 用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。binlog 是 mysql的逻辑日志(可以简单理解为记录的就是sql语句),并且由 Server 层进行记录,使用任何存储引擎的 mysql 数据库都会记录 binlog 日志。

1,binlog使用场景

在实际应用中, binlog 的主要使用场景有两个,分别是 主从复制数据恢复

  • 主从复制 :在 Master 端开启 binlog ,然后将 binlog 发送到各个 Slave 端, Slave 端重放 binlog 从而达到主从数据一致。
  • 数据恢复 :通过使用 mysqlbinlog 工具来恢复数据。

2,binlog刷盘时机

对于 InnoDB 存储引擎而言,只有在事务提交时才会记录 biglog ,此时记录还在内存中,那么 biglog是什么时候刷到磁盘中的呢?mysql 通过 sync_binlog 参数控制 biglog 的刷盘时机,取值范围是 0-N:

  • 0:不去强制要求,由系统自行判断何时写入磁盘;
  • 1:每次 commit 的时候都要将 binlog 写入磁盘;
  • N:每N个事务,才会将 binlog 写入磁盘。

从上面可以看出, sync_binlog 最安全的是设置是 1 ,这也是 MySQL 5.7.7之后版本的默认值。但是设置一个大一些的值可以提升数据库性能,因此实际情况下也可以将值适当调大,牺牲一定的一致性来获取更好的性能。

3,binlog日志格式

binlog 日志有三种格式,分别为 STATMENT 、 ROW 和 MIXED 。

在 MySQL 5.7.7 之前,默认的格式是 STATEMENT , MySQL 5.7.7 之后,默认值是 ROW。日志格式通过 binlog-format 指定。

STATMENT:基于SQL 语句的复制( statement-based replication, SBR ),每一条会修改数据的sql语句会记录到 binlog 中 。

优点:不需要记录每一行的变化,减少了 binlog 日志量,节约了 IO , 从而提高了性能;

缺点:在某些情况下会导致主从数据不一致,比如执行sysdate() 、 slepp() 等 。

ROW:基于行的复制(row-based replication, RBR ),不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了 。

优点:不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题 ;

缺点:会产生大量的日志,尤其是alter table 的时候会让日志暴涨

MIXED:基于STATMENT 和 ROW 两种模式的混合复制( mixed-based replication, MBR ),一般的复制使用 STATEMENT 模式保存 binlog ,对于 STATEMENT 模式无法复制的操作使用 ROW 模式保存 binlog。

猜你喜欢

转载自blog.csdn.net/u013277209/article/details/114436690
今日推荐