rocksdb icon indicating copy to clipboard operation
rocksdb copied to clipboard

DeleteRange doesn't work well with row_cache

Open jonahgao opened this issue 6 years ago • 4 comments

Expected behavior & Actual behavior

when row_cache is enabled,
after we delete a key by a DeleteRange call,
we can still Get the key and its value from the db

Steps to reproduce the behavior

#include <iostream>
#include <rocksdb/db.h>

int main() {
    rocksdb::Options ops;
    ops.max_write_buffer_number = 1;
    ops.create_if_missing = true;
    ops.row_cache = rocksdb::NewLRUCache(1024);

    rocksdb::DB *db = nullptr;
    auto s = rocksdb::DB::Open(ops, "./db", &db);
    assert(s.ok());

    const std::string key = "mykey";

    s = db->Put(rocksdb::WriteOptions(), key, "myvalue");
    assert(s.ok());

    // flush so we can use the row cache, not memtable
    s = db->Flush(rocksdb::FlushOptions());
    assert(s.ok());
    std::string value;
    s = db->Get(rocksdb::ReadOptions(), key, &value);
    assert(s.ok());

    s = db->DeleteRange(rocksdb::WriteOptions(), db->DefaultColumnFamily(), "a", "z");
    assert(s.ok());

    value.clear();
    s = db->Get(rocksdb::ReadOptions(), key, &value);
    // status should be NotFound, but the program's output is an OK
    std::cout << "status: " << s.ToString() << ", value: " << value << std::endl;

    return 0;
}

jonahgao avatar Jul 12 '18 14:07 jonahgao

Thanks for reporting. I think the most we can promise right now is making it explicitly unsupported, i.e., disallow range deletions when row cache is enabled. If you want to contribute code for purging the row cache when DeleteRange happens, we should be able to review and land it.

ajkr avatar Jul 12 '18 17:07 ajkr

Thank for your reply @ajkr , I'll look into this and try to fix it.

jonahgao avatar Jul 13 '18 08:07 jonahgao

@ajkr Could you tell me which PR fix this BUG, thanks?

XinzeChi avatar Feb 03 '24 05:02 XinzeChi

Re-open the issue so we remember to add some safeguard before it's supported.

The above test passes now. But if DeleteRange() and row key is from the same SST file, then it still fails.

const Snapshot* snap = db_->GetSnapshot();
ASSERT_OK(db_->DeleteRange(rocksdb::WriteOptions(),
                           db_->DefaultColumnFamily(), "a", "z"));
ASSERT_OK(Flush());

std::string value;
Status s = db_->Get(ReadOptions(), "a", &value);
std::cout << "status: " << s.ToString() << ", value: " << value << std::endl;
value.clear();
s = db_->Get(ReadOptions(), "a", &value);

// status should be NotFound, but the program's output is an OK
std::cout << "status: " << s.ToString() << ", value: " << value << std::endl;


status: NotFound: , value:
status: OK, value: myval

cbi42 avatar Apr 05 '24 21:04 cbi42