mirror of
https://gitflic.ru/project/erthink/libmdbx.git
synced 2025-01-26 10:06:07 +00:00
mdbx: переработка инициализации, проверки и импорта dbi-хендлов в транзакциях.
Ранее инициализация в транзакциях структур данных, связанных с dbi-хендлами и subDb, выполнялась непосредственно при запуске транзакций. Что в сценариях с большим кол-вом dbi-дексприторов (например libfpta) порождало заметные накладные расходы, которые расли линейно от общего кол-ва открытых subDb, а не от реально используемых в транзакции. При использовании одной-двух сотен хендлов, при старте каждой транзакции могли копироваться и/или обнуляться десятки килобайт. Теперь этот недостаток устранен. Изменена схема инициализации, валидации и импорта хендлов открытых после старта транзакции: 1) Инициализация теперь выполняется отложенна, а при старте транзации обнуляется только массив с однобайтовыми статустами dbi-хендлов. При этом доступнва опция сборки `MDBX_ENABLE_DBI_SPARSE`, при активации которой используется битовая карты, что снижает объем инициализации при старте транзакции в 8 раз (CHAR_BIT). 2) Переработана валидация dbi-хендлов на входах API, с уменьшением кол-ва проверок и ветвлений до теоретического минимума. 3) Переработ импорт dbi-хендов открытых после старта транзакци, теперь при этом не захватывается мьютекс.
This commit is contained in:
parent
796e56b9b9
commit
e6af7d7c53
@ -531,6 +531,7 @@ add_mdbx_option(MDBX_ENABLE_BIGFOOT "Chunking long list of retired pages during
|
|||||||
add_mdbx_option(MDBX_ENABLE_PGOP_STAT "Gathering statistics for page operations" ON)
|
add_mdbx_option(MDBX_ENABLE_PGOP_STAT "Gathering statistics for page operations" ON)
|
||||||
add_mdbx_option(MDBX_ENABLE_PROFGC "Profiling of GC search and updates" OFF)
|
add_mdbx_option(MDBX_ENABLE_PROFGC "Profiling of GC search and updates" OFF)
|
||||||
mark_as_advanced(MDBX_ENABLE_PROFGC)
|
mark_as_advanced(MDBX_ENABLE_PROFGC)
|
||||||
|
add_mdbx_option(MDBX_ENABLE_DBI_SPARSE "FIXME" ON)
|
||||||
|
|
||||||
if(NOT MDBX_AMALGAMATED_SOURCE)
|
if(NOT MDBX_AMALGAMATED_SOURCE)
|
||||||
if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE_UPPERCASE STREQUAL "DEBUG")
|
if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE_UPPERCASE STREQUAL "DEBUG")
|
||||||
|
8
mdbx.h
8
mdbx.h
@ -1921,7 +1921,7 @@ enum MDBX_error_t {
|
|||||||
MDBX_TOO_LARGE = -30417,
|
MDBX_TOO_LARGE = -30417,
|
||||||
|
|
||||||
/** A thread has attempted to use a not owned object,
|
/** A thread has attempted to use a not owned object,
|
||||||
* e.g. a transaction that started by another thread. */
|
* e.g. a transaction that started by another thread */
|
||||||
MDBX_THREAD_MISMATCH = -30416,
|
MDBX_THREAD_MISMATCH = -30416,
|
||||||
|
|
||||||
/** Overlapping read and write transactions for the current thread */
|
/** Overlapping read and write transactions for the current thread */
|
||||||
@ -1936,8 +1936,12 @@ enum MDBX_error_t {
|
|||||||
/** Alternative/Duplicate LCK-file is exists and should be removed manually */
|
/** Alternative/Duplicate LCK-file is exists and should be removed manually */
|
||||||
MDBX_DUPLICATED_CLK = -30413,
|
MDBX_DUPLICATED_CLK = -30413,
|
||||||
|
|
||||||
|
/** Some cursors and/or other resources should be closed before subDb or
|
||||||
|
* corresponding DBI-handle could be (re)used */
|
||||||
|
MDBX_DANGLING_DBI = -30412,
|
||||||
|
|
||||||
/* The last of MDBX-added error codes */
|
/* The last of MDBX-added error codes */
|
||||||
MDBX_LAST_ADDED_ERRCODE = MDBX_DUPLICATED_CLK,
|
MDBX_LAST_ADDED_ERRCODE = MDBX_DANGLING_DBI,
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
MDBX_ENODATA = ERROR_HANDLE_EOF,
|
MDBX_ENODATA = ERROR_HANDLE_EOF,
|
||||||
|
1
mdbx.h++
1
mdbx.h++
@ -559,6 +559,7 @@ MDBX_DECLARE_EXCEPTION(thread_mismatch);
|
|||||||
MDBX_DECLARE_EXCEPTION(transaction_full);
|
MDBX_DECLARE_EXCEPTION(transaction_full);
|
||||||
MDBX_DECLARE_EXCEPTION(transaction_overlapping);
|
MDBX_DECLARE_EXCEPTION(transaction_overlapping);
|
||||||
MDBX_DECLARE_EXCEPTION(duplicated_lck_file);
|
MDBX_DECLARE_EXCEPTION(duplicated_lck_file);
|
||||||
|
MDBX_DECLARE_EXCEPTION(dangling_map_id);
|
||||||
#undef MDBX_DECLARE_EXCEPTION
|
#undef MDBX_DECLARE_EXCEPTION
|
||||||
|
|
||||||
[[noreturn]] LIBMDBX_API void throw_too_small_target_buffer();
|
[[noreturn]] LIBMDBX_API void throw_too_small_target_buffer();
|
||||||
|
@ -5,9 +5,9 @@ N | MASK | ENV | TXN | DB | PUT | DBI | NOD
|
|||||||
2 |0000 0004|ALLOC_COLSC|TXN_DIRTY |DUPSORT | |DBI_FRESH |F_DUPDATA|P_OVERFLOW| |
|
2 |0000 0004|ALLOC_COLSC|TXN_DIRTY |DUPSORT | |DBI_FRESH |F_DUPDATA|P_OVERFLOW| |
|
||||||
3 |0000 0008|ALLOC_SSCAN|TXN_SPILLS |INTEGERKEY| |DBI_CREAT | |P_META | |
|
3 |0000 0008|ALLOC_SSCAN|TXN_SPILLS |INTEGERKEY| |DBI_CREAT | |P_META | |
|
||||||
4 |0000 0010|ALLOC_FIFO |TXN_HAS_CHILD |DUPFIXED |NOOVERWRITE|DBI_VALID | |P_BAD | |
|
4 |0000 0010|ALLOC_FIFO |TXN_HAS_CHILD |DUPFIXED |NOOVERWRITE|DBI_VALID | |P_BAD | |
|
||||||
5 |0000 0020| |TXN_DRAINED_GC|INTEGERDUP|NODUPDATA |DBI_USRVALID| |P_LEAF2 | |
|
5 |0000 0020| |TXN_DRAINED_GC|INTEGERDUP|NODUPDATA | | |P_LEAF2 | |
|
||||||
6 |0000 0040| | |REVERSEDUP|CURRENT |DBI_DUPDATA | |P_SUBP | |
|
6 |0000 0040| | |REVERSEDUP|CURRENT |DBI_OLDEN | |P_SUBP | |
|
||||||
7 |0000 0080| | | |ALLDUPS |DBI_AUDITED | | | |
|
7 |0000 0080| | | |ALLDUPS |DBI_LINDO | | | |
|
||||||
8 |0000 0100| _MAY_MOVE | | | | | | | <= |
|
8 |0000 0100| _MAY_MOVE | | | | | | | <= |
|
||||||
9 |0000 0200| _MAY_UNMAP| | | | | | | <= |
|
9 |0000 0200| _MAY_UNMAP| | | | | | | <= |
|
||||||
10|0000 0400| | | | | | | | |
|
10|0000 0400| | | | | | | | |
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#cmakedefine01 MDBX_ENABLE_BIGFOOT
|
#cmakedefine01 MDBX_ENABLE_BIGFOOT
|
||||||
#cmakedefine01 MDBX_ENABLE_PGOP_STAT
|
#cmakedefine01 MDBX_ENABLE_PGOP_STAT
|
||||||
#cmakedefine01 MDBX_ENABLE_PROFGC
|
#cmakedefine01 MDBX_ENABLE_PROFGC
|
||||||
|
#cmakedefine01 MDBX_ENABLE_DBI_SPARSE
|
||||||
|
|
||||||
/* Windows */
|
/* Windows */
|
||||||
#cmakedefine01 MDBX_WITHOUT_MSVC_CRT
|
#cmakedefine01 MDBX_WITHOUT_MSVC_CRT
|
||||||
|
1803
src/core.c
1803
src/core.c
File diff suppressed because it is too large
Load Diff
@ -1192,19 +1192,23 @@ struct MDBX_txn {
|
|||||||
/* Array of MDBX_db records for each known DB */
|
/* Array of MDBX_db records for each known DB */
|
||||||
MDBX_db *mt_dbs;
|
MDBX_db *mt_dbs;
|
||||||
|
|
||||||
|
#if MDBX_ENABLE_DBI_SPARSE
|
||||||
|
unsigned *mt_dbi_sparse;
|
||||||
|
#endif /* MDBX_ENABLE_DBI_SPARSE */
|
||||||
|
|
||||||
/* Non-shared DBI state flags inside transaction */
|
/* Non-shared DBI state flags inside transaction */
|
||||||
#define DBI_DIRTY 0x01 /* DB was written in this txn */
|
#define DBI_DIRTY 0x01 /* DB was written in this txn */
|
||||||
#define DBI_STALE 0x02 /* Named-DB record is older than txnID */
|
#define DBI_STALE 0x02 /* Named-DB record is older than txnID */
|
||||||
#define DBI_FRESH 0x04 /* Named-DB handle opened in this txn */
|
#define DBI_FRESH 0x04 /* Named-DB handle opened in this txn */
|
||||||
#define DBI_CREAT 0x08 /* Named-DB handle created in this txn */
|
#define DBI_CREAT 0x08 /* Named-DB handle created in this txn */
|
||||||
#define DBI_VALID 0x10 /* Handle is valid, see also DB_VALID */
|
#define DBI_VALID 0x10 /* Handle is valid, see also DB_VALID */
|
||||||
#define DBI_USRVALID 0x20 /* As DB_VALID, but not set for FREE_DBI */
|
#define DBI_OLDEN 0x40 /* Handle was closed/reopened outside txn */
|
||||||
#define DBI_AUDIT 0x40 /* Internal flag for accounting during audit */
|
#define DBI_LINDO 0x80 /* Lazy initialization done for DBI-slot */
|
||||||
/* Array of non-shared txn's flags of DBI */
|
/* Array of non-shared txn's flags of DBI */
|
||||||
uint8_t *mt_dbi_state;
|
uint8_t *mt_dbi_state;
|
||||||
|
|
||||||
/* Array of sequence numbers for each DB handle. */
|
/* Array of sequence numbers for each DB handle. */
|
||||||
MDBX_atomic_uint32_t *mt_dbi_seqs;
|
uint32_t *mt_dbi_seqs;
|
||||||
MDBX_cursor **mt_cursors;
|
MDBX_cursor **mt_cursors;
|
||||||
|
|
||||||
MDBX_canary mt_canary;
|
MDBX_canary mt_canary;
|
||||||
@ -1660,7 +1664,8 @@ typedef struct MDBX_node {
|
|||||||
/* mdbx_dbi_open() flags */
|
/* mdbx_dbi_open() flags */
|
||||||
#define DB_USABLE_FLAGS (DB_PERSISTENT_FLAGS | MDBX_CREATE | MDBX_DB_ACCEDE)
|
#define DB_USABLE_FLAGS (DB_PERSISTENT_FLAGS | MDBX_CREATE | MDBX_DB_ACCEDE)
|
||||||
|
|
||||||
#define DB_VALID 0x8000 /* DB handle is valid, for me_db_flags */
|
#define DB_VALID 0x8000u /* DB handle is valid, for me_db_flags */
|
||||||
|
#define DB_POISON 0x7fffu /* update pending */
|
||||||
#define DB_INTERNAL_FLAGS DB_VALID
|
#define DB_INTERNAL_FLAGS DB_VALID
|
||||||
|
|
||||||
#if DB_INTERNAL_FLAGS & DB_USABLE_FLAGS
|
#if DB_INTERNAL_FLAGS & DB_USABLE_FLAGS
|
||||||
|
@ -286,6 +286,8 @@ DEFINE_EXCEPTION(thread_mismatch)
|
|||||||
DEFINE_EXCEPTION(transaction_full)
|
DEFINE_EXCEPTION(transaction_full)
|
||||||
DEFINE_EXCEPTION(transaction_overlapping)
|
DEFINE_EXCEPTION(transaction_overlapping)
|
||||||
DEFINE_EXCEPTION(duplicated_lck_file)
|
DEFINE_EXCEPTION(duplicated_lck_file)
|
||||||
|
DEFINE_EXCEPTION(dangling_map_id)
|
||||||
|
|
||||||
#undef DEFINE_EXCEPTION
|
#undef DEFINE_EXCEPTION
|
||||||
|
|
||||||
__cold const char *error::what() const noexcept {
|
__cold const char *error::what() const noexcept {
|
||||||
@ -372,6 +374,7 @@ __cold void error::throw_exception() const {
|
|||||||
CASE_EXCEPTION(transaction_full, MDBX_TXN_FULL);
|
CASE_EXCEPTION(transaction_full, MDBX_TXN_FULL);
|
||||||
CASE_EXCEPTION(transaction_overlapping, MDBX_TXN_OVERLAPPING);
|
CASE_EXCEPTION(transaction_overlapping, MDBX_TXN_OVERLAPPING);
|
||||||
CASE_EXCEPTION(duplicated_lck_file, MDBX_DUPLICATED_CLK);
|
CASE_EXCEPTION(duplicated_lck_file, MDBX_DUPLICATED_CLK);
|
||||||
|
CASE_EXCEPTION(dangling_map_id, MDBX_DANGLING_DBI);
|
||||||
#undef CASE_EXCEPTION
|
#undef CASE_EXCEPTION
|
||||||
default:
|
default:
|
||||||
if (is_mdbx_error())
|
if (is_mdbx_error())
|
||||||
|
@ -163,6 +163,13 @@
|
|||||||
#error MDBX_AVOID_MSYNC must be defined as 0 or 1
|
#error MDBX_AVOID_MSYNC must be defined as 0 or 1
|
||||||
#endif /* MDBX_AVOID_MSYNC */
|
#endif /* MDBX_AVOID_MSYNC */
|
||||||
|
|
||||||
|
/** FIXME */
|
||||||
|
#ifndef MDBX_ENABLE_DBI_SPARSE
|
||||||
|
#define MDBX_ENABLE_DBI_SPARSE 1
|
||||||
|
#elif !(MDBX_ENABLE_DBI_SPARSE == 0 || MDBX_ENABLE_DBI_SPARSE == 1)
|
||||||
|
#error MDBX_ENABLE_DBI_SPARSE must be defined as 0 or 1
|
||||||
|
#endif /* MDBX_ENABLE_DBI_SPARSE */
|
||||||
|
|
||||||
/** Controls sort order of internal page number lists.
|
/** Controls sort order of internal page number lists.
|
||||||
* This mostly experimental/advanced option with not for regular MDBX users.
|
* This mostly experimental/advanced option with not for regular MDBX users.
|
||||||
* \warning The database format depend on this option and libmdbx built with
|
* \warning The database format depend on this option and libmdbx built with
|
||||||
|
Loading…
Reference in New Issue
Block a user