From 710411aea6a2c74f7ca912988878d79aeffcefce Mon Sep 17 00:00:00 2001 From: Andrew Kryczka Date: Thu, 27 Jul 2017 20:16:25 -0700 Subject: [PATCH] fix asan/valgrind for TableCache cleanup Summary: Breaking commit: d12691b86fb788f0ee7180db626c4ea2445fa976 In the above commit, I moved the `TableCache` cleanup logic from `Version` destructor into `PurgeObsoleteFiles`. I missed cleaning up `TableCache` entries for the current `Version` during DB destruction. This PR adds that logic to `VersionSet` destructor. One unfortunate side effect is now we're potentially deleting `TableReader`s after `column_family_set_.reset()`, which means we can't call `BlockBasedTableReader::Close` a second time as the block cache might already be destroyed. Closes https://github.com/facebook/rocksdb/pull/2662 Differential Revision: D5515108 Pulled By: ajkr fbshipit-source-id: 2cb820e19aa813e0d258d17f76b2d7b6b7ee0b18 --- db/version_set.cc | 8 ++++++-- table/block_based_table_reader.cc | 4 ++++ table/block_based_table_reader.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/db/version_set.cc b/db/version_set.cc index ffbdd46cd..f8465027b 100644 --- a/db/version_set.cc +++ b/db/version_set.cc @@ -2327,10 +2327,14 @@ void CloseTables(void* ptr, size_t) { VersionSet::~VersionSet() { // we need to delete column_family_set_ because its destructor depends on // VersionSet - column_family_set_->get_table_cache()->ApplyToAllCacheEntries(&CloseTables, - false); + Cache* table_cache = column_family_set_->get_table_cache(); + table_cache->ApplyToAllCacheEntries(&CloseTables, false /* thread_safe */); column_family_set_.reset(); for (auto file : obsolete_files_) { + if (file->table_reader_handle) { + table_cache->Release(file->table_reader_handle); + TableCache::Evict(table_cache, file->fd.GetNumber()); + } delete file; } obsolete_files_.clear(); diff --git a/table/block_based_table_reader.cc b/table/block_based_table_reader.cc index 3c4f0b80e..a0b58c6b2 100644 --- a/table/block_based_table_reader.cc +++ b/table/block_based_table_reader.cc @@ -2083,6 +2083,9 @@ Status BlockBasedTable::DumpTable(WritableFile* out_file) { } void BlockBasedTable::Close() { + if (rep_->closed) { + return; + } rep_->filter_entry.Release(rep_->table_options.block_cache.get()); rep_->index_entry.Release(rep_->table_options.block_cache.get()); rep_->range_del_entry.Release(rep_->table_options.block_cache.get()); @@ -2099,6 +2102,7 @@ void BlockBasedTable::Close() { rep_->dummy_index_reader_offset, cache_key); rep_->table_options.block_cache.get()->Erase(key); } + rep_->closed = true; } Status BlockBasedTable::DumpIndexBlock(WritableFile* out_file) { diff --git a/table/block_based_table_reader.h b/table/block_based_table_reader.h index 8b3494ef5..3acc3a8fb 100644 --- a/table/block_based_table_reader.h +++ b/table/block_based_table_reader.h @@ -467,6 +467,7 @@ struct BlockBasedTable::Rep { // A value of kDisableGlobalSequenceNumber means that this feature is disabled // and every key have it's own seqno. SequenceNumber global_seqno; + bool closed = false; }; } // namespace rocksdb