RocksDB 源码分析 – WAL
WAL
RocksDB
的 WAL
格式和 LevelDB
相同,划分为固定大小的 block
,用 crc32c
校验。写 WAL
时会禁用 mmap()
和 direct I/O
,见 env_posix.cc:OptimizeForLogWrite()
,看来是性能不好或者效果不明显。
WAL
还会设置 write time life hint
:fcntl(fd, F_SET_RW_HINT, RWH_WRITE_LIFE_SHORT)
,具体作用不太清楚,man page
描述也很模糊。也会用 fallocate()
预先分配空间,preallocation block size
是根据 write buffer size
、max_total_wal_size
等配置计算的。
刷盘
WAL
的刷盘策略可配:
- 设置
WriteOptions::sync
,写完后立刻刷盘。 - 设置
DBOptions::wal_bytes_per_sync
,每写一定数据会刷盘。 - 最后是由操作系统来刷盘。
manual_wal_flush
WAL
是用 WritableFileWriter
写的,内部会用 AlignedBuffer
缓冲数据,只有当 buffer
满了或者主动 flush
、sync
时才会真正写文件,buffer
的最大大小由 DBOptions::writable_file_max_buffer_size
配置。
一般情况下每次都会 flush
,但可以配置 DBOptions::manual_wal_flush
,主动调 flushWAL()
或者 buffer
满了时才写文件,在某些场景下可提高性能,如 MyRocks
的 2pc
,见 FlushWAL; less fwrite, faster writes。
TODO
几个问题先留着,等后面看到时再补充:
WAL
切换:LevelDB
是memtable
满了后,切到新的memtable + WAL
,而RocksDB
有column family
,当flush
时,会切到新的WAL
;当WAL
大小超过DBOptions::max_total_wal_size
也会切换。WAL
清理:LevelDB
当memtable compaction
完成,WAL
可以删。RocksDB
不是立即删除的,而是先archive
,根据配置DBOptions::WAL_ttl_seconds, DBOptions::WAL_size_limit_MB
清理,好像是为了replication
。- 复用之前的
WAL
,见DBOptions::recycle_log_file_num
。 - 最近好像才实现写失败的
recovery
,见db/error_handler
。
留下评论