diff --git a/db/column_family_test.cc b/db/column_family_test.cc index 302be3b71..24730bc11 100644 --- a/db/column_family_test.cc +++ b/db/column_family_test.cc @@ -147,7 +147,7 @@ class ColumnFamilyTest : public testing::Test { void Close() { for (auto h : handles_) { if (h) { - delete h; + db_->DestroyColumnFamilyHandle(h); } } handles_.clear(); @@ -258,7 +258,7 @@ class ColumnFamilyTest : public testing::Test { void DropColumnFamilies(const std::vector& cfs) { for (auto cf : cfs) { ASSERT_OK(db_->DropColumnFamily(handles_[cf])); - delete handles_[cf]; + db_->DestroyColumnFamilyHandle(handles_[cf]); handles_[cf] = nullptr; names_[cf] = ""; } @@ -2046,7 +2046,7 @@ TEST_F(ColumnFamilyTest, ReadDroppedColumnFamily) { ASSERT_OK(db_->DropColumnFamily(handles_[2])); } else { // delete CF two - delete handles_[2]; + db_->DestroyColumnFamilyHandle(handles_[2]); handles_[2] = nullptr; } // Make sure iterator created can still be used. diff --git a/db/db_impl.cc b/db/db_impl.cc index 8a6f5831e..a445db805 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -5557,6 +5557,10 @@ Status DB::CreateColumnFamily(const ColumnFamilyOptions& cf_options, Status DB::DropColumnFamily(ColumnFamilyHandle* column_family) { return Status::NotSupported(""); } +Status DB::DestroyColumnFamilyHandle(ColumnFamilyHandle* column_family) { + delete column_family; + return Status::OK(); +} DB::~DB() { } diff --git a/db/db_test_util.cc b/db/db_test_util.cc index cb76a36f9..1b5d406e7 100644 --- a/db/db_test_util.cc +++ b/db/db_test_util.cc @@ -442,7 +442,7 @@ void DBTestBase::Reopen(const Options& options) { void DBTestBase::Close() { for (auto h : handles_) { - delete h; + db_->DestroyColumnFamilyHandle(h); } handles_.clear(); delete db_; diff --git a/include/rocksdb/db.h b/include/rocksdb/db.h index 8a703232f..3a1d6b33c 100644 --- a/include/rocksdb/db.h +++ b/include/rocksdb/db.h @@ -147,7 +147,9 @@ class DB { // in rocksdb::kDefaultColumnFamilyName. // If everything is OK, handles will on return be the same size // as column_families --- handles[i] will be a handle that you - // will use to operate on column family column_family[i] + // will use to operate on column family column_family[i]. + // Before delete DB, you have to close All column families by calling + // DestroyColumnFamilyHandle() with all the handles. static Status Open(const DBOptions& db_options, const std::string& name, const std::vector& column_families, std::vector* handles, DB** dbptr); @@ -173,6 +175,11 @@ class DB { // only records a drop record in the manifest and prevents the column // family from flushing and compacting. virtual Status DropColumnFamily(ColumnFamilyHandle* column_family); + // Close a column family specified by column_family handle and destroy + // the column family handle specified to avoid double deletion. This call + // deletes the column family handle by default. Use this method to + // close column family instead of deleting column family handle directly + virtual Status DestroyColumnFamilyHandle(ColumnFamilyHandle* column_family); // Set the database entry for "key" to "value". // If "key" already exists, it will be overwritten. diff --git a/include/rocksdb/utilities/stackable_db.h b/include/rocksdb/utilities/stackable_db.h index 32eb1ed84..7565088e0 100644 --- a/include/rocksdb/utilities/stackable_db.h +++ b/include/rocksdb/utilities/stackable_db.h @@ -40,6 +40,11 @@ class StackableDB : public DB { return db_->DropColumnFamily(column_family); } + virtual Status DestroyColumnFamilyHandle( + ColumnFamilyHandle* column_family) override { + return db_->DestroyColumnFamilyHandle(column_family); + } + using DB::Put; virtual Status Put(const WriteOptions& options, ColumnFamilyHandle* column_family, const Slice& key,