RocksDB 源码分析 – WAL

WAL

RocksDBWAL 格式和 LevelDB 相同,划分为固定大小的 block,用 crc32c 校验。写 WAL 时会禁用 mmap()direct I/O,见 env_posix.cc:OptimizeForLogWrite(),看来是性能不好或者效果不明显。 WAL 还会设置 write time life hintfcntl(fd, F_SET_RW_HINT, RWH_WRITE_LIFE_SHORT),具体作用不太清楚,man page 描述也很模糊。也会用 fallocate() 预先分配空间,preallocation block size 是根据 write buffer sizemax_total_wal_size 等配置计算的。

刷盘

WAL 的刷盘策略可配:

  • 设置 WriteOptions::sync,写完后立刻刷盘。
  • 设置 DBOptions::wal_bytes_per_sync,每写一定数据会刷盘。
  • 最后是由操作系统来刷盘。

manual_wal_flush

WAL 是用 WritableFileWriter 写的,内部会用 AlignedBuffer 缓冲数据,只有当 buffer 满了或者主动 flushsync 时才会真正写文件,buffer 的最大大小由 DBOptions::writable_file_max_buffer_size 配置。 一般情况下每次都会 flush,但可以配置 DBOptions::manual_wal_flush,主动调 flushWAL() 或者 buffer 满了时才写文件,在某些场景下可提高性能,如 MyRocks2pc,见 FlushWAL; less fwrite, faster writes

TODO

几个问题先留着,等后面看到时再补充:

  • WAL 切换:LevelDBmemtable 满了后,切到新的 memtable + WAL,而 RocksDBcolumn family,当 flush 时,会切到新的 WAL;当 WAL 大小超过 DBOptions::max_total_wal_size 也会切换。
  • WAL 清理:LevelDBmemtable compaction 完成,WAL 可以删。RocksDB 不是立即删除的,而是先 archive,根据配置 DBOptions::WAL_ttl_seconds, DBOptions::WAL_size_limit_MB 清理,好像是为了 replication
  • 复用之前的 WAL,见 DBOptions::recycle_log_file_num
  • 最近好像才实现写失败的 recovery,见 db/error_handler

分类:

更新时间: