详解MySQL事务日志——redo log

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 详解MySQL事务日志——redo log

前言


你知道MySQL 中是如何保证数据不丢失的吗?即便是MySQL发生异常重启了,数据也可以恢复。你了解MySQL产生的事务日志redo log是干嘛的吗,明白它的工作机制吗?


redo log介绍


redo log又叫“重做日志”,是存储引擎层 (innoDB) 生成的日志,记录的是"物理级别"上的页修改操作,比如页号x,偏移量y写入了'z'数据,主要目的为了保证数据不丢失,当MySQL发生宕机的时候,可以利用redo log日志进行数据恢复,如下图所示。

1671200093604.jpg

默认的redo log日志文件为ib_logfile0, ib_logfile1,如下图:

1671200099953.jpg

那想过为什么要"多此一举"先写入到redo log磁盘文件中,然后再落到数据库表中?而不直接落到数据库表中?

主要是因为顺序IO性能远高于随机IO。

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

redo log是通过顺序IO"追加"的方式写入到文件末尾,而且写入的内容也是物理日志,比如比如,某个事务将系统表空间中第10号页面中偏移量为 100 处的那个字节的值 1 改成 2等信息,日志占用空间也很小。


redo log整体流程


事务在写入到数据库中涉及到redo log的整体流程如下图所示:

1671200114034.jpg

性能不够,缓存来凑。由于CPU的性能远远大于磁盘,为了消除这个鸿沟,引入了两个缓存,Buffer Poolredo log bufferBuffer Pool用来存放各种操作,比如写入数据时,先写到内存中,然后由后台线程再刷写到磁盘。redo log buffer用来存放重做日志,后续刷到磁盘中。

  1. 先将原始数据从磁盘中读入到Buffer Pool
  2. 修改Buffer Pool中的数据
  3. 生成一条重做日志并写入redo log buffer,记录数据修改后的值
  4. 当事务提交时,将redo log buffer中的内容追加磁盘中的redo log文件中
  5. 将磁盘日志文件redo log file 内容刷到数据库表中

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


redo log落盘策略


事务的日志是先写入到redo log buffer 中是很快的,那如何保证redo log buffer中的信息高效的落到磁盘日志文件中呢?

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

InnoDB引擎提供了 innodb_flush_log_at_trx_commit 参数,该参数控制 commit提交事务时,如何将 redo log buffer 中的日志刷新到 redo log file 的3种策略。

  1. innodb_flush_log_at_trx_commit=1

1671200126447.jpg

  • 每次事务提交时都将进行同步, 执行主动刷盘操作,如上图的红线位置,所以只要事务提交成功,redo log记录就一定在硬盘里,不会有田可数据丢失。
  • 该种方式是MySQL innoDB存储引擎默认的刷盘机制。
  • 如果事务执行期间MySQL挂了或宕机,这部分日志丢了,但是事务并没有提交,所以日志丢了也不会有损

失。可以保证ACID的D,数据绝对不会丢失,但是效率最差的。

  1. innodb_flush_log_at_trx_commit=2

1671200133215.jpg

  • 为2时,只要事务提交成功,redo log buffer中的内容只写入文件系统缓存(pagecache
  • 如果仅仅只是MySQL挂了不会有任何数据丢失,但是操作系统宕机可能会有1秒数据的丢失,这种情况下无法满足ACID中的D
  • 数值2的效率是高于数值等于1的
  1. innodb_flush_log_at_trx_commit=0

1671200138848.jpg

  • 为0时,后台线程每隔1秒进行一次重做日志的刷盘操作,因此MySQL挂了最多丢失1秒钟内的事务。
  • 这种方式效率是最高的,这种策略也有丢失数据的风险,也无法保证持久性。
  1. 其他被动触发刷盘的场景

除了上面3种策略进行刷盘以外,还有两种场景会让一个没有提交的事务的 redo log 写入到磁盘中。

  • redo log buffer 占用的空间即将达到 innodb_log_buffer_size 一半的时候,后台线程会主动写盘。注意,由于这个事务并没有提交,所以这个写盘动作只是 write,而没有调用 fsync,也就是只留在了文件系统的 page cache
  • 并行的事务提交的时候,顺带将这个事务的 redo log buffer 持久化到磁盘。假设一个事务 A 执行到一半,已经写了一些 redo logbuffer 中,这时候有另外一个线程的事务 B 提交,如果 innodb_flush_log_at_trx_commit 设置的是 1,那么按照这个参数的逻辑,事务 B 要把 redo log buffer 里的日志全部持久化到磁盘。这时候,就会带上事务 A 在 redo log buffer 里的日志一起持久化到磁盘。

小结:

我们可以根据实际的业务场景,在性能和持久性做一些权衡,但建议使用默认值,虽然操作系统宕机的概率理论小于数据库宕机的概率,但是一般既然使用了事务,那么数据的安全相对来说更重要些。


redo log写入数据页机制


目前事务日志已经落入到磁盘的redo log file中了,MySQL会去读取这个文件将数据写入到数据页中。

很显然,目前对redo log file会进行读和写的操作。在日志文件组中有两个重要的“指针”,分别是 write pos、``checkpoint

  • write pos是当前记录的位置,一边写一边后移
  • checkpoint是当前要擦除的位置,也是往后推移

1671200148439.jpg

  • 每次刷盘 redo log 记录到日志文件组中,write pos 位置就会后移更新。
  • 每次MySQL加载日志文件组恢复数据时,会清空加载过的 redo log 记录,并把checkpoint后移更新。
  • 如果write pos 追上 checkpoint ,表示日志文件组满了,这时候不能再写入新的 redo log记录,MySQL 得停下来,清空一些记录,把 checkpoint 推进一下,如下图:

1671200154450.jpg

这就是整个redo log file中的日志恢复到数据页中的过程。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
9天前
|
SQL 安全 关系型数据库
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
事务是MySQL中一组不可分割的操作集合,确保所有操作要么全部成功,要么全部失败。本文利用SQL演示并总结了事务操作、事务四大特性、并发事务问题、事务隔离级别。
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
|
15天前
|
SQL 存储 关系型数据库
Mysql并发控制和日志
通过深入理解和应用 MySQL 的并发控制和日志管理技术,您可以显著提升数据库系统的效率和稳定性。
68 10
|
11天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
41 3
|
15天前
|
SQL 关系型数据库 MySQL
MySQL进阶突击系列(04)事务隔离级别、AICD、CAP、BASE原则一直搞不懂? | 看这篇就够了
本文详细介绍了数据库事务的四大特性(AICD原则),包括原子性、隔离性、一致性和持久性,并深入探讨了事务并发问题与隔离级别。同时,文章还讲解了分布式系统中的CAP理论及其不可能三角关系,以及BASE原则在分布式系统设计中的应用。通过具体案例和图解,帮助读者理解事务处理的核心概念和最佳实践,为应对相关技术面试提供了全面的知识准备。
|
28天前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
2月前
|
关系型数据库 MySQL
mysql事务特性
原子性:一个事务内的操作统一成功或失败 一致性:事务前后的数据总量不变 隔离性:事务与事务之间相互不影响 持久性:事务一旦提交发生的改变不可逆
|
2月前
|
SQL 关系型数据库 MySQL
【赵渝强老师】MySQL的全量日志文件
MySQL全量日志记录所有操作的SQL语句,默认禁用。启用后,可通过`show variables like %general_log%检查状态,使用`set global general_log=ON`临时开启,执行查询并查看日志文件以追踪SQL执行详情。
|
2月前
|
关系型数据库 MySQL 数据库
MySQL事务隔离级别及默认隔离级别的设置
在数据库系统中,事务隔离级别是一个关键的概念,它决定了事务在并发执行时如何相互隔离。MySQL提供了四种事务隔离级别,每种级别都解决了不同的并发问题。本文将详细介绍这些隔离级别以及MySQL的默认隔离级别。
|
11天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
39 3
|
11天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE 'log_%';`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
54 2