redo日志
作者:互联网
InnoDB存储引擎是以页为单位来管理存储空间的。在真正访问页面之前,需要将页面加载到Buffer Pool中。事务又具备一个持久性的特性,即在事务提交之后即使系统发生崩溃导致内存中的数据都丢失了,这个事务对数据库所作的修改也不能丢失。redo日志就是我们需要记录的事务对数据库所作的修改。
redo日志格式:
针对事务对数据库的不同的修改场景,定义了多种类型的redo日志。绝大多数redo日志都有以下的通用结构:
Type |
Space ID |
Page number |
data |
type:这条redo日志的类型
space ID:表空间ID
page number:页号
data:这条redo日志的具体内容
当用InnoDB记录行格式的时候,如果没有显式的定义主键,并且表中也没有定义为非null的unique键,那么InnoDB会主动为我们添加一个名为row_id的隐藏列作为主键。
row_id隐藏列的赋值方式:
服务器会在内存中维护一个全局变量,每当向包含row_id列的表中插入一条数据时,就会将这个全局变量值赋给row_id,并且全局变量自增一;
每当这个全局变量的值为256的倍数时,就会将改变量的值刷新到系统表空间页号为7的页面中一个属性为Max Row ID中;
当系统启动时,就会将这个Max Row ID属性加载到内存中,并将该值加上256后赋值给前面提到的全局变量。
简单的redo日志:
如上述提到的Max Row ID属性占用的存储空间是8字节,当这个属性改变时,就会向系统表空间为7的页面的相应偏移量处写入8字节的值。这个操作实际是在Buffer Pool中实现的,需要把这次对页面的修改记录在redo日志中。记录这种对页面的简单修改的redo日志称为物理日志。根据页面写入数据的多少划分了以下几种不同的redo日志:
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):表示在页面某个偏移量出写入了一个字节序列的redo日志类型;
前面提到的Max Row ID属性占用8字节,在修改页面中的这个属性时,会记录一条MLOG_8BYTE类型的redo日志。它的结构如下图所示:
MLOG_WRITE_STRING类型的日志不能确定具体数据占用多少字节,所以在日志中会添加一个len字段:
复杂一些的redo日志:
有时,执行一条语句时会修改非常多的页面。因此提出了一些新的redo日志。
MLOG_REC_INSERT(type字段对应的十进制数字为9):表示在插入一条使用非紧凑行格式记录时,redo日志类型。
MLOG_COMP_REC_INSERT(type字段对应的十进制数字为38):表示在插入一条使用紧凑行格式记录时,redo日志类型。
MLOG_COMP_PAGE_CREATE:(type字段对应的十进制数字为58):表示在创建一个存储紧凑行格式记录的页面时,redo日志的类型。
MLOG_COMP_REC_DELETE(type字段对应的十进制数字为42):表示在删除一条使用紧凑行格式记录时,redo日志的类型。
...
这些redo日志既包含了物理层面的意思,又包含了逻辑层面的意思。
从物理层面来看:这些redo日志声明了对哪个表空间的哪个页进行修改
从逻辑层面来看:在系统崩溃重启后,并不能直接根据这些日志的记载恢复某个数据,而是需要预先调用准备好的函数,执行完这些函数才能将页面恢复到崩溃前的样子。
以MLOG_COMP_REC_INSERT类型的redo日志为例:
参考:《MySql是怎样运行的》——小孩子4919
标签:MLOG,字段,type,日志,redo,页面 来源: https://www.cnblogs.com/codestart/p/16304900.html