C++ 备份正在运行的rocksdb实例

C++ 备份正在运行的rocksdb实例,c++,rocksdb,C++,Rocksdb,我希望以安全的方式将正在运行的rocksdb实例备份到同一磁盘上的某个位置,并且在备份过程中不会中断处理 我读过: rocksdb/utilities/{checkpoint.h,backupable_db.{h,cc}中的文档 我的问题是,对CreateNewBackupWithMetadata的调用是否标记为非线程安全,以表示对此函数的两个并发调用将具有不安全行为,或者表示对数据库的任何并发调用都将不安全。我已经检查了实现,它似乎正在创建一个检查点——第二篇文章声称它用于MyRock

我希望以安全的方式将正在运行的rocksdb实例备份到同一磁盘上的某个位置,并且在备份过程中不会中断处理

我读过:

  • rocksdb/utilities/{checkpoint.h,backupable_db.{h,cc}中的文档
我的问题是,对
CreateNewBackupWithMetadata
的调用是否标记为非线程安全,以表示对函数的两个并发调用将具有不安全行为,或者表示对数据库的任何并发调用都将不安全。我已经检查了实现,它似乎正在创建一个检查点——第二篇文章声称它用于MyRocks的在线备份——但我仍然不确定,调用的哪一部分不是线程安全的

我目前认为这是不安全的,因为
CreateBackup…
调用
DisableFileDeletions
和更高版本的
EnableFileDeletions
,当然,如果进行两个重叠调用,可能会导致问题。由于SST文件是不可变的,我不担心它们,但不确定通过插入修改WAL是否会损坏备份。我认为触发备份刷新应该可以防止这种情况,但我想确定一下


非常感谢您的指点和帮助。

我最终深入研究了实现方法,以下是我的发现:

回想一下,rocksdb数据库由Memtables、SST和单个WAL组成,可防止Memtables中的数据崩溃

调用
rocksdb::BackupEngine::CreateBackupWithMetadata
时,内部没有锁定,因此如果两个调用同时处于活动状态,则此调用是快速的。最值得注意的是,此调用会禁用/启用文件删除功能,如果一个调用调用了此功能,而另一个调用仍处于活动状态,则会导致另一个调用的失败

通过创建
rocksdb::Checkpoint
,将文件从数据库复制到备份的过程可以防止在调用处于活动状态时对数据库进行修改,如果
flush\u before\u backup
设置为true,将首先刷新Memtables,从而清除活动WAL

CreateCustomCheckpoint
的调用在内部调用
DB\u filecheckpoint.cc
中的
DB::GetLiveFiles
GetLiveFiles
获取全局数据库锁(
\u mutex
),可选地刷新Memtables,并检索sst列表。如果在持有全局数据库锁时发生刷新
GetLiveFiles
,则此时WAL必须为空,这意味着列表应始终包含SST文件,这些文件表示从检查点开始的完整和一致的数据库状态。由于SST是不可变的,并且由于备份调用关闭了通过压缩删除文件的功能,因此您应该始终获得完整的备份,而不保留对数据库的写入。但是,这当然意味着,当发生并发更新时,不可能确定备份中最后一次写入/序列号

对于非刷新版本,可能存在WAL文件,这些文件是在与
GetLiveFiles
不同的调用中检索的,其间没有锁,即这些文件不一定一致,但我没有进一步调查,因为非刷新情况不适用于我的使用