Delay verify compaction output table (#3979)

Summary:
Verify table will load SST into `TableCache`
it occupy memory & `TableCache`‘s capacity ...
but no logic use them
it's unnecessary ...

so , we verify them after all sub compact finished
Closes https://github.com/facebook/rocksdb/pull/3979

Differential Revision: D8389946

Pulled By: ajkr

fbshipit-source-id: 54bd4f474f9e7b3accf39c3068b1f36a27ec4c49
This commit is contained in:
奏之章 2018-06-15 12:28:06 -07:00 committed by Facebook Github Bot
parent 4faaab70a6
commit f23fed19a1
2 changed files with 79 additions and 47 deletions

View File

@ -607,6 +607,69 @@ Status CompactionJob::Run() {
} }
} }
if (status.ok()) {
thread_pool.clear();
std::vector<const FileMetaData*> files_meta;
for (const auto& state : compact_->sub_compact_states) {
for (const auto& output : state.outputs) {
files_meta.emplace_back(&output.meta);
}
}
ColumnFamilyData* cfd = compact_->compaction->column_family_data();
auto prefix_extractor =
compact_->compaction->mutable_cf_options()->prefix_extractor.get();
std::atomic<size_t> next_file_meta_idx(0);
auto verify_table = [&](Status& output_status) {
while (true) {
size_t file_idx = next_file_meta_idx.fetch_add(1);
if (file_idx >= files_meta.size()) {
break;
}
// Verify that the table is usable
// We set for_compaction to false and don't OptimizeForCompactionTableRead
// here because this is a special case after we finish the table building
// No matter whether use_direct_io_for_flush_and_compaction is true,
// we will regard this verification as user reads since the goal is
// to cache it here for further user reads
InternalIterator* iter = cfd->table_cache()->NewIterator(
ReadOptions(), env_options_, cfd->internal_comparator(),
files_meta[file_idx]->fd, nullptr /* range_del_agg */,
prefix_extractor, nullptr,
cfd->internal_stats()->GetFileReadHist(
compact_->compaction->output_level()),
false, nullptr /* arena */, false /* skip_filters */,
compact_->compaction->output_level());
auto s = iter->status();
if (s.ok() && paranoid_file_checks_) {
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {}
s = iter->status();
}
delete iter;
if (!s.ok()) {
output_status = s;
break;
}
}
};
for (size_t i = 1; i < compact_->sub_compact_states.size(); i++) {
thread_pool.emplace_back(verify_table,
std::ref(compact_->sub_compact_states[i].status));
}
verify_table(compact_->sub_compact_states[0].status);
for (auto& thread : thread_pool) {
thread.join();
}
for (const auto& state : compact_->sub_compact_states) {
if (!state.status.ok()) {
status = state.status;
break;
}
}
}
TablePropertiesCollection tp; TablePropertiesCollection tp;
for (const auto& state : compact_->sub_compact_states) { for (const auto& state : compact_->sub_compact_states) {
for (const auto& output : state.outputs) { for (const auto& output : state.outputs) {
@ -1175,33 +1238,7 @@ Status CompactionJob::FinishCompactionOutputFile(
ColumnFamilyData* cfd = sub_compact->compaction->column_family_data(); ColumnFamilyData* cfd = sub_compact->compaction->column_family_data();
TableProperties tp; TableProperties tp;
if (s.ok() && current_entries > 0) { if (s.ok() && current_entries > 0) {
// Verify that the table is usable
// We set for_compaction to false and don't OptimizeForCompactionTableRead
// here because this is a special case after we finish the table building
// No matter whether use_direct_io_for_flush_and_compaction is true,
// we will regard this verification as user reads since the goal is
// to cache it here for further user reads
InternalIterator* iter = cfd->table_cache()->NewIterator(
ReadOptions(), env_options_, cfd->internal_comparator(), meta->fd,
nullptr /* range_del_agg */,
sub_compact->compaction->mutable_cf_options()->prefix_extractor.get(),
nullptr,
cfd->internal_stats()->GetFileReadHist(
compact_->compaction->output_level()),
false, nullptr /* arena */, false /* skip_filters */,
compact_->compaction->output_level());
s = iter->status();
if (s.ok() && paranoid_file_checks_) {
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
}
s = iter->status();
}
delete iter;
// Output to event logger and fire events. // Output to event logger and fire events.
if (s.ok()) {
tp = sub_compact->builder->GetTableProperties(); tp = sub_compact->builder->GetTableProperties();
sub_compact->current_output()->table_properties = sub_compact->current_output()->table_properties =
std::make_shared<TableProperties>(tp); std::make_shared<TableProperties>(tp);
@ -1212,7 +1249,6 @@ Status CompactionJob::FinishCompactionOutputFile(
current_entries, current_bytes, current_entries, current_bytes,
meta->marked_for_compaction ? " (need compaction)" : ""); meta->marked_for_compaction ? " (need compaction)" : "");
} }
}
std::string fname; std::string fname;
FileDescriptor output_fd; FileDescriptor output_fd;
if (meta != nullptr) { if (meta != nullptr) {

View File

@ -405,19 +405,15 @@ class VersionBuilder::Rep {
} }
}; };
if (max_threads <= 1) {
load_handlers_func();
} else {
std::vector<port::Thread> threads; std::vector<port::Thread> threads;
for (int i = 0; i < max_threads; i++) { for (int i = 1; i < max_threads; i++) {
threads.emplace_back(load_handlers_func); threads.emplace_back(load_handlers_func);
} }
load_handlers_func();
for (auto& t : threads) { for (auto& t : threads) {
t.join(); t.join();
} }
} }
}
void MaybeAddFile(VersionStorageInfo* vstorage, int level, FileMetaData* f) { void MaybeAddFile(VersionStorageInfo* vstorage, int level, FileMetaData* f) {
if (levels_[level].deleted_files.count(f->fd.GetNumber()) > 0) { if (levels_[level].deleted_files.count(f->fd.GetNumber()) > 0) {