大家好,我是热心的大肚皮,皮哥。
redo日志是啥
我们知道,InnoDB是以页为单位来管理存储空间的,增删查改其实都在访问页面(读页面、写页面、创建页面等操作),之前聊Buffer Pool时说过,操作前,都是将磁盘数据加载到缓冲区中,然后在操作,聊事务时,有个持久性(Durability)的特性,也就是事务提交后,系统崩溃,也不能丢失这个事务的修改。
如果简单粗暴的刷新16K的索引页,会造成性能浪费,并且页在Buffer Pool中以随机的方式存在,随机IO的刷新效果也差的多。而且也没必要每次事务提交时,将全部修改的页面刷新到磁盘上,只要把修改的内容记录一下就好,这样事务完成时,哪怕出现故障也可以快速恢复。
那么怎么去记录呢?比如,某个事务将user表中的第6条纪录的第8个字段的值由1修改为2,而假设物理地址在第6个页面中偏移量为88处,只需要记录:
将user表空间第6号页面中偏移量为88处的值更新为2.
这样事务提交时,这种记录空间使用极小,而且采用顺序写入磁盘。这就是redo log(redo日志)。
redo日志格式
根据上面我们可以想象到redo日志的格式,如下。
- type:这条redo 日志的类型。
- space ID:表空间id。
- page number:页号。
- data:这条日志的具体内容。
其实这也是通用的数据格式。为了节约空间,作者在type中也做了区分,分别是:
- MLOG_1BYTE(type对应的十进制数字为1):页面某个偏移量写入1个字节的redo日志类型。
- MLOG_2BYTE(type对应的十进制数字为2):页面某个偏移量写入2个字节的redo日志类型。
- MLOG_4BYTE(type对应的十进制数字为4):页面某个偏移量写入4个字节的redo日志类型。
- MLOG_8BYTE(type对应的十进制数字为8):页面某个偏移量写入8个字节的redo日志类型。具体如下:
- MLOG_WRITE_STRING(type对应的十进制数字为30):页面某个偏移量写入1个字节序列的redo日志类型。具体如下:
大家看到这里其实也会很好奇,这些数据格式如此简单,怎么满足其他复杂的场景呢?比如索引的修改、大批量数据删除时的场景呢?对于复杂的一些场景,作者也提出了一些新的redo日志类型。如下:
- MLOG_REC_INSERT(type对应的十进制数字为9):在插入一条使用非紧凑行格式(REDUNDANT)的记录。
- MLOG_COMP_REC_INSERT(type对应的十进制数字为38):在插入一条使用紧凑行格式(COMPACT、DYNAMIC、COMPRESSED)的记录。
- MLOG_COMP_PAGE_CREATE(type对应的十进制数字为58):在创建一条存储紧凑行格式的页面。
- MLOG_COMP_REC_DELETE(type对应的十进制数字为42):在删除一条使用紧凑行格式的记录。
- MLOG_COMP_LIST_START_DELETE(type对应的十进制数字为44):从某条给定记录开始删除页面中一系列使用紧凑行格式的记录。
- MLOG_COMP_LIST_END_DELETE(type对应的十进制数字为43):删除页面中一系列使用紧凑行格式的记录一直到redo 日志中对应的记录为止。
redo日志还有很多类型就不一一列举了,其实分这么种类型最主要的目的是节约资源提高性能,能不存就不存,这里给大家展示MLOG_COMP_REC_INSERT的数据结构。