后台错误处理
目前在RocksDB中,写操作期间的任何错误(对WAL的写操作、Memtable刷新、后台压缩等)都会导致数据库实例在默认情况下进入只读模式,不接受进一步的用户写操作。变量ErrorHandler::bgerror被设置为failure状态。 DBOptions::paranoid_checks选项控制RocksDB检查和标记错误的侵略性。此选项的默认值为true。 下表显示了考虑错误并可能影响数据库操作的各种场景。
Error Reason When bg_error_ is set
Sync WAL (BackgroundErrorReason::kWriteCallback) Always
Memtable insert failure (BackgroundErrorReason::kMemTable) Always
Memtable flush (BackgroundErrorReason::kFlush)
DBOptions::paranoid_checks is true
SstFileManager::IsMaxAllowedSpaceReached()
reports max allowed space reached during
memtable flush (BackgroundErrorReason::kFlush) Always
SstFileManager::IsMaxAllowedSpaceReached()
reports max allowed space reached
during compaction (BackgroundErrorReason::kCompaction) Always
DB::CompactFiles (BackgroundErrorReason::kCompaction)
DBOptions::paranoid_checks is true
Background compaction (BackgroundErrorReason:::kCompaction) DBOptions::paranoid_checks is true
Write (BackgroundErrorReason::kWriteCallback) DBOptions::paranoid_checks is true
检测
一旦数据库实例进入只读模式,下面的前台操作将在所有后续调用上返回错误状态-
DB::Write, DB::Put, DB::Delete, DB::SingleDelete, DB::DeleteRange, DB::Merge DB:IngestExternalFile DB:CompactFiles DB:CompactRange DB:Flush
返回的状态将指示错误代码、子代码以及严重程度。错误的严重程度可以通过调用Status::severity()来确定。有4个严重级别,它们的定义如下-
1、Status::Severity::kSoftError——这种严重程度的错误不会阻止对数据库的写操作,但它确实意味着数据库处于降级模式。后台压缩可能无法及时运行。 2、Status::Severity::kHardError——数据库处于只读模式,但是一旦错误原因得到解决,就可以将其转换回读写模式。 3、状态::Severity::kFatalError -数据库处于只读模式。恢复的惟一方法是关闭数据库,纠正错误的根本原因,然后重新打开数据库。 4、Status::Severity::kUnrecoverableError——这是最高的严重程度,表示数据库损坏。可以关闭和重新打开数据库,但是数据库的内容可能不再正确。
除此之外,一旦遇到后台错误,就会调用一个通知回调EventListener::OnBackgroundError。
恢复
有两种方法可以在不关闭数据库的情况下从后台错误中恢复
1、如果EventListener::OnBackgroundError回调确定其严重程度不足以停止对数据库的进一步写入,则可以覆盖错误状态。 它可以通过设置bg_error参数来实现这一点。这样做是有风险的,因为RocksDB可能无法保证数据库的一致性。 在覆盖错误之前,检查错误的背后原因和严重程度。 调用DB::Resume()手动恢复数据库并将其置于读写模式。该函数将刷新所有列族的memtables,清除错误,清除所有过时的文件,并重新启动后台刷新和压缩操作。
2、自动恢复从后台错误。这是通过轮询系统来确保底层错误条件得到解决,然后按照与DB::Resume()相同的步骤来恢复写功能。 通知回调EventListener::OnErrorRecoveryBegin和EventListener::OnErrorRecoveryCompleted分别在恢复过程的开始和结束时调用,以通知用户状态。 目前,只支持从文件系统自动恢复ENOSPC错误。如果错误发生在WAL同步期间,只有在2PC不使用时才会进行恢复。 在未来,我们会增加更多的案例。