[MySQL] update语句的redo log过程
Posted 陶士涵的菜地
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[MySQL] update语句的redo log过程相关的知识,希望对你有一定的参考价值。
update语句是如何执行 , 如何将执行后的新数据持久化在磁盘中
可以假设两种情境:
1. 假设mysql在更新之后只更新内存中的数据就返回,然后再某一时刻进行IO将数据页持久化。这样所有操作都是在内存中,可以想象此时的MySQL性能是特别高的。但是,如果在更新完内存又还没有进行持久化的这段时间,MySQL宕机了,那么我们的数据就丢失了。
2. 另外一种情况:每次MySQL将内存中的页更新好后,立刻进行IO,只有数据落盘后才返回。此时我们可以保证数据一定是正确的。但是,每一次的操作,都要进行IO,此时MySQL的效率变得非常低。
我们来看看MySQL是如何做到保证性能的情况下,还保证数据不丢的。
update 表 set a = 1 where id = 1;
如何保证数据一致性
重做日志(redo log)
这里要介绍一个很重要的日志模块,称为rodo log(重做日志)。重做日志是InnoDB引擎特有的。
重做日志在更新数据的时候,会记录在哪个数据页更新了什么数据,并且只要成功的在重做日志记录了这次更新,不需要将内存中的数据页写回磁盘,就可以认为这次更新已经完成了。
1. MySQL里有一个名词,叫WAL技术,WAL的全称是Write-Ahead-Logging,它的关键点就是先写日志,再写磁盘,也就是说只要保证了日志的落盘,数据就一定正确。此时只要保存了日志,就算此时MySQL宕机了,没有将数据页写回磁盘,也可以在之后利用日志进行恢复。
但是,InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是1GB。固定大小也就造成了一个问题,redo log是会被写满的。
2. InnoDB采取了循环写的方式。注意看,这里有两个指针。write_pos表示当前写的位置,只要有记录更新了,write_pos就会往后移动。而check_point表示检查点,只要InnoDB将check_point指向的修改记录更新到了磁盘中,check_point将会往后移动。
如果我们把这一行数据所在的内存页更新好了,并且写入了rodo log
中,此时将返回修改成功的提示。然后在rodo log
中表现为记录了在某一个内存页的更新记录
此时在磁盘中,数据a未改变,在内存中,a改为了1,在rodo log中记录了这个内存页的更新记录,write_pos往后移动。
3. 只有成功的写回了磁盘,check_point才可以往后移动。这个设计,使得rodo log是可以无限重复使用的。
以上是关于[MySQL] update语句的redo log过程的主要内容,如果未能解决你的问题,请参考以下文章
MySQL实战45讲_02| MySQL的两阶段提交(bin log+redo log)
纯手绘图解 - MySQL undo log、redo log、binlog