InnoDB事务日志(redo log 和 undo log)详解

本文介绍了MySQL InnoDB存储引擎中的redo log与undo log机制,包括它们如何在故障恢复过程中发挥作用,以及InnoDB如何通过这些日志确保数据的一致性和事务的持久性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了最大程度避免数据写入时io瓶颈带来的性能问题,MySQL采用了这样一种缓存机制:当query修改数据库内数据时,InnoDB先将该数据从磁盘读取到内存中,修改内存中的数据拷贝,并将该修改行为持久化到磁盘上的事务日志(先写redo log buffer,再定期批量写入),而不是每次都直接将修改过的数据记录到硬盘内,等事务日志持久化完成之后,内存中的脏数据可以慢慢刷回磁盘,称之为Write-Ahead Logging。事务日志采用的是追加写入,顺序io会带来更好的性能优势。

为了避免脏数据刷回磁盘过程中,掉电或系统故障带来的数据丢失问题,InnoDB采用事务日志(redo log)来解决该问题。


【redo log】

用于在实例故障恢复时,继续那些已经commit但数据尚未完全回写到磁盘的事务。

The redo log is a disk-based data structure used during crash recovery to correct data written by incomplete transactions. 

通常会初始化2个或更多的 ib_logfile 存储 redo log,由参数 innodb_log_files_in_group 确定个数,命名从 ib_logfile0 开始,依次写满 ib_logfile 并顺序重用(in a circular fashion)。如果最后1个 ib_logfile 被写满,而第一个ib_logfile 中所有记录的事务对数据的变更已经被持久化到磁盘中,将清空并重用之。

在写入量比较高的情况下,redo log 的大小将显著地影响写入性能。

innodb_log_file_size 用来控制 ib_logfile 的大小。5.5版本及以前:默认5MB,最大4G。

所有事务日志累加大小不超过4G,事务日志过大,checkpoint会减少,在节省磁盘io的同时,大的事务日志也意味着数据库crash后,恢复起来较慢。

官方文档建议innodb_log_file_size的设置可参考 show engine innodb status \G

Log sequence number -Last checkpoint < (innodb_log_files_in_group * innodb_log_file_size ) * 0.75


【undo log】

记录了数据修改的前镜像。存放于ibdata中。(提一句,DDL操作会修改数据字典,该信息也存放在ibdata中)

用于在实例故障恢复时,借助undo log将尚未commit的事务,回滚到事务开始前的状态。

An undo log is a collection of undo log records associated with a single transaction. An undo log record contains information about how to undo the latest change by a transaction to a clustered index record. If another transaction needs to see the original data (as part of a consistent read operation), the unmodified data is retrieved from the undo log records. Undo logs exist within undo log segments, which are contained within rollback segments. Rollback segments are physically part of the system tablespace. For related information, see Section 14.6, “InnoDB Multi-Versioning”.



The InnoDB crash recovery process consists of several steps:(指的是MySQL server crash,不包括hardware failure 或者 server system error)


Redo log application
Redo log application is the first step and is performed during initialization, before accepting any connections. If all changes are flushed from the buffer pool to the tablespaces (ibdata* and *.ibd files) at the time of the shutdown or crash, redo log application is skipped. InnoDB also skips redo log application if redo log files are missing at startup.

Removing redo logs to speed up recovery is not recommended, even if some data loss is acceptable. Removing redo logs should only be considered after a clean shutdown, with innodb_fast_shutdown set to 0 or 1.

Roll back of incomplete transactions
Incomplete transactions are any transactions that were active at the time of crash or fast shutdown. The time it takes to roll back an incomplete transaction can be three or four times the amount of time a transaction is active before it is interrupted, depending on server load.

You cannot cancel transactions that are being rolled back. In extreme cases, when rolling back transactions is expected to take an exceptionally long time, it may be faster to start InnoDB with an innodb_force_recovery setting of 3 or greater. See Section 14.23.2, “Forcing InnoDB Recovery”.

Change buffer merge
Applying changes from the change buffer (part of the system tablespace) to leaf pages of secondary indexes, as the index pages are read to the buffer pool.

Purge
Deleting delete-marked records that are no longer visible to active transactions.

The steps that follow redo log application do not depend on the redo log (other than for logging the writes) and are performed in parallel with normal processing. Of these, only rollback of incomplete transactions is special to crash recovery. The insert buffer merge and the purge are performed during normal processing.

After redo log application, InnoDB attempts to accept connections as early as possible, to reduce downtime. As part of crash recovery, InnoDB rolls back transactions that were not committed or in XA PREPARE state when the server crashed. The rollback is performed by a background thread, executed in parallel with transactions from new connections. Until the rollback operation is completed, new connections may encounter locking conflicts with recovered transactions.



参考资料:

(1)https://dev.mysql.com/doc/refman/5.5/en/innodb-redo-log.html

(2)https://dev.mysql.com/doc/refman/5.5/en/innodb-undo-logs.html

(3)https://dev.mysql.com/doc/refman/5.5/en/innodb-recovery.html#innodb-crash-recovery

(4)http://www.cnblogs.com/Bozh/archive/2013/03/18/2966494.html



<think>我们正在讨论MySQL日志系统。用户之前询问了UndoLogRedoLog的区别,现在用户的新问题是:“如何关闭redologundolog日志”。这是一个关于配置MySQL日志的问题。首先,我需要明确一点:在MySQL中,RedoLogUndoLogInnoDB存储引擎的核心组件,用于保证事务的ACID特性(原子性、一致性、隔离性、持久性)。因此,通常不建议关闭它们,因为关闭它们会导致数据库无法正常工作。但是,为了回答用户的问题,我需要说明:1.RedoLog(重做日志UndoLog(回滚日志)是InnoDB引擎内部使用的,没有提供直接关闭的配置选项。2.如果用户想要减少日志记录,可以考虑调整日志相关的参数,但无法完全关闭。参考引用[4][5]中提到:-RedoLog用于保证事务的持久性。-UndoLog用于事务回滚MVCC(多版本并发控制)。-它们都是InnoDB实现事务的关键组成部分。因此,我们可以这样回答用户:由于RedoLogUndoLogInnoDB存储引擎实现事务的关键机制,MySQL官方没有提供关闭它们的选项。如果强制不写入这些日志,数据库将无法保证事务的原子性持久性,在崩溃时可能导致数据丢失或不一致。但是,我们可以调整一些参数来减少日志的生成或调整日志的行为,例如:-设置`innodb_flush_log_at_trx_commit`来控制RedoLog的刷盘频率,但这并不关闭RedoLog。-设置`innodb_undo_log_truncate``innodb_max_undo_log_size`来管理UndoLog的空间,避免过度膨胀。如果用户的需求是减少日志写入以提高性能,我们可以提供一些优化建议,而不是关闭日志。如果用户的需求是禁用整个事务(例如只使用MyISAM引擎),那么可以避免使用InnoDB引擎。但是MyISAM引擎不提供事务支持,也不使用RedoLogUndoLog。然而,这通常不推荐,因为InnoDB提供了更好的可靠性并发性能。因此,回答的重点是:1.无法关闭RedoLogUndoLog。2.解释为什么无法关闭。3.提供替代方案(如使用非事务引擎)或优化建议。注意:用户可能误解了日志的作用,我们需要解释关闭这些日志的后果。根据引用[3],如果写入RedoLog失败,事务会回滚,这说明了RedoLog的重要性。同样,UndoLog用于回滚MVCC,也是不可或缺的。因此,我们给出如下回答:</think>### MySQL Redo LogUndo Log 关闭操作详解MySQL中,**Redo LogUndo LogInnoDB存储引擎的核心组件,无法完全关闭**。它们是实现事务ACID特性的关键机制: - **Redo Log**:保证持久性(Durability),确保事务提交后数据不丢失[^4] - **Undo Log**:保证原子性(Atomicity),支持事务回滚MVCC[^5] 但可以通过以下方式调整其行为: --- ### 一、Redo Log 行为调整 #### 1. **禁用持久性保证**(不推荐) 修改配置文件`my.cnf`: ```ini [mysqld] innodb_flush_log_at_trx_commit = 0 ``` 效果: - 日志每秒写入OS缓存一次(不立即刷盘) - 崩溃时可能丢失最后1秒的事务[^4] - **风险**:破坏ACID的持久性保证 #### 2. **减少日志写入频率** ```ini innodb_flush_log_at_trx_commit = 2 ``` - 事务提交时写入OS缓存,每秒刷盘一次 - 服务器崩溃时可能丢失数据,但操作系统崩溃不会[^4] --- ### 二、Undo Log 行为调整 #### 1. **禁用独立表空间** ```ini innodb_undo_tablespaces = 0 ``` - 将undo log存储在系统表空间(ibdata1) - 无法完全禁用,但可避免单独文件管理 #### 2. **自动清理机制** ```ini innodb_undo_log_truncate = ON innodb_max_undo_log_size = 1G ``` - 当日志超过1GB时自动清理历史版本 - 减少磁盘占用但**不影响核心功能** --- ### 三、替代方案(禁用事务) 如果需要完全避免日志,可切换存储引擎: ```sql ALTER TABLE table_name ENGINE = MyISAM; ``` **后果**: 1. 失去事务支持(无法回滚) 2. 崩溃后可能数据损坏 3. 不支持行级锁MVCC 4. 不保证ACID特性[^5] --- ### 四、关键风险提示 | 操作 | 风险等级 | 主要后果 | |---------------------|----------|------------------------------| | 关闭redo刷盘 | ⚠️高危 | 数据丢失、事务不一致 | | 关闭undo管理 | ⚠️高危 | 无法回滚、MVCC失效 | | 切换MyISAM引擎 | ⚠️⚠️严重 | 完全丧失ACID保证 | | 调整日志参数 | ⚠️中危 | 性能下降或数据不一致风险增加 | > **生产环境强烈建议**: > 任何日志调整操作前必须备份数据,并仅在测试环境验证。核心事务系统应保持默认配置: > ```ini > innodb_flush_log_at_trx_commit=1 # 确保每次提交刷盘 > innodb_undo_log_truncate=ON # 启用自动undo清理 > ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值