mysql中的各种日志文件redo log、undo log和binlog

mysql中的各种日志文件redo log、undo log和binlog

  • mysql中的各种日志文件redo log、undo log和binlog
    • 1.MySQL日志文件类型
    • 2.redo log日志
      • 2.1 作用
      • 2.2工作原理:
      • 2.3详解
    • 3.undo log日志
    • 4.binlog日志
    • 5.总结

mysql中的各种日志文件redo log、undo log和binlog

1.MySQL日志文件类型

日志类型 重做日志(redo log )
回滚日志( undo log )
二进制日志(binlog )
错误日志(errorlog )
慢查询日志( slow query log )
一般查询日志(general log )
中继日志(relay log )

其中,比较重要的包括redo log 、undo log 和 binlog。redo log 是重做日志,提供前滚操作;undo log 是回滚日志,提供回滚操作;binlog是二进制文件,用于记录数据库的所有更改操作。

mysql中的各种日志文件redo log、undo log和binlog_第1张图片

2.redo log日志

MySQL的redo log(重做日志)是MySQL InnoDB存储引擎的一部分,用于确保事务的持久性。下面将详细介绍MySQL的redo log。

mysql中的各种日志文件redo log、undo log和binlog_第2张图片

2.1 作用

持久性保证:当事务提交时,redo log会被写入到磁盘,即使数据库发生故障或崩溃,已提交的事务也可以通过redo log进行恢复,确保数据的持久性。

2.2工作原理:

  1. 写前日志(Write-Ahead Logging, WAL):InnoDB采用写前日志策略,即先写日志,再写磁盘。当事务执行修改操作时,会先将修改记录到redo log buffer中。
  2. 事务提交:在事务提交时,会将redo log buffer中的日志刷新到redo log file中,采用追加写的方式。
  3. 异步写入:redo log的写入是异步的,即事务的提交不需要等待redo log完全写入磁盘。这样可以提高数据库的性能和吞吐量。
  4. 崩溃恢复:如果数据库发生故障或崩溃,可以通过读取redo log来重做(replay)已经提交但尚未写入磁盘的事务,确保数据的一致性。

2.3详解

MySQL 中数据是以页为单位,你查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放入到 Buffer Pool 中。后续的查询都是先从 Buffer Pool 中找,没有命中再去硬盘加载,减少硬盘 IO 开销,提升性能。更新表数据的时候,也是如此,发现 Buffer Pool 里存在要更新的数据,就直接在 Buffer Pool 里更新。然后会把“在某个数据页上做了什么修改”记录到重做日志缓存(redo log buffer)里,接着刷盘到 redo log 文件里。

理想情况,事务一提交就会进行刷盘操作,但实际上,刷盘的时机是根据策略来进行的。

小贴士: 每条 redo 记录由“表空间号+数据页号+偏移量+修改数据长度+具体修改的数据”组成

刷盘时机

InnoDB 存储引擎为 redo log 的刷盘策略提供了 innodb_flush_log_at_trx_commit 参数,它支持三种策略:

0 :设置为 0 的时候,表示每次事务提交时不进行刷盘操作
1 :设置为 1 的时候,表示每次事务提交时都将进行刷盘操作(默认值)
2 :设置为 2 的时候,表示每次事务提交时都只把 redo log buffer 内容写入 page cache
innodb_flush_log_at_trx_commit 参数默认为 1 ,也就是说当事务提交时会调用 fsync 对 redo log 进行刷盘

另外,InnoDB 存储引擎有一个后台线程,每隔1 秒,就会把 redo log buffer 中的内容写到文件系统缓存(page cache),然后调用 fsync 刷盘。也就是说,一个没有提交事务的 redo log 记录,也可能会刷盘。

为什么呢?

因为在事务执行过程 redo log 记录是会写入redo log buffer 中,这些 redo log 记录会被后台线程刷盘。

mysql中的各种日志文件redo log、undo log和binlog_第3张图片

日志文件组

硬盘上存储的 redo log 日志文件不只一个,而是以一个日志文件组的形式出现的,每个的redo日志文件大小都是一样的。

比如可以配置为一组4个文件,每个文件的大小是 1GB,整个 redo log 日志文件组可以记录4G的内容。

它采用的是环形数组形式,从头开始写,写到末尾又回到头循环写,如下图所示。

mysql中的各种日志文件redo log、undo log和binlog_第4张图片

二阶段提交

为了解决两份日志之间的逻辑一致问题,InnoDB存储引擎使用两阶段提交方案

原理很简单,将redo log的写入拆成了两个步骤prepare和commit,这就是两阶段提交

3.undo log日志

我们知道如果想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚。

在 MySQL 中,恢复机制是通过 回滚日志(undo log) 实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,我们直接利用 回滚日志 中的信息将数据回滚到修改之前的样子即可!

并且,回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚将之前未完成的事务。

另外,MVCC 的实现依赖于:隐藏字段、Read View、undo log。在内部实现中,InnoDB 通过数据行的 DB_TRX_ID 和 Read View 来判断数据的可见性,如不可见,则通过数据行的 DB_ROLL_PTR 找到 undo log 中的历史版本。

每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 Read View 之前已经提交的修改和该事务本身做的修改

4.binlog日志

redo log 它是物理日志,记录内容是“在某个数据页上做了什么修改”,属于 InnoDB 存储引擎。

而 binlog 是逻辑日志,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”,属于MySQL Server 层。

不管用什么存储引擎,只要发生了表数据更新,都会产生 binlog 日志。

那 binlog 到底是用来干嘛的?

可以说MySQL数据库的数据备份、主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性。
binlog会记录所有涉及更新数据的逻辑操作,并且是顺序写。

binlog的格式

binlog 日志有三种格式,可以通过binlog_format参数指定。

  • statement
  • row
  • mixed

指定statement,记录的内容是SQL语句原文,比如执行一条update T set update_time=now() where id=1,记录的内容如下。

mysql中的各种日志文件redo log、undo log和binlog_第5张图片

同步数据时,会执行记录的SQL语句,但是有个问题,update_time=now()这里会获取当前系统时间,直接执行会导致与原库的数据不一致。

为了解决这种问题,我们需要指定为row,记录的内容不再是简单的SQL语句了,还包含操作的具体数据。

row格式记录的内容看不到详细信息,要通过mysqlbinlog工具解析出来。

update_time=now()变成了具体的时间update_time=1627112756247,条件后面的@1、@2、@3 都是该行数据第 1 个~3 个字段的原始值(假设这张表只有 3 个字段)。

这样就能保证同步数据的一致性,通常情况下都是指定为row, 这样可以为数据库的恢复与同步带来更好的可靠性。

但是这种格式,需要更大的容量来记录,比较占用空间 ,恢复与同步时会更消耗IO资源,影响执行速度。

所以就有了一种折中的方案,指定为mixed,记录的内容是前两者的混合。

MySQL会判断这条SQL语句是否可能引起数据不一致,如果是,就用row格式,否则就用statement格式。

redo log(重做日志)让InnoDB存储引擎拥有了崩溃恢复能力。
binlog(归档日志)保证了MySQL集群架构的数据一致性。
虽然它们都属于持久化的保证,但是侧重点不同。

在执行更新语句过程,会记录redo log与binlog两块日志,以基本的事务为单位,redo log在事务执行过程中可以不断写入,而binlog只有在提交事务时才写入,所以redo log与binlog的写入时机不一样。

5.总结

MySQL InnoDB 引擎使用 redo log(重做日志) 保证事务的持久性,使用 undo log(回滚日志) 来保证事务的原子性

MySQL数据库的数据备份、主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性。

你可能感兴趣的:(Mysql,数据库)