doc: 阅读redo log document
This commit is contained in:
@@ -201,3 +201,54 @@ redo log头部格式通常包含3部分:
|
|||||||
|
|
||||||
之后redo log body部分,根据重做日志类型的不同会存储不同内容。
|
之后redo log body部分,根据重做日志类型的不同会存储不同内容。
|
||||||
|
|
||||||
|
#### LSN
|
||||||
|
LSN代表的是日志序列号,其大小为8字节,且单调递增。`LSN代表事务写入redo log的总字节数`。
|
||||||
|
|
||||||
|
##### 页LSN
|
||||||
|
在每个页的头部,都存在`FIL_PAGE_LSN`,其记录了该页的lsn。在页中,`LSN`代表该页最后刷新时的lsn大小。
|
||||||
|
|
||||||
|
FIL_PAGE_LSN在`buffer pool page`和`disk page`中均存在,二者记录的值不同:
|
||||||
|
- `buffer pool page` header中`FIL_PAGE_LSN`记录的是`内存页最后被修改的LSN`
|
||||||
|
- `disk page` header中`FIL_PAGE_LSN`记录的是最后被刷新到磁盘的页对应的最大修改LSN
|
||||||
|
|
||||||
|
在执行crash recovery过程中,会从CHECKPOINT开始,一直到redo log file末尾,逐条处理redo log record,对于每条redo log record关联的页,会比较`record_lsn`和`FIL_PAGE_LSN`的大小:
|
||||||
|
- `record_lsn <= FIL_PAGE_LSN`:代表当前redo record对应的修改已经包含在页中,当前redo log record直接跳过即可
|
||||||
|
- `record_lsn > FIL_PAGE_LSN`:代表当前redo record中的修改不存在于页中,需要对页应用record修改,并在修改完后更新页的`FIL_PAGE_LSN`
|
||||||
|
|
||||||
|
##### 查看LSN
|
||||||
|
可以通过`show engine innodb status`来查看LSN情况,核心数值如下:
|
||||||
|
- `log sequence number`:代表当前LSN
|
||||||
|
- `log flushed up to`: 代表已经刷新到磁盘文件中的LSN
|
||||||
|
- `last checkpoint at`: 代表页已经刷新到磁盘的LSN
|
||||||
|
|
||||||
|
#### recovery
|
||||||
|
innodb在启动时,`不管上次数据库运行是否正常关闭,都会尝试执行恢复`。
|
||||||
|
|
||||||
|
`redo log是物理日志,故而恢复速度相较逻辑日志要快得多`,恢复操作仅需从`checkpoint`开始。
|
||||||
|
|
||||||
|
例如,对于如下数据表
|
||||||
|
```sql
|
||||||
|
create table t (
|
||||||
|
a int,
|
||||||
|
b int,
|
||||||
|
primary key(a),
|
||||||
|
key(b)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
若执行sql语句
|
||||||
|
```sql
|
||||||
|
insert into t select 1,2;
|
||||||
|
```
|
||||||
|
在执行时,需要修改如下内容:
|
||||||
|
- 聚簇索引页(包含数据)
|
||||||
|
- 辅助索引页
|
||||||
|
|
||||||
|
故而,其记录重做日志内容大致为
|
||||||
|
```
|
||||||
|
page(2,3), offset 32, value 1,2; # 聚簇索引页
|
||||||
|
page(2,4), offset 64, value 2; # 辅助索引页
|
||||||
|
```
|
||||||
|
由上述示例可知,redo log为物理日志,记录的是对页的物理修改,故而`redo log是幂等的`。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user