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数据库,在数据库运行时动态创建一个新的列族,然后关闭数据库:

  1. s = DB::Open(rocksdb_options, path_to_db, &db);
  2. ...
  3. // Create column family, and rocksdb will persist the options.
  4. ColumnFamilyHandle* cf;
  5. s = db->CreateColumnFamily(ColumnFamilyOptions(), "new_cf", &cf);
  6. ...
  7. // close DB
  8. delete cf;
  9. delete db;

由于在RocksDB 4.3或更高版本中,每个RocksDB实例都会自动将其最新的一组选项存储到一个选项文件中,所以我们可以在下次打开数据库时使用该文件构造选项。 这与RocksDB 4.2或更早的版本不同,在后者中,我们需要记住每个列族的所有选项,以便成功地打开一个DB。现在让我们看看它是如何工作的。

首先,我们调用LoadLatestOptions()来加载目标RocksDB数据库使用的最新一组选项:

  1. DBOptions loaded_db_opt;
  2. std::vector<ColumnFamilyDescriptor> loaded_cf_descs;
  3. LoadLatestOptions(path_to_db, Env::Default(), &loaded_db_opt,
  4. &loaded_cf_descs);

不支持选项

由于C++没有反射,下面的用户定义函数和指针类型选项将只使用默认值初始化。 详细信息可以在rocksdb/utilities/options_util.h中找到:

  1. * env
  2. * memtable_factory
  3. * compaction_filter_factory
  4. * prefix_extractor
  5. * comparator
  6. * merge_operator
  7. * compaction_filter
  8. * cache in BlockBasedTableOptions
  9. * table_factory other than BlockBasedTableFactory

对于那些不受支持的用户定义函数,开发人员需要手动指定它们。 在这个例子中,我们在BlockBasedTableOptions和CompactionFilter中初始化缓存:

  1. for (size_t i = 0; i < loaded_cf_descs.size(); ++i) {
  2. auto* loaded_bbt_opt = reinterpret_cast<BlockBasedTableOptions*>(
  3. loaded_cf_descs[0].options.table_factory->GetOptions());
  4. loaded_bbt_opt->block_cache = cache;
  5. }
  6. loaded_cf_descs[0].options.compaction_filter = new MyCompactionFilter();

现在我们执行完整性检查,以确保一组选项是安全的,以打开目标数据库:

  1. Status s = CheckOptionsCompatibility(
  2. kDBPath, Env::Default(), db_options, loaded_cf_descs);

如果返回值表示OK状态,我们可以继续使用加载的选项集打开目标RocksDB数据库:

  1. 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中找到:

  1. [Version]
  2. rocksdb_version=4.3.0
  3. options_file_version=1.1
  4. [DBOptions]
  5. stats_dump_period_sec=600
  6. max_manifest_file_size=18446744073709551615
  7. bytes_per_sync=8388608
  8. delayed_write_rate=2097152
  9. WAL_ttl_seconds=0
  10. ...
  11. [CFOptions "default"]
  12. compaction_style=kCompactionStyleLevel
  13. compaction_filter=nullptr
  14. num_levels=6
  15. table_factory=BlockBasedTable
  16. comparator=leveldb.BytewiseComparator
  17. compression_per_level=kNoCompression:kNoCompression:kNoCompression:kSnappyCompression:kSnappyCompression:kSnappyCompression
  18. ...
  19. [TableOptions/BlockBasedTable "default"]
  20. format_version=2
  21. whole_key_filtering=true
  22. skip_table_builder_flush=false
  23. no_block_cache=false
  24. checksum=kCRC32c
  25. filter_policy=rocksdb.BuiltinBloomFilter
  26. ....