]> git-server-git.apps.pok.os.sepia.ceph.com Git - rocksdb.git/commitdiff
Make a copy of MutableCFOptions to avoid race condition (#4876)
authorYanqin Jin <yanqin@fb.com>
Sat, 12 Jan 2019 01:40:44 +0000 (17:40 -0800)
committerYanqin Jin <yanqin@fb.com>
Thu, 31 Jan 2019 23:06:08 +0000 (15:06 -0800)
Summary:
If we do not do this, then reading MutableCFOptions may have a race condition
with SetOptions which modifies MutableCFOptions.

Also reserve space in advance for vectors to avoid reallocation changing the
address of its elements.

Test plan
```
$make clean && make -j32 all check
$make clean && COMPILE_WITH_TSAN=1 make -j32 all check
$make clean && COMPILE_WITH_ASAN=1 make -j32 all check
```
Pull Request resolved: https://github.com/facebook/rocksdb/pull/4876

Differential Revision: D13644500

Pulled By: riversand963

fbshipit-source-id: 4b8112c5c819d5a2922bb61ad1521b3d2fb2fd47

db/db_impl_compaction_flush.cc

index f6a3ffd1deed0d355919427718dcb2dbdaf3ecb2..5847f05dd3e46634486a25c8ac419f765eb1eb4c 100644 (file)
@@ -222,8 +222,7 @@ Status DBImpl::FlushMemTablesToOutputFiles(
   Status status;
   for (auto& arg : bg_flush_args) {
     ColumnFamilyData* cfd = arg.cfd_;
-    const MutableCFOptions& mutable_cf_options =
-        *cfd->GetLatestMutableCFOptions();
+    MutableCFOptions mutable_cf_options = *cfd->GetLatestMutableCFOptions();
     SuperVersionContext* superversion_context = arg.superversion_context_;
     Status s = FlushMemTableToOutputFile(cfd, mutable_cf_options, made_progress,
                                          job_context, superversion_context,
@@ -276,7 +275,9 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
   }
   autovector<Directory*> distinct_output_dirs;
   std::vector<FlushJob> jobs;
+  std::vector<MutableCFOptions> all_mutable_cf_options;
   int num_cfs = static_cast<int>(cfds.size());
+  all_mutable_cf_options.reserve(num_cfs);
   for (int i = 0; i < num_cfs; ++i) {
     auto cfd = cfds[i];
     Directory* data_dir = GetDataDir(cfd, 0U);
@@ -295,8 +296,8 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
       distinct_output_dirs.emplace_back(data_dir);
     }
 
-    const MutableCFOptions& mutable_cf_options =
-        *cfd->GetLatestMutableCFOptions();
+    all_mutable_cf_options.emplace_back(*cfd->GetLatestMutableCFOptions());
+    const MutableCFOptions& mutable_cf_options = all_mutable_cf_options.back();
     const uint64_t* max_memtable_id = &(bg_flush_args[i].max_memtable_id_);
     jobs.emplace_back(
         dbname_, cfds[i], immutable_db_options_, mutable_cf_options,
@@ -432,8 +433,7 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
       if (!cfds[i]->IsDropped() && !mems.empty()) {
         tmp_cfds.emplace_back(cfds[i]);
         mems_list.emplace_back(&mems);
-        mutable_cf_options_list.emplace_back(
-            cfds[i]->GetLatestMutableCFOptions());
+        mutable_cf_options_list.emplace_back(&all_mutable_cf_options[i]);
       }
     }
 
@@ -1460,6 +1460,7 @@ Status DBImpl::RunManualCompaction(ColumnFamilyData* cfd, int input_level,
 void DBImpl::GenerateFlushRequest(const autovector<ColumnFamilyData*>& cfds,
                                   FlushRequest* req) {
   assert(req != nullptr);
+  req->reserve(cfds.size());
   for (const auto cfd : cfds) {
     if (nullptr == cfd) {
       // cfd may be null, see DBImpl::ScheduleFlushes