doc: 阅读mysql文档

This commit is contained in:
asahi
2025-06-30 00:35:19 +08:00
parent 8e90e58987
commit 26d4122be9
2 changed files with 53 additions and 6 deletions

View File

@@ -107,5 +107,56 @@ redo log和 bin log日志写入磁盘的时机也有所不同
`innodb_flush_log_at_trx_commit`参数设置为`0``2`虽然可以在一定幅度上提高性能但是会丧失数据库的ACID特性。
#### log block
在innodb中redo都是以512字节的大小为单位进行存储的即redo log buffer、redo log file都是以block的形式进行保存block的大小为512字节。
##### block & atomic
若针对相同的页redo log的大小大于512字节那么其会被分割为多个block进行存储。且由于redo log block的大小和磁盘扇区相同故而在将block时无需使用double write机制针对特定的block起写入为原子的要么写入成功要么写入失败不会像页page一样存在dirty的情况。
redo log block中包含的内容除了日志本身外还包含`log block header``log block tailer`内容。`log block header + log block content + log block tailer`合计占用512字节其中各部分大小如下
- `log block header`: 12字节大小
- `log block content`: 492字节大小
- `log block tailer`: 8字节大小
如上所示每个redo log block可实际存储的内容大小为492字节。
##### log block header
log block header大小为12字节由如下部分组成
- `LOG_BLOCK_HDR_NO`: 占用4字节
- `LOG_BLOCK_HDR_DATA_LEN`: 占用2字节
- `LOG_BLOCK_FIRST_REC_GROUP`: 占用2字节
- `LOG_BLOCK_CHECKPOINT_NO`: 占用4字节
###### `LOG_BLOCK_HDR_NO`
log buffer由log block所组成可以将log buffer看作是log block的数组故而log block header中`LOG_BLOCK_HDR_NO`起代表当前block在buffer中的位置。
`LOG_BLOCK_HDR_NO`由于表示的是log buffer中的数组小标故而可知`LOG_BLOCK_HDR_NO`其是递增的,并且可以循环使用。`LOG_BLOCK_HDR_NO`的大小为4字节但是其首位用作`flush bit`,故而,其可表示的最大长度为`2^31 bytes = 2GiB`
##### `LOG_BLOCK_HDR_DATA_LEN`
`LOG_BLOCK_HDR_DATA_LEN`大小为2字节代表`log block`所占用的大小当log block被写满时该值为`0x200`表示当前log block使用完`block`中所有的可用空间即log block的大小为512字节。
##### `LOG_BLOCK_FIRST_REC_GROUP`
`LOG_BLOCK_FIRST_REC_GROUP`占用2个字节表示log block中第一个日志所处的偏移量。
`LOG_BLOCK-FIRST_REC_GROUP`的取值可能存在如下场景:
- 该值大小和`LOG_BLOCK_HDR_DATA_LEN`相同则代表当前block中`不包含新的日志`
下图表示`事务T1的重做日志占用762字节``事务T2的重做日志占用100字节`的场景。
<img alt="" class="has" src="https://i-blog.csdnimg.cn/blog_migrate/41c0ed462afe1e9d56e1e53f11175f9a.jpeg">
由于每个block中最多只能保存492字节的数据故而T1事务的762字节需要分布在两个block中第一个block保存492字节的数据第二个block中保存剩余270字节的数据。
- 其中左侧的block`LOG_BLOCK_FIRST_REC_GROUP`值为12代表第一个record开始的位置紧接在log block header之后
- 而右侧的block`LOG_BLOCK_FIRST_REC_GROUP`的值为`12 + 270 = 282 bytes`。在存放第一条record之前不仅有log block header对应的12字节还有之前T1剩余日志的270字节
##### `LOG_BLOCK_CHECKPOINT_NO`
`LOG_BLOCK_CHECKPOINT_NO`占用4字节大小代表log block最后被写入时的检查点第四字节的值。
LSNlog sequence number为一个`全局唯一且单调递增的64位数字当发生数据修改时redo log内容会增加此时LSN也会增加`
CHECKPOINT则是一个LSN值同样为64位整数代表位于`CHECKPOINT`之前所有的修改已经被持久化到数据库中,`位于CHECKPOINT之前的redo log内容可以被安全的覆盖`