Leveldb:是否存在写后读风险?

Leveldb: does read-after-write hazard exist?

根据Leveldb官方文档:

By default, each write to leveldb is asynchronous: it returns after pushing the write from the process into the operating system. The transfer from operating system memory to the underlying persistent storage happens asynchronously.

所以我想知道是否会发生这样的写后读危害:

  1. db->Put(leveldb::WriteOptions(), "key", "value1");
  2. (Step1完成后)db->Put(leveldb::WriteOptions(), "key", "value2");//异步
  3. db->Get(leveldb::ReadOptions(), "key", &result);//有没有可能result == "value1"而不是"value2"?

我写了一个程序来测试它:

#include <iostream>
#include <leveldb/db.h>
#include <sstream>
#include <cstdlib>
#include <cassert>

using namespace std;
leveldb::DB* db;
leveldb::Options options;

int main()
{
    options.create_if_missing = true;
    leveldb::DB::Open(options, "test.db", &db);
    for(int i=0; i<10000000; ++i)
    {
        stringstream ss;
        ss << i;
        string sbefore = ss.str();
        db->Put(leveldb::WriteOptions(), "x", sbefore);
        if (!(std::rand() % 4))
        {
            string safter;
            db->Get(leveldb::ReadOptions(), "x", &safter);
            assert(sbefore == safter);
        }
    }
    delete db;
}

在这种情况下似乎断言总是正确的,但我不确定这是否是一般规则。

So I was wondering whether read-after-write hazard would happen like this:

[Bad things]

不,您不必为此担心。 Put()s 记录在内存中,并在每个 Get() 时检查;读取不是直接从磁盘。请参阅 DBImpl::Get() 的这一部分: https://github.com/google/leveldb/blob/dac40d25f6ce69c8b6685ab09f240cb63cfd5ab3/db/db_impl.cc#L1135