Change ErrorHandler methods to return const Status& (#7539)

Summary:
This change eliminates the need for a lot of the PermitUncheckedError calls on return from ErrorHandler methods.  The calls are no longer needed as the status is returned as a reference rather than a copy.  Additionally, this means that the originating status (recovery_error_, bg_error_) is not cleared implicitly as a result of calling one of these methods.

For this class, I do not know if the proper behavior should be to call PermitUncheckedError in the destructor or if the checked state should be cleared when the status is cleared.  I did tests both ways.  Without the code in the destructor, the status will need to be cleared in at least some of the places where it is set to OK.  When running tests, I found no instances where this class was destructed with a non-OK, non-checked Status.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/7539

Reviewed By: anand1976

Differential Revision: D25340565

Pulled By: pdillinger

fbshipit-source-id: 1730c035c81a475875ea745226112030ec25136c
This commit is contained in:
mrambacher 2020-12-07 20:09:55 -08:00 committed by Facebook GitHub Bot
parent 8a06fe278f
commit db03172d08
7 changed files with 68 additions and 98 deletions

View File

@ -1555,9 +1555,7 @@ Status CompactionJob::FinishCompactionOutputFile(
"CompactionJob::FinishCompactionOutputFile:" "CompactionJob::FinishCompactionOutputFile:"
"MaxAllowedSpaceReached"); "MaxAllowedSpaceReached");
InstrumentedMutexLock l(db_mutex_); InstrumentedMutexLock l(db_mutex_);
// Should handle return error? db_error_handler_->SetBGError(s, BackgroundErrorReason::kCompaction);
db_error_handler_->SetBGError(s, BackgroundErrorReason::kCompaction)
.PermitUncheckedError();
} }
} }
#endif #endif

View File

@ -4607,8 +4607,7 @@ Status DBImpl::IngestExternalFiles(
// TODO: distinguish between MANIFEST write and CURRENT renaming // TODO: distinguish between MANIFEST write and CURRENT renaming
const IOStatus& io_s = versions_->io_status(); const IOStatus& io_s = versions_->io_status();
// Should handle return error? // Should handle return error?
error_handler_.SetBGError(io_s, BackgroundErrorReason::kManifestWrite) error_handler_.SetBGError(io_s, BackgroundErrorReason::kManifestWrite);
.PermitUncheckedError();
} }
// Resume writes to the DB // Resume writes to the DB

View File

@ -130,12 +130,10 @@ IOStatus DBImpl::SyncClosedLogs(JobContext* job_context) {
} }
if (!io_s.ok()) { if (!io_s.ok()) {
if (total_log_size_ > 0) { if (total_log_size_ > 0) {
error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlush) error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlush);
.PermitUncheckedError();
} else { } else {
// If the WAL is empty, we use different error reason // If the WAL is empty, we use different error reason
error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlushNoWAL) error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlushNoWAL);
.PermitUncheckedError();
} }
TEST_SYNC_POINT("DBImpl::SyncClosedLogs:Failed"); TEST_SYNC_POINT("DBImpl::SyncClosedLogs:Failed");
return io_s; return io_s;
@ -192,8 +190,7 @@ Status DBImpl::FlushMemTableToOutputFile(
s = io_s; s = io_s;
if (!io_s.ok() && !io_s.IsShutdownInProgress() && if (!io_s.ok() && !io_s.IsShutdownInProgress() &&
!io_s.IsColumnFamilyDropped()) { !io_s.IsColumnFamilyDropped()) {
error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlush) error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlush);
.PermitUncheckedError();
} }
} else { } else {
TEST_SYNC_POINT("DBImpl::SyncClosedLogs:Skip"); TEST_SYNC_POINT("DBImpl::SyncClosedLogs:Skip");
@ -253,31 +250,23 @@ Status DBImpl::FlushMemTableToOutputFile(
// be pessimistic and try write to a new MANIFEST. // be pessimistic and try write to a new MANIFEST.
// TODO: distinguish between MANIFEST write and CURRENT renaming // TODO: distinguish between MANIFEST write and CURRENT renaming
if (!versions_->io_status().ok()) { if (!versions_->io_status().ok()) {
// Should handle return error?
if (total_log_size_ > 0) { if (total_log_size_ > 0) {
// If the WAL is empty, we use different error reason // If the WAL is empty, we use different error reason
error_handler_.SetBGError(io_s, BackgroundErrorReason::kManifestWrite) error_handler_.SetBGError(io_s,
.PermitUncheckedError(); BackgroundErrorReason::kManifestWrite);
} else { } else {
error_handler_ error_handler_.SetBGError(io_s,
.SetBGError(io_s, BackgroundErrorReason::kManifestWriteNoWAL) BackgroundErrorReason::kManifestWriteNoWAL);
.PermitUncheckedError();
} }
} else if (total_log_size_ > 0) { } else if (total_log_size_ > 0) {
// Should handle return error? error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlush);
error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlush)
.PermitUncheckedError();
} else { } else {
// If the WAL is empty, we use different error reason // If the WAL is empty, we use different error reason
// Should handle return error? error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlushNoWAL);
error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlushNoWAL)
.PermitUncheckedError();
} }
} else { } else {
Status new_bg_error = s; Status new_bg_error = s;
// Should handle return error? error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush);
error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush)
.PermitUncheckedError();
} }
} else { } else {
// If we got here, then we decided not to care about the i_os status (either // If we got here, then we decided not to care about the i_os status (either
@ -302,9 +291,7 @@ Status DBImpl::FlushMemTableToOutputFile(
TEST_SYNC_POINT_CALLBACK( TEST_SYNC_POINT_CALLBACK(
"DBImpl::FlushMemTableToOutputFile:MaxAllowedSpaceReached", "DBImpl::FlushMemTableToOutputFile:MaxAllowedSpaceReached",
&new_bg_error); &new_bg_error);
// Should handle this error? error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush);
error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush)
.PermitUncheckedError();
} }
} }
#endif // ROCKSDB_LITE #endif // ROCKSDB_LITE
@ -645,9 +632,8 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
error_handler_.GetBGError().ok()) { error_handler_.GetBGError().ok()) {
Status new_bg_error = Status new_bg_error =
Status::SpaceLimit("Max allowed space was reached"); Status::SpaceLimit("Max allowed space was reached");
// Should Handle this error? error_handler_.SetBGError(new_bg_error,
error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush) BackgroundErrorReason::kFlush);
.PermitUncheckedError();
} }
} }
} }
@ -664,31 +650,23 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
// be pessimistic and try write to a new MANIFEST. // be pessimistic and try write to a new MANIFEST.
// TODO: distinguish between MANIFEST write and CURRENT renaming // TODO: distinguish between MANIFEST write and CURRENT renaming
if (!versions_->io_status().ok()) { if (!versions_->io_status().ok()) {
// Should handle return error?
if (total_log_size_ > 0) { if (total_log_size_ > 0) {
// If the WAL is empty, we use different error reason // If the WAL is empty, we use different error reason
error_handler_.SetBGError(io_s, BackgroundErrorReason::kManifestWrite) error_handler_.SetBGError(io_s,
.PermitUncheckedError(); BackgroundErrorReason::kManifestWrite);
} else { } else {
error_handler_ error_handler_.SetBGError(io_s,
.SetBGError(io_s, BackgroundErrorReason::kManifestWriteNoWAL) BackgroundErrorReason::kManifestWriteNoWAL);
.PermitUncheckedError();
} }
} else if (total_log_size_ > 0) { } else if (total_log_size_ > 0) {
// Should Handle this error? error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlush);
error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlush)
.PermitUncheckedError();
} else { } else {
// If the WAL is empty, we use different error reason // If the WAL is empty, we use different error reason
// Should Handle this error? error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlushNoWAL);
error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlushNoWAL)
.PermitUncheckedError();
} }
} else { } else {
Status new_bg_error = s; Status new_bg_error = s;
// Should Handle this error? error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush);
error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush)
.PermitUncheckedError();
} }
} }
@ -1266,11 +1244,9 @@ Status DBImpl::CompactFilesImpl(
job_context->job_id, status.ToString().c_str()); job_context->job_id, status.ToString().c_str());
IOStatus io_s = compaction_job.io_status(); IOStatus io_s = compaction_job.io_status();
if (!io_s.ok()) { if (!io_s.ok()) {
error_handler_.SetBGError(io_s, BackgroundErrorReason::kCompaction) error_handler_.SetBGError(io_s, BackgroundErrorReason::kCompaction);
.PermitUncheckedError();
} else { } else {
error_handler_.SetBGError(status, BackgroundErrorReason::kCompaction) error_handler_.SetBGError(status, BackgroundErrorReason::kCompaction);
.PermitUncheckedError();
} }
} }
@ -3121,10 +3097,9 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
auto err_reason = versions_->io_status().ok() auto err_reason = versions_->io_status().ok()
? BackgroundErrorReason::kCompaction ? BackgroundErrorReason::kCompaction
: BackgroundErrorReason::kManifestWrite; : BackgroundErrorReason::kManifestWrite;
error_handler_.SetBGError(io_s, err_reason).PermitUncheckedError(); error_handler_.SetBGError(io_s, err_reason);
} else { } else {
error_handler_.SetBGError(status, BackgroundErrorReason::kCompaction) error_handler_.SetBGError(status, BackgroundErrorReason::kCompaction);
.PermitUncheckedError();
} }
if (c != nullptr && !is_manual && !error_handler_.IsBGWorkStopped()) { if (c != nullptr && !is_manual && !error_handler_.IsBGWorkStopped()) {
// Put this cfd back in the compaction queue so we can retry after some // Put this cfd back in the compaction queue so we can retry after some

View File

@ -170,7 +170,7 @@ Status DBImpl::TEST_WaitForCompact(bool wait_unscheduled) {
while ((bg_bottom_compaction_scheduled_ || bg_compaction_scheduled_ || while ((bg_bottom_compaction_scheduled_ || bg_compaction_scheduled_ ||
bg_flush_scheduled_ || bg_flush_scheduled_ ||
(wait_unscheduled && unscheduled_compactions_)) && (wait_unscheduled && unscheduled_compactions_)) &&
(error_handler_.GetBGError() == Status::OK())) { (error_handler_.GetBGError().ok())) {
bg_cv_.Wait(); bg_cv_.Wait();
} }
return error_handler_.GetBGError(); return error_handler_.GetBGError();

View File

@ -850,8 +850,7 @@ void DBImpl::WriteStatusCheckOnLocked(const Status& status) {
if (immutable_db_options_.paranoid_checks && !status.ok() && if (immutable_db_options_.paranoid_checks && !status.ok() &&
!status.IsBusy() && !status.IsIncomplete()) { !status.IsBusy() && !status.IsIncomplete()) {
// Maybe change the return status to void? // Maybe change the return status to void?
error_handler_.SetBGError(status, BackgroundErrorReason::kWriteCallback) error_handler_.SetBGError(status, BackgroundErrorReason::kWriteCallback);
.PermitUncheckedError();
} }
} }
@ -863,8 +862,7 @@ void DBImpl::WriteStatusCheck(const Status& status) {
!status.IsBusy() && !status.IsIncomplete()) { !status.IsBusy() && !status.IsIncomplete()) {
mutex_.Lock(); mutex_.Lock();
// Maybe change the return status to void? // Maybe change the return status to void?
error_handler_.SetBGError(status, BackgroundErrorReason::kWriteCallback) error_handler_.SetBGError(status, BackgroundErrorReason::kWriteCallback);
.PermitUncheckedError();
mutex_.Unlock(); mutex_.Unlock();
} }
} }
@ -877,8 +875,7 @@ void DBImpl::IOStatusCheck(const IOStatus& io_status) {
io_status.IsIOFenced()) { io_status.IsIOFenced()) {
mutex_.Lock(); mutex_.Lock();
// Maybe change the return status to void? // Maybe change the return status to void?
error_handler_.SetBGError(io_status, BackgroundErrorReason::kWriteCallback) error_handler_.SetBGError(io_status, BackgroundErrorReason::kWriteCallback);
.PermitUncheckedError();
mutex_.Unlock(); mutex_.Unlock();
} }
} }
@ -1810,15 +1807,10 @@ Status DBImpl::SwitchMemtable(ColumnFamilyData* cfd, WriteContext* context) {
} }
// We may have lost data from the WritableFileBuffer in-memory buffer for // We may have lost data from the WritableFileBuffer in-memory buffer for
// the current log, so treat it as a fatal error and set bg_error // the current log, so treat it as a fatal error and set bg_error
// Should handle return error?
if (!io_s.ok()) { if (!io_s.ok()) {
// Should handle return error? error_handler_.SetBGError(io_s, BackgroundErrorReason::kMemTable);
error_handler_.SetBGError(io_s, BackgroundErrorReason::kMemTable)
.PermitUncheckedError();
} else { } else {
// Should handle return error? error_handler_.SetBGError(s, BackgroundErrorReason::kMemTable);
error_handler_.SetBGError(s, BackgroundErrorReason::kMemTable)
.PermitUncheckedError();
} }
// Read back bg_error in order to get the right severity // Read back bg_error in order to get the right severity
s = error_handler_.GetBGError(); s = error_handler_.GetBGError();

View File

@ -267,10 +267,11 @@ void ErrorHandler::CancelErrorRecovery() {
// This can also get called as part of a recovery operation. In that case, we // This can also get called as part of a recovery operation. In that case, we
// also track the error separately in recovery_error_ so we can tell in the // also track the error separately in recovery_error_ so we can tell in the
// end whether recovery succeeded or not // end whether recovery succeeded or not
Status ErrorHandler::SetBGError(const Status& bg_err, BackgroundErrorReason reason) { const Status& ErrorHandler::SetBGError(const Status& bg_err,
BackgroundErrorReason reason) {
db_mutex_->AssertHeld(); db_mutex_->AssertHeld();
if (bg_err.ok()) { if (bg_err.ok()) {
return Status::OK(); return bg_err;
} }
bool paranoid = db_options_.paranoid_checks; bool paranoid = db_options_.paranoid_checks;
@ -363,11 +364,11 @@ Status ErrorHandler::SetBGError(const Status& bg_err, BackgroundErrorReason reas
// c) all other errors are mapped to hard error. // c) all other errors are mapped to hard error.
// 3) for other cases, SetBGError(const Status& bg_err, BackgroundErrorReason // 3) for other cases, SetBGError(const Status& bg_err, BackgroundErrorReason
// reason) will be called to handle other error cases. // reason) will be called to handle other error cases.
Status ErrorHandler::SetBGError(const IOStatus& bg_io_err, const Status& ErrorHandler::SetBGError(const IOStatus& bg_io_err,
BackgroundErrorReason reason) { BackgroundErrorReason reason) {
db_mutex_->AssertHeld(); db_mutex_->AssertHeld();
if (bg_io_err.ok()) { if (bg_io_err.ok()) {
return Status::OK(); return bg_io_err;
} }
ROCKS_LOG_WARN(db_options_.info_log, "Background IO error %s", ROCKS_LOG_WARN(db_options_.info_log, "Background IO error %s",
bg_io_err.ToString().c_str()); bg_io_err.ToString().c_str());
@ -382,7 +383,6 @@ Status ErrorHandler::SetBGError(const IOStatus& bg_io_err,
} }
Status new_bg_io_err = bg_io_err; Status new_bg_io_err = bg_io_err;
Status s;
DBRecoverContext context; DBRecoverContext context;
if (bg_io_err.GetDataLoss()) { if (bg_io_err.GetDataLoss()) {
// First, data loss is treated as unrecoverable error. So it can directly // First, data loss is treated as unrecoverable error. So it can directly
@ -393,8 +393,8 @@ Status ErrorHandler::SetBGError(const IOStatus& bg_io_err,
if (recovery_in_prog_ && recovery_error_.ok()) { if (recovery_in_prog_ && recovery_error_.ok()) {
recovery_error_ = bg_err; recovery_error_ = bg_err;
} }
EventHelpers::NotifyOnBackgroundError(db_options_.listeners, reason, &s, EventHelpers::NotifyOnBackgroundError(db_options_.listeners, reason,
db_mutex_, &auto_recovery); &bg_err, db_mutex_, &auto_recovery);
recover_context_ = context; recover_context_ = context;
return bg_error_; return bg_error_;
} else if (bg_io_err.GetRetryable()) { } else if (bg_io_err.GetRetryable()) {
@ -405,8 +405,9 @@ Status ErrorHandler::SetBGError(const IOStatus& bg_io_err,
// soft error. In other cases, treat the retryable IO error as hard // soft error. In other cases, treat the retryable IO error as hard
// error. // error.
bool auto_recovery = false; bool auto_recovery = false;
EventHelpers::NotifyOnBackgroundError(db_options_.listeners, reason, &s, EventHelpers::NotifyOnBackgroundError(db_options_.listeners, reason,
db_mutex_, &auto_recovery); &new_bg_io_err, db_mutex_,
&auto_recovery);
if (BackgroundErrorReason::kCompaction == reason) { if (BackgroundErrorReason::kCompaction == reason) {
Status bg_err(new_bg_io_err, Status::Severity::kSoftError); Status bg_err(new_bg_io_err, Status::Severity::kSoftError);
if (bg_err.severity() > bg_error_.severity()) { if (bg_err.severity() > bg_error_.severity()) {
@ -446,12 +447,11 @@ Status ErrorHandler::SetBGError(const IOStatus& bg_io_err,
return StartRecoverFromRetryableBGIOError(bg_io_err); return StartRecoverFromRetryableBGIOError(bg_io_err);
} }
} else { } else {
s = SetBGError(new_bg_io_err, reason); return SetBGError(new_bg_io_err, reason);
} }
return s;
} }
Status ErrorHandler::OverrideNoSpaceError(Status bg_error, Status ErrorHandler::OverrideNoSpaceError(const Status& bg_error,
bool* auto_recovery) { bool* auto_recovery) {
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
if (bg_error.severity() >= Status::Severity::kFatalError) { if (bg_error.severity() >= Status::Severity::kFatalError) {
@ -507,7 +507,11 @@ Status ErrorHandler::ClearBGError() {
// Signal that recovery succeeded // Signal that recovery succeeded
if (recovery_error_.ok()) { if (recovery_error_.ok()) {
Status old_bg_error = bg_error_; Status old_bg_error = bg_error_;
// Clear and check the recovery IO and BG error
bg_error_ = Status::OK(); bg_error_ = Status::OK();
recovery_io_error_ = IOStatus::OK();
bg_error_.PermitUncheckedError();
recovery_io_error_.PermitUncheckedError();
recovery_in_prog_ = false; recovery_in_prog_ = false;
soft_error_no_bg_work_ = false; soft_error_no_bg_work_ = false;
EventHelpers::NotifyOnErrorRecoveryCompleted(db_options_.listeners, EventHelpers::NotifyOnErrorRecoveryCompleted(db_options_.listeners,
@ -557,6 +561,7 @@ Status ErrorHandler::RecoverFromBGError(bool is_manual) {
// during the recovery process. While recovering, the only operations that // during the recovery process. While recovering, the only operations that
// can generate background errors should be the flush operations // can generate background errors should be the flush operations
recovery_error_ = Status::OK(); recovery_error_ = Status::OK();
recovery_error_.PermitUncheckedError();
Status s = db_->ResumeImpl(recover_context_); Status s = db_->ResumeImpl(recover_context_);
if (s.ok()) { if (s.ok()) {
soft_error_no_bg_work_ = false; soft_error_no_bg_work_ = false;
@ -578,13 +583,15 @@ Status ErrorHandler::RecoverFromBGError(bool is_manual) {
#endif #endif
} }
Status ErrorHandler::StartRecoverFromRetryableBGIOError(IOStatus io_error) { const Status& ErrorHandler::StartRecoverFromRetryableBGIOError(
const IOStatus& io_error) {
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
db_mutex_->AssertHeld(); db_mutex_->AssertHeld();
if (bg_error_.ok() || io_error.ok()) { if (bg_error_.ok()) {
return Status::OK(); return bg_error_;
} } else if (io_error.ok()) {
if (db_options_.max_bgerror_resume_count <= 0 || recovery_in_prog_) { return io_error;
} else if (db_options_.max_bgerror_resume_count <= 0 || recovery_in_prog_) {
// Auto resume BG error is not enabled, directly return bg_error_. // Auto resume BG error is not enabled, directly return bg_error_.
return bg_error_; return bg_error_;
} }
@ -603,7 +610,7 @@ Status ErrorHandler::StartRecoverFromRetryableBGIOError(IOStatus io_error) {
new port::Thread(&ErrorHandler::RecoverFromRetryableBGIOError, this)); new port::Thread(&ErrorHandler::RecoverFromRetryableBGIOError, this));
if (recovery_io_error_.ok() && recovery_error_.ok()) { if (recovery_io_error_.ok() && recovery_error_.ok()) {
return Status::OK(); return recovery_error_;
} else { } else {
TEST_SYNC_POINT("StartRecoverRetryableBGIOError:RecoverFail"); TEST_SYNC_POINT("StartRecoverRetryableBGIOError:RecoverFail");
return bg_error_; return bg_error_;
@ -668,6 +675,7 @@ void ErrorHandler::RecoverFromRetryableBGIOError() {
TEST_SYNC_POINT("RecoverFromRetryableBGIOError:RecoverSuccess"); TEST_SYNC_POINT("RecoverFromRetryableBGIOError:RecoverSuccess");
Status old_bg_error = bg_error_; Status old_bg_error = bg_error_;
bg_error_ = Status::OK(); bg_error_ = Status::OK();
bg_error_.PermitUncheckedError();
EventHelpers::NotifyOnErrorRecoveryCompleted(db_options_.listeners, EventHelpers::NotifyOnErrorRecoveryCompleted(db_options_.listeners,
old_bg_error, db_mutex_); old_bg_error, db_mutex_);
recovery_in_prog_ = false; recovery_in_prog_ = false;

View File

@ -31,17 +31,14 @@ class ErrorHandler {
InstrumentedMutex* db_mutex) InstrumentedMutex* db_mutex)
: db_(db), : db_(db),
db_options_(db_options), db_options_(db_options),
bg_error_(Status::OK()),
recovery_error_(Status::OK()),
recovery_io_error_(IOStatus::OK()),
cv_(db_mutex), cv_(db_mutex),
end_recovery_(false), end_recovery_(false),
recovery_thread_(nullptr), recovery_thread_(nullptr),
db_mutex_(db_mutex), db_mutex_(db_mutex),
auto_recovery_(false), auto_recovery_(false),
recovery_in_prog_(false), recovery_in_prog_(false),
soft_error_no_bg_work_(false) {} soft_error_no_bg_work_(false) {
~ErrorHandler() { // Clear the checked flag for uninitialized errors
bg_error_.PermitUncheckedError(); bg_error_.PermitUncheckedError();
recovery_error_.PermitUncheckedError(); recovery_error_.PermitUncheckedError();
recovery_io_error_.PermitUncheckedError(); recovery_io_error_.PermitUncheckedError();
@ -53,13 +50,14 @@ class ErrorHandler {
Status::Code code, Status::Code code,
Status::SubCode subcode); Status::SubCode subcode);
Status SetBGError(const Status& bg_err, BackgroundErrorReason reason); const Status& SetBGError(const Status& bg_err, BackgroundErrorReason reason);
Status SetBGError(const IOStatus& bg_io_err, BackgroundErrorReason reason); const Status& SetBGError(const IOStatus& bg_io_err,
BackgroundErrorReason reason);
Status GetBGError() { return bg_error_; } Status GetBGError() const { return bg_error_; }
Status GetRecoveryError() { return recovery_error_; } Status GetRecoveryError() const { return recovery_error_; }
Status ClearBGError(); Status ClearBGError();
@ -110,9 +108,9 @@ class ErrorHandler {
// Used to store the context for recover, such as flush reason. // Used to store the context for recover, such as flush reason.
DBRecoverContext recover_context_; DBRecoverContext recover_context_;
Status OverrideNoSpaceError(Status bg_error, bool* auto_recovery); Status OverrideNoSpaceError(const Status& bg_error, bool* auto_recovery);
void RecoverFromNoSpace(); void RecoverFromNoSpace();
Status StartRecoverFromRetryableBGIOError(IOStatus io_error); const Status& StartRecoverFromRetryableBGIOError(const IOStatus& io_error);
void RecoverFromRetryableBGIOError(); void RecoverFromRetryableBGIOError();
}; };