RocksDB 选项文件
在 RocksDB 4.3中,我们添加了一组功能,使管理rocksdb选项更加容易。
在每次成功调用DB::Open(), SetOptions(), 和 CreateColumnFamily() / DropColumnFamily() 时, 每个 RocksDB 数据库都会自动将其当前选项集保存到一个文件中。
LoadLatestOptions()/LoadOptionsFromFile() (https://github.com/facebook/rocksdb/blob/master/include/rocksdb/utilities/options_util.h#L20-L58) : 从选项文件构造rocksdb options对象的函数。
CheckOptionsCompatibility (https://github.com/facebook/rocksdb/blob/master/include/rocksdb/utilities/options_util.h#L64-L77) : 对两组RocksDB选项执行兼容性检查的函数。
有了上述选项文件支持,开发人员不再需要维护以前创建的rocksdb实例的完整选项集。 此外,当需要更改选项时,checkOptionsCompatibility() 可以进一步确保生成的选项集可以成功打开同一RocksDB数据库,而不会损坏基础数据。
例子
下面是一个正在运行的示例,展示了新特性如何使管理RocksDB选项变得更容易。 更完整的示例可以在examples/options_file_example.cc中找到。( https://github.com/facebook/rocksdb/blob/master/examples/options_file_example.cc )
假设我们打开一个RocksDB数据库,在数据库运行时动态创建一个新的列族,然后关闭数据库:
s = DB::Open(rocksdb_options, path_to_db, &db);
...
// Create column family, and rocksdb will persist the options.
ColumnFamilyHandle* cf;
s = db->CreateColumnFamily(ColumnFamilyOptions(), "new_cf", &cf);
...
// close DB
delete cf;
delete db;
由于在RocksDB 4.3或更高版本中,每个RocksDB实例都会自动将其最新的一组选项存储到一个选项文件中,所以我们可以在下次打开数据库时使用该文件构造选项。 这与RocksDB 4.2或更早的版本不同,在后者中,我们需要记住每个列族的所有选项,以便成功地打开一个DB。现在让我们看看它是如何工作的。
首先,我们调用LoadLatestOptions()来加载目标RocksDB数据库使用的最新一组选项:
DBOptions loaded_db_opt;
std::vector<ColumnFamilyDescriptor> loaded_cf_descs;
LoadLatestOptions(path_to_db, Env::Default(), &loaded_db_opt,
&loaded_cf_descs);
不支持选项
由于C++没有反射,下面的用户定义函数和指针类型选项将只使用默认值初始化。 详细信息可以在rocksdb/utilities/options_util.h中找到:
* env
* memtable_factory
* compaction_filter_factory
* prefix_extractor
* comparator
* merge_operator
* compaction_filter
* cache in BlockBasedTableOptions
* table_factory other than BlockBasedTableFactory
对于那些不受支持的用户定义函数,开发人员需要手动指定它们。 在这个例子中,我们在BlockBasedTableOptions和CompactionFilter中初始化缓存:
for (size_t i = 0; i < loaded_cf_descs.size(); ++i) {
auto* loaded_bbt_opt = reinterpret_cast<BlockBasedTableOptions*>(
loaded_cf_descs[0].options.table_factory->GetOptions());
loaded_bbt_opt->block_cache = cache;
}
loaded_cf_descs[0].options.compaction_filter = new MyCompactionFilter();
现在我们执行完整性检查,以确保一组选项是安全的,以打开目标数据库:
Status s = CheckOptionsCompatibility(
kDBPath, Env::Default(), db_options, loaded_cf_descs);
如果返回值表示OK状态,我们可以继续使用加载的选项集打开目标RocksDB数据库:
s = DB::Open(loaded_db_opt, kDBPath, loaded_cf_descs, &handles, &db);
忽略未知选项
如果新版本的选项文件与旧版本的RocksDB一起使用(例如,由于bug降级时),旧版本的RocksDB可能不知道一些新选项。 ignore_unknown_options标志可用于处理此类情况。ignore_unknown_options被添加为LoadLatestOptions、LoadOptionsFromFile、CheckOptionsCompatibility、GetDBOptionsFromMap、GetColumnFamilyOptionsFromMap、GetBlockBasedTableOptionsFromMap和GetPlainTableOptionsFromMap的参数。 默认情况下,它被设置为false。
RocksDB选项文件格式
RocksDB选项文件是一个遵循INI文件格式的文本文件。 每个RocksDB选项文件都有一个版本节、一个DBOptions节以及每个列族的一个CFOptions和TableOptions节。 下面是一个示例RocksDB选项文件。完整的例子可以在examples/rocksdb_option_file_example.ini中找到:
[Version]
rocksdb_version=4.3.0
options_file_version=1.1
[DBOptions]
stats_dump_period_sec=600
max_manifest_file_size=18446744073709551615
bytes_per_sync=8388608
delayed_write_rate=2097152
WAL_ttl_seconds=0
...
[CFOptions "default"]
compaction_style=kCompactionStyleLevel
compaction_filter=nullptr
num_levels=6
table_factory=BlockBasedTable
comparator=leveldb.BytewiseComparator
compression_per_level=kNoCompression:kNoCompression:kNoCompression:kSnappyCompression:kSnappyCompression:kSnappyCompression
...
[TableOptions/BlockBasedTable "default"]
format_version=2
whole_key_filtering=true
skip_table_builder_flush=false
no_block_cache=false
checksum=kCRC32c
filter_policy=rocksdb.BuiltinBloomFilter
....