Mysql InnoDB 执行流程

本文详细解析了InnoDB中update操作的步骤,重点阐述redo log记录修改日志、undo log支持回滚,以及为何先写redo log再刷盘的策略优化

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

本文章通过一次update来总结下InnoDB的运行流程,从中也加深下 mysql 中 redo log、undo log 的作用。

 

当我们执行下面的语句时:

BEGIN;
	UPDATE student 
	SET age = 3 
	WHERE
	id = 1;
COMMIT;

1、根据更新条件从硬盘读取id=1的数据页到 buffer poll 的内存页中。并且对该记录的索引进行加锁。

2、对内存页中id=1的这条数据先写入到undo log中文件。方便后面回滚操作,并且其他事物当前时间窗口基于MVCC版本读时,会根据undo log中的事物id 去判断是否能看到当前版本的记录。

3、对内存页中id=1的记录进行修改操作。此时为脏读状态,因为内存页和磁盘页数据不一致。将这个page 加入到buffer pooll 的脏读链表中。

4、将修改操日志写入 Redo Log Buffer 区域中,注意这里只记录修改了哪个Page 的中哪些内容。当前如果down机修改数据会丢失,因为还没提交事物。

5、提交事物

6、根据设置的innodb_flush_log_at_trx_commit策略来决定redo log的刷盘时机。这里假设我们设置提交及刷盘策略。那么这时mysql down掉的话,数据不会丢失,因为在mysql下次重启时会加载redo log文件,对buffer poll 进行重放操作。

7、写归档日志(binlog)到os cache ,(如果sync_binlog设置为1时还会强制把os cache内容刷盘)。

8、binlog写入完成后会把binlog文件信息写入到redo log中,这样redo中结果数据和binlog内容保证了完全相同。

9、最后mysql 异步 io 线程在某个时刻会把 buffer pool 中的脏读页面刷到对应的磁盘页面上。

 

 

 

你可能会问提交事物时为什么不直接把buffer poll中修改的缓存页信息刷到磁盘中,还要先写到redo log buffer 、刷盘到redo log文件中。

原因有二点:

1、redo log buffer 页中记录的内容比较少(只记录哪个表分区下的哪个页的偏移量下的修改内容),只是记录修改日志,并不是修改数据的具体内容。而直接执行刷新缓存页将会是将整个页(16k)的内容刷到盘上。

2、redo log文件是日志文件,也就是说是一行一行的顺序追加写内容,要比随机写快很多(减少磁盘磁头寻址等)。 

如果我们修改了多条数据,这些数据可能散落在不同的磁盘页上(因为数据在磁盘存储位置是逻辑连续,空闲页使用链表连接,提高磁盘空间的复用),所以如果直接刷盘会特别慢(页面内容多,page 页位置随机)

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值