news 2026/4/22 0:35:04

MySQL Undo/Redo Log详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL Undo/Redo Log详解

一、核心概念对比

特性Redo LogUndo Log
主要目的保证事务的持久性保证事务的原子性和MVCC
写入时机事务进行中,数据修改前事务进行中,数据修改后
内容记录物理修改操作记录逻辑修改前的数据
存储方式顺序写入,循环覆盖随机写入,按需清理
生命周期事务提交后,数据刷盘后可清理事务提交后,但需保留至没有事务依赖
恢复方向前滚(redo)回滚(undo)
文件ib_logfile0, ib_logfile1ibdata1或独立表空间

二、Redo Log详细原理

1.物理结构

# 查看Redo Log配置 SHOW VARIABLES LIKE 'innodb_log%'; # 重要参数: # innodb_log_file_size = 每个文件大小(默认48M-2G) # innodb_log_files_in_group = 文件数量(默认2) # innodb_log_buffer_size = 缓冲区大小(默认16M)

2.写入流程(两阶段提交)

-- 示例:UPDATE users SET balance=200 WHERE id=1; 1. 内存阶段: - 修改Buffer Pool中的数据页 - 将修改记录写入Log Buffer 2. 准备阶段(Prepare): - Log Buffer中的Redo记录刷入Redo Log文件 - 此时Redo Log状态为"prepare" 3. 提交阶段(Commit): - Binlog写入完成 - Redo Log状态改为"commit" - 事务提交成功

3.Checkpoint机制

# Checkpoint过程示意 def checkpoint_process(): # 1. 找到最老的脏页LSN(Log Sequence Number) oldest_dirty_lsn = find_oldest_dirty_page() # 2. 将这个LSN写入Redo Log头 write_checkpoint_to_redo(oldest_dirty_lsn) # 3. 刷新脏页到磁盘 flush_dirty_pages_to_disk() # 4. 清理Redo Log空间 # 从checkpoint前的Redo Log可以安全覆盖

三、Undo Log详细原理

1.存储结构

-- Undo Log段管理 CREATE TABLE t ( id INT PRIMARY KEY, name VARCHAR(20), balance DECIMAL(10,2) ) ENGINE=InnoDB; -- Undo Log包含: -- 1. 回滚指针:DB_ROLL_PTR(指向旧版本) -- 2. 事务ID:DB_TRX_ID(最近修改的事务ID) -- 3. 删除标记:DELETED_BIT

2.版本链构建

# 数据行的版本链示意 当前行 (id=1, name='Alice', balance=100) ↓ roll_ptr Undo Log 1: (balance=50, trx_id=100) ← UPDATE操作前的版本 ↓ roll_ptr Undo Log 2: (name='Bob', trx_id=80) ← 更早的UPDATE ↓ roll_ptr NULL (初始版本)

3.MVCC实现

-- 读已提交(Read Committed)隔离级别下的可见性判断 SELECT * FROM users WHERE id=1; -- InnoDB判断流程: -- 1. 获取当前事务ID: current_trx_id -- 2. 获取当前活跃事务列表: active_trx_list -- 3. 从当前行开始遍历版本链: -- - 如果 trx_id < current_trx_id 且 trx_id不在活跃列表中 -- 且 trx_id <= up_limit_id(快照上限) -- - 则该版本对当前事务可见 -- 4. 否则继续查找更早版本

四、实际应用场景

场景1:银行转账事务

START TRANSACTION; -- 步骤1:A账户扣款 UPDATE accounts SET balance=balance-100 WHERE id=1; -- Undo Log记录: (balance=原始值, trx_id=当前事务) -- Redo Log记录: 页面修改信息 -- 步骤2:B账户入账 UPDATE accounts SET balance=balance+100 WHERE id=2; -- Undo Log记录: (balance=原始值, trx_id=当前事务) -- Redo Log记录: 页面修改信息 COMMIT; -- Binlog写入 → Redo Log状态改为commit

恢复场景

  • 如果在COMMIT前崩溃:

    • Redo Log处于prepare状态

    • 重启后根据Binlog决定是否提交

    • 使用Undo Log回滚未提交的修改

  • 如果在COMMIT后崩溃:

    • Redo Log为commit状态

    • 重启后重做已提交的事务

场景2:长事务问题

-- 危险的长时间查询 START TRANSACTION; SELECT * FROM large_table WHERE ... FOR UPDATE; -- 执行复杂业务逻辑(耗时10分钟) -- ... COMMIT; -- 问题: -- 1. Undo Log无法清理,导致undo表空间膨胀 -- 2. 阻塞Purge线程 -- 3. 可能触发“事务ID耗尽”问题

监控脚本

-- 监控长时间运行的事务 SELECT trx_id, trx_started, TIMEDIFF(NOW(), trx_started) AS duration, trx_state, trx_operation_state FROM information_schema.INNODB_TRX WHERE TIMEDIFF(NOW(), trx_started) > '00:05:00' ORDER BY trx_started; -- 监控Undo Log使用 SHOW ENGINE INNODB STATUS\G -- 查看"TRANSACTIONS"部分

场景3:批量数据处理优化

-- 错误的批量更新(产生大量Undo) START TRANSACTION; UPDATE large_table SET status=1 WHERE create_date < '2024-01-01'; -- 影响100万行,产生大量Undo Log COMMIT; -- 优化的批量更新 SET AUTOCOMMIT=0; SET UNIQUE_CHECKS=0; SET FOREIGN_KEY_CHECKS=0; -- 分批次处理 DECLARE done INT DEFAULT FALSE; DECLARE batch_size INT DEFAULT 1000; DECLARE last_id INT DEFAULT 0; REPEAT START TRANSACTION; UPDATE large_table SET status=1 WHERE id > last_id AND create_date < '2024-01-01' LIMIT batch_size; SET last_id = LAST_INSERT_ID(); COMMIT; -- 每个批次提交,释放Undo SELECT SLEEP(0.1); -- 避免过度消耗资源 UNTIL ROW_COUNT() = 0 END REPEAT; SET AUTOCOMMIT=1; SET UNIQUE_CHECKS=1; SET FOREIGN_KEY_CHECKS=1;

五、性能优化实战

1.Redo Log优化配置

# my.cnf配置示例 [mysqld] # Redo Log文件大小,建议设置为缓冲池的1/4到1/2 # 对于8G内存,Buffer Pool通常6G,Redo Log设为2G innodb_log_file_size = 2G innodb_log_files_in_group = 4 # 总大小=2G*4=8G # Log Buffer大小,大事务可适当调大 innodb_log_buffer_size = 64M # 刷盘策略,根据数据安全需求选择 # 1-最安全,每次提交都刷盘(默认) # 2-折中,每次提交写OS缓存,每秒刷盘 # 0-性能最好,每秒刷盘,可能丢失1秒数据 innodb_flush_log_at_trx_commit = 1

2.Undo表空间管理

-- MySQL 8.0+ 独立Undo表空间 -- 查看Undo配置 SELECT * FROM information_schema.INNODB_TABLESPACES WHERE SPACE_TYPE = 'Undo'; -- 监控Undo空间使用 SELECT tablespace_name, file_size / 1024 / 1024 AS file_size_mb, allocated_size / 1024 / 1024 AS allocated_mb FROM information_schema.FILES WHERE file_name LIKE '%undo%'; -- 设置Undo表空间自动清理 SET GLOBAL innodb_undo_log_truncate = ON; SET GLOBAL innodb_max_undo_log_size = 1 * 1024 * 1024 * 1024; -- 1GB SET GLOBAL innodb_purge_rseg_truncate_frequency = 128;

3.高并发写入优化

-- 场景:秒杀活动,大量并发写入 -- 问题:Redo Log成为瓶颈 -- 解决方案1:临时调整刷盘策略(活动期间) SET GLOBAL innodb_flush_log_at_trx_commit = 2; -- 活动结束后恢复为1 -- 解决方案2:组提交优化 -- MySQL已自动支持,确保参数合理 SHOW VARIABLES LIKE 'binlog_group%'; SHOW VARIABLES LIKE 'innodb_flush_log_at_timeout'; -- 解决方案3:拆分热点数据 -- 将热点账户分散到不同数据页 UPDATE account_001 SET ... WHERE user_id=1; -- 分表

六、故障恢复实战

场景:Redo Log损坏恢复

# 1. 检查Redo Log状态 mysql> SHOW ENGINE INNODB STATUS\G # 2. 如果有备份,优先使用备份恢复 # 使用Percona XtraBackup或mysqldump备份 # 3. 强制恢复模式(谨慎使用) # 在my.cnf中添加 [mysqld] innodb_force_recovery = 1 # 1-6,数字越大越激进 # 4. 恢复步骤 # 4.1 停止MySQL sudo systemctl stop mysql # 4.2 备份原数据文件 cp -r /var/lib/mysql /var/lib/mysql_backup # 4.3 移除损坏的Redo Log mv /var/lib/mysql/ib_logfile* /tmp/ # 4.4 启动MySQL(会自动创建新的Redo Log) sudo systemctl start mysql # 4.5 使用mysqlbinlog恢复未同步的数据 mysqlbinlog mysql-bin.000001 | mysql -u root -p

七、监控与维护脚本

-- 1. Redo Log监控 SELECT 'Redo Log' AS metric, CONCAT(ROUND(SUM(LENGTH)/1024/1024, 2), ' MB') AS current_size, CONCAT(ROUND(variable_value/1024/1024, 2), ' MB') AS configured_size, ROUND(SUM(LENGTH)*100/variable_value, 2) AS usage_percent FROM information_schema.INNODB_BUFFER_PAGE JOIN information_schema.GLOBAL_VARIABLES ON variable_name = 'innodb_log_file_size' WHERE PAGE_TYPE LIKE 'IBUF%' GROUP BY variable_value; -- 2. Undo空间监控 SELECT FORMAT_BYTES(SUM(current_size)) AS active_undo_size, FORMAT_BYTES(SUM(undo_size)) AS total_undo_size, COUNT(*) AS undo_segments, ROUND(SUM(current_size)*100/SUM(undo_size), 2) AS usage_pct FROM information_schema.INNODB_METRICS WHERE NAME LIKE '%undo%'; -- 3. 长事务和Undo关联查询 SELECT r.trx_id AS waiting_trx_id, r.trx_mysql_thread_id AS waiting_thread, TIMEDIFF(NOW(), r.trx_started) AS wait_time, b.trx_id AS blocking_trx_id, b.trx_mysql_thread_id AS blocking_thread, bl.lock_table AS locked_table FROM information_schema.INNODB_LOCK_WAITS w INNER JOIN information_schema.INNODB_TRX b ON b.trx_id = w.blocking_trx_id INNER JOIN information_schema.INNODB_TRX r ON r.trx_id = w.requesting_trx_id INNER JOIN information_schema.INNODB_LOCKS bl ON bl.lock_id = w.blocking_lock_id;

八、最佳实践总结

Redo Log优化:

  1. 大小配置:总大小 = Buffer Pool的25%-50%

  2. IO优化:使用SSD,单独磁盘存放Redo Log

  3. 监控告警:设置Redo Log切换频率告警(> 20次/小时需扩容)

Undo Log优化:

  1. 避免长事务:事务时间控制在5秒内

  2. 定期清理:启用innodb_undo_log_truncate

  3. 版本控制:及时提交只读事务,释放快照

通用建议:

  1. 定期备份:Redo Log不是备份,需配合Binlog和物理备份

  2. 压力测试:在高并发场景测试Redo/Undo配置

  3. 版本升级:MySQL 8.0在Undo管理上有显著改进

  4. 监控完备:使用Prometheus+Granafa监控Redo/Undo指标

故障预案:

  1. 保持Redo Log在独立磁盘

  2. 定期测试恢复流程

  3. 设置合理的innodb_force_recovery预案

  4. 重要业务开启双1配置(sync_binlog=1,innodb_flush_log_at_trx_commit=1

通过深入理解Redo和Undo Log的工作原理,可以更好地设计数据库架构、优化性能,并在故障时快速恢复,确保业务的连续性和数据的安全性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 3:31:11

大数据领域日志数据的存储优化与性能调优

大数据领域日志数据的存储优化与性能调优关键词&#xff1a;大数据、日志数据、存储优化、性能调优、数据处理摘要&#xff1a;本文围绕大数据领域中日志数据的存储优化与性能调优展开。首先介绍了相关背景知识&#xff0c;包括目的、预期读者等。接着详细解释了日志数据存储和…

作者头像 李华
网站建设 2026/4/18 3:31:26

【毕业设计】机器学习基于cnn卷积网络识别树叶是否存在病变

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/18 3:37:30

交互式世界建模新方案!腾讯混元发布世界模型WorldPlay,兼顾实时生成与长期几何一致性;5万条样本!Med-Banana-50K支持增删病灶双向编辑

世界模型正驱动计算智能领域的重心逐渐从语言任务拓展至视觉与空间推理&#xff0c;通过构建动态三维环境的模拟能力&#xff0c;这些模型使智能体得以感知并与复杂场景交互&#xff0c;从而为具身智能、游戏开发等领域开启了新的研究与应用前景。世界模型的前沿正聚焦于实时交…

作者头像 李华
网站建设 2026/4/18 3:33:04

深度学习毕设选题推荐:人工智能基于python的鲜花识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/18 2:23:35

【论文阅读】Steering Your Diffusion Policy with Latent Space Reinforcement Learning

【论文阅读】Steering Your Diffusion Policy with Latent Space Reinforcement Learning1 团队与发表时间2. 问题背景与核心思路3. 具体做法3.1 模型设计3.2 Loss 设计3.3 数据设计4 实验效果5 结论6 扩散模型进行RL的方案6.1 纯离线设置 (Purely Offline Setting)6.2 在线设置…

作者头像 李华
网站建设 2026/4/18 3:31:09

深度测评专科生必用的8款AI论文软件

深度测评专科生必用的8款AI论文软件 2026年专科生论文写作工具测评&#xff1a;如何选择适合自己的AI助手 随着AI技术的不断进步&#xff0c;越来越多的专科生开始借助AI工具提升论文写作效率。然而&#xff0c;面对市场上琳琅满目的论文辅助软件&#xff0c;如何挑选真正适合自…

作者头像 李华