写点什么

MySQL 三个重要日志

  • 2023-08-16
    浙江
  • 本文字数:2198 字

    阅读完需:约 7 分钟

在 MySQL 中,有三个重要的日志文件,分别是 undolog、redolog 和 binlog。这三个日志文件在 MySQL 中扮演着不同的角色。

一. undo log

在数据库事务的四大特性中,原子性是指事务中的所有操作要么全部成功,要么全部失败回滚。实现原子性的底层机制之一就是通过使用 Undo Log。


undolog 是 innodb 引擎独有的日志,主要是为事务而准备的,采用循环写覆盖的方式提供回滚能力。它用于记录修改操作的反向操作。当 MySQL 执行一个事务时,它将对数据进行修改,同时也将反向操作(如果我们执行了 insert 操作,那么日志中就会新增一条相反的 delete 的 sql)记录到 undolog 中。如果 MySQL 在执行事务的过程中出现故障或者回滚操作,它可以通过 undolog 中的信息进行恢复。

另外,undolog 还有一个作用,通过 ReadView + undo log 实现多行版本控制(MVCC):当读取的某一行被其他事务锁定时,它可以从 undolog 中分析出该行记录以前的数据是什么,从而提供该行版本信息,让用户实现非锁定一致性读取。

二. redo log

MySQL 的数据都是存在磁盘中的,当我们要更新一条记录的时候,得先要从磁盘读取该记录,然后在内存中修改这条记录。修改完这条记录不是直接写回到磁盘,而是缓存起来。为此,Innodb 存储引擎设计了一个缓冲池(Buffer Pool),来提高数据库的读写性能。


Buffer Pool 是提高了读写但是 Buffer Pool 是基于内存的,而内存总不可靠,万一 MySQL 在执行事务的过程中遇到系统故障或者崩溃,还没来得及落盘的数据就会丢失。为了解决这个问题,引入了 redo log, undo log 也是 innodb 引擎独有的日志,主要是为事务而准备的,使用了 WAL 技术(Write-Ahead Logging),也就是预写日志。


它的关键点就是先写日志,再写磁盘。对应到 Mysql 中具体操作,就是每次更新操作,先写日志,然后更新内存数据,最后等系统压力小的时候再进行 IO 更新磁盘数据。避免了每一次更新都需要进行 IO 操作。redo log 是保证了事务持久性的关键。


当我们从数据库中获取到数据并对其进行修改操作之后,这个修改操作就会优先被存放到 redo log buffer 中,最终就会被写入到 redo log file 中。


后续,InnoDB 引擎会在适当的时候将 redo log 的写入磁盘,写入磁盘的时机是由 MySQL 系统参数设置决定的,我们可以键入下面这条 SQL 查看:

SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
复制代码

innodb_flush_log_at_trx_commit 有 3 种值:0、1、2,默认为 1。


当设置为 1 的时候:事务每次提交都会将 log buffer 中的日志写入 os buffer 并调用 fsync()刷到 log file on disk 中。这种方式即使系统崩溃也不会丢失任何数据,但是因为每次提交都写入磁盘,IO 的性能较差。

 

当设置为 0 的时候:事务提交时不会将 log buffer 中日志写入到 os buffer,而是每秒写入 os buffer 并调用 fsync()写入到 log file on disk 中。也就是说设置为 0 时是(大约)每秒刷新写入到磁盘中的,当系统崩溃,最多会丢失 1 秒钟的数据。


当设置为 2 的时候:每次提交都仅写入到 os buffer,然后是每秒调用 fsync()将 os buffer 中的日志写入到 log file on disk。

redo log 和 undo log 都属于 InnoDB 存储引擎的日志,并且主要是为事务而准备的,他们的区别在于 : redo log 记录了此次事务「完成后」的数据状态,记录的是更新之后的值;


undo log 记录了此次事务「开始前」的数据状态,记录的是更新之前的值; 事务提交之前发生了崩溃,重启后会通过 undo log 回滚事务,事务提交之后发生了崩溃,重启后会通过 redo log 恢复事务,如下图:

三. binlog

MySQL 在完成一条更新操作后,Server 层还会生成一条 binlog,等之后事务提交的时候,会将该事物执行过程中产生的所有 binlog 统一写入 binlog 文件。在正式运行环境,binlog 非常重要,其关系到数据能否被找回的问题,binlog 采用了追加写的方式,记录了所有数据库表结构变更和表数据修改的日志,不会记录查询类的操作,比如 SELECT 和 SHOW 操作。


redo log 和 binlog 有什么区别?

1、适用对象不同:

binlog 是 MySQL 的 Server 层实现的日志,所有存储引擎都可以使用; redo log 是 Innodb 存储引擎实现的日志; 2、文件格式不同:

bin log 则是记录修改的动作,例如 update table set name='zhangsan' whrere id=1 ,redo log 存储的物理日志,即修改的数据内容 


2、写入方式不同:

binlog 采用追加写的方式,写满一个文件,就创建一个新的文件继续写,不会覆盖以前的日志,保存的是全量的日志。 redo log 是循环写,日志空间大小是固定,全部写满就从头开始,保存未被刷入磁盘的脏页日志。 


3、用途不同:

binlog 用于备份恢复、主从复制;

 redo log 用于停电等故障恢复。

 

查看 mysql 是否开启 binlog 同步功能

show variables like 'log_bin';
复制代码

查询的结果显示为 ON 则表示 MySQL 开启了 binlog。如果数据库的 binlog 处于关闭的状态,建议通过修改 Mysql 的配置文件:Windows 下的 Mysql 配置文件是 my.ini ,Linux 下 Mysql 的配置文件是 my.cnf。


[mysqld]# 开启binloglog-bin = mysql-binbinlog_format = ROWexpire_logs_days = 30
复制代码

添加相关配置后重启数据库即可

 

四.总结

 这三个日志不仅可以用于恢复数据库的状态,同时还可以增强数据库的性能和可靠性。对于 MySQL 的性能来说,redolog 和 undolog 是至关重要的,他们通过控制事务的提交和回滚,保证了修改的正确性。binlog 则更多的是用于备份和数据复制的场合,做到业务连续不中断。


而对于 MySQL 的可靠性来说,这三种日志都很重要,每种日志都发挥了不同的作用,从而最大程度的提高了 MySQL 的可靠性。

用户头像

云数据智能操作系统领军者 2022-12-05 加入

浙江数新网络有限公司是一家拥抱开源,专注于云数据平台的大数据服务商,致力于结合全球云数仓先进理念,打造适合中国落地路径的云数仓体系。

评论

发布
暂无评论
MySQL三个重要日志_MySQL_数新网络官方账号_InfoQ写作社区