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.
所以我想知道是否会发生这样的写后读危害:
db->Put(leveldb::WriteOptions(), "key", "value1");
- (Step1完成后)
db->Put(leveldb::WriteOptions(), "key", "value2");
//异步
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
根据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.
所以我想知道是否会发生这样的写后读危害:
db->Put(leveldb::WriteOptions(), "key", "value1");
- (Step1完成后)
db->Put(leveldb::WriteOptions(), "key", "value2");
//异步 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