同步写入 - Synchronous Writes

在默认情况下,levedb中的每一次写操作都是异步的:它会在把写入操作从进程中推送到操作系统后返回,而从操作系统内存到底层持久化存储的传输是异步的。对于特定的写操作,是可以打开同步sync标志使写操作一直到数据被传输到底层存储器后再返回。(在基于Posix标准的操作系统系统中,这一步是通过在写操作返回之前调用fsync(…)fdatasync(…)nsync(…, MS_SYNC)实现的。)

  1. leveldb::WriteOptions write_options;
  2. write_options.sync = true;
  3. db->Put(write_options, ...);

异步写操作一般比同步写操作快很多很多。但异步写入的缺点是,在机器宕机时有可能导致最后几步的更新丢失。请注意,如果是在写入过程中的宕机(而非重新启动),即使sync设置为false,更新操作也会认为已经将更新从内存中推送到了操作系统。

通常可以安全地使用异步写入。比如,当加载大量数据到数据库中时,可以通过在宕机后重新启动批量加载来处理丢失的更新。有一个可用的混合方案,将多次写入的第N次写入设置为同步的,并在宕机重启后的情况下,批量加载由前一次运行的最后一次同步写入之后重新开始。(同步写入时可以更新描述宕机后批量加载重新开始的标记。)

WriteBatch提供一个代替异步写操作的选择:将多个更新操作放置在同一个WriteBatch对象中然后使用同步写入一起应用(write_options.sync设置为ture);这时同步写入的额外成本开销将在这批次中所有的写入操作中摊销。