mysql之redo log原理


mysql事务的原理

事务的原子性和持久性通过redo log来保证,而一致性通过undo log来保证,隔离性则通过锁来保证,这里主要阐述redo log和undo log的原理.

redo log

redo log记录对页的修改操作,其具体指的是redo log缓冲区和redo log文件,redo log缓冲区是内存中的概念,而redo log文件是磁盘中的概念.

原理

当执行一个事务时,事务中有对数据的修改操作,那么会将具体的修改记录成日志,本质上是记录对页的某个偏移位置的修改日志.不同的修改操作,生成的日志类型不同.如果事务提交成功,那么这些日志也一定会存在于redo log缓冲区中,然后redo log缓冲区的这些日志会根据我们配置的innodb_flush_log_at_trx_commit来决定何时刷入磁盘,默认值是1,代表事务提交后刷入磁盘,0代表每隔1s刷入到磁盘,2代表等待操作系统刷入到磁盘.

如果数据被刷到redo log文件,那么数据就不会丢失,那么对于磁盘上页的修改就可以根据redo log文件来进行,但是我们必须记录哪些日志是执行过的,哪些是没有执行过的.我们把redo log缓冲区中的每个字节都编上一个字节号,随着日志不断写入缓冲区,字节号不断增加,我们这个称为Log Sequence Number,简写为LSN.如果日志被同步到redo log文件中,那么这个LSN就是刷新到redo log文件的LSN,如果redo log文件中的日志应用到页的修改,那么这个就是对数据持久化的LSN,也被称为checkpoint LSN.

假设mysql宕机重启,redo log文件的LSN为1000,checkpoint LSN为900,那么900以前的这些日志对应的数据肯定已经持久化到页中了,因此我们只需要使用LSN为900-1000的redo log日志所记录的对页的修改来恢复数据.

类比

如果了解过redis的aof持久化日志,那么这两者有一定的相似之处

undo log

如果我们执行一个insert语句,那么最终会在页中的某个地方产生数据.那么undo log其实记录的是那个地方的历史版本是什么样的,这样才能用于回滚或者用于MVCC.undo log和数据都需要保存到磁盘中,但并没有和redo log文件一样有undo log文件,undo log是通过redo log文件来持久化的.对于undo log可以简单的这么理解:对于insert语句,undo log记录一条逆向delete语句,对于delete语句,undo log记录一条逆向的insert语句,对于update语句,好比记录一条逆向的update语句.

参考资料

mysql技术内幕-innodb存储引擎 7.2 事务的视线


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!