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刷到磁盘,保证数据一致性。