【图⽂详解】MySQL系列之redolog、undolog和binlog详解这篇⽂章主要介绍了MySQL系列之redo log、undo log和binlog详解,本⽂给⼤家介绍的⾮常详细,对⼤家的学习或⼯作具有⼀定的参考借鉴价值,需要的朋友可以参考下。
事务的实现
redo log保证事务的持久性,undo log⽤来帮助事务回滚及MVCC的功能。
InnoDB存储引擎体系结构
redo log:Write Ahead Log策略
事务提交时,先写重做⽇志再修改页;当由于发⽣宕机⽽导致数据丢失时,就可以通过重做⽇志来完成数据的恢复。
InnoDB⾸先将重做⽇志信息先放到重做⽇志缓存;
然后,按⼀定频率刷新到重做⽇志⽂件。
重做⽇志⽂件: 在默认情况,InnoDB存储引擎的数据⽬录下会有两个名为ib_logfile1和ib_logfile2的⽂件。每个InnoDB存储引擎⾄少有1个重做⽇志⽂件组(group),每个⽂件组下⾄少有2个重做⽇志⽂件。
下⾯图⼀,很好说明重做⽇志组以循环写⼊⽅式运⾏,InnoDB存储引擎先写ib_logfile1,当达到⽂件最后时,会切换⾄重做⽇志⽂件
ib_logfile2.
⽽图2,增加⼀个OS Buffer,有助于理解fsync过程。
关于log group,称为重做⽇志组,是⼀个逻辑上的概念。InnoDB存储引擎实际只有⼀个log group。
log group中第⼀个redo log file,其前2KB部分保存4个512字节⼤⼩块:
重做⽇志缓冲刷新到磁盘
下⾯三种情况刷新:
Master Thread每⼀秒将重做⽇志缓冲刷新到重做⽇志⽂件
每个事务提交时会将重做⽇志缓冲刷新到重做⽇志⽂件
当重做⽇志缓冲池剩余空间⼩于1/2时,重做⽇志刷新到重做⽇志⽂件
补充上述三种情况第⼆种,触发写磁盘过程由参数innodb_flush_log_at_trx_commit控制,表⽰提交(commit)操作时,处理重做⽇志的⽅式。
参数 innodb_flush_log_at_trx_commit 有效值有0、1、2
0表⽰当提交事务时,并不将事务的重做⽇志写⼊磁盘上⽇志⽂件,⽽是等待主线程每秒刷新。
1表⽰在执⾏commit时将重做⽇志缓冲同步写到磁盘,即伴有fsync的调⽤
2表⽰将重做⽇志异步写到磁盘,即写到⽂件系统的缓存中。不保证commit时肯定会写⼊重做⽇志⽂件。
0,当数据库发⽣宕机时,部分⽇志未刷新到磁盘,因此会丢失最后⼀段时间的事务。
2,当操作系统宕机时,重启数据库后会丢失未从⽂件系统缓存刷新到重做⽇志⽂件那部分事务。
下图有助于理解
重做⽇志块
在InnoDB存储引擎中,重做⽇志都是以512字节进⾏存储的。意味着重做⽇志缓存、重做⽇志⽂件都是以块(block)的⽅式进⾏保存的,每块512字节。
重做⽇志头12字节,重做⽇志尾8字节,故每个重做⽇志块实际可以存储492字节。
重做⽇志格式
redo log是基于页的格式来记录的。默认情况下,innodb的页⼤⼩是16KB(由 innodb_page_size变量控制),⼀个页内可以存放⾮常多的log block(每个512字节),⽽log block中记录的⼜是数据页的变化。
log body的格式分为4部分:
mysql中delete语句redo_log_type:占⽤1个字节,表⽰redo log的⽇志类型。
space:表⽰表空间的ID,采⽤压缩的⽅式后,占⽤的空间可能⼩于4字节。
page_no:表⽰页的偏移量,同样是压缩过的。
redo_log_body表⽰每个重做⽇志的数据部分,恢复时会调⽤相应的函数进⾏解析。例如insert语句和delete语句写⼊redo log的内容是不⼀样的。
如下图,分别是insert和delete⼤致的记录⽅式。
redo⽇志恢复
下⾯ LSN (Log Sequence Number) 代表 checkpoint,当数据库在 LSN 为10000时发⽣宕机,恢复操作仅恢复LSN10000-
LSN13000范围内⽇志
undo log
undo log的作⽤:
undo是逻辑⽇志,只是将数据库逻辑地恢复到原来的样⼦;所有修改都被逻辑地取消了,但是数据结
构和页本⾝在回滚之后可能不⼤相同。
undo log有两个作⽤:提供回滚和多个⾏版本控制(MVCC)。
InnoDB存储引擎回滚时,对于每个INSERT,会完成⼀个DELETE;对于每个DELETE,会执⾏⼀个INSERT;对于每个UPDATE,会执⾏⼀个相反的UPDATE,将修改前的⾏放回去。
MVCC: 当⽤户读取⼀⾏记录时,若该记录已经被其他事务占⽤,当前事务可以通过undo读取之前的⾏版本信息,以此实现⾮锁定读取。
undo log的存储⽅式:
innodb存储引擎对undo的管理采⽤段的⽅式。rollback segment称为回滚段,每个回滚段中有1024个undo log segment。
在以前⽼版本,只⽀持1个rollback segment,这样就只能记录1024个undo log segment。后来MySQL5.5可以⽀持128个rollback segment,即⽀持128*1024个undo操作,还可以通过变量 innodb_undo_logs (5.6版本以前该变量是 innodb_rollback_segments )⾃定义多少个rollback segment,默认值为128。
undo log默认存放在共享表空间中。
事务提交undo log处理过程
当事务提交时,InnoDB存储引擎会做以下两件事:
1、将undo log放⼊⼀个列表中,以供之后的purge使⽤,是否可以最终删除undo log及所在页由purge线程来判断
2、判断undo log 所在的页是否可以重⽤,若可以,分配给下个事务使⽤
当事务提交时,⾸先将undo log放⼊链表中,然后判断undo页的使⽤空间是否⼩于3/4,若是,则表⽰该undo页可以被重⽤,之后新的undo log记录在当前undo log的后⾯
undo log分为: