diff --git a/src/api-env.c b/src/api-env.c index a1878cc3..78251213 100644 --- a/src/api-env.c +++ b/src/api-env.c @@ -1118,13 +1118,16 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t si } const size_t unit_ps = (globals.sys_pagesize > (size_t)pagesize) ? globals.sys_pagesize : (size_t)pagesize; - const size_t unit_ag = (globals.sys_allocation_granularity > unit_ps) ? globals.sys_allocation_granularity : unit_ps; + const size_t unit_ag = (globals.sys_allocation_granularity > unit_ps && + (growth_step < 0 || (size_t)growth_step >= globals.sys_allocation_granularity)) + ? globals.sys_allocation_granularity + : unit_ps; size_lower = ceil_powerof2(size_lower, unit_ps); size_upper = ceil_powerof2(size_upper, unit_ag); size_now = ceil_powerof2(size_now, unit_ag); /* LY: подбираем значение size_upper: - * - кратное размеру страницы + * - кратное размеру unit_ag (размеру страницы БД и системному размеру выделения) * - без нарушения MAX_MAPSIZE и MAX_PAGENO */ while (unlikely((size_t)size_upper > MAX_MAPSIZE || (uint64_t)size_upper / pagesize > MAX_PAGENO + 1)) { if ((size_t)size_upper < unit_ag + MIN_MAPSIZE || (size_t)size_upper < (size_t)pagesize * (MIN_PAGENO + 1)) { diff --git a/src/dxb.c b/src/dxb.c index 28520e0c..6206f0f2 100644 --- a/src/dxb.c +++ b/src/dxb.c @@ -570,7 +570,7 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc, const mdbx_mode_t mode_bit size_t expected_filesize = 0; const size_t used_bytes = pgno2bytes(env, header.geometry.first_unallocated); - const size_t used_aligned2os_bytes = ceil_powerof2(used_bytes, globals.sys_pagesize); + const size_t used_aligned2os_bytes = ceil_powerof2(used_bytes, globals.sys_allocation_granularity); if ((env->flags & MDBX_RDONLY) /* readonly */ || lck_rc != MDBX_RESULT_TRUE /* not exclusive */ || /* recovery mode */ env->stuck_meta >= 0) { @@ -843,13 +843,13 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc, const mdbx_mode_t mode_bit if (lck_rc == /* lck exclusive */ MDBX_RESULT_TRUE) { //-------------------------------------------------- shrink DB & update geo /* re-check size after mmap */ - if ((env->dxb_mmap.current & (globals.sys_pagesize - 1)) != 0 || env->dxb_mmap.current < used_bytes) { + if (floor_powerof2(env->dxb_mmap.current, globals.sys_pagesize) < used_bytes) { ERROR("unacceptable/unexpected datafile size %" PRIuPTR, env->dxb_mmap.current); return MDBX_PROBLEM; } if (env->dxb_mmap.current != env->geo_in_bytes.now) { - header.geometry.now = bytes2pgno(env, env->dxb_mmap.current); - NOTICE("need update meta-geo to filesize %" PRIuPTR " bytes, %" PRIaPGNO " pages", env->dxb_mmap.current, + header.geometry.now = bytes2pgno(env, env->geo_in_bytes.now); + NOTICE("need update meta-geo to filesize %" PRIuPTR " bytes, aligned %" PRIaPGNO " pages", env->geo_in_bytes.now, header.geometry.now); } diff --git a/src/osal.c b/src/osal.c index 199d2cc2..711a4477 100644 --- a/src/osal.c +++ b/src/osal.c @@ -3517,7 +3517,8 @@ void osal_ctor(void) { SYSTEM_INFO si; GetSystemInfo(&si); globals.sys_pagesize = si.dwPageSize; - globals.sys_allocation_granularity = si.dwAllocationGranularity; + globals.sys_allocation_granularity = + (si.dwAllocationGranularity > globals.sys_pagesize) ? si.dwAllocationGranularity : globals.sys_pagesize; #else globals.sys_pagesize = sysconf(_SC_PAGE_SIZE); globals.sys_allocation_granularity = (MDBX_WORDBITS > 32) ? 65536 : 16384; @@ -3533,8 +3534,9 @@ void osal_ctor(void) { globals.sys_allocation_granularity = globals.sys_unified_cache_block; } #endif /* AT_UCACHEBSIZE */ - #endif + if (globals.sys_allocation_granularity > 4 * MEGABYTE && globals.sys_pagesize < MEGABYTE) + globals.sys_allocation_granularity = 4 * MEGABYTE; assert(globals.sys_pagesize > 0 && (globals.sys_pagesize & (globals.sys_pagesize - 1)) == 0); assert(globals.sys_allocation_granularity >= globals.sys_pagesize && globals.sys_allocation_granularity % globals.sys_pagesize == 0);