|
|
|
@ -2077,11 +2077,11 @@ struct VersionSet::ManifestWriter { |
|
|
|
|
bool done; |
|
|
|
|
InstrumentedCondVar cv; |
|
|
|
|
ColumnFamilyData* cfd; |
|
|
|
|
VersionEdit* edit; |
|
|
|
|
const autovector<VersionEdit*>& edit_list; |
|
|
|
|
|
|
|
|
|
explicit ManifestWriter(InstrumentedMutex* mu, ColumnFamilyData* _cfd, |
|
|
|
|
VersionEdit* e) |
|
|
|
|
: done(false), cv(mu), cfd(_cfd), edit(e) {} |
|
|
|
|
const autovector<VersionEdit*>& e) |
|
|
|
|
: done(false), cv(mu), cfd(_cfd), edit_list(e) {} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
VersionSet::VersionSet(const std::string& dbname, const DBOptions* db_options, |
|
|
|
@ -2150,20 +2150,32 @@ void VersionSet::AppendVersion(ColumnFamilyData* column_family_data, |
|
|
|
|
|
|
|
|
|
Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data, |
|
|
|
|
const MutableCFOptions& mutable_cf_options, |
|
|
|
|
VersionEdit* edit, InstrumentedMutex* mu, |
|
|
|
|
Directory* db_directory, bool new_descriptor_log, |
|
|
|
|
const autovector<VersionEdit*>& edit_list, |
|
|
|
|
InstrumentedMutex* mu, Directory* db_directory, |
|
|
|
|
bool new_descriptor_log, |
|
|
|
|
const ColumnFamilyOptions* new_cf_options) { |
|
|
|
|
mu->AssertHeld(); |
|
|
|
|
// num of edits
|
|
|
|
|
auto num_edits = edit_list.size(); |
|
|
|
|
if (num_edits == 0) { |
|
|
|
|
return Status::OK(); |
|
|
|
|
} else if (num_edits > 1) { |
|
|
|
|
// no group commits for column family add or drop
|
|
|
|
|
for (auto& edit : edit_list) { |
|
|
|
|
assert(!edit->IsColumnFamilyManipulation()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// column_family_data can be nullptr only if this is column_family_add.
|
|
|
|
|
// in that case, we also need to specify ColumnFamilyOptions
|
|
|
|
|
if (column_family_data == nullptr) { |
|
|
|
|
assert(edit->is_column_family_add_); |
|
|
|
|
assert(num_edits == 1); |
|
|
|
|
assert(edit_list[0]->is_column_family_add_); |
|
|
|
|
assert(new_cf_options != nullptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// queue our request
|
|
|
|
|
ManifestWriter w(mu, column_family_data, edit); |
|
|
|
|
ManifestWriter w(mu, column_family_data, edit_list); |
|
|
|
|
manifest_writers_.push_back(&w); |
|
|
|
|
while (!w.done && &w != manifest_writers_.front()) { |
|
|
|
|
w.cv.Wait(); |
|
|
|
@ -2183,7 +2195,7 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data, |
|
|
|
|
return Status::ShutdownInProgress(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::vector<VersionEdit*> batch_edits; |
|
|
|
|
autovector<VersionEdit*> batch_edits; |
|
|
|
|
Version* v = nullptr; |
|
|
|
|
std::unique_ptr<BaseReferencedVersionBuilder> builder_guard(nullptr); |
|
|
|
|
|
|
|
|
@ -2191,24 +2203,26 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data, |
|
|
|
|
ManifestWriter* last_writer = &w; |
|
|
|
|
assert(!manifest_writers_.empty()); |
|
|
|
|
assert(manifest_writers_.front() == &w); |
|
|
|
|
if (edit->IsColumnFamilyManipulation()) { |
|
|
|
|
if (w.edit_list.front()->IsColumnFamilyManipulation()) { |
|
|
|
|
// no group commits for column family add or drop
|
|
|
|
|
LogAndApplyCFHelper(edit); |
|
|
|
|
batch_edits.push_back(edit); |
|
|
|
|
LogAndApplyCFHelper(w.edit_list.front()); |
|
|
|
|
batch_edits.push_back(w.edit_list.front()); |
|
|
|
|
} else { |
|
|
|
|
v = new Version(column_family_data, this, current_version_number_++); |
|
|
|
|
builder_guard.reset(new BaseReferencedVersionBuilder(column_family_data)); |
|
|
|
|
auto* builder = builder_guard->version_builder(); |
|
|
|
|
for (const auto& writer : manifest_writers_) { |
|
|
|
|
if (writer->edit->IsColumnFamilyManipulation() || |
|
|
|
|
if (writer->edit_list.front()->IsColumnFamilyManipulation() || |
|
|
|
|
writer->cfd->GetID() != column_family_data->GetID()) { |
|
|
|
|
// no group commits for column family add or drop
|
|
|
|
|
// also, group commits across column families are not supported
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
last_writer = writer; |
|
|
|
|
LogAndApplyHelper(column_family_data, builder, v, last_writer->edit, mu); |
|
|
|
|
batch_edits.push_back(last_writer->edit); |
|
|
|
|
for (const auto& edit : writer->edit_list) { |
|
|
|
|
LogAndApplyHelper(column_family_data, builder, v, edit, mu); |
|
|
|
|
batch_edits.push_back(edit); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
builder->SaveTo(v->storage_info()); |
|
|
|
|
} |
|
|
|
@ -2231,7 +2245,8 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data, |
|
|
|
|
if (new_descriptor_log) { |
|
|
|
|
// if we're writing out new snapshot make sure to persist max column family
|
|
|
|
|
if (column_family_set_->GetMaxColumnFamily() > 0) { |
|
|
|
|
edit->SetMaxColumnFamily(column_family_set_->GetMaxColumnFamily()); |
|
|
|
|
w.edit_list.front()->SetMaxColumnFamily( |
|
|
|
|
column_family_set_->GetMaxColumnFamily()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2242,7 +2257,7 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data, |
|
|
|
|
mu->Unlock(); |
|
|
|
|
|
|
|
|
|
TEST_SYNC_POINT("VersionSet::LogAndApply:WriteManifest"); |
|
|
|
|
if (!edit->IsColumnFamilyManipulation() && |
|
|
|
|
if (!w.edit_list.front()->IsColumnFamilyManipulation() && |
|
|
|
|
db_options_->max_open_files == -1) { |
|
|
|
|
// unlimited table cache. Pre-load table handle now.
|
|
|
|
|
// Need to do it out of the mutex.
|
|
|
|
@ -2268,12 +2283,13 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data, |
|
|
|
|
|
|
|
|
|
unique_ptr<WritableFileWriter> file_writer( |
|
|
|
|
new WritableFileWriter(std::move(descriptor_file), opt_env_opts)); |
|
|
|
|
descriptor_log_.reset(new log::Writer(std::move(file_writer), 0, false)); |
|
|
|
|
descriptor_log_.reset( |
|
|
|
|
new log::Writer(std::move(file_writer), 0, false)); |
|
|
|
|
s = WriteSnapshot(descriptor_log_.get()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!edit->IsColumnFamilyManipulation()) { |
|
|
|
|
if (!w.edit_list.front()->IsColumnFamilyManipulation()) { |
|
|
|
|
// This is cpu-heavy operations, which should be called outside mutex.
|
|
|
|
|
v->PrepareApply(mutable_cf_options, true); |
|
|
|
|
} |
|
|
|
@ -2315,7 +2331,7 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data, |
|
|
|
|
new_manifest_file_size = descriptor_log_->file()->GetFileSize(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (edit->is_column_family_drop_) { |
|
|
|
|
if (w.edit_list.front()->is_column_family_drop_) { |
|
|
|
|
TEST_SYNC_POINT("VersionSet::LogAndApply::ColumnFamilyDrop:0"); |
|
|
|
|
TEST_SYNC_POINT("VersionSet::LogAndApply::ColumnFamilyDrop:1"); |
|
|
|
|
TEST_SYNC_POINT("VersionSet::LogAndApply::ColumnFamilyDrop:2"); |
|
|
|
@ -2335,12 +2351,12 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data, |
|
|
|
|
|
|
|
|
|
// Install the new version
|
|
|
|
|
if (s.ok()) { |
|
|
|
|
if (edit->is_column_family_add_) { |
|
|
|
|
if (w.edit_list.front()->is_column_family_add_) { |
|
|
|
|
// no group commit on column family add
|
|
|
|
|
assert(batch_edits.size() == 1); |
|
|
|
|
assert(new_cf_options != nullptr); |
|
|
|
|
CreateColumnFamily(*new_cf_options, edit); |
|
|
|
|
} else if (edit->is_column_family_drop_) { |
|
|
|
|
CreateColumnFamily(*new_cf_options, w.edit_list.front()); |
|
|
|
|
} else if (w.edit_list.front()->is_column_family_drop_) { |
|
|
|
|
assert(batch_edits.size() == 1); |
|
|
|
|
column_family_data->SetDropped(); |
|
|
|
|
if (column_family_data->Unref()) { |
|
|
|
@ -2363,7 +2379,7 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data, |
|
|
|
|
|
|
|
|
|
manifest_file_number_ = pending_manifest_file_number_; |
|
|
|
|
manifest_file_size_ = new_manifest_file_size; |
|
|
|
|
prev_log_number_ = edit->prev_log_number_; |
|
|
|
|
prev_log_number_ = w.edit_list.front()->prev_log_number_; |
|
|
|
|
} else { |
|
|
|
|
std::string version_edits; |
|
|
|
|
for (auto& e : batch_edits) { |
|
|
|
|