Memory Problem Of Destorying ColumnFamilyHandle after deleting the CF

Summary:
When destorying column family handle after the column family has been deleted, the handle may hold share pointers of some objects in ColumnFamilyOptions, but in the destructor, the destructing order may cause some of the objects to be destoryed before being used by the following steps. Fix it by making a copy of the option object and destory it as the last step.
Closes https://github.com/facebook/rocksdb/pull/3610

Differential Revision: D7281025

Pulled By: siying

fbshipit-source-id: ac18f3b2841788cba4ccfa1abd8d59158c1113bc
main
Siying Dong 7 years ago committed by Facebook Github Bot
parent d1b26507bd
commit 93d52696bf
  1. 3
      db/column_family.cc
  2. 4
      db/column_family.h
  3. 12
      db/column_family_test.cc

@ -54,6 +54,9 @@ ColumnFamilyHandleImpl::~ColumnFamilyHandleImpl() {
#endif // ROCKSDB_LITE #endif // ROCKSDB_LITE
// Job id == 0 means that this is not our background process, but rather // Job id == 0 means that this is not our background process, but rather
// user thread // user thread
// Need to hold some shared pointers owned by the initial_cf_options
// before final cleaning up finishes.
ColumnFamilyOptions initial_cf_options_copy = cfd_->initial_cf_options();
JobContext job_context(0); JobContext job_context(0);
mutex_->Lock(); mutex_->Lock();
if (cfd_->Unref()) { if (cfd_->Unref()) {

@ -370,6 +370,10 @@ class ColumnFamilyData {
bool initialized() const { return initialized_.load(); } bool initialized() const { return initialized_.load(); }
const ColumnFamilyOptions& initial_cf_options() {
return initial_cf_options_;
}
Env::WriteLifeTimeHint CalculateSSTWriteHint(int level); Env::WriteLifeTimeHint CalculateSSTWriteHint(int level);
private: private:

@ -2791,6 +2791,18 @@ TEST_F(ColumnFamilyTest, CompactionSpeedupTwoColumnFamilies) {
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed()); ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
} }
TEST_F(ColumnFamilyTest, CreateAndDestoryOptions) {
std::unique_ptr<ColumnFamilyOptions> cfo(new ColumnFamilyOptions());
ColumnFamilyHandle* cfh;
Open();
ASSERT_OK(db_->CreateColumnFamily(*(cfo.get()), "yoyo", &cfh));
cfo.reset();
ASSERT_OK(db_->Put(WriteOptions(), cfh, "foo", "bar"));
ASSERT_OK(db_->Flush(FlushOptions(), cfh));
ASSERT_OK(db_->DropColumnFamily(cfh));
ASSERT_OK(db_->DestroyColumnFamilyHandle(cfh));
}
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
TEST_F(ColumnFamilyTest, FlushCloseWALFiles) { TEST_F(ColumnFamilyTest, FlushCloseWALFiles) {
SpecialEnv env(Env::Default()); SpecialEnv env(Env::Default());

Loading…
Cancel
Save