面试官:你能聊聊 binlog、undo log、redo log 吗?

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 本文详细解析了MySQL数据库中的三种日志:binlog、undo log和redo log。binlog用于记录数据库的所有表结构变更及数据修改,支持归档、主从复制和数据恢复;undo log用于事务回滚,确保事务的原子性和实现多版本控制;redo log则用于crash-safe,确保数据库异常重启后已提交记录不丢失。文章通过实例和图表,深入浅出地介绍了每种日志的特点、应用场景及其实现机制。适合数据库开发者和运维人员阅读。

Hi,你好,我是猿java。

工作或者面试中,经常会遇到 MySQL 数据库 binlog、undo log、redo log 相关的知识点,今天我们就来一起深入分析这三种 log。

申明:本文基于 MySQL 8.0.30,默认为 InnoDB 引擎;InnoDB 由 Innobase Oy公司所开发,2006年五月时由甲骨文公司并购。

前言

在正式进入主题之前,我们先看一张 MySQL的架构示意图:

mysql-arch.png

在上述 MySQL架构图中是不是看到了红色字体:binlog、undo log、redo log?

没错,这就是 MySQL数据库里三种 log日志的分布图,我们再看一张日志在磁盘上的存储图(此处是Mac os安装 MySQL):

mysql-log.png

binlog

binlog,是 binary log的英文缩写,翻译为二进制日志或者归档日志(带有业务含义),它是从 MySQL 3.23.14版本引入的。binlog是在 MySQL Server层实现,因此所有引擎都可以使用它。

binlog包含的信息

  • MySQL数据库所有的表结构变更以及表数据修改的二进制日志(像 select,show这种查询类的操作,不会记录);
  • 每条语句使用更新数据多长时间的信息;

binlog日志的三个用途

  • 归档日志
  • 主从复制
  • 数据恢复

binlog日志的三种类型

  • Statement-based logging:语句模式,包含产生数据更改(插入、更新、删除)的 SQL语句;
  • Row-based logging:行模式,用于记录单个行的更改,从 MySQL 5.1版本引入;
  • Mixed logging:混合模式,默认使用语句模式,可以按需自动切换到行模式,从 MySQL 5.1版本引入;

接下来,我们来查看下 binlog日志到底长啥样:

我们先创建一张user表,然后对user表进行增删改查操作,具体操作截图如下:

binlog-crud.png

查看上述操作的 binlog日志信息,查看指令和结果截图如下:

# 查看 binlog是否开启,8.0.30 默认是开启的
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.02 sec)

# 查看所有的binlog日志文件
mysql> show binary logs;

# 查看某个 binlog的具体信息,通过指令也可以看出binlog是以 event的方式存储
mysql> show binlog events in 'binlog.000001'

binlog.png

查看上面的 binlog日志我们可以看出,在 binlog中,并没有把我们执行的 SQL语句直接存储,而是转换成了一些逻辑步骤,所以, binlog它是一种逻辑日志。

undo log

undo log: 翻译成撤销日志或回滚日志,用于事务回滚,保证了事务 ACID 特性中的原子性(Atomicity),同时还可以配合 ReadView 实现多版本控制(MVCC)。

undo log 相关参数

可以通过 show variables like '%undo%'; 指令查看 undo log相关参数:

mysql> show variables like '%undo%';
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| innodb_max_undo_log_size | 1073741824 |
| innodb_undo_directory    | ./         |
| innodb_undo_log_encrypt  | OFF        |
| innodb_undo_log_truncate | ON         |
| innodb_undo_tablespaces  | 2          |
+--------------------------+------------+
5 rows in set (0.01 sec)
  • innodb_max_undo_log_size:一个 undo log文件对应的最大值,默认 1G;
  • innodb_undo_directory:undo log文件存放的目录;
  • innodb_undo_log_encrypt:是否对 undo log文件开启空间压缩,默认是关闭;
  • innodb_undo_log_truncate:单个文件超过最大值时,是否对 undo log文件进行切分,默认为打开状态;
  • innodb_undo_tablespaces:单个文件超过最大值时,undo log文件会被切分为几份,默认是 2;

事务回滚

在事务提交之前,MySQL 会将更新前的数据记录到 undo log 日志文件里,当事务回滚时,可以利用 undo log 来进行回滚。如下图:

mysql-log-undolog.png

每当 InnoDB 引擎执行一条更新操作(修改、删除、新增)时,就会生成对应的一条回滚指令记录在 undo log 里,比如:

  • InnoDB 引擎执行 insert 操作,则会在 undo log 日志里面保存一条相反的 delete 语句;比如: insert into t(id, name) values(1,'zhangsan'); 则 undo log 对应的回滚日志为 delete from t where id = 1;
  • InnoDB 引擎执行 delete 操作,则会在 undo log 日志里面保存一条相反的 insert 语句;比如: delete from t where id = 1; 则 undo log 对应的回滚日志为 insert into t(id, name) values(1,'zhangsan');
  • InnoDB 引擎执行 update 操作,则会在 undo log 日志里面保存一条相反的 update 语句;比如: update t set name = 'lisi' where id = 1; 则 undo log 对应的回滚日志为 update t set name = 'zhangsan' where id = 1;

undo log 和 ReadView 实现多版本控制(MVCC)

在 InnoDB引擎中,可以多个事务对同一条数据记录进行更新操作,当出现异常时,能及时进行数据回滚,那么 InnoDB是如何能精确的把数据回滚到具体的哪一个版本呢?这就是 InnoDB的多版本控制机制。

如下图:有 3个事务分别对表中id = 1行记录进行更新操作,因此,在undo log文件中就会产生3条逻辑回滚日志
mysql-log-mvcc.png

redo log

redo log,翻译成重做日志,用于crash-safe,即当数据库发生异常重启,可以保证之前提交的记录不会丢失,它是 InnoDB引擎独有的日志。

常见问题

为什么需要 binlog,redo log两份log

MySQL 如何辨别 binlog 的完整性?

  • statement 格式的 binlog,文件末尾有 COMMIT;
  • row 格式的 binlog,文件末尾有一个 XID event。

redo log 和 binlog 是怎么关联起来的?

它们有一个共同的数据字段,叫 XID。崩溃恢复的时候,会按顺序扫描 redo log:如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。

处于 prepare 阶段的 redo log 加上完整 binlog,重启就能恢复,MySQL 为什么要这么设计?

其实,这个问题还是跟我们在反证法中说到的数据与备份的一致性有关。在时刻 B,也就是 binlog 写完以后 MySQL 发生崩溃,这时候 binlog 已经写入了,之后就会被从库(或者用这个 binlog 恢复出来的库)使用。所以,在主库上也要提交这个事务。采用这个策略,主库和备库的数据就保证了一致性。

为什么需要两阶段提交呢?

两阶段提交是经典的分布式系统问题,并不是 MySQL 独有的。如果必须要举一个场景,来说明这么做的必要性的话,那就是事务的持久性问题。对于 InnoDB 引擎来说,如果 redo log 提交完成了,事务就不能回滚(如果这还允许回滚,就可能覆盖掉别的事务的更新)。而如果 redo log 直接提交,然后 binlog 写入的时候失败,InnoDB 又回滚不了,数据和 binlog 日志又不一致了。两阶段提交就是为了给所有人一个机会,当每个人都说“我 ok”的时候,再一起提交。

总结

  • undo log(回滚日志):是 Innodb 存储引擎层的逻辑日志,实现了事务中的原子性,主要用于事务回滚和 MVCC。
  • redo log(重做日志):是 Innodb 存储引擎层的物理日志,是循环写,实现了事务中的持久性,主要用于掉电等故障恢复;
  • binlog (归档日志):是 Server 层生成的日志,所有引擎都可使用,主要用于数据备份、数据恢复和主从复制;

参考文献

binlog官方文档

undo log官方文档

redo log官方文档

学习交流

如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注:猿java,持续输出硬核文章。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
3天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
16 3
|
19天前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
1月前
|
存储 JSON 网络协议
Docker面试整理-如何查看和管理Docker容器的日志?
通过本文的介绍,我们了解了如何查看和管理Docker容器的日志,包括使用 `docker logs`命令、配置日志驱动、设置日志选项和集中日志管理。掌握这些技能,不仅可以在面试中展示专业水平,也能在实际工作中高效
164 3
|
1月前
|
关系型数据库 MySQL 数据库
【赵渝强老师】MySQL的binlog日志文件
MySQL的binlog日志记录了所有对数据库的更改操作(不包括SELECT和SHOW),主要用于主从复制和数据恢复。binlog有三种模式,可通过设置binlog_format参数选择。示例展示了如何启用binlog、设置格式、查看日志文件及记录的信息。
121 6
|
2月前
|
SQL 存储 关系型数据库
美团面试:binlog、redo log、undo log的底层原理是什么?它们分别实现ACID的哪个特性?
老架构师尼恩在其读者交流群中分享了关于 MySQL 中 redo log、undo log 和 binlog 的面试题及其答案。这些问题涵盖了事务的 ACID 特性、日志的一致性问题、SQL 语句的执行流程等。尼恩详细解释了这些日志的作用、所在架构层级、日志形式、缓存机制以及写文件方式等内容。他还提供了多个面试题的详细解答,帮助读者系统化地掌握这些知识点,提升面试表现。此外,尼恩还推荐了《尼恩Java面试宝典PDF》和其他技术圣经系列PDF,帮助读者进一步巩固知识,实现“offer自由”。
美团面试:binlog、redo log、undo log的底层原理是什么?它们分别实现ACID的哪个特性?
|
2月前
|
存储 关系型数据库 MySQL
MySQL中的Redo Log、Undo Log和Binlog:深入解析
【10月更文挑战第21天】在数据库管理系统中,日志是保障数据一致性和完整性的关键机制。MySQL作为一种广泛使用的关系型数据库管理系统,提供了多种日志类型来满足不同的需求。本文将详细介绍MySQL中的Redo Log、Undo Log和Binlog,从背景、业务场景、功能、底层实现原理、使用措施等方面进行详细分析,并通过Java代码示例展示如何与这些日志进行交互。
240 0
|
1月前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
335 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
14天前
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
|
2月前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
332 3
|
23天前
|
存储 监控 安全
什么是事件日志管理系统?事件日志管理系统有哪些用处?
事件日志管理系统是IT安全的重要工具,用于集中收集、分析和解释来自组织IT基础设施各组件的事件日志,如防火墙、路由器、交换机等,帮助提升网络安全、实现主动威胁检测和促进合规性。系统支持多种日志类型,包括Windows事件日志、Syslog日志和应用程序日志,通过实时监测、告警及可视化分析,为企业提供强大的安全保障。然而,实施过程中也面临数据量大、日志管理和分析复杂等挑战。EventLog Analyzer作为一款高效工具,不仅提供实时监测与告警、可视化分析和报告功能,还支持多种合规性报告,帮助企业克服挑战,提升网络安全水平。