diff --git a/ircd/db.cc b/ircd/db.cc index 68f9beb4f..54a0e800a 100644 --- a/ircd/db.cc +++ b/ircd/db.cc @@ -109,6 +109,8 @@ ircd::db::init::direct_io_test_file_path ircd::db::init::init() try { + const ctx::uninterruptible::nothrow ui; + #ifdef IRCD_DB_HAS_ALLOCATOR database::allocator::init(); #endif @@ -1049,7 +1051,7 @@ ircd::db::for_each(database &d, { std::unique_ptr tit; { - const ctx::uninterruptible ui; + const ctx::uninterruptible::nothrow ui; throw_on_error { d.d->GetUpdatesSince(seq, &tit) @@ -1543,11 +1545,17 @@ ircd::db::txn::checkpoint::checkpoint(txn &t) ircd::db::txn::checkpoint::~checkpoint() noexcept { - const ctx::uninterruptible ui; + const ctx::uninterruptible::nothrow ui; if(likely(!std::uncaught_exceptions())) - throw_on_error { t.wb->PopSavePoint() }; + throw_on_error + { + t.wb->PopSavePoint() + }; else - throw_on_error { t.wb->RollbackToSavePoint() }; + throw_on_error + { + t.wb->RollbackToSavePoint() + }; } // @@ -1931,6 +1939,7 @@ ircd::db::_make_iterators(database &d, std::vector ret; const ctx::stack_usage_assertion sua; + const ctx::uninterruptible::nothrow ui; throw_on_error { d.d->NewIterators(opts, handles, &ret) @@ -2729,6 +2738,7 @@ ircd::db::setopt(column &column, { std::string{key}, std::string{val} } }; + const ctx::uninterruptible::nothrow ui; throw_on_error { d.d->SetOptions(c, options) @@ -2746,10 +2756,15 @@ ircd::db::ingest(column &column, opts.allow_global_seqno = true; opts.allow_blocking_flush = true; + const ctx::uninterruptible::nothrow ui; + const auto &copts + { + d.d->GetOptions(c) + }; + // Automatically determine if we can avoid issuing new sequence // numbers by considering this ingestion as "backfill" of missing // data which did actually exist but was physically removed. - const auto &copts{d.d->GetOptions(c)}; opts.ingest_behind = copts.allow_ingest_behind; const std::vector files { @@ -2757,7 +2772,6 @@ ircd::db::ingest(column &column, }; const std::lock_guard lock{d.write_mutex}; - const ctx::uninterruptible::nothrow ui; throw_on_error { d.d->IngestExternalFile(c, files, opts) @@ -3002,6 +3016,8 @@ ircd::db::bytes(column &column, const std::pair &key, const gopts &gopts) { + const ctx::uninterruptible::nothrow ui; + database &d(column); database::column &c(column); const rocksdb::Range range[1] @@ -3032,6 +3048,8 @@ ircd::db::has(column &column, auto opts(make_opts(gopts)); if(c.table_opts.filter_policy && (false)) { + const ctx::uninterruptible::nothrow ui; + auto opts(make_opts(gopts)); const scope_restore read_tier { @@ -3208,9 +3226,11 @@ ircd::db::prop_str ircd::db::property(const column &column, const string_view &name) { + const ctx::uninterruptible::nothrow ui; + std::string ret; - database::column &c(mutable_cast(column)); database &d(mutable_cast(column)); + database::column &c(mutable_cast(column)); if(!d.d->GetProperty(c, slice(name), &ret)) throw not_found { @@ -3228,9 +3248,11 @@ ircd::db::prop_int ircd::db::property(const column &column, const string_view &name) { + const ctx::uninterruptible::nothrow ui; + uint64_t ret(0); - database::column &c(mutable_cast(column)); database &d(mutable_cast(column)); + database::column &c(mutable_cast(column)); if(!d.d->GetIntProperty(c, slice(name), &ret)) throw not_found { @@ -3248,9 +3270,11 @@ ircd::db::prop_map ircd::db::property(const column &column, const string_view &name) { + const ctx::uninterruptible::nothrow ui; + std::map ret; - database::column &c(mutable_cast(column)); database &d(mutable_cast(column)); + database::column &c(mutable_cast(column)); if(!d.d->GetMapProperty(c, slice(name), &ret)) ret.emplace(std::string{name}, property(column, name)); @@ -3260,6 +3284,8 @@ ircd::db::property(const column &column, ircd::db::options ircd::db::getopt(const column &column) { + const ctx::uninterruptible::nothrow ui; + database &d(mutable_cast(column)); database::column &c(mutable_cast(column)); return options @@ -3271,9 +3297,12 @@ ircd::db::getopt(const column &column) size_t ircd::db::bytes(const column &column) { + const ctx::uninterruptible::nothrow ui; + rocksdb::ColumnFamilyMetaData cfm; database &d(mutable_cast(column)); database::column &c(mutable_cast(column)); + assert(bool(c.handle)); d.d->GetColumnFamilyMetaData(c.handle.get(), &cfm); return cfm.size; @@ -3282,9 +3311,12 @@ ircd::db::bytes(const column &column) size_t ircd::db::file_count(const column &column) { + const ctx::uninterruptible::nothrow ui; + rocksdb::ColumnFamilyMetaData cfm; database &d(mutable_cast(column)); database::column &c(mutable_cast(column)); + assert(bool(c.handle)); d.d->GetColumnFamilyMetaData(c.handle.get(), &cfm); return cfm.file_count; @@ -3293,6 +3325,8 @@ ircd::db::file_count(const column &column) std::vector ircd::db::files(const column &column) { + const ctx::uninterruptible::nothrow ui; + database::column &c(mutable_cast(column)); database &d(*c.d); @@ -4666,7 +4700,7 @@ ircd::db::_seek(database::column &c, const string_view &key, const rocksdb::ReadOptions &ropts) { - const ctx::uninterruptible::nothrow ui; + const ctx::uninterruptible ui; const ctx::stack_usage_assertion sua; rocksdb::ColumnFamilyHandle *const &cf(c); @@ -4791,7 +4825,7 @@ ircd::db::_seek(const vector_view<_read_op> &op, assert(ret.size() == val.size()); const ctx::stack_usage_assertion sua; - const ctx::uninterruptible::nothrow ui; + const ctx::uninterruptible ui; assert(op.size() >= 1); database &d(std::get<0>(op[0])); @@ -4874,10 +4908,11 @@ ircd::db::seek(database::column &c, const rocksdb::ReadOptions &opts, std::unique_ptr &it) { + const ctx::uninterruptible ui; + const ctx::stack_usage_assertion sua; + if(!it) { - const ctx::uninterruptible::nothrow ui; - database &d(*c.d); rocksdb::ColumnFamilyHandle *const &cf(c); it.reset(d.d->NewIterator(opts, cf)); @@ -4893,8 +4928,6 @@ ircd::db::_seek(database::column &c, rocksdb::Iterator &it) try { - const ctx::uninterruptible ui; - util::timer timer{util::timer::nostart}; if constexpr(RB_DEBUG_DB_SEEK) timer = util::timer{}; @@ -4940,8 +4973,6 @@ ircd::db::_seek(database::column &c, rocksdb::Iterator &it) try { - const ctx::stack_usage_assertion sua; - bool valid_it; util::timer timer{util::timer::nostart}; if constexpr(RB_DEBUG_DB_SEEK) @@ -4992,6 +5023,8 @@ rocksdb::Iterator & ircd::db::_seek_lower_(rocksdb::Iterator &it, const string_view &sv) { + assert(!ctx::interruptible()); + it.SeekForPrev(slice(sv)); return it; } @@ -5001,6 +5034,8 @@ rocksdb::Iterator & ircd::db::_seek_upper_(rocksdb::Iterator &it, const string_view &sv) { + assert(!ctx::interruptible()); + it.Seek(slice(sv)); return it; } @@ -5017,6 +5052,8 @@ rocksdb::Iterator & ircd::db::_seek_(rocksdb::Iterator &it, const pos &p) { + assert(!ctx::interruptible()); + switch(p) { case pos::NEXT: it.Next(); break; diff --git a/ircd/db_database.cc b/ircd/db_database.cc index 5cd8a7a5a..253c1f7f9 100644 --- a/ircd/db_database.cc +++ b/ircd/db_database.cc @@ -102,6 +102,7 @@ ircd::db::sync(database &d) sequence(d) }; + const ctx::uninterruptible::nothrow ui; throw_on_error { d.d->SyncWAL() @@ -121,6 +122,7 @@ ircd::db::flush(database &d, sequence(d) }; + const ctx::uninterruptible::nothrow ui; throw_on_error { d.d->FlushWAL(sync) @@ -205,6 +207,8 @@ void ircd::db::check(database &d) { assert(d.d); + + const ctx::uninterruptible ui; throw_on_error { d.d->VerifyChecksum() @@ -218,6 +222,7 @@ ircd::db::check(database &d, assert(file); assert(d.d); + const ctx::uninterruptible ui; const auto &opts { d.d->GetOptions() @@ -255,6 +260,7 @@ void ircd::db::resume(database &d) { assert(d.d); + const ctx::uninterruptible::nothrow ui; const std::lock_guard lock { @@ -295,6 +301,7 @@ ircd::db::refresh(database &d) { assert(d.d); + const ctx::uninterruptible ui; throw_on_error { #ifdef IRCD_DB_HAS_SECONDARY @@ -316,6 +323,7 @@ ircd::db::bgpause(database &d) { assert(d.d); + const ctx::uninterruptible::nothrow ui; throw_on_error { d.d->PauseBackgroundWork() @@ -339,6 +347,7 @@ ircd::db::bgcontinue(database &d) name(d) }; + const ctx::uninterruptible::nothrow ui; throw_on_error { d.d->ContinueBackgroundWork() @@ -350,19 +359,20 @@ ircd::db::bgcancel(database &d, const bool &blocking) { assert(d.d); + log::debug { log, "[%s] Canceling all background work...", name(d) }; + const ctx::uninterruptible::nothrow ui; rocksdb::CancelAllBackgroundWork(d.d.get(), blocking); if(!blocking) return; assert(d.env); assert(d.env->st); - const ctx::uninterruptible::nothrow ui; for(auto &pool : d.env->st->pool) if(pool) { log::debug @@ -452,6 +462,8 @@ ircd::db::fdeletions(database &d, const bool &enable, const bool &force) { + const ctx::uninterruptible::nothrow ui; + if(enable) throw_on_error { @@ -474,6 +486,7 @@ ircd::db::setopt(database &d, { std::string{key}, std::string{val} } }; + const ctx::uninterruptible ui; throw_on_error { d.d->SetDBOptions(options) @@ -543,6 +556,7 @@ ircd::db::loglevel(const database &d) ircd::db::options ircd::db::getopt(const database &d) { + const ctx::uninterruptible::nothrow ui; return options { d.d->GetDBOptions() @@ -573,17 +587,14 @@ ircd::db::file_count(const database &d) /// Get the list of WAL (Write Ahead Log) files. std::vector -ircd::db::wals(const database &cd) +ircd::db::wals(const database &d) { - auto &d - { - mutable_cast(cd) - }; + const ctx::uninterruptible::nothrow ui; std::vector> vec; throw_on_error { - d.d->GetSortedWalFiles(vec) + mutable_cast(d).d->GetSortedWalFiles(vec) }; std::vector ret(vec.size()); @@ -612,14 +623,15 @@ ircd::db::files(const database &d) /// most current list is to flush all columns first and ensure no database /// activity took place between the flushing and this query. std::vector -ircd::db::files(const database &cd, +ircd::db::files(const database &d, uint64_t &msz) { + const ctx::uninterruptible::nothrow ui; + std::vector ret; - auto &d(mutable_cast(cd)); throw_on_error { - d.d->GetLiveFiles(ret, &msz, false) + mutable_cast(d).d->GetLiveFiles(ret, &msz, false) }; return ret; @@ -631,11 +643,12 @@ ircd::db::errors(const database &d) return d.errors; } +[[gnu::hot]] uint64_t -ircd::db::sequence(const database &cd) +ircd::db::sequence(const database &d) { - database &d(mutable_cast(cd)); - return d.d->GetLatestSequenceNumber(); + const ctx::critical_assertion ca; + return mutable_cast(d).d->GetLatestSequenceNumber(); } rocksdb::Cache * @@ -657,6 +670,7 @@ ircd::db::property(const database &cd, { uint64_t ret(0); database &d(mutable_cast(cd)); + const ctx::uninterruptible::nothrow ui; if(!d.d->GetAggregatedIntProperty(slice(name), &ret)) throw not_found { @@ -722,6 +736,7 @@ ircd::db::default_description { "default" } }; +[[gnu::hot]] ircd::db::database & ircd::db::database::get(column &column) { @@ -729,6 +744,7 @@ ircd::db::database::get(column &column) return *column.d; } +[[gnu::hot]] const ircd::db::database & ircd::db::database::get(const column &column) { @@ -1101,6 +1117,8 @@ try }()} ,d{[this] { + const ctx::uninterruptible::nothrow ui; + std::vector handles; // filled by DB::Open() std::vector columns(this->column_names.size()); std::transform(begin(this->column_names), end(this->column_names), begin(columns), [] @@ -1115,7 +1133,9 @@ try { log::notice { - log, "Checking database @ `%s' columns[%zu]", path, columns.size() + log, "Checking database @ `%s' columns[%zu]", + path, + columns.size() }; throw_on_error @@ -1125,7 +1145,8 @@ try log::info { - log, "Database @ `%s' check complete", path + log, "Database @ `%s' check complete", + path }; } @@ -1230,6 +1251,7 @@ try ,uuid{[this] { std::string ret; + const ctx::uninterruptible::nothrow ui; throw_on_error { d->GetDbIdentity(ret) @@ -1240,6 +1262,7 @@ try ,checkpointer{[this] { rocksdb::Checkpoint *checkpointer{nullptr}; + const ctx::uninterruptible::nothrow ui; throw_on_error { rocksdb::Checkpoint::Create(this->d.get(), &checkpointer) @@ -1593,6 +1616,7 @@ ircd::db::drop(database::column &c) sequence(d) }; + const ctx::uninterruptible::nothrow ui; throw_on_error { c.d->d->DropColumnFamily(c.handle.get()) @@ -3672,6 +3696,7 @@ ircd::db::database::sst::tool(const vector_view &args) ircd::db::database::sst::scan::scan(database &d, const string_view &fpath) { + const ctx::uninterruptible::nothrow ui; const auto &opts { d.d->GetOptions() @@ -3708,6 +3733,7 @@ ircd::db::database::sst::scan::scan(database &d, const string_view &fpath, const closure &call) { + const ctx::uninterruptible::nothrow ui; const auto &opts { d.d->GetOptions() @@ -3764,6 +3790,7 @@ ircd::db::database::sst::dump::dump(db::column column, const key_range &range, const string_view &path_) { + const ctx::uninterruptible::nothrow ui; database::column &c(column); const database &d(column); std::string path @@ -3850,6 +3877,7 @@ ircd::db::database::sst::info::vector::vector(const database &d) ircd::db::database::sst::info::vector::vector(const db::column &column) { + const ctx::uninterruptible::nothrow ui; database::column &c(mutable_cast(column)); database &d(*c.d); @@ -3895,8 +3923,8 @@ ircd::db::database::sst::info::vector::vector(const db::column &column) ircd::db::database::sst::info::info(const database &d_, const string_view &filename) { - auto &d(mutable_cast(d_)); const ctx::uninterruptible::nothrow ui; + auto &d(mutable_cast(d_)); std::vector v; d.d->GetLiveFilesMetaData(&v); @@ -4023,13 +4051,14 @@ ircd::db::database::sst::info::operator=(rocksdb::TableProperties &&tp) // wal::info::vector // -ircd::db::database::wal::info::vector::vector(const database &d_) +ircd::db::database::wal::info::vector::vector(const database &d) { - auto &d{mutable_cast(d_)}; + const ctx::uninterruptible::nothrow ui; + std::vector> vec; throw_on_error { - d.d->GetSortedWalFiles(vec) + mutable_cast(d).d->GetSortedWalFiles(vec) }; this->resize(vec.size()); @@ -4041,14 +4070,15 @@ ircd::db::database::wal::info::vector::vector(const database &d_) // wal::info::info // -ircd::db::database::wal::info::info(const database &d_, +ircd::db::database::wal::info::info(const database &d, const string_view &filename) { - auto &d{mutable_cast(d_)}; + const ctx::uninterruptible::nothrow ui; + std::vector> vec; throw_on_error { - d.d->GetSortedWalFiles(vec) + mutable_cast(d).d->GetSortedWalFiles(vec) }; for(const auto &ptr : vec)