Skip to content

Commit 3f146bd

Browse files
author
caijieming
committed
issue=1114: LogAndApply multi-thread safe
1 parent 95b34b9 commit 3f146bd

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

src/leveldb/db/version_set.cc

+26-1
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,16 @@ void VersionSet::InstallVersionSnapshot(Version* v, VersionEdit* edit) {
10511051
}
10521052
}
10531053

1054-
// dump version and snapshot
1054+
// multi thread safe
1055+
// Information kept for every waiting manifest writer
1056+
struct VersionSet::ManifestWriter {
1057+
Status status;
1058+
VersionEdit* edit;
1059+
bool done;
1060+
port::CondVar cv;
1061+
1062+
explicit ManifestWriter(port::Mutex* mu) : done(false), cv(mu) { }
1063+
};
10551064
Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu) {
10561065
if (edit->has_log_number_) {
10571066
assert(edit->log_number_ >= log_number_);
@@ -1074,6 +1083,17 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu) {
10741083
edit->SetLastSequence(last_sequence_);
10751084
}
10761085

1086+
mu->AssertHeld();
1087+
// multi write control, do not batch edit write, but multi thread safety
1088+
ManifestWriter w(mu);
1089+
w.edit = edit;
1090+
manifest_writers_.push_back(&w);
1091+
while (!w.done && &w != manifest_writers_.front()) {
1092+
w.cv.Wait();
1093+
}
1094+
assert(manifest_writers_.front() == &w);
1095+
1096+
// first manifest writer, batch edit
10771097
Version* v = new Version(this);
10781098
{
10791099
VersionSetBuilder builder(this, current_);
@@ -1189,6 +1209,11 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu) {
11891209
Log(options_->info_log, "[%s][dfs error] set force_switch_manifest", dbname_.c_str());
11901210
}
11911211

1212+
// TODO: batch write manifest finish, no need
1213+
manifest_writers_.pop_front();
1214+
if (!manifest_writers_.empty()) {
1215+
manifest_writers_.front()->cv.Signal();
1216+
}
11921217
return s;
11931218
}
11941219

src/leveldb/db/version_set.h

+3
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ class VersionSet {
279279
friend class Compaction;
280280
friend class Version;
281281
friend class VersionSetBuilder;
282+
struct ManifestWriter;
282283

283284
void Finalize(Version* v);
284285

@@ -326,6 +327,8 @@ class VersionSet {
326327
uint64_t log_number_;
327328
uint64_t prev_log_number_; // 0 or backing store for memtable being compacted
328329

330+
std::deque<ManifestWriter*> manifest_writers_;
331+
329332
// Opened lazily
330333
WritableFile* descriptor_file_;
331334
log::Writer* descriptor_log_;

0 commit comments

Comments
 (0)