衔接上篇,本篇来讲讲 修改过程中的
redo log
,以及
LSN
前面讲 MTR
我们只提到 insert
对底层页面产生的原子操作。如果在执行过程中对记录发生了修改,有意思的事情就发生了:
- 不管怎么,页面都是刷到内存中操作;
- 存在内存 -> buffer pool【这块之前也说过】
- 直接改 bufferpool 中的页记录
- 改完这就是脏页了,加入 buffer pool 的
instance
的flu_list
就来说说 flu_list
和 LSN
的联系。
-
修改完缓存页,将页面对应的控制块插入
flu_list
-
写入
oldest_modification
,newest_modification
o_m
:第一次被修改时,对应的MTR
开始时对应的LSN
赋值给这个变量n_m
:每一次修改变量,对应的LSN
都会被写入到这
所以这里也暗示:不管被修改多少次,
flu_list
只会有第一次修改的控制块,此后都是不断修改n_m
-
插入控制块的顺序是头插法。所以越靠近末尾的
LSN
越小,越先被刷入磁盘。
Checkpoint
checkpoint
的设计就是为了在循环写入 ib_logfile0-N
过程中,标记哪些 redo log
以及是无用的【无用是指数据页已经刷盘了,真正持久化了,redo log 此时也就不需要再做什么宕机恢复啥的。】
这个时候引入:checkpoint_lsn
,代表当前系统中可以被覆盖的 redo
日志总量是多少。
来看看一次 checkpoint
的流程:
首先
redo log
如果被覆盖,说明脏页以及被刷盘。而脏页和LSN
联系的地方是:
flu_list
上的o_m, n_m
-
首先如果脏页已经刷盘,
flu_list
中一定是没有这个控制块了,那么flu_list
中最小的控制块【最后面的LSN
最小】是目前最新要刷盘的页。把目前最小的控制块的
o_m
赋值给checkpoint_lsn
。 -
将
checkpoint_lsn
和对应的redo log
的全局日志偏移量以及目前为止做了多少次checkpoint
这个次数,写入日志文件的管理信息中。
总结
总结一下 redo log
的特点和流程:
「特点」
- redo log 尽可能少,不然产生速度过快,脏页刷盘和log落盘都是很影响吞吐和性能的
- 因为不知道哪些 redo log 已经落盘,redo log 必须是可重入的,也就是 幂等性
- 为了可以加速重放,一个 redo log 只涉及到一个 page 的改动。所以实际存储的log file中存储的是修改的逻辑日志:
<page id, record offset, [update field(f1, v1)...]>
- redo log 分类:
page redo log, space redo log, extra logic redo log
「组织」
sn
每次增加一个mtr
的log,这个值就是加上当前的log量。【指向当前写入的最后量】lsn
这个值会加上blockheader & blocktrailer
,每496b为一个单位划分【逻辑增长,这个不会被物理上的log循环给截断】ib_logfile
这个默认是2,所以是物理循环的。lsn
每增长两个就会换到下一个文件继续写。
未完待续。。。