5

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

我读过了:

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

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

任何指针或帮助表示赞赏。

4

1 回答 1

4

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

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

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

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

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

对于非刷新版本,可能有 WAL 文件,它们是在GetLiveFiles与不适用于我的使用。

于 2018-03-22T14:53:41.380 回答