From 0ef0f49e2e3b33c5b89e5834ed0e12ce3edd6629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Wed, 19 Feb 2025 23:38:15 +0300 Subject: [PATCH] =?UTF-8?q?mdbx:=20=D1=83=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=D0=B7=D0=BB=D0=B8=D1=88=D0=BD?= =?UTF-8?q?=D0=B5=D0=B3=D0=BE=20=D0=BF=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80?= =?UTF-8?q?=D0=B5=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D1=80=D0=B8?= =?UTF-8?q?=20=D1=81=D0=BC=D0=B5=D0=BD=D0=B5=20=D1=80=D0=B0=D0=B7=D0=BC?= =?UTF-8?q?=D0=B5=D1=80=D0=B0=20=D0=91=D0=94=20=D0=B2=D0=BE=20=D0=B2=D1=80?= =?UTF-8?q?=D0=B5=D0=BC=D1=8F=20=D0=BE=D1=82=D0=BA=D1=80=D1=8B=D1=82=D0=B8?= =?UTF-8?q?=D1=8F=20(backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Изменение геометрии (увеличение размера) больших БД может быть не возможно после их открытия вследствие системных ограничений (отсутствия свободного адресного пространства). Поэтому API предусматривает возможность запросить изменение геометрии/размера БД перед её открытием. В этом сценарии ранее могло выдаваться лишнее/ненужное предупреждение о несоответствии файла БД новому размеру. Теперь этот недостаток исправлен. Спасибо Илье Михееву (Erigon) за сообщение об этом недочете. --- ChangeLog.md | 7 +++++++ src/dxb.c | 16 +++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index f9df0108..a1859394 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -11,7 +11,14 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx Благодарности: - [Erigon](https://docs.erigon.tech/) за спонсорство. + - [Илье Михееву](https://t.me/IlyaMkhv) за сообщение о лишнем/ненужном предупреждении несоответствия файла БД новому размеру. +Исправления: + + - Устранение лишнего/ненужного предупреждения в сценарии изменения размера БД посредством вызова `mdbx_env_set_geometry()` до её открытия. + API предусматривает возможность запросить изменение геометрии/размера БД перед её открытием, чтобы избежать как лишних накладных расходов, + так и потенциальных ошибок из-за нехватки адресного пространства. В этом сценарии ранее могло выдаваться лишнее/ненужное предупреждение + о несоответствии файла БД новому размеру. Теперь этот недостаток исправлен. -------------------------------------------------------------------------------- diff --git a/src/dxb.c b/src/dxb.c index aa222025..22379d33 100644 --- a/src/dxb.c +++ b/src/dxb.c @@ -567,6 +567,7 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc, const mdbx_mode_t mode_bit return err; } + bool new_size_from_user = false; const size_t used_bytes = pgno2bytes(env, header.geometry.first_unallocated); const size_t used_aligned2os_bytes = ceil_powerof2(used_bytes, globals.sys_pagesize); if ((env->flags & MDBX_RDONLY) /* readonly */ @@ -601,6 +602,8 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc, const mdbx_mode_t mode_bit /* pre-shrink if enabled */ env->geo_in_bytes.now = used_bytes + env->geo_in_bytes.shrink - used_bytes % env->geo_in_bytes.shrink; + /* сейчас БД еще не открыта, поэтому этот вызов не изменит геометрию, но проверит и скорректирует параметры + * с учетом реального размера страницы. */ err = mdbx_env_set_geometry(env, env->geo_in_bytes.lower, env->geo_in_bytes.now, env->geo_in_bytes.upper, env->geo_in_bytes.grow, env->geo_in_bytes.shrink, header.pagesize); if (unlikely(err != MDBX_SUCCESS)) { @@ -608,8 +611,10 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc, const mdbx_mode_t mode_bit return (err == MDBX_EINVAL) ? MDBX_INCOMPATIBLE : err; } - /* update meta fields */ - header.geometry.now = bytes2pgno(env, env->geo_in_bytes.now); + /* altering fields to match geometry given from user */ + new_size_from_user = header.geometry.now != bytes2pgno(env, env->geo_in_bytes.now); + if (new_size_from_user) + header.geometry.now = bytes2pgno(env, env->geo_in_bytes.now); header.geometry.lower = bytes2pgno(env, env->geo_in_bytes.lower); header.geometry.upper = bytes2pgno(env, env->geo_in_bytes.upper); header.geometry.grow_pv = pages2pv(bytes2pgno(env, env->geo_in_bytes.grow)); @@ -646,9 +651,10 @@ __cold int dxb_setup(MDBX_env *env, const int lck_rc, const mdbx_mode_t mode_bit env->geo_in_bytes.now, bytes2pgno(env, env->geo_in_bytes.now), filesize_before, bytes2pgno(env, (size_t)filesize_before)); } else { - WARNING("filesize mismatch (expect %" PRIuSIZE "b/%" PRIaPGNO "p, have %" PRIu64 "b/%" PRIaPGNO "p)", - env->geo_in_bytes.now, bytes2pgno(env, env->geo_in_bytes.now), filesize_before, - bytes2pgno(env, (size_t)filesize_before)); + if (!new_size_from_user) + WARNING("filesize mismatch (expect %" PRIuSIZE "b/%" PRIaPGNO "p, have %" PRIu64 "b/%" PRIaPGNO "p)", + env->geo_in_bytes.now, bytes2pgno(env, env->geo_in_bytes.now), filesize_before, + bytes2pgno(env, (size_t)filesize_before)); if (filesize_before < used_bytes) { ERROR("last-page beyond end-of-file (last %" PRIaPGNO ", have %" PRIaPGNO ")", header.geometry.first_unallocated, bytes2pgno(env, (size_t)filesize_before));