boltdb源码阅读

2022-03-10 00:00:00 数据 操作 文件 事务 节点
本文作者:刘代明(常用网名:行如风,常用游戏名:学长的棉被),一个文艺青年(纳尼?青年?是的,你没看错:世界卫生组织(2020年)对青年的定义:18-65周岁[来自百度百科])。现在奇虎360搜索技术部任web服务端技术专家职位。 本文为作者原创,祝大家阅读愉快。

2021-1-26日更新:经提醒,漏了freelist,现补上


前言

近抽时间看了boltdb的源码,代码量不大(大概4000行左右),而且支持事务,结构也很清晰,由于比较稳定,已经归档,确实是学习数据库的佳选择。而且不少出名的开源项目在使用它,比如etcd,InfluxDB等。

本文记录下笔者在阅读源码后了解到的其工作原理,以留备忘。

简介

boltdb数据库是一款go开发的k/v数据库。其设计源于LMDB(Lightning Memory-Mapped Database),持久化到单文件中,通过mmap将文件映射到内存,这样读文件可以减少一次IO,但是写文件并不是通过mmap,而是通过调用写函数进行seek+write,后面会具体讲。

通过B+树进行索引。

按块写入,块的大小根据操作系统获得,大部分操作系统都是4k.

支持事务:多个读事务可以并发执行,但是写事务是串行的。

工作流程

一段简单使用代码如下:

path := "./bolt.db"
    db, err := bolt.Open(path, 0666, nil)
    if err != nil {
        fmt.Println("open db failed:", path, err)
        return
    }
    defer db.Close()

    tx, err := db.Begin(true)
    if err != nil {
        fmt.Println("begin trans failed:", err)
        return
    }
    defer tx.Rollback()

    bucket, err := tx.CreateBucketIfNotExists([]byte("nums"))
    if err != nil {
        fmt.Println("create bucket failed")
        return
    }
    kv := []byte("128")

    bucket.Put(kv, kv)

    val := bucket.Get(kv)
    fmt.Println(val)

    tx.Commit()

相关文章