Summary:
https://github.com/facebook/rocksdb/issues/9984 changes the behavior of RocksDB: if logger creation failed during `SanitizeOptions()`,
`DB::Open()` will fail. However, since `SanitizeOptions()` is called in `DBImpl::DBImpl()`, we cannot
directly expose the error to caller without some additional work.
This is a first version proposal which:
- Adds a new member `init_logger_creation_s` to `DBImpl` to store the result of init logger creation
- Checks the error during `DB::Open()` and return it to caller if non-ok
This is not very ideal. We can alternatively move the logger creation logic out of the `SanitizeOptions()`.
Since `SanitizeOptions()` is used in other places, we need to check whether this change breaks anything
in case other callers of `SanitizeOptions()` assumes that a logger should be created.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/10223
Test Plan: make check
Reviewed By: pdillinger
Differential Revision:
D37321717
Pulled By: riversand963
fbshipit-source-id:
58042358a86369d606549dd9938933dd47591c4b
Status s = TryReopen(options);
ASSERT_EQ(nullptr, options.info_log);
- ASSERT_TRUE(s.IsAborted());
+ ASSERT_TRUE(s.IsIOError());
SyncPoint::GetInstance()->DisableProcessing();
SyncPoint::GetInstance()->ClearAllCallBacks();
bool read_only)
: dbname_(dbname),
own_info_log_(options.info_log == nullptr),
- initial_db_options_(SanitizeOptions(dbname, options, read_only)),
+ init_logger_creation_s_(),
+ initial_db_options_(SanitizeOptions(dbname, options, read_only,
+ &init_logger_creation_s_)),
env_(initial_db_options_.env),
io_tracer_(std::make_shared<IOTracer>()),
immutable_db_options_(initial_db_options_),
Status DBImpl::CloseImpl() { return CloseHelper(); }
DBImpl::~DBImpl() {
+ // TODO: remove this.
+ init_logger_creation_s_.PermitUncheckedError();
+
InstrumentedMutexLock closing_lock_guard(&closing_mutex_);
if (closed_) {
return;
std::unique_ptr<VersionSet> versions_;
// Flag to check whether we allocated and own the info log file
bool own_info_log_;
+ Status init_logger_creation_s_;
const DBOptions initial_db_options_;
Env* const env_;
std::shared_ptr<IOTracer> io_tracer_;
};
extern Options SanitizeOptions(const std::string& db, const Options& src,
- bool read_only = false);
+ bool read_only = false,
+ Status* logger_creation_s = nullptr);
extern DBOptions SanitizeOptions(const std::string& db, const DBOptions& src,
- bool read_only = false);
+ bool read_only = false,
+ Status* logger_creation_s = nullptr);
extern CompressionType GetCompressionFlush(
const ImmutableCFOptions& ioptions,
namespace ROCKSDB_NAMESPACE {
Options SanitizeOptions(const std::string& dbname, const Options& src,
- bool read_only) {
- auto db_options = SanitizeOptions(dbname, DBOptions(src), read_only);
+ bool read_only, Status* logger_creation_s) {
+ auto db_options =
+ SanitizeOptions(dbname, DBOptions(src), read_only, logger_creation_s);
ImmutableDBOptions immutable_db_options(db_options);
auto cf_options =
SanitizeOptions(immutable_db_options, ColumnFamilyOptions(src));
}
DBOptions SanitizeOptions(const std::string& dbname, const DBOptions& src,
- bool read_only) {
+ bool read_only, Status* logger_creation_s) {
DBOptions result(src);
if (result.env == nullptr) {
if (!s.ok()) {
// No place suitable for logging
result.info_log = nullptr;
+ if (logger_creation_s) {
+ *logger_creation_s = s;
+ }
}
}
DBImpl* impl = new DBImpl(db_options, dbname, seq_per_batch, batch_per_txn);
if (!impl->immutable_db_options_.info_log) {
- s = Status::Aborted("Failed to create logger");
+ s = impl->init_logger_creation_s_;
delete impl;
return s;
+ } else {
+ assert(impl->init_logger_creation_s_.ok());
}
s = impl->env_->CreateDirIfMissing(impl->immutable_db_options_.GetWalDir());
if (s.ok()) {
db = nullptr;
// Now try opening read-write and make sure it fails, for safety.
- ASSERT_TRUE(DB::Open(opts, name, &db).IsAborted());
+ ASSERT_TRUE(DB::Open(opts, name, &db).IsIOError());
}
TEST_F(BackupEngineTest, ProgressCallbackDuringBackup) {