Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 248ba01

Browse files
committedJun 14, 2022
Fix heap use after free bug
Fix close db slowly when force evict disabled
1 parent 7035f41 commit 248ba01

12 files changed

+39
-11
lines changed
 

‎db/db_impl.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,6 @@ DBImpl::DBImpl(const DBOptions& options, const std::string& dbname,
287287
initial_db_options_(SanitizeOptions(dbname, options)),
288288
immutable_db_options_(initial_db_options_),
289289
mutable_db_options_(initial_db_options_),
290-
table_evict_type_(mutable_db_options_.table_evict_type),
291290
stats_(immutable_db_options_.statistics.get()),
292291
db_lock_(nullptr),
293292
mutex_(stats_, env_, DB_MUTEX_WAIT_MICROS,
@@ -457,6 +456,7 @@ DBImpl::DBImpl(const DBOptions& options, const std::string& dbname,
457456
versions_.reset(new VersionSet(dbname_, &immutable_db_options_, &env_options_,
458457
seq_per_batch, table_cache_.get(),
459458
write_buffer_manager_, &write_controller_));
459+
versions_->set_table_evict_type(mutable_db_options_.table_evict_type);
460460
column_family_memtables_.reset(
461461
new ColumnFamilyMemTablesImpl(versions_->GetColumnFamilySet()));
462462

@@ -1591,7 +1591,7 @@ Status DBImpl::SetDBOptions(
15911591
new_options.bytes_per_sync = 1024 * 1024;
15921592
}
15931593
mutable_db_options_ = new_options;
1594-
table_evict_type_ = mutable_db_options_.table_evict_type;
1594+
versions_->set_table_evict_type(mutable_db_options_.table_evict_type);
15951595
env_options_for_compaction_ = EnvOptions(
15961596
BuildDBOptions(immutable_db_options_, mutable_db_options_));
15971597
env_options_for_compaction_ = env_->OptimizeForCompactionTableWrite(

‎db/db_impl.h

-1
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,6 @@ class DBImpl : public DB {
827827
const DBOptions initial_db_options_;
828828
const ImmutableDBOptions immutable_db_options_;
829829
MutableDBOptions mutable_db_options_;
830-
std::atomic<int> table_evict_type_;
831830
Statistics* stats_;
832831
std::unordered_map<std::string, RecoveredTransaction*>
833832
recovered_transactions_;

‎db/db_impl_files.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ void DBImpl::PurgeObsoleteFiles(JobContext& state, bool schedule_only) {
445445
}
446446
++i;
447447
}
448-
int table_evict_type = table_evict_type_;
448+
int table_evict_type = versions_->table_evict_type();
449449

450450
for (const auto& candidate_file : candidate_files) {
451451
const std::string& to_delete = candidate_file.file_name;

‎db/dbformat.h

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#pragma once
1111
#include <stdio.h>
1212

13+
#include <memory>
1314
#include <numeric>
1415
#include <string>
1516
#include <utility>
@@ -613,6 +614,8 @@ extern Status ReadRecordFromWriteBatch(Slice* input, char* tag,
613614
uint32_t* column_family, Slice* key,
614615
Slice* value, Slice* blob, Slice* xid);
615616

617+
class LifeCycle : public std::enable_shared_from_this<LifeCycle> {};
618+
616619
// When user call DeleteRange() to delete a range of keys,
617620
// we will store a serialized RangeTombstone in MemTable and SST.
618621
// the struct here is a easy-understood form

‎db/table_cache.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ TableCache::TableCache(const ColumnFamilyOptions& initial_cf_options,
140140
const ImmutableDBOptions& db_options,
141141
const EnvOptions* env_options, Cache* const cache)
142142
: initial_cf_options_(initial_cf_options),
143-
ioptions_(db_options, initial_cf_options_),
143+
ioptions_(db_options, initial_cf_options_, shared_from_this()),
144144
env_options_(*env_options),
145145
cache_(cache),
146146
immortal_tables_(false) {}

‎db/table_cache.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct FileDescriptor;
3535
class GetContext;
3636
class HistogramImpl;
3737

38-
class TableCache {
38+
class TableCache : public LifeCycle {
3939
public:
4040
TableCache(const ColumnFamilyOptions& initial_cf_options,
4141
const ImmutableDBOptions& db_options,

‎db/version_set.cc

+5-2
Original file line numberDiff line numberDiff line change
@@ -2996,12 +2996,15 @@ VersionSet::~VersionSet() {
29962996
// VersionSet
29972997
Cache* table_cache = column_family_set_->get_table_cache();
29982998
column_family_set_.reset();
2999+
int table_evict_type = table_evict_type();
29993000
for (auto& file : obsolete_files_) {
30003001
if (file.metadata->table_reader_handle) {
30013002
table_cache->Release(file.metadata->table_reader_handle);
30023003
}
3003-
if (file.table_cache) {
3004-
file.table_cache->ForceEvict(file.metadata->fd.GetNumber(), nullptr);
3004+
if (file.table_cache && table_evict_type != kSkipForceEvict) {
3005+
file.table_cache->ForceEvict(
3006+
file.metadata->fd.GetNumber(),
3007+
table_evict_type == kAlwaysForceEvict ? file.metadata : nullptr);
30053008
} else {
30063009
TableCache::Evict(table_cache, file.metadata->fd.GetNumber());
30073010
}

‎db/version_set.h

+4
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,9 @@ class VersionSet {
11211121
new_options.writable_file_max_buffer_size;
11221122
}
11231123

1124+
int table_evict_type() const { return table_evict_type_; }
1125+
void set_table_evict_type(int type) { table_evict_type_ = type; }
1126+
11241127
const ImmutableDBOptions* db_options() const { return db_options_; }
11251128

11261129
static uint64_t GetNumLiveVersions(Version* dummy_versions);
@@ -1223,6 +1226,7 @@ class VersionSet {
12231226
std::vector<std::string> obsolete_manifests_;
12241227

12251228
const bool seq_per_batch_;
1229+
std::atomic<int> table_evict_type_{0};
12261230

12271231
// env options for all reads and writes except compactions
12281232
EnvOptions env_options_;

‎options/cf_options.cc

+7
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ ImmutableCFOptions::ImmutableCFOptions(const ImmutableDBOptions& db_options,
9595
}
9696
}
9797

98+
ImmutableCFOptions::ImmutableCFOptions(const ImmutableDBOptions& db_options,
99+
const ColumnFamilyOptions& cf_options,
100+
std::shared_ptr<LifeCycle> _life_cycle)
101+
: ImmutableCFOptions(db_options, cf_options) {
102+
life_cycle = _life_cycle;
103+
}
104+
98105
// Multiple two operands. If they overflow, return op1.
99106
uint64_t MultiplyCheckOverflow(uint64_t op1, double op2) {
100107
if (op1 == 0 || op2 <= 0) {

‎options/cf_options.h

+6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ struct ImmutableCFOptions {
2828
ImmutableCFOptions(const ImmutableDBOptions& db_options,
2929
const ColumnFamilyOptions& cf_options);
3030

31+
ImmutableCFOptions(const ImmutableDBOptions& db_options,
32+
const ColumnFamilyOptions& cf_options,
33+
std::shared_ptr<LifeCycle> life_cycle);
34+
3135
CompactionStyle compaction_style;
3236

3337
CompactionPri compaction_pri;
@@ -135,6 +139,8 @@ struct ImmutableCFOptions {
135139

136140
std::shared_ptr<std::vector<std::unique_ptr<IntTblPropCollectorFactory>>>
137141
int_tbl_prop_collector_factories_for_blob;
142+
143+
std::weak_ptr<LifeCycle> life_cycle;
138144
};
139145

140146
struct BlobConfig {

‎table/block_based_table_reader.cc

+7-3
Original file line numberDiff line numberDiff line change
@@ -3205,9 +3205,13 @@ void BlockBasedTable::Close() {
32053205
rep_->dummy_index_reader_offset, cache_key);
32063206
erased_count += rep_->table_options.block_cache.get()->Erase(key);
32073207

3208-
RecordTick(rep_->ioptions.statistics, BLOCK_CACHE_ERASE, 2);
3209-
RecordTick(rep_->ioptions.statistics, BLOCK_CACHE_ERASE_FAILURES,
3210-
2 - erased_count);
3208+
auto life_cycle = rep_->cf_life_cycle.lock();
3209+
3210+
if (life_cycle) {
3211+
RecordTick(rep_->ioptions.statistics, BLOCK_CACHE_ERASE, 2);
3212+
RecordTick(rep_->ioptions.statistics, BLOCK_CACHE_ERASE_FAILURES,
3213+
2 - erased_count);
3214+
}
32113215
}
32123216
rep_->closed = true;
32133217
}

‎table/block_based_table_reader.h

+2
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ struct BlockBasedTable::Rep {
445445
const InternalKeyComparator& _internal_comparator, bool skip_filters,
446446
int _level, const bool _immortal_table)
447447
: ioptions(_ioptions),
448+
cf_life_cycle(_ioptions.life_cycle),
448449
env_options(_env_options),
449450
table_options(_table_opt),
450451
filter_policy(skip_filters ? nullptr : _table_opt.filter_policy.get()),
@@ -460,6 +461,7 @@ struct BlockBasedTable::Rep {
460461
immortal_table(_immortal_table) {}
461462

462463
const ImmutableCFOptions& ioptions;
464+
std::weak_ptr<LifeCycle> cf_life_cycle;
463465
const EnvOptions& env_options;
464466
const BlockBasedTableOptions table_options;
465467
const FilterPolicy* const filter_policy;

0 commit comments

Comments
 (0)
Please sign in to comment.