Asynchronous Leveldb:是否存在写后读危险?

Asynchronous Leveldb:是否存在写后读危险?,asynchronous,leveldb,Asynchronous,Leveldb,根据Leveldb的官方文件: 默认情况下,对leveldb的每次写入都是异步的:它在将写入从进程推送到操作系统后返回。从操作系统内存到底层持久存储的传输是异步进行的 所以我想知道是否会发生这样的先读后写危险: db->Put(leveldb::WriteOptions(),“key”,“value1”) (步骤1完成后)db->Put(leveldb::WriteOptions(),“key”,“value2”)//异步 db->Get(leveldb::ReadOptions(),“key”

根据Leveldb的官方文件:

默认情况下,对leveldb的每次写入都是异步的:它在将写入从进程推送到操作系统后返回。从操作系统内存到底层持久存储的传输是异步进行的

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

  • db->Put(leveldb::WriteOptions(),“key”,“value1”)
  • (步骤1完成后)
    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;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    使用名称空间std;
    leveldb::DB*DB;
    leveldb::选项;
    int main()
    {
    options.create_如果_missing=true;
    leveldb::DB::Open(选项“test.DB”、&DB);
    对于(int i=0;iGet(leveldb::ReadOptions(),“x”,&safter);
    断言(sbefore==safter);
    }
    }
    删除数据库;
    }
    
    在这种情况下,这个断言似乎总是正确的,但我不确定这是否是一条普遍规律

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

    [坏事]

    不,您不必担心。Put()记录在内存中,并在每次Get()时检查;读取不是直接从磁盘进行的。请参阅DBImpl::Get()的这一部分: