环境
MacBook pro
前言
今天再看MySQL技术内幕
第二版书时,对二次写很疑惑;
明明有redo 文件,并且记录了所有的变化,而且还是物理日志;
为什么在断电的情况下,还是不能恢复数据?
查阅资料后,大体了解下,但是依然似懂非懂,做个笔记
日志的数据格式
这里给出网上说法:
物理日志
A. 记录完整的Page
B. 记录Page中被修改的部分(page中的偏移,内容和长度
逻辑日志
记录在关系(表)上的一个元组操作。
A. 插入一行记录。
B. 修改一行记录。
C. 删除一行记录。
逻辑日志比起物理的日志,显得简洁的多。而且占用的空间也要小的多。
逻辑物理日志
如果一个数据库操作(DDL,DML,DCL)产生的日志跨越了多个页面,那么会产生多个物理页面的日志,但对于每个物理页面日志,里面记录则是逻辑信息。这里我举一个简单的INSERT操作来说明几种日志形式。
举个例子的话就是:
比如:innodb表T(c1,c2, key key_c1(c1)),插入记录row1(1,’abc’)
逻辑日志:
<insert OP, T, 1,’abc’>
逻辑物理日志:
因为表T含有索引key_c1
, 一次插入操作至少涉及两次B树操作,二次B树必然涉及至少两个物理页面,因此至少有两条日志
<insert OP, page_no_1, log_body>
<insert OP, page_no_2, log_body>
物理日志:
由于一次INSERT操作,物理上来说要修改页头信息(如,页内的记录数要加1),要修改相邻记录里的链表指针,要修改Slot属性等,因此对应逻辑物理日志的每一条日志,都会有N条物理日志产生。
< group_id,file_id,page_no,offset1, value1>
< group_id,file_id,page_no,offset2, value2>
……
< group_id,file_id,page_no,offsetN, valueN>
为什么需要二次写
如果是纯物理日志格式,是完全可以做到的,
但是redo采用的是逻辑物理格式。
其每页都会才是一个物理日志,但是每个物理日志里面记录的又是逻辑信息。
这就导致,当发生页断裂时,即写某个页到磁盘时,系统断电了,导致只写了一部分,那么就会无法重做redo的情况。
比如 : 由于 innodb page
16K 一般系统是4K,当一个update语句需要对页内记录加1,当第一个4K中记录加1后,
系统挂了,重启恢复时候,因为页内是逻辑日志,只记录了要做加1操作,但是innodb不知道从哪里给记录加1,如果给16K里的所有记录加1,就会导致4K里面的记录加2,必然导致数据不一致。
也就是说 类似上面这中操作 页内记录数加1,还有 修改页头信息、slot信息修改
等操作而言,它们都要求页
是处于一个一致性的状态。
否则就无法正确重做redo。