2012年(27)
分类: 数据库开发技术
2012-04-17 09:13:24
WAL(write-ahead log,预写式日志)文件格式
WAL日志包括一个头和0到多个框(frames),每个框记录一个页(page)修改的内容。对数据库所有的修改都通过修改框的方式写入WAL日志。单个的WAL日志可记录多个事务。WAL日志中的内容会定期修改到数据库文件中,这个操作成为检查点。
单个WAL日志可多次使用。也就是说,WAL可以被框占满,当检查点动作过后,其他的框又能写到原来的位置上。WAL日志总是从开始到结尾顺序增长。附加到框后面的检查总数(checksums)和计数(counters)用来确定WAL中的那些框有效,哪些框是以前检查点动作操作完成的。
WAL头有32字节长,包括以下8个32位的大端无符号整数
0: Magic number. 0x377f0682 or 0x377f0683
4: File format version. Currently 3007000
8: Database page size. Example: 1024
12: Checkpoint sequence number
16: Salt-1, random integer incremented with each checkpoint
20: Salt-2, a different random integer changing with each ckpt
24: Checksum-1 (first part of checksum for first 24 bytes of header).
28: Checksum-2 (second part of checksum for first 24 bytes of header).
跟在WAL头上的是0到多个框。每个框由一个24字节的框头(frame-header)和一个页大小的页数据组成。框头是6个大端的32位无符号整数,如下:
0: Page number.
4: For commit records, the size of the database image in pages after the commit. For all other records, zero.
8: Salt-1 (copied from the header)
12: Salt-2 (copied from the header)
16: Checksum-1.
20: Checksum-2.
当一个框满足下面条件时,才被认为是有效的:
1. 在框头中Salt-1和salt-2的值跟在wal头里面的一致
2. 框头的最后的8个字节的校验和完全匹配一下内容的校验结果包括在WAL头上最开始的8个字节和当前框的所有内容。
如果WAL文件的开头4个字节是0x377f0683,那么校验和就使用32位的大端计算,如果是0x377f0682,则用小端计算。校验和始终存储在框头使用大端模式存储而无论使用什么模式计算的。校验和的计算方法如下:
for i from 0 to n-1 step 2:
s0 += x[i] + s1;
s1 += x[i+1] + s0;
endfor
请注意, S0和S1都以相反的顺序使用斐波纳契重的加权校验(斐波纳契的最大重量上的第一个元素被总结的顺序出现。 )的S1值跨越序列的所有32位,而S0省略了最后期限。
当进行检查点操作时,WAL检查点操作被VFS.xSync-ed调用,然后WAL有效的内容被执行到数据库里面。VFS.xSync操作可能导致写障碍,所有写入推出的xSync前必须完成前,任何写启动后xSync开始。
每个检查点操作之后,salt-1的值就会增加,salt-2的值是随机数。这在WAL中可以防止在同一时间被视为有效的和被检查点一起崩溃后的旧的和新的框架。