-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enable cf uses separete write buffer manager #343
Changes from 38 commits
5079707
e3ada2d
fadfef3
6ae46ff
cd5a294
af33283
ab43653
b25567e
033d847
199d704
c47e7d8
004be9b
30b7862
41775e2
0095aa8
964cf81
64fbf24
e373067
4ce4cef
e67df36
755c10f
79ac364
62cbf09
6f6d326
6b5aabd
d621893
e29df90
37d455c
9d24a9f
a1ca8a9
c38c417
9924742
8fbaf5c
85d43bf
21b9ae5
4f509cf
8ecc649
947c94b
ebb40a1
d79241f
5e404af
35caf14
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -419,8 +419,7 @@ class DBImpl : public DB { | |
virtual Status GetSortedWalFiles(VectorLogPtr& files) override; | ||
virtual Status GetCurrentWalFile( | ||
std::unique_ptr<LogFile>* current_log_file) override; | ||
virtual Status GetCreationTimeOfOldestFile( | ||
uint64_t* creation_time) override; | ||
virtual Status GetCreationTimeOfOldestFile(uint64_t* creation_time) override; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Revert this line, need to commit without running clang-format locally. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
|
||
virtual Status GetUpdatesSince( | ||
SequenceNumber seq_number, std::unique_ptr<TransactionLogIterator>* iter, | ||
|
@@ -2283,6 +2282,13 @@ class DBImpl : public DB { | |
Directories directories_; | ||
|
||
WriteBufferManager* write_buffer_manager_; | ||
// For simplicity, CF based write buffer manager does not support stall the | ||
// write. | ||
// Note: std::shared_ptr<WriteBufferManager> is store in ColumnfamilyOptions | ||
// which is destroyed before DBimpl, so we use | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you had any actual error caused by not using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, UnregisterDB is used after VersionSet is destroyed. |
||
// std::shared_ptr<WriteBufferManager> here in the vector. | ||
autovector<std::shared_ptr<WriteBufferManager>> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment that this is only modified in Open, and lock is not needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
cf_based_write_buffer_manager_; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If CreateColumnFamily passed in an option not in the list, return error. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
|
||
WriteThread write_thread_; | ||
WriteBatch tmp_batch_; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1625,6 +1625,22 @@ Status DBImpl::Open(const DBOptions& db_options, const std::string& dbname, | |
} | ||
|
||
DBImpl* impl = new DBImpl(db_options, dbname, seq_per_batch, batch_per_txn); | ||
for (auto cf : column_families) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic of this block of code is quite isolated. I think it's better to wrap a private function for it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer not, adding a member function has both mental overhead and compilation overhead. Plus this block can't be exactly reused elsewhere. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the major benefit of a private function is better readability: people can skip the detail when they don't care the very detail of the block. Other benefits include better testability, and more modular code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, it is always a trade-off to extract a sub-routine. Reading function has a significant context switch overhead, and for non-pure function that modifies states it is mostly needed to read the implementation of the function. In RocksDB codebase it is generally preferred to use inlined code rather than many small functions. Some believe it helps with code quality. |
||
if (cf.options.cf_write_buffer_manager != nullptr) { | ||
bool already_exist = false; | ||
for (auto m : impl->cf_based_write_buffer_manager_) { | ||
if (m == cf.options.cf_write_buffer_manager) { | ||
already_exist = true; | ||
break; | ||
} | ||
} | ||
if (!already_exist) { | ||
impl->cf_based_write_buffer_manager_.push_back( | ||
cf.options.cf_write_buffer_manager); | ||
} | ||
} | ||
} | ||
|
||
s = impl->env_->CreateDirIfMissing(impl->immutable_db_options_.GetWalDir()); | ||
if (s.ok()) { | ||
std::vector<std::string> paths; | ||
|
@@ -1896,20 +1912,34 @@ Status DBImpl::Open(const DBOptions& db_options, const std::string& dbname, | |
} | ||
if (s.ok()) { | ||
impl->StartPeriodicWorkScheduler(); | ||
|
||
// Newly created handles are already registered during | ||
// `CreateColumnFamily`. We must clear them all to avoid duplicate | ||
// registration. | ||
if (impl->write_buffer_manager_) { | ||
// Newly created handles are already registered during | ||
// `CreateColumnFamily`. We must clear them all to avoid duplicate | ||
// registration. | ||
impl->write_buffer_manager_->UnregisterDB(impl); | ||
for (auto* cf : *handles) { | ||
} | ||
for (auto m : impl->cf_based_write_buffer_manager_) { | ||
m->UnregisterDB(impl); | ||
} | ||
|
||
for (size_t i = 0; i < (*handles).size(); ++i) { | ||
auto cf_opt = column_families[i].options; | ||
|
||
auto* cf = (*handles)[i]; | ||
std::string cf_name = cf->GetName(); | ||
auto* write_buffer_manager = cf_opt.cf_write_buffer_manager != nullptr | ||
? cf_opt.cf_write_buffer_manager.get() | ||
: impl->write_buffer_manager_; | ||
if (write_buffer_manager) { | ||
if (cf->GetName() == kDefaultColumnFamilyName) { | ||
impl->write_buffer_manager_->RegisterColumnFamily( | ||
impl, impl->default_cf_handle_); | ||
write_buffer_manager->RegisterColumnFamily(impl, | ||
impl->default_cf_handle_); | ||
} else if (cf->GetName() == kPersistentStatsColumnFamilyName) { | ||
impl->write_buffer_manager_->RegisterColumnFamily( | ||
write_buffer_manager->RegisterColumnFamily( | ||
impl, impl->persist_stats_cf_handle_); | ||
} else { | ||
impl->write_buffer_manager_->RegisterColumnFamily(impl, cf); | ||
write_buffer_manager->RegisterColumnFamily(impl, cf); | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1304,6 +1304,11 @@ Status DBImpl::PreprocessWrite(const WriteOptions& write_options, | |
if (UNLIKELY(status.ok() && write_buffer_manager_->ShouldFlush())) { | ||
write_buffer_manager_->MaybeFlush(this); | ||
} | ||
for (auto write_buffer_manager : cf_based_write_buffer_manager_) { | ||
if (UNLIKELY(status.ok() && write_buffer_manager->ShouldFlush())) { | ||
write_buffer_manager->MaybeFlush(this); | ||
} | ||
} | ||
|
||
if (UNLIKELY(status.ok() && !trim_history_scheduler_.Empty())) { | ||
InstrumentedMutexLock l(&mutex_); | ||
|
@@ -2282,6 +2287,12 @@ size_t DBImpl::GetWalPreallocateBlockSize(uint64_t write_buffer_size) const { | |
bsize = std::min<size_t>(bsize, buffer_size); | ||
} | ||
} | ||
for (auto manager : cf_based_write_buffer_manager_) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be min(db_write_buffer_size, sum(cf_wbm_size) + db_wbm_size). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
size_t buffer_size = manager->flush_size(); | ||
if (buffer_size > 0) { | ||
bsize = std::min<size_t>(bsize, buffer_size); | ||
} | ||
} | ||
|
||
return bsize; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -967,23 +967,33 @@ class DBTestBase : public testing::Test { | |
|
||
DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_); } | ||
|
||
void CreateColumnFamilies(const std::vector<std::string>& cfs, | ||
const Options& options); | ||
void CreateColumnFamilies( | ||
const std::vector<std::string>& cfs, const Options& options, | ||
std::unordered_map<std::string, std::shared_ptr<WriteBufferManager>> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not the intended use case of this function. If you have different options for each cf, use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
wfms = {}); | ||
|
||
void CreateAndReopenWithCF(const std::vector<std::string>& cfs, | ||
const Options& options); | ||
void CreateAndReopenWithCF( | ||
const std::vector<std::string>& cfs, const Options& options, | ||
std::unordered_map<std::string, std::shared_ptr<WriteBufferManager>> | ||
wfms = {}); | ||
|
||
void ReopenWithColumnFamilies(const std::vector<std::string>& cfs, | ||
const std::vector<Options>& options); | ||
|
||
void ReopenWithColumnFamilies(const std::vector<std::string>& cfs, | ||
const Options& options); | ||
void ReopenWithColumnFamilies( | ||
const std::vector<std::string>& cfs, const Options& options, | ||
std::unordered_map<std::string, std::shared_ptr<WriteBufferManager>> | ||
wfms = {}); | ||
|
||
Status TryReopenWithColumnFamilies(const std::vector<std::string>& cfs, | ||
const std::vector<Options>& options); | ||
Status TryReopenWithColumnFamilies( | ||
const std::vector<std::string>& cfs, const std::vector<Options>& options, | ||
std::unordered_map<std::string, std::shared_ptr<WriteBufferManager>> | ||
wfms = {}); | ||
|
||
Status TryReopenWithColumnFamilies(const std::vector<std::string>& cfs, | ||
const Options& options); | ||
Status TryReopenWithColumnFamilies( | ||
const std::vector<std::string>& cfs, const Options& options, | ||
std::unordered_map<std::string, std::shared_ptr<WriteBufferManager>> | ||
wfms = {}); | ||
|
||
void Reopen(const Options& options); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving this block out looks better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done