MySQL中的Redo Log、Undo Log和Binary Log

Redo Log

工作机制
  • 预写日志(WAL) :想象你正在为一本书编写内容。在正式将内容写入书本之前,你会先在一个草稿本上写下你要记录的内容。这样即使突然发生意外(比如墨水洒了),你也可以根据草稿本恢复丢失的内容。Redo Log就像是这个草稿本,在数据真正改变之前,先把即将发生的更改记下来。
    • 具体流程
      • 当一个事务开始执行并修改数据时,InnoDB首先会在内存中做这些修改,并同时把这些变更记录到Redo Log Buffer中(相当于草稿本)。
      • 这些日志随后会被异步刷新到磁盘上的Redo Log文件中(相当于正式的书本)。如果系统崩溃,在重启后,InnoDB会检查Redo Log,并重新应用那些还没来得及写入磁盘的数据更改,确保数据的一致性。
      • 循环使用:Redo Log由一系列固定大小的日志文件组成,当一个日志文件满了之后,会继续写入下一个日志文件,形成循环使用模式。这就像一本用完了就换下一本的日记本。
      • 检查点(Checkpoint):定期将内存中的脏页刷新到磁盘,并更新检查点位置。这有助于缩短数据库恢复时间并释放Redo Log空间。类似于你定期整理你的笔记本,确保所有重要信息都已保存好。
配置与注意事项
  • innodb_log_file_size:决定每本"日记本"的大小。较大的日记本可以减少更换日记本的频率,但可能会增加恢复时间。建议根据实际工作负载调整此值。例如,对于高并发写操作较多的应用,可能需要更大的Redo Log文件以减少日志切换的频率。
  • innodb_flush_log_at_trx_commit:控制什么时候把草稿纸上的内容搬到正式日记本上。
    • 设置为1表示每次完成一个事务就搬;
    • 设置为0表示每隔一段时间批量搬运;
    • 设置为2则是每次完成事务只放到操作系统缓存里,不立即搬到硬盘上。
  • innodb_flush_method:定义如何刷新数据和日志文件到磁盘,不同的设置会影响性能和安全性。例如,O_DIRECT可以绕过操作系统的缓存直接写入磁盘,提高性能但可能增加I/O负担。

Undo Log

工作机制
  • 多版本并发控制(MVCC) :假设你在编辑一篇文章,但是你希望保留每个版本以便随时回退。Undo Log就像是保存文章旧版本的地方。每当你要修改文章时,它会保存当前版本,这样如果需要撤销修改或者其他人想看之前的版本,就可以找到。
    • 快照读取:如果你想要查看文章的历史版本,可以通过Undo Log获取该版本的信息。这对于实现非锁定读非常重要。例如,两个用户同时读取同一张表的不同版本,而不会互相干扰。
    • 回滚段(Rollback Segments):用于存储撤销信息,使得可以回滚未完成的事务。
    • 清理机制:一旦确认没有人再需要某个旧版本的文章了,就可以删除或覆盖这部分Undo Log空间。这有助于防止表空间无限增长。
配置与注意事项
  • innodb_undo_tablespaces:指定Undo表空间的数量,增加数量可以帮助分散Undo Log的压力,就像准备更多的抽屉存放不同版本的文章。从MySQL 5.7开始支持此功能。
  • innodb_undo_log_truncate:启用自动收缩功能来管理Undo表空间的增长,防止其无限制增长,类似于定期清理不再需要的旧版本文章。
  • innodb_purge_rseg_truncate_frequency:控制Undo Log的清理频率,影响系统回收已不再使用的Undo Log页的速度。
  • innodb_max_undo_log_size:设置触发自动收缩的最大Undo Log大小。

Binary Log (Binlog)

工作机制
  • 逻辑日志 :不同于Redo和Undo Log,Binlog更像是一个详细的修改记录簿,记录了所有对数据库的操作(如SQL语句或行变更),而不是具体的物理数据页的变化。
    • 事件驱动:每当有事务执行完毕并提交时,相关的变更信息就会被记录到Binlog中。
    • 格式选择
      • STATEMENT:仅记录做了什么操作;
      • ROW:记录每一行的具体变化;
      • MIXED:根据情况选择STATEMENT或ROW的最佳记录方式。
配置与注意事项
  • 开启Binlog需要在MySQL配置文件中设置log-bin参数。
  • 根据需求选择合适的Binlog格式(STATEMENT, ROW, MIXED)。ROW格式更适合高并发环境,因为它能准确地记录每一行的变化,避免了基于STATEMENT可能存在的不确定性问题。
  • expire_logs_days:设置Binlog文件的过期天数,超过这个时间的日志文件将被自动删除,帮助控制磁盘使用量。
  • sync_binlog:控制Binlog的同步频率,0表示由操作系统决定,N表示每N次事务提交后同步到磁盘。较高的值可以提高性能但降低可靠性。

区别详解

目的
  • Redo Log:像一个保险箱,确保即使系统崩溃也能找回未保存的数据。
  • Undo Log:像是一个时光机,允许你撤销未完成的修改或者查看历史版本的数据。
  • Binlog:则是一个记录员,记录所有的数据库操作,用于数据恢复、复制和迁移。
内容形式
  • Redo Log:关注于如何重建数据页,记录的是数据页的物理变化。
  • Undo Log:保存的是数据的旧版本,用于回滚事务和支持MVCC。
  • Binlog:记录的是用户执行的所有操作,描述了事务的具体操作。
生命周期管理
  • Redo Log:随检查点推进而覆盖,周期性地将日志条目应用到数据页,并释放相应的日志空间。
  • Undo Log:依赖于事务状态及其对应的MVCC视图,当没有事务再需要某个Undo Log记录时,它会被标记为可重用。
  • Binlog:需手动或按策略清理,通常通过设置过期时间或手动命令来管理Binlog文件。

示例说明

假设你在一家公司负责文档管理系统,以下是每个日志类型在实际操作中的作用:

  • Redo Log:当你正在编辑一份重要的报告时,系统会先将你做的每一个改动记录下来。如果突然停电,你可以根据这些记录恢复未保存的工作。这就像是你在编辑Word文档时,Office软件会自动保存临时文件,以防意外丢失。

  • Undo Log:当你在编辑文档时,系统会保存每个版本,让你可以轻松撤销任何你不满意的修改,或者查看以前的版本。这就像是Word中的"撤销"功能,可以回退到任意步骤。

  • Binlog:当你需要备份整个文档库或将文档库迁移到另一个服务器时,系统会记录所有操作,确保你可以完全复制或恢复文档库的状态。这就像是你将整个项目文件夹复制到外部硬盘以备不时之需。

更详细的配置示例

Redo Log 配置
bash 复制代码
[mysqld]
innodb_log_file_size = 512M
innodb_log_files_in_group = 3
innodb_flush_log_at_trx_commit = 1
innodb_flush_method = O_DIRECT
  • innodb_log_file_size=512M:设置每个Redo Log文件大小为512MB,适用于高并发场景。
  • innodb_log_files_in_group=3:设置Redo Log组中有3个文件,提供冗余和更高的吞吐量。
  • innodb_flush_log_at_trx_commit=1:确保每个事务提交时都会将日志刷到磁盘,保证数据安全。
  • innodb_flush_method=O_DIRECT:绕过操作系统缓存,直接写入磁盘,提高性能。
Undo Log 配置
bash 复制代码
[mysqld]
innodb_undo_tablespaces = 4
innodb_undo_log_truncate = ON
innodb_max_undo_log_size = 1G
  • innodb_undo_tablespaces=4:设置4个Undo表空间,分散Undo Log压力。
  • innodb_undo_log_truncate=ON:开启自动收缩功能,防止Undo Log无限增长。
  • innodb_max_undo_log_size=1G:设置触发自动收缩的最大Undo Log大小为1GB。
Binary Log 配置
bash 复制代码
[mysqld]
log-bin = mysql-bin
binlog_format = ROW
expire_logs_days = 7
sync_binlog = 1
  • log-bin=mysql-bin:开启Binlog,并设置前缀为mysql-bin。
  • binlog_format=ROW:选择Row格式记录Binlog,适合高并发环境。
  • expire_logs_days=7:设置Binlog文件过期时间为7天。
  • sync_binlog=1:确保每个事务提交时都将Binlog刷到磁盘,保证数据一致性。
相关推荐
广州智造3 小时前
OptiStruct实例:3D实体转子分析
数据库·人工智能·算法·机器学习·数学建模·3d·性能优化
技术宝哥6 小时前
Redis(2):Redis + Lua为什么可以实现原子性
数据库·redis·lua
学地理的小胖砸7 小时前
【Python 操作 MySQL 数据库】
数据库·python·mysql
dddaidai1237 小时前
Redis解析
数据库·redis·缓存
数据库幼崽8 小时前
MySQL 8.0 OCP 1Z0-908 121-130题
数据库·mysql·ocp
Amctwd8 小时前
【SQL】如何在 SQL 中统计结构化字符串的特征频率
数据库·sql
betazhou8 小时前
基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
linux·数据库·mysql·oracle·ogg
lyrhhhhhhhh9 小时前
Spring 框架 JDBC 模板技术详解
java·数据库·spring
喝醉的小喵10 小时前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
付出不多11 小时前
Linux——mysql主从复制与读写分离
数据库·mysql