我发现重新打开以某种方式创建的数据库时出现以下错误。
Invalid argument: leveldb.BytewiseComparator: does not match existing comparator
我相信这是因为在不指定 CF 的情况下打开数据库时,会在不使用自定义选项的情况下创建默认 CF。 我认为问题可能出在代码中https://github.com/rust-rocksdb/rust-rocksdb/blob/master/src/db.rs#L214 。
一个可能的解决方法是将检查https://github.com/rust-rocksdb/rust-rocksdb/blob/master/src/db.rs#L219在empty
检查之前移动并添加默认值到 cf 字符串列表。
重现步骤:
感谢您的报告!
我要看看这个问题。 不幸的是,我认为您的建议不会奏效,因为所有列族(不仅是默认列族)都使用默认选项:
https://github.com/rust-rocksdb/rust-rocksdb/blob/master/src/db.rs#L123
似乎应该为每个列族分别提供一个比较器。 似乎我们需要为这种情况提供稍微不同的 API。
谢谢@DarkEld3r。 我也有同样的想法。 老实说,我很困惑为什么比较器完全出于您给出的确切原因而工作。 我认为它有机会修复它,因为当它遍历条件的 else 侧时发生了任何魔法。
老实说,我很困惑为什么比较器完全出于您给出的确切原因而工作。
我想您已经使用create_cf
调用创建了列族,并使用了与 DB 相同的选项? 这些选项被传递给rocksdb,所以我想这就是一切都按预期工作的原因。
@zach-schoenberger 您在步骤 4 中使用什么方法打开数据库?
@zach-schoenberger 看看这里。
@aleksuss谢谢,我完全错过了open_cf_descriptors
功能。 我可以确认以下内容对我有用:
let path = "...";
fn comparator(left: &[u8], right: &[u8]) -> Ordering {
right.cmp(left)
}
let mut options = Options::default();
options.create_if_missing(true);
options.set_comparator("comparator", comparator);
{
let mut db = DB::open(&options, &path).expect("Unable to create a DB");
db.create_cf("cf1", &options).expect("Unable ");
}
{
let mut cf_options = Options::default();
cf_options.set_comparator("comparator", comparator);
let descriptors = vec![ColumnFamilyDescriptor::new("cf1", cf_options)];
let _ = DB::open_cf_descriptors(&options, &path, descriptors);
}
有趣的。 一开始我绝对不会这么想的。 我将更新以使用上述内容。 对我来说绝对不是直觉。 我正在使用 DB::open_cf() 和 DB::open()。 通过仅包含带有初始 DB::open_cf 而不是 DB::open 的“默认”cf 名称,我确实让我的原始场景看起来可以工作,但我更喜欢上面的内容,因为它似乎尊重这些选项。
最有用的评论
@zach-schoenberger 看看这里。