redo
redo日志会把事务在执行过程中对数据库所做的所有修改都记录下来,在之后系统崩溃重启后可以把事务所做的任何修改都恢复出来。
redo日志占用的空间非常小且是顺序写入磁盘的;
- 存储表空间ID、页号、偏移量以及需要更新的值所需的存储空间是很小的
- 每执行一条语句就可能产生若干条redo日志
格式
-
type
:该条redo
日志的类型。 -
space ID
:表空间ID。 -
page number
:页号。 -
data
:该条redo
日志的具体内容。
把一条记录插入到一个页面时需要更改的地方非常多,除了数据要修改以外,还有什么File Header
、Page Header
、Page Directory
等等部分都需要修改。
有的原子性操作会生成多条redo日志,需要分到同一个组内执行,会再最后一条redo日志后边加上一条特殊类型的redo日志,一组redo日志必须要以这个类型的redo日志为结尾。相当于分隔符
mtr:Mini-Transaction,向某个索引对应的
B+树中插入一条记录的过程也算是一个
Mini-Transaction
redo日志写入过程
block
通过mtr
生成的redo
日志都放在了大小为512字节
的页
中叫redo log block
redo日志缓冲区
- 会申请一片redo log buffer,被划分成若干个连续的redo log block,写到log buffer中的redo日志是顺序的,先在前面的block中写,如果写满了,就往下一个写,所以有buf_free全局变量来标识redo应该写到哪个位置了。有可能会追尾,写到最早的block里(写满了的话)
- 且写的时候往往是一个mtr的一组redo日志一起写。而且因为事务是可以并发执行的,所以不同事务的mtr可能是交替写入log buffer的
redo日志的刷盘时机
- log buffer空间不足
- 事务提交时
- 后台线程定时刷新(1s)
- checkpoint
- 关闭
LSN(log sequence number):初始为8704,表示redo日志所写到的位置,所以每一组mtr生成的redo都有唯一一个LSN,值越小说明redo日志越早
flushed_to_disk_lsn:已刷新到磁盘的redo log地址。
checkpoint:redo日志追尾!如果redo对应的脏页已经刷新到磁盘,则这一段redo已经没有用了,可以被后续的redo重用。checkpoint_lsn就是用来记录当前可以覆盖的redo对应的lsn值。
- 如果来不及从做checkpoint,则需要从flush链表中把那些最早修改的脏页刷新到磁盘。
redo日志的使用:崩溃恢复后,需要读取使用的redo日志可能很多,分布在不同的页,会把他们根据页号和空间号做hash放到hash表里,相同的key对应的redo日志放在同一个key的链表中,恢复的时候遍历哈希表,对每个页进行redo日志执行(且需要按照顺序)。