0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-25 16:22:35 +01:00

ircd::db: Move the write mutex to a global and lock for compaction points too.

This commit is contained in:
Jason Volk 2018-08-26 20:24:38 -07:00
parent edbc0984c5
commit cd74a39330
2 changed files with 18 additions and 6 deletions

View file

@ -109,6 +109,9 @@ ircd::db::request
0, // don't prespawn because this is static 0, // don't prespawn because this is static
}; };
decltype(ircd::db::write_mutex)
ircd::db::write_mutex;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// init // init
@ -6624,9 +6627,6 @@ ircd::db::compact(column &column,
d.d->GetColumnFamilyMetaData(c, &cfmd); d.d->GetColumnFamilyMetaData(c, &cfmd);
for(const auto &level : cfmd.levels) for(const auto &level : cfmd.levels)
{ {
ctx::interruption_point();
ctx::uninterruptible::nothrow ui;
if(level_ != -1 && level.level != level_) if(level_ != -1 && level.level != level_)
continue; continue;
@ -6640,6 +6640,16 @@ ircd::db::compact(column &column,
return std::move(metadata.name); return std::move(metadata.name);
}); });
// Locking the write_mutex here prevents writes during a column's
// compaction. This is needed because if contention occurs inside
// rocksdb we will hit some std::mutex's which do not use the
// rocksdb::port wrapper and deadlock the process. (It is an error
// on the part of rocksdb to directly use std::mutex rather than their
// port wrapper).
ctx::interruption_point();
const std::lock_guard<decltype(write_mutex)> lock{write_mutex};
const ctx::uninterruptible::nothrow ui;
log::debug log::debug
{ {
log, "'%s':'%s' COMPACT level:%d files:%zu size:%zu", log, "'%s':'%s' COMPACT level:%d files:%zu size:%zu",
@ -7295,9 +7305,10 @@ ircd::db::commit(database &d,
// This lock is necessary to serialize entry into rocksdb's write impl // This lock is necessary to serialize entry into rocksdb's write impl
// otherwise there's a risk of a deadlock if their internal pthread // otherwise there's a risk of a deadlock if their internal pthread
// mutexes are contended. // mutexes are contended. This is because a few parts of rocksdb are
thread_local ctx::mutex mutex; // using std::mutex directly when they ought to be using their
const std::lock_guard<decltype(mutex)> lock{mutex}; // rocksdb::port wrapper.
const std::lock_guard<decltype(write_mutex)> lock{write_mutex};
const ctx::uninterruptible ui; const ctx::uninterruptible ui;
throw_on_error throw_on_error

View file

@ -44,6 +44,7 @@ namespace ircd::db
extern conf::item<size_t> request_pool_size; extern conf::item<size_t> request_pool_size;
extern conf::item<size_t> request_pool_stack_size; extern conf::item<size_t> request_pool_stack_size;
extern ctx::pool request; extern ctx::pool request;
extern ctx::mutex write_mutex;
// reflections // reflections
string_view reflect(const rocksdb::Env::Priority &p); string_view reflect(const rocksdb::Env::Priority &p);