MySQL事务日志-Redo Log工作原理分析

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS SQL Server,基础系列 2核4GB
简介: 事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。

事务的隔离性是通过锁实现,而事务的原子性、和持久性则是通过事务日志实现。在MySQL中,事务日志分为两类,一个是Redo Log,也叫重做日志,另一个是Undo Log,也叫回滚日志;其中Redo Log保证事务的持久性,Undo Log保证的是事务的原子性

2.1 Redo Log

2.1.1 Redo Log与持久性

事务开启后,执行的所有的操作都是记录在事务日志中,这部分数据并没有写入磁盘表,需要把当前事务提交,才会将事务日志记录的数据写入到磁盘表中。Redo Log是用于保证事务的ACID中的持久性的,关于什么是持久性我们必须弄清楚这一点。

  • 事务的持久性:事务提交成功后,数据被保存到磁盘表中,即使发生系统崩溃、断电或其他故障,只要表、磁盘等软硬件设备不被损坏,那么数据将永久保持在磁盘中。

这里存在一个疑问,事务都提交成功了,系统发生崩溃、断电或其他故障不是本就不会影响到磁盘表中的数据吗?当然前提是磁盘表中的数据没有损坏,那这个持久性到底保障的是什么呢?

需要注意:事务的持久性指的是事务一旦提交成功,才能保障后续的流程(崩溃、宕机等问题的处理)。可不是保证事务一定能提交成功。如果事务在提交过程中出现问题,这个问题包括事务运行过程中的问题(一般是客户端的代码问题),也包括MySQL服务器自身的问题(一般是执行commit命令时宕机、系统奔溃等)。但不管是客户端或者是MySQL服务器本身的问题导致的提交失败,MySQL都会将其标记为提交失败,客户端接收到MySQL响应的提交失败请求后可以做其他的补偿处理。

如果一个事务被标记为提交成功,那么数据能够正常写入磁盘表,并且不怕MySQL宕机、服务器崩溃等,如果一个事务被标记为失败,那么该出现的问题还是会出现的。那么也可以这么理解:如何让事务能够快速被标记为成功,或许才是是事务日志真正所要考虑的问题,毕竟能够快速标记为成功,那就少一份执行commit时MySQL宕机、服务器崩溃的风险。

2.1.2 Redo Log的工作原理

Redo日志也叫重做日志,在InnoDB存储引擎中使用。它记录了数据在内存中更改之后但还未持久化到磁盘表之前的信息。它的主要作用是在系统崩溃后能够重新执行(redo)那些已经提交但尚未写入磁盘的数据更改。如果在事务提交时,此时数据库崩溃或者宕机,那么当系统重启进行恢复时,就可以根据Redo Log中记录的日志,把数据库恢复到崩溃前的一个状态。因此Redo Log 是InnoDB实现事务持久性的强力保证。

Tips:Redo Log主要保障的是事务的持久性,即只要事务提交成功,那么数据就能够永久保存到数据库中,否则就属于提交失败,就应该进行事务回滚(根据Undo 日志回滚),客户端也可以做一些事务提交失败的代码流程。

  • Redo的运行流程:

首先在操作表时,会将表数据从磁盘(.idb)加载到内存缓冲池中(Buffer Pool),对表所有的操作都会记录一份到Redo Buffer日志(内存中的Redo日志)中,其根据一定的策略将数据刷新到Redo Log中(磁盘中的Redo日志)。在事务最终要提交时(执行了commit),如果数据库或系统突然宕机,那么当数据库或系统重启时,就可以根据Redo Log日志中的记录进行数据的恢复。

Redo Log的工作原理如图所示:

在提交事务时,为什么不直接将数据写入数据库表呢?而是要先写入Redo Log中呢?看似好像“多此一举”?其实不然。写入Redo Log的好处如下:

  • 原因一:Redo Log的结构简单。

Redo Log 记录的是物理层面上的数据修改,因此Redo也叫物理日志。这些修改记录包含了数据页的物理地址(Page Number)和修改的具体内容(如页内数据的前后变化)。在系统重启时,InnoDB 会读取 Redo Log 文件,并根据其中的记录重做对数据页的修改。

Redo Log的日志格式:

正因为Redo Log中记录的数据结构简单,只记录一些物理地址以及一些变更状态等信息。因此数据先写入Redo Log要比直接写入到表快多了。其次,Redo Log作为“临时存储的数据区域”,当Redo Buffer中的数据已经到达一定大小后,Redo Buffer也会将这部分数据写入到Redo Log中,此时数据还未提交,但是已经写入到磁盘中了。

Tips:上面流程中这种先写日志,再写磁盘,只有日志写入成功,才算事务提交成功的技术思想在MySQL也叫做WAL技术 (Write-Ahead Logging日志先行)。

  • 原因二:顺序IO性能远高于随机IO。

数据在MySQL中存储是以页为单位,事务中操作的数据可能遍布在不同的页中,如果直接写入到磁盘中对应的页中,是随机IO写入,效率低。

而Redo Log是通过往Redo Log日志中追加数据的方式,属于顺序IO,效率高。这样可能会影响Redo Log恢复数据时的性能,但可以保证在提交时期能够快速写入Redo Log日志记录本次事务的更改。

2.1.3 Redo Log的落盘策略

事务的日志是先写入到redo log buffer中的,并且这个过程是非常快的,那redo log buffer在什么时候会写入磁盘呢?

redo log buffer不是直接将日志内容刷盘到redo log file中,而是先刷入到操作系统的文件系统缓存 (page cache)中去。最后,日志内容会从操作系统的文件系统缓存中刷到磁盘的日志文件中,至于什么时候触发这个动作,MySQL的innoDB引擎提供了3种策略可选。

Tips:Redo Log Buffer 刷新到 page cache 后,如果是MySQL宕机则问题不大,但是如果整个系统宕机数据将会丢失,因为数据都保存在操作系统的page cache中。不过这个过程很快,而且整个系统宕机概率相对MySQL会小很多。

InnoDB引擎提供了 innodb_flush_log_at_trx_commit 参数,该参数控制 commit提交事务时,如何将 redo log buffer中的日志刷新到 redo log file的3种策略,取值有0、1、2;默认为1。

mysql> select @@innodb_flush_log_at_trx_commit;
+----------------------------------+
| @@innodb_flush_log_at_trx_commit |
+----------------------------------+
|                                1 |
+----------------------------------+
1 row in set (0.00 sec)
  • 0:代表每秒将Redo Buffer中的数据刷到OS buffer然后立即从OS buffer刷到Redo Log磁盘文件中。

为0时,后台线程每隔1秒进行一次重做日志的刷盘操作。在这种情况下,MySQL宕机最多丢失1s内的事务数据,这种方式效率最高,但是安全性最低

  • 1:代表每次提交事务都将Redo Buffer同步到OS Buffer然后立即从OS Buffer刷到Redo Log磁盘文件中(默认值)

为1时,每次事务提交时都将进行同步, 执行主动刷盘操作。在这种情况下,MySQL宕机最多丢失1次事务的数据,安全性最高,效率偏低

  • 2:代表每次提交都将Redo Buffer中的数据刷到OS Buffer,然后再隔一秒从OS Buffer刷到Redo Log磁盘文件中。

为2时,只要事务提交成功,redo log buffer中的内容只写入文件系统缓存(pagecache)。在这种情况下,如果是MySQL宕机,最多丢失1次事务的数据,但是如果是操作系统宕机,则可能会丢失1s内的数据。安全性和效率折中。

  • 测试不同的redo刷盘策略对性能的影响:
mysql> truncate userinfo;
Query OK, 0 rows affected (0.01 sec)

mysql> set global innodb_flush_log_at_trx_commit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> call test_insert(10000);
Query OK, 1 row affected (0.42 sec)

mysql> truncate userinfo;
Query OK, 0 rows affected (0.01 sec)

mysql> set global innodb_flush_log_at_trx_commit=1;
Query OK, 0 rows affected (0.00 sec)

mysql> call test_insert(10000);
Query OK, 1 row affected (17.36 sec)

mysql> truncate userinfo;
Query OK, 0 rows affected (0.01 sec)

mysql> set global innodb_flush_log_at_trx_commit=2;
Query OK, 0 rows affected (0.00 sec)

mysql> call test_insert(10000);
Query OK, 1 row affected (0.46 sec)

mysql>

Redo Buffer 除了上面3种策略进行刷盘以外,还有另外一种特殊的场景:redo log buffer占用的空间即将达到 innodb_log_buffer_size 一半的时候,后台线程会主动写盘。需要注意,由于这个事务并没有提交,所以这个写盘动作只是 write,而没有调用 fsync,也就是只留在了文件系统的 page cache

2.1.4 Redo Log的系统参数

  • innodb_log_buffer_sizeRedo Buffer的大小,默认16M

  • innodb_log_file_size:单个Redo Log事务日志文件的最大大小,默认48M

  • innodb_log_files_groupRedo Log日志文件的个数,默认2个

  • innodb_log_group_home_dirRedo Log的存放路径;默认值为./代表当前MySQL的数据目录(Linux默认是/var/lib/mysql

  • innodb_log_checksums:启用或禁用Relo log数据页的校验,默认开启。

  • innodb_log_compressed_pages:指定是否将重新压缩的页写入Redo Log,默认是开启状态

show variables like '%innodb_log%';

#

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3天前
|
SQL 存储 关系型数据库
Mysql并发控制和日志
通过深入理解和应用 MySQL 的并发控制和日志管理技术,您可以显著提升数据库系统的效率和稳定性。
26 10
|
15天前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
1月前
|
SQL 关系型数据库 MySQL
【赵渝强老师】MySQL的全量日志文件
MySQL全量日志记录所有操作的SQL语句,默认禁用。启用后,可通过`show variables like %general_log%检查状态,使用`set global general_log=ON`临时开启,执行查询并查看日志文件以追踪SQL执行详情。
|
1月前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
282 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
9天前
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
|
2月前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
316 3
|
4月前
|
Kubernetes Ubuntu Windows
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
142 3
|
19天前
|
存储 监控 安全
什么是事件日志管理系统?事件日志管理系统有哪些用处?
事件日志管理系统是IT安全的重要工具,用于集中收集、分析和解释来自组织IT基础设施各组件的事件日志,如防火墙、路由器、交换机等,帮助提升网络安全、实现主动威胁检测和促进合规性。系统支持多种日志类型,包括Windows事件日志、Syslog日志和应用程序日志,通过实时监测、告警及可视化分析,为企业提供强大的安全保障。然而,实施过程中也面临数据量大、日志管理和分析复杂等挑战。EventLog Analyzer作为一款高效工具,不仅提供实时监测与告警、可视化分析和报告功能,还支持多种合规性报告,帮助企业克服挑战,提升网络安全水平。
|
1月前
|
存储 监控 安全
什么是日志管理,如何进行日志管理?
日志管理是对IT系统生成的日志数据进行收集、存储、分析和处理的实践,对维护系统健康、确保安全及获取运营智能至关重要。本文介绍了日志管理的基本概念、常见挑战、工具的主要功能及选择解决方案的方法,强调了定义管理目标、日志收集与分析、警报和报告、持续改进等关键步骤,以及如何应对数据量大、安全问题、警报疲劳等挑战,最终实现日志数据的有效管理和利用。
|
2月前
|
Python
log日志学习
【10月更文挑战第9天】 python处理log打印模块log的使用和介绍
42 0

相关产品

  • 云数据库 RDS MySQL 版
  • 下一篇
    DataWorks