Notes on BoltDB
BoltDB 实现了一个 COW BTree, 本身功能比较简单, 代码也比较简洁。我们进入代码之前,可以先讲讲它的大致流程。
这篇文章写的时候,已经有一篇很好的博客了:https://youjiali1995.github.io/storage/boltdb/
我不打算讲的那么细,就介绍一下大致的流程。
API
在讨论实现之前,先要理解 boltdb api, 庆幸的是,这部分逻辑比较简单,可以看看这里:https://www.zupzup.org/boltdb-example/
磁盘读写
BoltDB 用 pwrite(3)
来写盘,用 mmap(2)
来读盘。它会先 mmap
映射一块比较大的空间,然后每次写的时候,调用 pwrite(3)
来写。
这里要说到 Buffer 管理了。成熟的存储引擎大部分自己实现了一份 Buffer Pool Manager 来管理内存。BoltDB 比较小巧,利用了 mmap(2)
的文件映射,在只读模式下打开数据库文件,然后读取对应的内容。
Golang 的 syscall.Mmap
有 mmap 的功能,但是 CGo 和 syscall.Mmap
申请的内存都不由 Go runtime 管,应该是直接由 OS 管的你需要手动的去负责它们,比如下面的 case:
mmap
可以映射大于本文件的空间,pwrite
写大于文件的空间的时候,行为类似 lseek
,会把文件撑大。db 的元信息会记录文件分配的 size, 那么,BoltDB 会重新调用 DB.mmap
,来重新映射。这个时候 BoltDB 会对内存的内容走一次 dereference
,这个调用会把 mmap
的内容拷贝一份,然后解除对 mmap 的 []byte
的引用。
磁盘结构
别的文章应该已经介绍过磁盘结构详细的 align 了,我就讲讲大致流程。
bolt 的磁盘结构以 page 为组织单位,page 的大小是
page 有下面几种:
const (
branchPageFlag = 0x01
leafPageFlag = 0x02
metaPageFlag = 0x04
freelistPageFlag = 0x10
)
相关文章