fsync directory after creating current file in NewDB()
Summary: One of our users reported current file corruption. The machine was rebooted during the time. This is the only think I can think of which could cause current file corruption. Just add this paranoid check. Test Plan: make all check Reviewers: haobo, igor Reviewed By: haobo CC: yhchiang, dhruba, leveldb Differential Revision: https://reviews.facebook.net/D18495
This commit is contained in:
parent
3a171dcb51
commit
9efbd85ac9
@ -487,7 +487,7 @@ Status DBImpl::NewDB() {
|
||||
}
|
||||
if (s.ok()) {
|
||||
// Make "CURRENT" file that points to the new manifest file.
|
||||
s = SetCurrentFile(env_, dbname_, 1);
|
||||
s = SetCurrentFile(env_, dbname_, 1, db_directory_.get());
|
||||
} else {
|
||||
env_->DeleteFile(manifest);
|
||||
}
|
||||
|
@ -226,7 +226,8 @@ bool ParseFileName(const std::string& fname,
|
||||
}
|
||||
|
||||
Status SetCurrentFile(Env* env, const std::string& dbname,
|
||||
uint64_t descriptor_number) {
|
||||
uint64_t descriptor_number,
|
||||
Directory* directory_to_fsync) {
|
||||
// Remove leading "dbname/" and add newline to manifest file name
|
||||
std::string manifest = DescriptorFileName(dbname, descriptor_number);
|
||||
Slice contents = manifest;
|
||||
@ -237,7 +238,11 @@ Status SetCurrentFile(Env* env, const std::string& dbname,
|
||||
if (s.ok()) {
|
||||
s = env->RenameFile(tmp, CurrentFileName(dbname));
|
||||
}
|
||||
if (!s.ok()) {
|
||||
if (s.ok()) {
|
||||
if (directory_to_fsync != nullptr) {
|
||||
directory_to_fsync->Fsync();
|
||||
}
|
||||
} else {
|
||||
env->DeleteFile(tmp);
|
||||
}
|
||||
return s;
|
||||
|
@ -20,6 +20,7 @@
|
||||
namespace rocksdb {
|
||||
|
||||
class Env;
|
||||
class Directory;
|
||||
|
||||
enum FileType {
|
||||
kLogFile,
|
||||
@ -100,7 +101,8 @@ extern bool ParseFileName(const std::string& filename,
|
||||
// Make the CURRENT file point to the descriptor file with the
|
||||
// specified number.
|
||||
extern Status SetCurrentFile(Env* env, const std::string& dbname,
|
||||
uint64_t descriptor_number);
|
||||
uint64_t descriptor_number,
|
||||
Directory* directory_to_fsync);
|
||||
|
||||
// Make the IDENTITY file for the db
|
||||
extern Status SetIdentityFile(Env* env, const std::string& dbname);
|
||||
|
@ -363,7 +363,7 @@ class Repairer {
|
||||
// Install new manifest
|
||||
status = env_->RenameFile(tmp, DescriptorFileName(dbname_, 1));
|
||||
if (status.ok()) {
|
||||
status = SetCurrentFile(env_, dbname_, 1);
|
||||
status = SetCurrentFile(env_, dbname_, 1, nullptr);
|
||||
} else {
|
||||
env_->DeleteFile(tmp);
|
||||
}
|
||||
|
@ -1731,7 +1731,8 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data,
|
||||
// If we just created a new descriptor file, install it by writing a
|
||||
// new CURRENT file that points to it.
|
||||
if (s.ok() && new_descriptor_log) {
|
||||
s = SetCurrentFile(env_, dbname_, pending_manifest_file_number_);
|
||||
s = SetCurrentFile(env_, dbname_, pending_manifest_file_number_,
|
||||
db_directory);
|
||||
if (s.ok() && pending_manifest_file_number_ > manifest_file_number_) {
|
||||
// delete old manifest file
|
||||
Log(options_->info_log,
|
||||
@ -1741,9 +1742,6 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data,
|
||||
// of it later
|
||||
env_->DeleteFile(DescriptorFileName(dbname_, manifest_file_number_));
|
||||
}
|
||||
if (!options_->disableDataSync && db_directory != nullptr) {
|
||||
db_directory->Fsync();
|
||||
}
|
||||
}
|
||||
|
||||
if (s.ok()) {
|
||||
|
Loading…
Reference in New Issue
Block a user