2018-01-24 00:39:44 +01:00
|
|
|
// Matrix Construct
|
|
|
|
//
|
|
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
|
|
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
|
|
|
//
|
|
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
|
|
// copyright notice and this permission notice is present in all copies. The
|
|
|
|
// full license for this software is available in the LICENSE file.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2023-01-19 05:47:09 +01:00
|
|
|
/// Enable extensive log messages covering the entire RocksDB callback surface.
|
|
|
|
/// This is only useful for developers specifically working on the backend of
|
|
|
|
/// the DB and no real use for developers making frontend queries to it.
|
|
|
|
/// Massively verbose.
|
2018-05-29 10:42:48 +02:00
|
|
|
///
|
2023-01-19 05:47:09 +01:00
|
|
|
#define RB_DEBUG_DB_ENV 0
|
2018-05-29 10:42:48 +02:00
|
|
|
|
|
|
|
/// This #define is more useful to developers making queries to the database.
|
|
|
|
/// It is still so verbose that it goes beyond what is tolerable and generally
|
|
|
|
/// useful even in debug-mode builds, thus the manual #define being required.
|
|
|
|
///
|
2022-06-15 22:46:38 +02:00
|
|
|
#define RB_DEBUG_DB_SEEK 0
|
|
|
|
#define RB_DEBUG_DB_SEEK_ROW 0
|
|
|
|
#define RB_DEBUG_DB_PREFETCH 0
|
2022-06-16 04:10:13 +02:00
|
|
|
#define RB_DEBUG_DB_CACHE 0
|
|
|
|
#define RB_DEBUG_DB_CACHE_HIT 0
|
2022-07-11 23:47:34 +02:00
|
|
|
#define RB_DEBUG_DB_ALLOCATOR 0
|
2018-05-29 10:42:48 +02:00
|
|
|
|
2022-06-15 00:16:57 +02:00
|
|
|
/// Set this #define to 1 or 2 to enable extensive log messages for the
|
2018-08-16 13:48:21 +02:00
|
|
|
/// experimental db environment-port implementation. This is only useful
|
|
|
|
/// for developers working on the port impl and want to debug all locking
|
|
|
|
/// and unlocking etc.
|
|
|
|
///
|
2022-06-15 00:16:57 +02:00
|
|
|
#define RB_DEBUG_DB_PORT 0
|
2018-08-16 13:48:21 +02:00
|
|
|
|
2023-02-22 00:39:44 +01:00
|
|
|
// RocksDB doesn't use exceptions, but our units don't know to optimize for
|
|
|
|
// that from their headers. This adds noexcept to every function in their API.
|
|
|
|
#pragma clang attribute push([[gnu::nothrow]], apply_to=any(hasType(functionType)))
|
2019-01-23 22:51:17 +01:00
|
|
|
#include <rocksdb/version.h>
|
|
|
|
#include <rocksdb/status.h>
|
|
|
|
#include <rocksdb/db.h>
|
|
|
|
#include <rocksdb/cache.h>
|
|
|
|
#include <rocksdb/comparator.h>
|
|
|
|
#include <rocksdb/merge_operator.h>
|
|
|
|
#include <rocksdb/perf_level.h>
|
|
|
|
#include <rocksdb/perf_context.h>
|
|
|
|
#include <rocksdb/iostats_context.h>
|
|
|
|
#include <rocksdb/listener.h>
|
|
|
|
#include <rocksdb/statistics.h>
|
|
|
|
#include <rocksdb/convenience.h>
|
|
|
|
#include <rocksdb/env.h>
|
|
|
|
#include <rocksdb/slice_transform.h>
|
|
|
|
#include <rocksdb/utilities/checkpoint.h>
|
|
|
|
#include <rocksdb/filter_policy.h>
|
|
|
|
#include <rocksdb/table.h>
|
|
|
|
#include <rocksdb/sst_file_manager.h>
|
2021-11-18 02:07:24 +01:00
|
|
|
#include <rocksdb/sst_file_reader.h>
|
2019-01-23 22:51:17 +01:00
|
|
|
#include <rocksdb/sst_dump_tool.h>
|
|
|
|
#include <rocksdb/compaction_filter.h>
|
2019-04-20 23:22:08 +02:00
|
|
|
#include <rocksdb/wal_filter.h>
|
2020-09-15 04:53:35 +02:00
|
|
|
#include <rocksdb/rate_limiter.h>
|
2023-03-18 05:24:18 +01:00
|
|
|
#if __has_include(<rocksdb/advanced_cache.h>)
|
|
|
|
#include <rocksdb/advanced_cache.h>
|
|
|
|
#endif
|
2023-02-22 00:39:44 +01:00
|
|
|
#pragma clang attribute pop
|
2019-01-23 22:51:17 +01:00
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
#include "db_has.h"
|
|
|
|
#include "db_port.h"
|
|
|
|
#include "db_env.h"
|
|
|
|
#include "db_env_state.h"
|
|
|
|
|
|
|
|
#pragma GCC visibility push(hidden)
|
2018-01-24 00:39:44 +01:00
|
|
|
namespace ircd::db
|
|
|
|
{
|
|
|
|
struct throw_on_error;
|
2018-08-23 13:19:32 +02:00
|
|
|
struct error_to_status;
|
2018-01-24 00:39:44 +01:00
|
|
|
|
2020-06-16 07:34:08 +02:00
|
|
|
constexpr auto BLOCKING { rocksdb::ReadTier::kReadAllTier };
|
|
|
|
constexpr auto NON_BLOCKING { rocksdb::ReadTier::kBlockCacheTier };
|
2018-01-24 00:39:44 +01:00
|
|
|
|
2018-08-23 13:02:12 +02:00
|
|
|
// state
|
2018-01-30 18:58:36 +01:00
|
|
|
extern log::log rog;
|
2020-09-15 10:53:30 +02:00
|
|
|
extern conf::item<bool> enable_wal;
|
2020-10-12 01:05:55 +02:00
|
|
|
extern conf::item<bool> read_checksum;
|
2018-08-22 23:08:27 +02:00
|
|
|
extern conf::item<size_t> request_pool_size;
|
|
|
|
extern conf::item<size_t> request_pool_stack_size;
|
2018-12-28 21:57:32 +01:00
|
|
|
extern ctx::pool::opts request_pool_opts;
|
2018-08-19 04:30:25 +02:00
|
|
|
extern ctx::pool request;
|
2018-01-24 00:39:44 +01:00
|
|
|
|
2018-08-23 13:02:12 +02:00
|
|
|
// reflections
|
2020-02-27 23:46:28 +01:00
|
|
|
string_view reflect(const rocksdb::Status::Code &);
|
2018-10-31 22:48:14 +01:00
|
|
|
string_view reflect(const rocksdb::Status::Severity &);
|
2018-01-24 00:39:44 +01:00
|
|
|
string_view reflect(const rocksdb::Env::Priority &p);
|
|
|
|
string_view reflect(const rocksdb::Env::IOPriority &p);
|
2018-11-02 09:07:09 +01:00
|
|
|
string_view reflect(const rocksdb::Env::WriteLifeTimeHint &);
|
2018-10-31 22:40:00 +01:00
|
|
|
string_view reflect(const rocksdb::WriteStallCondition &);
|
|
|
|
string_view reflect(const rocksdb::BackgroundErrorReason &);
|
2018-12-19 22:39:06 +01:00
|
|
|
string_view reflect(const rocksdb::CompactionReason &);
|
|
|
|
string_view reflect(const rocksdb::FlushReason &);
|
2018-01-24 00:39:44 +01:00
|
|
|
string_view reflect(const rocksdb::RandomAccessFile::AccessPattern &p);
|
|
|
|
const std::string &reflect(const rocksdb::Tickers &);
|
|
|
|
const std::string &reflect(const rocksdb::Histograms &);
|
2018-08-23 13:02:12 +02:00
|
|
|
|
2018-01-24 00:39:44 +01:00
|
|
|
// Frequently used get options and set options are separate from the string/map system
|
2023-02-17 00:39:01 +01:00
|
|
|
rocksdb::WriteOptions make_opts(const sopts &) noexcept;
|
|
|
|
rocksdb::ReadOptions make_opts(const gopts &) noexcept;
|
2018-01-24 00:39:44 +01:00
|
|
|
|
2023-02-28 00:19:49 +01:00
|
|
|
// Database options as ircd::conf items.
|
|
|
|
static const string_view confs_prefix {"ircd.db"};
|
|
|
|
using confs = std::vector<std::unique_ptr<conf::item<std::string>>>;
|
|
|
|
string_view make_conf_name(const mutable_buffer &, const pair<string_view> &, const string_view &);
|
|
|
|
string_view unmake_conf_name_key(const conf::item<void> &);
|
|
|
|
confs make_confs(const db::options &, const pair<string_view> &, const conf::set_cb &);
|
|
|
|
|
2018-01-24 00:39:44 +01:00
|
|
|
// Database options creator
|
2020-10-12 01:06:20 +02:00
|
|
|
static bool optstr_find_and_remove(std::string &optstr, const std::string &what);
|
2018-04-09 20:51:36 +02:00
|
|
|
rocksdb::DBOptions make_dbopts(std::string optstr, std::string *const &out = nullptr, bool *read_only = nullptr, bool *fsck = nullptr);
|
2018-11-03 02:08:40 +01:00
|
|
|
rocksdb::CompressionType find_supported_compression(const std::string &);
|
2018-01-24 00:39:44 +01:00
|
|
|
|
2019-01-29 20:13:58 +01:00
|
|
|
// Read column names from filesystem
|
|
|
|
std::vector<std::string> column_names(const std::string &path, const rocksdb::DBOptions &);
|
|
|
|
std::vector<std::string> column_names(const std::string &path, const std::string &options);
|
|
|
|
|
2018-01-24 00:39:44 +01:00
|
|
|
// Validation functors
|
2020-10-12 01:06:20 +02:00
|
|
|
static bool valid(const rocksdb::Status &);
|
2018-01-24 00:39:44 +01:00
|
|
|
using valid_proffer = std::function<bool (const rocksdb::Iterator &)>;
|
2020-10-12 01:06:20 +02:00
|
|
|
static bool valid(const rocksdb::Iterator &, const valid_proffer &);
|
|
|
|
static bool valid_eq(const rocksdb::Iterator &, const string_view &);
|
|
|
|
static bool valid_lte(const rocksdb::Iterator &, const string_view &);
|
|
|
|
static bool valid_gt(const rocksdb::Iterator &, const string_view &);
|
|
|
|
static void valid_or_throw(const rocksdb::Iterator &);
|
|
|
|
static void valid_eq_or_throw(const rocksdb::Iterator &, const string_view &);
|
2018-01-24 00:39:44 +01:00
|
|
|
|
2020-06-07 04:59:12 +02:00
|
|
|
// [GET] iterator seek suite
|
2023-04-16 02:08:03 +02:00
|
|
|
template<class pos> static bool seek(database::column &, const pos &, const rocksdb::ReadOptions &, std::unique_ptr<rocksdb::Iterator> &it, const bool lte = false);
|
|
|
|
static std::unique_ptr<rocksdb::Iterator> seek(column &, const string_view &key, const gopts &, const bool lte = false);
|
2020-10-12 01:06:20 +02:00
|
|
|
static std::pair<string_view, string_view> operator*(const rocksdb::Iterator &);
|
2018-01-24 00:39:44 +01:00
|
|
|
|
2020-06-07 04:59:12 +02:00
|
|
|
// [GET] read suite
|
2020-06-09 03:19:55 +02:00
|
|
|
using _read_op = std::tuple<column, string_view>;
|
|
|
|
using _read_closure = std::function<bool (column &, const column::delta &, const rocksdb::Status &)>;
|
2020-10-12 01:06:20 +02:00
|
|
|
static bool _read(const vector_view<_read_op> &, const rocksdb::ReadOptions &, const _read_closure & = {});
|
|
|
|
static rocksdb::Status _read(column &, const string_view &key, const rocksdb::ReadOptions &, const column::view_closure & = {});
|
2020-06-07 04:59:12 +02:00
|
|
|
|
2018-01-24 00:39:44 +01:00
|
|
|
// [SET] writebatch suite
|
2020-08-23 12:22:33 +02:00
|
|
|
string_view debug(const mutable_buffer &, const rocksdb::WriteBatch &);
|
2018-01-24 00:39:44 +01:00
|
|
|
bool has(const rocksdb::WriteBatch &, const op &);
|
|
|
|
void commit(database &, rocksdb::WriteBatch &, const rocksdb::WriteOptions &);
|
|
|
|
void commit(database &, rocksdb::WriteBatch &, const sopts &);
|
|
|
|
void append(rocksdb::WriteBatch &, column &, const column::delta &delta);
|
|
|
|
void append(rocksdb::WriteBatch &, const cell::delta &delta);
|
|
|
|
|
2020-06-05 00:17:09 +02:00
|
|
|
const descriptor &describe(const database::column &);
|
|
|
|
const std::string &name(const database::column &);
|
|
|
|
uint32_t id(const database::column &);
|
2019-08-25 02:40:31 +02:00
|
|
|
|
2020-06-05 00:17:09 +02:00
|
|
|
bool dropped(const database::column &);
|
|
|
|
void drop(database::column &); // Request to erase column from db
|
|
|
|
|
|
|
|
std::shared_ptr<const database::column> shared_from(const database::column &);
|
|
|
|
std::shared_ptr<database::column> shared_from(database::column &);
|
|
|
|
}
|
2020-09-22 04:14:17 +02:00
|
|
|
#pragma GCC visibility pop
|
2020-06-05 00:17:09 +02:00
|
|
|
|
|
|
|
#ifdef IRCD_DB_HAS_ALLOCATOR
|
|
|
|
/// Dynamic memory
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::allocator final
|
2020-06-05 00:17:09 +02:00
|
|
|
:rocksdb::MemoryAllocator
|
2018-01-24 00:39:44 +01:00
|
|
|
{
|
2020-06-05 00:17:09 +02:00
|
|
|
static const size_t ALIGN_DEFAULT;
|
|
|
|
static const size_t mlock_limit;
|
|
|
|
static const bool mlock_enabled;
|
|
|
|
static size_t mlock_current;
|
|
|
|
static unsigned cache_arena;
|
|
|
|
|
|
|
|
database *d {nullptr};
|
|
|
|
database::column *c {nullptr};
|
|
|
|
size_t alignment {ALIGN_DEFAULT};
|
|
|
|
unsigned arena {0};
|
|
|
|
signed arena_flags{0};
|
|
|
|
|
|
|
|
const char *Name() const noexcept override;
|
|
|
|
void *Allocate(size_t) noexcept override;
|
|
|
|
void Deallocate(void *) noexcept override;
|
|
|
|
size_t UsableSize(void *, size_t) const noexcept override;
|
|
|
|
|
|
|
|
allocator(database *const &,
|
|
|
|
database::column *const & = nullptr,
|
|
|
|
const unsigned &arena = 0,
|
|
|
|
const size_t &alignment = ALIGN_DEFAULT);
|
|
|
|
|
|
|
|
~allocator() noexcept;
|
|
|
|
|
|
|
|
static void init(), fini() noexcept;
|
2018-01-24 00:39:44 +01:00
|
|
|
};
|
2020-06-05 00:17:09 +02:00
|
|
|
#endif
|
2018-08-23 13:19:32 +02:00
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::cache final
|
2020-06-05 00:17:09 +02:00
|
|
|
:rocksdb::Cache
|
2018-08-23 13:19:32 +02:00
|
|
|
{
|
2020-06-05 00:17:09 +02:00
|
|
|
using Slice = rocksdb::Slice;
|
|
|
|
using Status = rocksdb::Status;
|
|
|
|
using deleter = void (*)(const Slice &key, void *value);
|
|
|
|
using callback = void (*)(void *, size_t);
|
|
|
|
using Statistics = rocksdb::Statistics;
|
|
|
|
|
|
|
|
static const int DEFAULT_SHARD_BITS;
|
|
|
|
static const double DEFAULT_HI_PRIO;
|
|
|
|
static const bool DEFAULT_STRICT;
|
|
|
|
|
|
|
|
database *d;
|
|
|
|
std::string name;
|
|
|
|
std::shared_ptr<struct database::stats> stats;
|
|
|
|
std::shared_ptr<struct database::allocator> allocator;
|
|
|
|
std::shared_ptr<rocksdb::Cache> c;
|
|
|
|
|
|
|
|
const char *Name() const noexcept override;
|
2023-03-18 05:24:18 +01:00
|
|
|
#ifdef IRCD_DB_HAS_CACHE_ITEMHELPER
|
|
|
|
Status Insert(const Slice &key, ObjectPtr, const CacheItemHelper *, size_t charge, Handle **, Priority) noexcept override;
|
|
|
|
#else
|
2020-06-05 00:17:09 +02:00
|
|
|
Status Insert(const Slice &key, void *value, size_t charge, deleter, Handle **, Priority) noexcept override;
|
2023-03-18 05:24:18 +01:00
|
|
|
#endif
|
|
|
|
#ifdef IRCD_DB_HAS_CACHE_ITEMHELPER
|
|
|
|
Handle *Lookup(const Slice &key, const CacheItemHelper *, CreateContext *, Priority, bool, Statistics *) noexcept override;
|
|
|
|
#else
|
2020-06-05 00:17:09 +02:00
|
|
|
Handle *Lookup(const Slice &key, Statistics *) noexcept override;
|
2023-03-18 05:24:18 +01:00
|
|
|
#endif
|
2020-06-05 00:17:09 +02:00
|
|
|
bool Ref(Handle *) noexcept override;
|
|
|
|
bool Release(Handle *, bool force_erase) noexcept override;
|
|
|
|
void *Value(Handle *) noexcept override;
|
|
|
|
void Erase(const Slice &key) noexcept override;
|
|
|
|
uint64_t NewId() noexcept override;
|
|
|
|
void SetCapacity(size_t capacity) noexcept override;
|
|
|
|
void SetStrictCapacityLimit(bool strict_capacity_limit) noexcept override;
|
|
|
|
bool HasStrictCapacityLimit() const noexcept override;
|
|
|
|
size_t GetCapacity() const noexcept override;
|
|
|
|
size_t GetUsage() const noexcept override;
|
|
|
|
size_t GetUsage(Handle *) const noexcept override;
|
|
|
|
size_t GetPinnedUsage() const noexcept override;
|
|
|
|
void DisownData() noexcept override;
|
2023-03-18 05:24:18 +01:00
|
|
|
#ifndef IRCD_DB_HAS_CACHE_ITEMHELPER
|
2020-06-05 00:17:09 +02:00
|
|
|
void ApplyToAllCacheEntries(callback, bool thread_safe) noexcept override;
|
2023-03-18 05:24:18 +01:00
|
|
|
#endif
|
2020-06-05 00:17:09 +02:00
|
|
|
void EraseUnRefEntries() noexcept override;
|
|
|
|
std::string GetPrintableOptions() const noexcept override;
|
|
|
|
#ifdef IRCD_DB_HAS_CACHE_GETCHARGE
|
|
|
|
size_t GetCharge(Handle *) const noexcept override;
|
|
|
|
#endif
|
2023-03-18 05:24:18 +01:00
|
|
|
#if defined(IRCD_DB_HAS_CACHE_GETDELETER) && !defined(IRCD_DB_HAS_CACHE_ITEMHELPER)
|
2021-09-15 09:02:26 +02:00
|
|
|
DeleterFn GetDeleter(Handle *) const noexcept override;
|
|
|
|
#endif
|
2023-03-18 05:24:18 +01:00
|
|
|
#ifdef IRCD_DB_HAS_CACHE_ITEMHELPER
|
|
|
|
using callbackstd = std::function<void (const Slice &, ObjectPtr, size_t, const CacheItemHelper *)>;
|
|
|
|
void ApplyToAllEntries(const callbackstd &, const ApplyToAllEntriesOptions &) noexcept override;
|
|
|
|
#elif defined(IRCD_DB_HAS_CACHE_APPLYTOALL)
|
2021-09-15 09:02:26 +02:00
|
|
|
using callbackstd = std::function<void (const Slice &, void *, size_t, DeleterFn)>;
|
|
|
|
void ApplyToAllEntries(const callbackstd &, const ApplyToAllEntriesOptions &) noexcept override;
|
|
|
|
#endif
|
2023-03-18 05:24:18 +01:00
|
|
|
#ifdef IRCD_DB_HAS_CACHE_ITEMHELPER
|
|
|
|
const CacheItemHelper *GetCacheItemHelper(Handle *) const noexcept override;
|
|
|
|
#endif
|
2020-06-05 00:17:09 +02:00
|
|
|
|
|
|
|
cache(database *const &,
|
|
|
|
std::shared_ptr<struct database::stats>,
|
|
|
|
std::shared_ptr<struct database::allocator>,
|
|
|
|
std::string name,
|
|
|
|
const ssize_t &initial_capacity = -1);
|
|
|
|
|
|
|
|
~cache() noexcept override;
|
2018-08-23 13:19:32 +02:00
|
|
|
};
|
2019-07-21 00:29:33 +02:00
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::comparator final
|
2020-06-05 00:17:09 +02:00
|
|
|
:rocksdb::Comparator
|
|
|
|
{
|
|
|
|
using Slice = rocksdb::Slice;
|
|
|
|
|
|
|
|
database *d;
|
|
|
|
db::comparator user;
|
|
|
|
|
|
|
|
bool CanKeysWithDifferentByteContentsBeEqual() const noexcept override;
|
|
|
|
bool IsSameLengthImmediateSuccessor(const Slice &s, const Slice &t) const noexcept override;
|
|
|
|
void FindShortestSeparator(std::string *start, const Slice &limit) const noexcept override;
|
|
|
|
void FindShortSuccessor(std::string *key) const noexcept override;
|
|
|
|
int Compare(const Slice &a, const Slice &b) const noexcept override;
|
|
|
|
bool Equal(const Slice &a, const Slice &b) const noexcept override;
|
|
|
|
const char *Name() const noexcept override;
|
|
|
|
|
|
|
|
comparator(database *const &d, db::comparator user);
|
|
|
|
};
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::prefix_transform final
|
2020-06-05 00:17:09 +02:00
|
|
|
:rocksdb::SliceTransform
|
|
|
|
{
|
|
|
|
using Slice = rocksdb::Slice;
|
|
|
|
|
|
|
|
database *d;
|
|
|
|
db::prefix_transform user;
|
|
|
|
|
|
|
|
const char *Name() const noexcept override;
|
|
|
|
bool InDomain(const Slice &key) const noexcept override;
|
|
|
|
bool InRange(const Slice &key) const noexcept override;
|
|
|
|
Slice Transform(const Slice &key) const noexcept override;
|
|
|
|
|
|
|
|
prefix_transform(database *const &d,
|
|
|
|
db::prefix_transform user)
|
|
|
|
noexcept
|
|
|
|
:d{d}
|
|
|
|
,user{std::move(user)}
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::mergeop final
|
2020-06-05 00:17:09 +02:00
|
|
|
:std::enable_shared_from_this<struct ircd::db::database::mergeop>
|
|
|
|
,rocksdb::AssociativeMergeOperator
|
|
|
|
{
|
|
|
|
database *d;
|
|
|
|
merge_closure merger;
|
|
|
|
|
|
|
|
bool Merge(const rocksdb::Slice &, const rocksdb::Slice *, const rocksdb::Slice &, std::string *, rocksdb::Logger *) const noexcept override;
|
|
|
|
const char *Name() const noexcept override;
|
|
|
|
|
2022-06-24 04:18:05 +02:00
|
|
|
mergeop(database *const &d, merge_closure merger = nullptr) noexcept;
|
2020-06-05 00:17:09 +02:00
|
|
|
~mergeop() noexcept;
|
|
|
|
};
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::compaction_filter final
|
2020-06-05 00:17:09 +02:00
|
|
|
:rocksdb::CompactionFilter
|
|
|
|
{
|
|
|
|
using Slice = rocksdb::Slice;
|
|
|
|
|
|
|
|
column *c;
|
|
|
|
database *d;
|
|
|
|
db::compactor user;
|
|
|
|
|
|
|
|
const char *Name() const noexcept override;
|
|
|
|
bool IgnoreSnapshots() const noexcept override;
|
|
|
|
Decision FilterV2(const int level, const Slice &key, const ValueType v, const Slice &oldval, std::string *newval, std::string *skipuntil) const noexcept override;
|
|
|
|
|
|
|
|
compaction_filter(column *const &c, db::compactor);
|
|
|
|
~compaction_filter() noexcept override;
|
|
|
|
};
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::stats final
|
2020-06-05 00:17:09 +02:00
|
|
|
:rocksdb::Statistics
|
|
|
|
{
|
2020-06-18 03:20:52 +02:00
|
|
|
static constexpr auto NUM_TICKER { rocksdb::TICKER_ENUM_MAX };
|
|
|
|
static constexpr auto NUM_HISTOGRAM { rocksdb::HISTOGRAM_ENUM_MAX };
|
|
|
|
|
2020-06-05 00:17:09 +02:00
|
|
|
struct passthru;
|
|
|
|
|
|
|
|
database *d {nullptr};
|
2020-06-18 04:03:23 +02:00
|
|
|
database::column *c {nullptr};
|
2020-06-18 03:20:52 +02:00
|
|
|
std::array<uint64_t, NUM_TICKER> ticker {{0}};
|
|
|
|
std::array<ircd::stats::item<uint64_t *>, NUM_TICKER> item;
|
|
|
|
std::array<struct db::histogram, NUM_HISTOGRAM> histogram;
|
|
|
|
|
2020-06-18 03:51:35 +02:00
|
|
|
// Additional custom stats
|
|
|
|
ircd::stats::item<uint64_t> get_copied;
|
|
|
|
ircd::stats::item<uint64_t> get_referenced;
|
|
|
|
ircd::stats::item<uint64_t> multiget_copied;
|
|
|
|
ircd::stats::item<uint64_t> multiget_referenced;
|
|
|
|
|
2020-06-18 03:20:52 +02:00
|
|
|
string_view make_name(const string_view &ticker_name) const; // tls buffer
|
2020-06-05 00:17:09 +02:00
|
|
|
|
|
|
|
uint64_t getTickerCount(const uint32_t tickerType) const noexcept override;
|
2020-06-18 03:20:52 +02:00
|
|
|
uint64_t getAndResetTickerCount(const uint32_t tickerType) noexcept override;
|
2020-06-05 00:17:09 +02:00
|
|
|
void recordTick(const uint32_t tickerType, const uint64_t count) noexcept override;
|
|
|
|
void setTickerCount(const uint32_t tickerType, const uint64_t count) noexcept override;
|
2020-06-18 03:20:52 +02:00
|
|
|
|
2020-06-05 00:17:09 +02:00
|
|
|
void histogramData(const uint32_t type, rocksdb::HistogramData *) const noexcept override;
|
|
|
|
void measureTime(const uint32_t histogramType, const uint64_t time) noexcept override;
|
|
|
|
bool HistEnabledForType(const uint32_t type) const noexcept override;
|
|
|
|
rocksdb::Status Reset() noexcept override;
|
|
|
|
|
2020-06-18 03:20:52 +02:00
|
|
|
stats() = default;
|
2020-06-18 04:03:23 +02:00
|
|
|
stats(database *const &d, database::column *const &c = nullptr);
|
2020-06-05 00:17:09 +02:00
|
|
|
~stats() noexcept;
|
|
|
|
};
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::stats::passthru final
|
2020-06-05 00:17:09 +02:00
|
|
|
:rocksdb::Statistics
|
|
|
|
{
|
|
|
|
std::array<rocksdb::Statistics *, 2> pass {{nullptr}};
|
|
|
|
|
|
|
|
void recordTick(const uint32_t tickerType, const uint64_t count) noexcept override;
|
|
|
|
void measureTime(const uint32_t histogramType, const uint64_t time) noexcept override;
|
|
|
|
bool HistEnabledForType(const uint32_t type) const noexcept override;
|
|
|
|
uint64_t getTickerCount(const uint32_t tickerType) const noexcept override;
|
|
|
|
void setTickerCount(const uint32_t tickerType, const uint64_t count) noexcept override;
|
|
|
|
void histogramData(const uint32_t type, rocksdb::HistogramData *) const noexcept override;
|
|
|
|
uint64_t getAndResetTickerCount(const uint32_t tickerType) noexcept override;
|
|
|
|
rocksdb::Status Reset() noexcept override;
|
|
|
|
|
|
|
|
passthru(rocksdb::Statistics *const &a, rocksdb::Statistics *const &b);
|
|
|
|
~passthru() noexcept;
|
|
|
|
};
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::column final
|
2020-06-05 00:17:09 +02:00
|
|
|
:std::enable_shared_from_this<database::column>
|
|
|
|
,rocksdb::ColumnFamilyDescriptor
|
|
|
|
{
|
|
|
|
database *d;
|
|
|
|
db::descriptor *descriptor;
|
|
|
|
std::type_index key_type;
|
|
|
|
std::type_index mapped_type;
|
|
|
|
comparator cmp;
|
|
|
|
prefix_transform prefix;
|
|
|
|
compaction_filter cfilter;
|
2020-12-21 07:10:14 +01:00
|
|
|
rocksdb::WriteStallCondition stall;
|
2020-06-05 00:17:09 +02:00
|
|
|
std::shared_ptr<struct database::stats> stats;
|
|
|
|
std::shared_ptr<struct database::allocator> allocator;
|
|
|
|
rocksdb::BlockBasedTableOptions table_opts;
|
2023-02-28 00:19:49 +01:00
|
|
|
const bool options_preconfiguration;
|
|
|
|
std::vector<std::unique_ptr<conf::item<std::string>>> confs;
|
2020-06-05 00:17:09 +02:00
|
|
|
custom_ptr<rocksdb::ColumnFamilyHandle> handle;
|
|
|
|
|
|
|
|
public:
|
|
|
|
operator const rocksdb::ColumnFamilyOptions &() const;
|
|
|
|
operator const rocksdb::ColumnFamilyHandle *() const;
|
|
|
|
operator const database &() const;
|
|
|
|
|
|
|
|
operator rocksdb::ColumnFamilyHandle *();
|
|
|
|
operator database &();
|
|
|
|
|
|
|
|
explicit column(database &d, db::descriptor &);
|
|
|
|
column() = delete;
|
|
|
|
column(column &&) = delete;
|
|
|
|
column(const column &) = delete;
|
|
|
|
column &operator=(column &&) = delete;
|
|
|
|
column &operator=(const column &) = delete;
|
|
|
|
~column() noexcept;
|
|
|
|
};
|
2019-08-25 02:40:31 +02:00
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::txn::handler
|
2019-07-21 00:29:33 +02:00
|
|
|
:rocksdb::WriteBatch::Handler
|
|
|
|
{
|
|
|
|
using Status = rocksdb::Status;
|
|
|
|
using Slice = rocksdb::Slice;
|
|
|
|
|
|
|
|
const database &d;
|
2020-05-13 03:51:21 +02:00
|
|
|
std::function<bool (const delta &)> cb;
|
2019-07-21 00:29:33 +02:00
|
|
|
bool _continue {true};
|
|
|
|
|
|
|
|
Status callback(const delta &) noexcept;
|
|
|
|
Status callback(const uint32_t &, const op &, const Slice &a, const Slice &b) noexcept;
|
|
|
|
|
|
|
|
bool Continue() noexcept override;
|
|
|
|
Status MarkRollback(const Slice &xid) noexcept override;
|
|
|
|
Status MarkCommit(const Slice &xid) noexcept override;
|
|
|
|
Status MarkEndPrepare(const Slice &xid) noexcept override;
|
|
|
|
Status MarkBeginPrepare(bool = false) noexcept override;
|
|
|
|
|
|
|
|
Status MergeCF(const uint32_t cfid, const Slice &, const Slice &) noexcept override;
|
|
|
|
Status SingleDeleteCF(const uint32_t cfid, const Slice &) noexcept override;
|
|
|
|
Status DeleteRangeCF(const uint32_t cfid, const Slice &, const Slice &) noexcept override;
|
|
|
|
Status DeleteCF(const uint32_t cfid, const Slice &) noexcept override;
|
|
|
|
Status PutCF(const uint32_t cfid, const Slice &, const Slice &) noexcept override;
|
|
|
|
|
|
|
|
handler(const database &d,
|
2020-05-13 03:51:21 +02:00
|
|
|
std::function<bool (const delta &)> cb)
|
2019-07-21 00:29:33 +02:00
|
|
|
:d{d}
|
2020-05-13 03:51:21 +02:00
|
|
|
,cb{std::move(cb)}
|
2019-07-21 00:29:33 +02:00
|
|
|
{}
|
|
|
|
};
|
2020-06-05 00:17:09 +02:00
|
|
|
|
|
|
|
/// Callback surface for iterating/recovering the write-ahead-log journal.
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::wal_filter
|
2020-06-05 00:17:09 +02:00
|
|
|
:rocksdb::WalFilter
|
|
|
|
{
|
|
|
|
using WriteBatch = rocksdb::WriteBatch;
|
|
|
|
using log_number_map = std::map<uint32_t, uint64_t>;
|
|
|
|
using name_id_map = std::map<std::string, uint32_t>;
|
|
|
|
|
|
|
|
static conf::item<bool> debug;
|
|
|
|
|
|
|
|
database *d {nullptr};
|
|
|
|
log_number_map log_number;
|
|
|
|
name_id_map name_id;
|
|
|
|
|
|
|
|
const char *Name() const noexcept override;
|
|
|
|
WalProcessingOption LogRecord(const WriteBatch &, WriteBatch *const replace, bool *replaced) const noexcept override;
|
|
|
|
WalProcessingOption LogRecordFound(unsigned long long log_nr, const std::string &name, const WriteBatch &, WriteBatch *const replace, bool *replaced) noexcept override;
|
|
|
|
void ColumnFamilyLogNumberMap(const log_number_map &, const name_id_map &) noexcept override;
|
|
|
|
|
|
|
|
wal_filter(database *const &);
|
|
|
|
~wal_filter() noexcept;
|
|
|
|
};
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::events final
|
2020-06-05 00:17:09 +02:00
|
|
|
:std::enable_shared_from_this<struct ircd::db::database::events>
|
|
|
|
,rocksdb::EventListener
|
|
|
|
{
|
|
|
|
database *d;
|
|
|
|
|
|
|
|
void OnFlushBegin(rocksdb::DB *, const rocksdb::FlushJobInfo &) noexcept override;
|
|
|
|
void OnFlushCompleted(rocksdb::DB *, const rocksdb::FlushJobInfo &) noexcept override;
|
|
|
|
void OnCompactionCompleted(rocksdb::DB *, const rocksdb::CompactionJobInfo &) noexcept override;
|
|
|
|
void OnTableFileDeleted(const rocksdb::TableFileDeletionInfo &) noexcept override;
|
|
|
|
void OnTableFileCreated(const rocksdb::TableFileCreationInfo &) noexcept override;
|
|
|
|
void OnTableFileCreationStarted(const rocksdb::TableFileCreationBriefInfo &) noexcept override;
|
|
|
|
void OnMemTableSealed(const rocksdb::MemTableInfo &) noexcept override;
|
|
|
|
void OnColumnFamilyHandleDeletionStarted(rocksdb::ColumnFamilyHandle *) noexcept override;
|
|
|
|
void OnExternalFileIngested(rocksdb::DB *, const rocksdb::ExternalFileIngestionInfo &) noexcept override;
|
|
|
|
void OnBackgroundError(rocksdb::BackgroundErrorReason, rocksdb::Status *) noexcept override;
|
|
|
|
void OnStallConditionsChanged(const rocksdb::WriteStallInfo &) noexcept override;
|
|
|
|
|
|
|
|
events(database *const &d)
|
|
|
|
noexcept
|
|
|
|
:d{d}
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::logger final
|
2020-06-05 00:17:09 +02:00
|
|
|
:std::enable_shared_from_this<struct database::logger>
|
|
|
|
,rocksdb::Logger
|
|
|
|
{
|
|
|
|
database *d;
|
|
|
|
|
|
|
|
void Logv(const rocksdb::InfoLogLevel level, const char *fmt, va_list ap) noexcept override;
|
|
|
|
void Logv(const char *fmt, va_list ap) noexcept override;
|
|
|
|
void LogHeader(const char *fmt, va_list ap) noexcept override;
|
|
|
|
|
|
|
|
rocksdb::Status Close() noexcept override;
|
|
|
|
|
2022-06-24 04:18:05 +02:00
|
|
|
logger(database *const &d) noexcept;
|
2020-06-05 00:17:09 +02:00
|
|
|
~logger() noexcept override;
|
|
|
|
};
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::database::rate_limiter
|
2020-09-15 04:53:35 +02:00
|
|
|
:std::enable_shared_from_this<struct database::rate_limiter>
|
|
|
|
,rocksdb::RateLimiter
|
|
|
|
{
|
|
|
|
using Statistics = rocksdb::Statistics;
|
|
|
|
using IOPriority = rocksdb::Env::IOPriority;
|
|
|
|
|
|
|
|
database *d {nullptr}; struct
|
|
|
|
{
|
|
|
|
int64_t count {0}, bytes {0};
|
|
|
|
}
|
|
|
|
requests[IOPriority::IO_TOTAL];
|
|
|
|
int64_t bytes_per_second {1_GiB};
|
|
|
|
|
|
|
|
bool IsRateLimited(OpType) noexcept override;
|
|
|
|
int64_t GetBytesPerSecond() const noexcept override;
|
|
|
|
int64_t GetSingleBurstBytes() const noexcept override;
|
|
|
|
int64_t GetTotalRequests(const IOPriority) const noexcept override;
|
|
|
|
int64_t GetTotalBytesThrough(const IOPriority) const noexcept override;
|
|
|
|
|
|
|
|
size_t RequestToken(size_t, size_t, IOPriority, Statistics *, OpType) noexcept override;
|
|
|
|
void SetBytesPerSecond(int64_t) noexcept override;
|
|
|
|
|
|
|
|
rate_limiter(database *const &);
|
|
|
|
~rate_limiter() noexcept;
|
|
|
|
};
|
|
|
|
|
2020-06-05 00:17:09 +02:00
|
|
|
//
|
|
|
|
// util
|
|
|
|
//
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::throw_on_error
|
2020-06-05 00:17:09 +02:00
|
|
|
{
|
|
|
|
throw_on_error(const rocksdb::Status & = rocksdb::Status::OK());
|
|
|
|
};
|
|
|
|
|
2020-09-22 04:14:17 +02:00
|
|
|
struct [[gnu::visibility("hidden")]]
|
|
|
|
ircd::db::error_to_status
|
2020-06-05 00:17:09 +02:00
|
|
|
:rocksdb::Status
|
|
|
|
{
|
|
|
|
error_to_status(const std::error_code &);
|
|
|
|
error_to_status(const std::system_error &);
|
|
|
|
error_to_status(const std::exception &);
|
|
|
|
};
|