备份 运行 rocksdb-instance

Backing up a running rocksdb-instance

我想以安全的方式将 运行 rocksdb-instance 备份到同一磁盘上的某个位置,并且在备份期间不会中断处理。

我已阅读:

我的问题是对 CreateNewBackupWithMetadata 的调用是否被标记为非线程安全来表达,对 this 函数的两个并发调用将有不安全的行为,或者表明ANY 对数据库的并发调用是不安全的。我已经检查了实现,它似乎正在创建一个检查点——第二篇文章声称它用于 MyRocks 的在线备份——但我仍然不确定,调用的哪一部分不是线程安全的。

我目前将其解释为,这是不安全的,因为 CreateBackup... 调用 DisableFileDeletions 和后来的 EnableFileDeletions,当然,如果进行了两次重叠调用,可能会造成麻烦.由于 SST 文件是不可变的,我并不担心它们,但不确定通过插入修改 WAL 是否会破坏备份。我假设触发备份刷新应该可以防止这种情况,但我想确定。

感谢任何指点或帮助。

我最终深入研究了实现方式,这是我的发现:

回想一下 rocksdb 数据库由 Memtables、SST 和单个 WAL 组成,它保护 Memtables 中的数据免于崩溃。

当您调用 rocksdb::BackupEngine::CreateBackupWithMetadata 时,没有内部锁定,因此如果两个调用同时处于活动状态,则此调用是活泼的。最值得注意的是,此调用确实 Disable/EnableFileDeletions,如果由一个调用调用,而另一个调用仍处于活动状态,则另一个调用会失败。

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

在内部调用 CreateCustomCheckpoint 调用 db_filecheckpoint.cc 中的 DB::GetLiveFilesGetLiveFiles 获取全局数据库锁 (_mutex),可选择刷新 Memtables,并检索 SST 列表。如果在持有全局 database-lock 时发生 GetLiveFiles 中的刷新,此时 WAL 必须为空,这意味着列表应始终包含 SST-files 代表完整且一致的数据库状态检查点的时间。由于 SST 是不可变的,并且由于 backup-call 关闭了通过压缩删除文件,因此您应该始终获得完整的备份而不保留对数据库的写入。然而,这当然意味着当并发更新发生时,无法确定备份中确切的最后一个 write/sequence 编号。

对于 non-flushing 版本,可能有 WAL-files,它们是在与 GetLiveFiles 不同的调用中检索的,两者之间没有锁定,即这些不一定一致,但我没有进一步调查,因为 non-flushing 案例不适用于我的使用。