From: Yanqin Jin Date: Sat, 12 Jan 2019 01:40:44 +0000 (-0800) Subject: Make a copy of MutableCFOptions to avoid race condition (#4876) X-Git-Tag: v5.18.3~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=acba14b3d903bed94a3345c471bd62b282c84f33;p=rocksdb.git Make a copy of MutableCFOptions to avoid race condition (#4876) 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 --- diff --git a/db/db_impl_compaction_flush.cc b/db/db_impl_compaction_flush.cc index f6a3ffd1..5847f05d 100644 --- a/db/db_impl_compaction_flush.cc +++ b/db/db_impl_compaction_flush.cc @@ -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 distinct_output_dirs; std::vector jobs; + std::vector all_mutable_cf_options; int num_cfs = static_cast(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& 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