mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-29 23:19:20 +08:00
mdbx: fix operation for unusual small/large system page size.
More for https://github.com/erthink/libmdbx/issues/157 Change-Id: I4f2ed54b50653d0375538b82c48590d1037cd93b
This commit is contained in:
parent
6cfac546a1
commit
f698f07ff9
@ -46,6 +46,7 @@ New features:
|
||||
- a spilled pages, including overflow/large pages, now can be reused and refunded/compactified in nested transactions;
|
||||
- more effective refunding/compactification especially for the loosed page cache.
|
||||
- Added `MDBX_ENABLE_REFUND` and `MDBX_PNL_ASCENDING` internal/advanced build options.
|
||||
- Added `mdbx_default_pagesize()` function.
|
||||
|
||||
Fixes:
|
||||
|
||||
@ -58,6 +59,7 @@ Fixes:
|
||||
- Fixed page leak in extra rare case the list of retired pages changed during update GC on transaction commit.
|
||||
- Fixed assertions to avoid false-positive UB detection by CLANG/LLVM (https://github.com/erthink/libmdbx/issues/153).
|
||||
- Fixed `MDBX_TXN_FULL` and regressive `MDBX_KEYEXIST` during large transaction commit with `MDBX_LIFORECLAIM` (https://github.com/erthink/libmdbx/issues/123).
|
||||
- Fixed operation on systems with unusual small/large page size, including PowerPC (https://github.com/erthink/libmdbx/issues/157).
|
||||
|
||||
|
||||
## v0.9.2 at 2020-11-27
|
||||
|
6
mdbx.h
6
mdbx.h
@ -2852,6 +2852,12 @@ LIBMDBX_INLINE_API(int, mdbx_env_get_maxdbs,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** \brief Returns the default size of database page for the current system.
|
||||
* \ingroup c_statinfo
|
||||
* \details Default size of database page depends on the size of the system
|
||||
* page and usually exactly match it. */
|
||||
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API size_t mdbx_default_pagesize(void);
|
||||
|
||||
/** \brief Get the maximum size of keys can write.
|
||||
* \ingroup c_statinfo
|
||||
*
|
||||
|
4
mdbx.h++
4
mdbx.h++
@ -1838,7 +1838,9 @@ public:
|
||||
bool is_empty() const;
|
||||
|
||||
/// \brief Returns default page size for current system/platform.
|
||||
static size_t default_pagesize() noexcept;
|
||||
static size_t default_pagesize() noexcept {
|
||||
return ::mdbx_default_pagesize();
|
||||
}
|
||||
|
||||
struct limits {
|
||||
limits() = delete;
|
||||
|
32
src/core.c
32
src/core.c
@ -346,10 +346,18 @@ __cold int mdbx_env_get_maxkeysize_ex(const MDBX_env *env,
|
||||
return (int)mdbx_limits_keysize_max((intptr_t)env->me_psize, flags);
|
||||
}
|
||||
|
||||
size_t mdbx_default_pagesize(void) {
|
||||
size_t pagesize = mdbx_syspagesize();
|
||||
mdbx_ensure(nullptr, is_powerof2(pagesize));
|
||||
pagesize = (pagesize >= MIN_PAGESIZE) ? pagesize : MIN_PAGESIZE;
|
||||
pagesize = (pagesize <= MAX_PAGESIZE) ? pagesize : MAX_PAGESIZE;
|
||||
return pagesize;
|
||||
}
|
||||
|
||||
__cold intptr_t mdbx_limits_keysize_max(intptr_t pagesize,
|
||||
MDBX_db_flags_t flags) {
|
||||
if (pagesize < 1)
|
||||
pagesize = (intptr_t)mdbx_syspagesize();
|
||||
pagesize = (intptr_t)mdbx_default_pagesize();
|
||||
if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||
|
||||
pagesize > (intptr_t)MAX_PAGESIZE ||
|
||||
!is_powerof2((size_t)pagesize)))
|
||||
@ -383,7 +391,7 @@ __cold int mdbx_env_get_maxvalsize_ex(const MDBX_env *env,
|
||||
__cold intptr_t mdbx_limits_valsize_max(intptr_t pagesize,
|
||||
MDBX_db_flags_t flags) {
|
||||
if (pagesize < 1)
|
||||
pagesize = (intptr_t)mdbx_syspagesize();
|
||||
pagesize = (intptr_t)mdbx_default_pagesize();
|
||||
if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||
|
||||
pagesize > (intptr_t)MAX_PAGESIZE ||
|
||||
!is_powerof2((size_t)pagesize)))
|
||||
@ -10004,7 +10012,8 @@ __cold int mdbx_env_create(MDBX_env **penv) {
|
||||
goto bailout;
|
||||
}
|
||||
env->me_os_psize = (unsigned)os_psize;
|
||||
mdbx_setup_pagesize(env, env->me_os_psize);
|
||||
mdbx_setup_pagesize(env, (env->me_os_psize < MAX_PAGESIZE) ? env->me_os_psize
|
||||
: MAX_PAGESIZE);
|
||||
|
||||
rc = mdbx_fastmutex_init(&env->me_dbi_lock);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
@ -10969,12 +10978,14 @@ static __cold int mdbx_setup_lck(MDBX_env *env, char *lck_pathname,
|
||||
|
||||
const size_t maxreaders =
|
||||
((size_t)size - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader);
|
||||
if (size > 65536 || maxreaders < 2 || maxreaders > MDBX_READERS_LIMIT) {
|
||||
mdbx_error("lck-size too big (up to %" PRIuPTR " readers)", maxreaders);
|
||||
if (maxreaders < 4) {
|
||||
mdbx_error("lck-size too small (up to %" PRIuPTR " readers)", maxreaders);
|
||||
err = MDBX_PROBLEM;
|
||||
goto bailout;
|
||||
}
|
||||
env->me_maxreaders = (unsigned)maxreaders;
|
||||
env->me_maxreaders = (maxreaders <= MDBX_READERS_LIMIT)
|
||||
? (unsigned)maxreaders
|
||||
: (unsigned)MDBX_READERS_LIMIT;
|
||||
|
||||
err = mdbx_mmap((env->me_flags & MDBX_EXCLUSIVE) | MDBX_WRITEMAP,
|
||||
&env->me_lck_mmap, (size_t)size, (size_t)size,
|
||||
@ -11388,7 +11399,8 @@ __cold int mdbx_env_delete(const char *pathname, MDBX_env_delete_mode_t mode) {
|
||||
memset(&dummy_env, 0, sizeof(dummy_env));
|
||||
dummy_env.me_flags =
|
||||
(mode == MDBX_ENV_ENSURE_UNUSED) ? MDBX_EXCLUSIVE : MDBX_ENV_DEFAULTS;
|
||||
dummy_env.me_psize = dummy_env.me_os_psize = (unsigned)mdbx_syspagesize();
|
||||
dummy_env.me_os_psize = (unsigned)mdbx_syspagesize();
|
||||
dummy_env.me_psize = (unsigned)mdbx_default_pagesize();
|
||||
dummy_env.me_pathname = (char *)pathname;
|
||||
|
||||
MDBX_handle_env_pathname env_pathname;
|
||||
@ -20119,7 +20131,7 @@ __cold MDBX_NOTHROW_CONST_FUNCTION intptr_t mdbx_limits_pgsize_max(void) {
|
||||
|
||||
__cold intptr_t mdbx_limits_dbsize_min(intptr_t pagesize) {
|
||||
if (pagesize < 1)
|
||||
pagesize = (intptr_t)mdbx_syspagesize();
|
||||
pagesize = (intptr_t)mdbx_default_pagesize();
|
||||
else if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||
|
||||
pagesize > (intptr_t)MAX_PAGESIZE ||
|
||||
!is_powerof2((size_t)pagesize)))
|
||||
@ -20130,7 +20142,7 @@ __cold intptr_t mdbx_limits_dbsize_min(intptr_t pagesize) {
|
||||
|
||||
__cold intptr_t mdbx_limits_dbsize_max(intptr_t pagesize) {
|
||||
if (pagesize < 1)
|
||||
pagesize = (intptr_t)mdbx_syspagesize();
|
||||
pagesize = (intptr_t)mdbx_default_pagesize();
|
||||
else if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||
|
||||
pagesize > (intptr_t)MAX_PAGESIZE ||
|
||||
!is_powerof2((size_t)pagesize)))
|
||||
@ -20144,7 +20156,7 @@ __cold intptr_t mdbx_limits_dbsize_max(intptr_t pagesize) {
|
||||
|
||||
__cold intptr_t mdbx_limits_txnsize_max(intptr_t pagesize) {
|
||||
if (pagesize < 1)
|
||||
pagesize = (intptr_t)mdbx_syspagesize();
|
||||
pagesize = (intptr_t)mdbx_default_pagesize();
|
||||
else if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||
|
||||
pagesize > (intptr_t)MAX_PAGESIZE ||
|
||||
!is_powerof2((size_t)pagesize)))
|
||||
|
@ -628,7 +628,7 @@ typedef struct MDBX_lockinfo {
|
||||
#if MDBX_WORDBITS >= 64
|
||||
#define MAX_MAPSIZE MAX_MAPSIZE64
|
||||
#define MDBX_READERS_LIMIT \
|
||||
((65536 - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader))
|
||||
((MAX_PAGESIZE - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader))
|
||||
#define MDBX_PGL_LIMIT MAX_PAGENO
|
||||
#else
|
||||
#define MDBX_READERS_LIMIT 1024
|
||||
|
@ -985,8 +985,6 @@ template class LIBMDBX_API_TYPE buffer<polymorphic_allocator>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
size_t env::default_pagesize() noexcept { return ::mdbx_syspagesize(); }
|
||||
|
||||
static inline MDBX_env_flags_t mode2flags(env::mode mode) {
|
||||
switch (mode) {
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user