mirror of https://github.com/facebook/rocksdb.git
Rely on PurgeObsoleteFiles Only for Options file clean up when remote compaction is enabled (#13139)
Summary: In PR https://github.com/facebook/rocksdb/issues/13074 , we added a logic to prevent stale OPTIONS file from getting deleted by `PurgeObsoleteFiles()` if the OPTIONS file is being referenced by any of the scheduled the remote compactions. `PurgeObsoleteFiles()` was not the only place that we were cleaning up the old OPTIONS file. We've been also directly cleaning up the old OPTIONS file as part of `SetOptions()`: `RenameTempFileToOptionsFile()` -> `DeleteObsoleteOptionsFiles()` unless FileDeletion is disabled. This was not caught by the UnitTest because we always preserve the last two OPTIONS file. A single call of `SetOptions()` was not enough to surface this issue in the previous PR. To keep things simple, we are just skipping the old OPTIONS file clean up in `RenameTempFileToOptionsFile()` if remote compaction is enabled. We let `PurgeObsoleteFiles()` clean up the old options file later after the compaction is done. Pull Request resolved: https://github.com/facebook/rocksdb/pull/13139 Test Plan: Updated UnitTest to reproduce the scenario. It's now passing with the fix. ``` ./compaction_service_test --gtest_filter="*PreservedOptionsRemoteCompaction*" ``` Reviewed By: cbi42 Differential Revision: D65974726 Pulled By: jaykorean fbshipit-source-id: 1907e8450d2ccbb42a93084f275e666648ef5b8c
This commit is contained in:
parent
ef119c9811
commit
3495c94761
|
@ -483,21 +483,29 @@ TEST_F(CompactionServiceTest, PreservedOptionsRemoteCompaction) {
|
||||||
ASSERT_OK(Flush());
|
ASSERT_OK(Flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_primary_called = false;
|
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency(
|
||||||
// This will be called twice. One from primary and one from remote.
|
{{"CompactionServiceTest::OptionsFileChanged",
|
||||||
// Try changing the option when called from remote. Otherwise, the new option
|
"DBImplSecondary::OpenAndCompact::BeforeLoadingOptions:1"}});
|
||||||
// will be used
|
|
||||||
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
|
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
|
||||||
"DBImpl::BackgroundCompaction:NonTrivial:BeforeRun", [&](void* /*arg*/) {
|
"DBImplSecondary::OpenAndCompact::BeforeLoadingOptions:0",
|
||||||
if (!is_primary_called) {
|
[&](void* arg) {
|
||||||
is_primary_called = true;
|
auto options_file_number = static_cast<uint64_t*>(arg);
|
||||||
return;
|
// Change the option twice before the compaction run
|
||||||
}
|
|
||||||
// Change the option right before the compaction run
|
|
||||||
ASSERT_OK(dbfull()->SetOptions(
|
ASSERT_OK(dbfull()->SetOptions(
|
||||||
{{"level0_file_num_compaction_trigger", "4"}}));
|
{{"level0_file_num_compaction_trigger", "4"}}));
|
||||||
ASSERT_EQ(4, dbfull()->GetOptions().level0_file_num_compaction_trigger);
|
ASSERT_EQ(4, dbfull()->GetOptions().level0_file_num_compaction_trigger);
|
||||||
dbfull()->TEST_DeleteObsoleteFiles();
|
ASSERT_TRUE(dbfull()->versions_->options_file_number() >
|
||||||
|
*options_file_number);
|
||||||
|
|
||||||
|
// Change the option twice before the compaction run
|
||||||
|
ASSERT_OK(dbfull()->SetOptions(
|
||||||
|
{{"level0_file_num_compaction_trigger", "5"}}));
|
||||||
|
ASSERT_EQ(5, dbfull()->GetOptions().level0_file_num_compaction_trigger);
|
||||||
|
ASSERT_TRUE(dbfull()->versions_->options_file_number() >
|
||||||
|
*options_file_number);
|
||||||
|
|
||||||
|
TEST_SYNC_POINT("CompactionServiceTest::OptionsFileChanged");
|
||||||
});
|
});
|
||||||
|
|
||||||
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
|
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
|
||||||
|
|
|
@ -5519,7 +5519,8 @@ Status DBImpl::WriteOptionsFile(const WriteOptions& write_options,
|
||||||
file_name, fs_.get());
|
file_name, fs_.get());
|
||||||
|
|
||||||
if (s.ok()) {
|
if (s.ok()) {
|
||||||
s = RenameTempFileToOptionsFile(file_name);
|
s = RenameTempFileToOptionsFile(file_name,
|
||||||
|
db_options.compaction_service != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s.ok() && GetEnv()->FileExists(file_name).ok()) {
|
if (!s.ok() && GetEnv()->FileExists(file_name).ok()) {
|
||||||
|
@ -5596,7 +5597,8 @@ Status DBImpl::DeleteObsoleteOptionsFiles() {
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
Status DBImpl::RenameTempFileToOptionsFile(const std::string& file_name) {
|
Status DBImpl::RenameTempFileToOptionsFile(const std::string& file_name,
|
||||||
|
bool is_remote_compaction_enabled) {
|
||||||
Status s;
|
Status s;
|
||||||
|
|
||||||
uint64_t options_file_number = versions_->NewFileNumber();
|
uint64_t options_file_number = versions_->NewFileNumber();
|
||||||
|
@ -5640,7 +5642,7 @@ Status DBImpl::RenameTempFileToOptionsFile(const std::string& file_name) {
|
||||||
my_disable_delete_obsolete_files = disable_delete_obsolete_files_;
|
my_disable_delete_obsolete_files = disable_delete_obsolete_files_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!my_disable_delete_obsolete_files) {
|
if (!my_disable_delete_obsolete_files && !is_remote_compaction_enabled) {
|
||||||
// TODO: Should we check for errors here?
|
// TODO: Should we check for errors here?
|
||||||
DeleteObsoleteOptionsFiles().PermitUncheckedError();
|
DeleteObsoleteOptionsFiles().PermitUncheckedError();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1469,7 +1469,8 @@ class DBImpl : public DB {
|
||||||
// The following two functions can only be called when:
|
// The following two functions can only be called when:
|
||||||
// 1. WriteThread::Writer::EnterUnbatched() is used.
|
// 1. WriteThread::Writer::EnterUnbatched() is used.
|
||||||
// 2. db_mutex is NOT held
|
// 2. db_mutex is NOT held
|
||||||
Status RenameTempFileToOptionsFile(const std::string& file_name);
|
Status RenameTempFileToOptionsFile(const std::string& file_name,
|
||||||
|
bool is_remote_compaction_enabled);
|
||||||
Status DeleteObsoleteOptionsFiles();
|
Status DeleteObsoleteOptionsFiles();
|
||||||
|
|
||||||
void NotifyOnManualFlushScheduled(autovector<ColumnFamilyData*> cfds,
|
void NotifyOnManualFlushScheduled(autovector<ColumnFamilyData*> cfds,
|
||||||
|
|
|
@ -956,6 +956,10 @@ Status DB::OpenAndCompact(
|
||||||
config_options.env = override_options.env;
|
config_options.env = override_options.env;
|
||||||
std::vector<ColumnFamilyDescriptor> all_column_families;
|
std::vector<ColumnFamilyDescriptor> all_column_families;
|
||||||
|
|
||||||
|
TEST_SYNC_POINT_CALLBACK(
|
||||||
|
"DBImplSecondary::OpenAndCompact::BeforeLoadingOptions:0",
|
||||||
|
&compaction_input.options_file_number);
|
||||||
|
TEST_SYNC_POINT("DBImplSecondary::OpenAndCompact::BeforeLoadingOptions:1");
|
||||||
std::string options_file_name =
|
std::string options_file_name =
|
||||||
OptionsFileName(name, compaction_input.options_file_number);
|
OptionsFileName(name, compaction_input.options_file_number);
|
||||||
|
|
||||||
|
|
|
@ -201,6 +201,7 @@ void BuildDBOptions(const ImmutableDBOptions& immutable_db_options,
|
||||||
options.metadata_write_temperature =
|
options.metadata_write_temperature =
|
||||||
immutable_db_options.metadata_write_temperature;
|
immutable_db_options.metadata_write_temperature;
|
||||||
options.wal_write_temperature = immutable_db_options.wal_write_temperature;
|
options.wal_write_temperature = immutable_db_options.wal_write_temperature;
|
||||||
|
options.compaction_service = immutable_db_options.compaction_service;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnFamilyOptions BuildColumnFamilyOptions(
|
ColumnFamilyOptions BuildColumnFamilyOptions(
|
||||||
|
|
Loading…
Reference in New Issue