mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:24:12 +08:00
mdbx: rework mmap-functions for osal.
- add 'length' and 'current' fields to mmap-object; - drop mdbx_mremap(); - do remap on-demand inside mdbx_mresize(); - add mdbx_mapresize() which re-creates Valgrind's region. - call resize on txn-begin. Change-Id: I82780f92c4947804e3f14fb7cb71ee655382f9bb
This commit is contained in:
parent
700ec68d06
commit
17e8429a29
24
mdbx.h
24
mdbx.h
@ -448,18 +448,18 @@ typedef struct MDBX_envinfo {
|
|||||||
uint64_t current; /* current datafile size */
|
uint64_t current; /* current datafile size */
|
||||||
uint64_t shrink; /* shrink theshold for datafile */
|
uint64_t shrink; /* shrink theshold for datafile */
|
||||||
uint64_t grow; /* growth step for datafile */
|
uint64_t grow; /* growth step for datafile */
|
||||||
} me_geo;
|
} mi_geo;
|
||||||
uint64_t me_mapsize; /* Size of the data memory map */
|
uint64_t mi_mapsize; /* Size of the data memory map */
|
||||||
uint64_t me_last_pgno; /* ID of the last used page */
|
uint64_t mi_last_pgno; /* ID of the last used page */
|
||||||
uint64_t me_recent_txnid; /* ID of the last committed transaction */
|
uint64_t mi_recent_txnid; /* ID of the last committed transaction */
|
||||||
uint64_t me_latter_reader_txnid; /* ID of the last reader transaction */
|
uint64_t mi_latter_reader_txnid; /* ID of the last reader transaction */
|
||||||
uint64_t me_meta0_txnid, me_meta0_sign;
|
uint64_t mi_meta0_txnid, mi_meta0_sign;
|
||||||
uint64_t me_meta1_txnid, me_meta1_sign;
|
uint64_t mi_meta1_txnid, mi_meta1_sign;
|
||||||
uint64_t me_meta2_txnid, me_meta2_sign;
|
uint64_t mi_meta2_txnid, mi_meta2_sign;
|
||||||
uint32_t me_maxreaders; /* max reader slots in the environment */
|
uint32_t mi_maxreaders; /* max reader slots in the environment */
|
||||||
uint32_t me_numreaders; /* max reader slots used in the environment */
|
uint32_t mi_numreaders; /* max reader slots used in the environment */
|
||||||
uint32_t me_dxb_pagesize; /* database pagesize */
|
uint32_t mi_dxb_pagesize; /* database pagesize */
|
||||||
uint32_t me_sys_pagesize; /* system pagesize */
|
uint32_t mi_sys_pagesize; /* system pagesize */
|
||||||
} MDBX_envinfo;
|
} MDBX_envinfo;
|
||||||
|
|
||||||
/* Return a string describing a given error code.
|
/* Return a string describing a given error code.
|
||||||
|
@ -660,11 +660,12 @@ struct MDBX_env {
|
|||||||
#define MDBX_ME_SIGNATURE UINT32_C(0x9A899641)
|
#define MDBX_ME_SIGNATURE UINT32_C(0x9A899641)
|
||||||
size_t me_signature;
|
size_t me_signature;
|
||||||
mdbx_mmap_t me_dxb_mmap; /* The main data file */
|
mdbx_mmap_t me_dxb_mmap; /* The main data file */
|
||||||
mdbx_mmap_t me_lck_mmap; /* The lock file */
|
|
||||||
#define me_map me_dxb_mmap.dxb
|
#define me_map me_dxb_mmap.dxb
|
||||||
#define me_lck me_lck_mmap.lck
|
|
||||||
#define me_fd me_dxb_mmap.fd
|
#define me_fd me_dxb_mmap.fd
|
||||||
|
#define me_mapsize me_dxb_mmap.length
|
||||||
|
mdbx_mmap_t me_lck_mmap; /* The lock file */
|
||||||
#define me_lfd me_lck_mmap.fd
|
#define me_lfd me_lck_mmap.fd
|
||||||
|
#define me_lck me_lck_mmap.lck
|
||||||
|
|
||||||
/* Failed to update the meta page. Probably an I/O error. */
|
/* Failed to update the meta page. Probably an I/O error. */
|
||||||
#define MDBX_FATAL_ERROR UINT32_C(0x80000000)
|
#define MDBX_FATAL_ERROR UINT32_C(0x80000000)
|
||||||
@ -688,7 +689,6 @@ struct MDBX_env {
|
|||||||
void *me_pbuf; /* scratch area for DUPSORT put() */
|
void *me_pbuf; /* scratch area for DUPSORT put() */
|
||||||
MDBX_txn *me_txn; /* current write transaction */
|
MDBX_txn *me_txn; /* current write transaction */
|
||||||
MDBX_txn *me_txn0; /* prealloc'd write transaction */
|
MDBX_txn *me_txn0; /* prealloc'd write transaction */
|
||||||
size_t me_mapsize; /* size of the data memory map */
|
|
||||||
MDBX_dbx *me_dbxs; /* array of static DB info */
|
MDBX_dbx *me_dbxs; /* array of static DB info */
|
||||||
uint16_t *me_dbflags; /* array of flags from MDBX_db.md_flags */
|
uint16_t *me_dbflags; /* array of flags from MDBX_db.md_flags */
|
||||||
unsigned *me_dbiseqs; /* array of dbi sequence numbers */
|
unsigned *me_dbiseqs; /* array of dbi sequence numbers */
|
||||||
@ -719,6 +719,7 @@ struct MDBX_env {
|
|||||||
#ifdef USE_VALGRIND
|
#ifdef USE_VALGRIND
|
||||||
int me_valgrind_handle;
|
int me_valgrind_handle;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
size_t lower; /* minimal size of datafile */
|
size_t lower; /* minimal size of datafile */
|
||||||
size_t upper; /* maximal size of datafile */
|
size_t upper; /* maximal size of datafile */
|
||||||
|
227
src/mdbx.c
227
src/mdbx.c
@ -1537,6 +1537,54 @@ static void mdbx_page_dirty(MDBX_txn *txn, MDBX_page *mp) {
|
|||||||
txn->mt_dirtyroom--;
|
txn->mt_dirtyroom--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mdbx_mapresize(MDBX_env *env, const pgno_t size_pgno,
|
||||||
|
const pgno_t limit_pgno) {
|
||||||
|
#ifdef USE_VALGRIND
|
||||||
|
const size_t prev_mapsize = env->me_mapsize;
|
||||||
|
void *const prev_mapaddr = env->me_map;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const size_t limit_bytes =
|
||||||
|
mdbx_roundup2(pgno2bytes(env, limit_pgno), env->me_os_psize);
|
||||||
|
const size_t size_bytes =
|
||||||
|
mdbx_roundup2(pgno2bytes(env, size_pgno), env->me_os_psize);
|
||||||
|
|
||||||
|
mdbx_info("resize datafile/mapping: "
|
||||||
|
"present %" PRIuPTR " -> %" PRIuPTR ", "
|
||||||
|
"limit %" PRIuPTR " -> %" PRIuPTR,
|
||||||
|
env->me_dbgeo.now, size_bytes, env->me_dbgeo.upper, limit_bytes);
|
||||||
|
|
||||||
|
mdbx_assert(env, limit_bytes >= size_bytes);
|
||||||
|
mdbx_assert(env, bytes2pgno(env, size_bytes) == size_pgno);
|
||||||
|
mdbx_assert(env, bytes2pgno(env, limit_bytes) == limit_pgno);
|
||||||
|
const int rc =
|
||||||
|
mdbx_mresize(env->me_flags, &env->me_dxb_mmap, size_bytes, limit_bytes);
|
||||||
|
|
||||||
|
if (rc == MDBX_SUCCESS) {
|
||||||
|
if (env->me_txn0)
|
||||||
|
env->me_txn0->mt_end_pgno = size_pgno;
|
||||||
|
env->me_dbgeo.now = size_bytes;
|
||||||
|
env->me_dbgeo.upper = limit_bytes;
|
||||||
|
} else {
|
||||||
|
mdbx_error("failed resize datafile/mapping: "
|
||||||
|
"present %" PRIuPTR " -> %" PRIuPTR ", "
|
||||||
|
"limit %" PRIuPTR " -> %" PRIuPTR ", errcode %d",
|
||||||
|
env->me_dbgeo.now, size_bytes, env->me_dbgeo.upper, limit_bytes,
|
||||||
|
rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_VALGRIND
|
||||||
|
if (prev_mapsize != env->me_mapsize || prev_mapaddr != env->me_map) {
|
||||||
|
VALGRIND_DISCARD(env->me_valgrind_handle);
|
||||||
|
env->me_valgrind_handle = 0;
|
||||||
|
if (env->me_mapsize)
|
||||||
|
env->me_valgrind_handle =
|
||||||
|
VALGRIND_CREATE_BLOCK(env->me_map, env->me_mapsize, "mdbx");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate page numbers and memory for writing. Maintain me_last_reclaimed,
|
/* Allocate page numbers and memory for writing. Maintain me_last_reclaimed,
|
||||||
* me_reclaimed_pglist and mt_next_pgno. Set MDBX_TXN_ERROR on failure.
|
* me_reclaimed_pglist and mt_next_pgno. Set MDBX_TXN_ERROR on failure.
|
||||||
*
|
*
|
||||||
@ -1835,36 +1883,24 @@ static int mdbx_page_alloc(MDBX_cursor *mc, unsigned num, MDBX_page **mp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == MDBX_MAP_FULL) {
|
if (rc == MDBX_MAP_FULL && next < head->mm_geo.upper) {
|
||||||
mdbx_assert(env, next > txn->mt_end_pgno);
|
mdbx_assert(env, next > txn->mt_end_pgno);
|
||||||
if (unlikely(pgno2bytes(env, next) <= env->me_mapsize)) {
|
pgno_t growth_pgno = bytes2pgno(
|
||||||
pgno_t growth_pgno = txn->mt_next_pgno + head->mm_geo.grow;
|
env,
|
||||||
if (growth_pgno > MAX_PAGENO)
|
mdbx_roundup2(pgno2bytes(env, txn->mt_next_pgno + head->mm_geo.grow),
|
||||||
growth_pgno = MAX_PAGENO;
|
env->me_os_psize));
|
||||||
size_t growth_bytes =
|
if (growth_pgno > head->mm_geo.upper)
|
||||||
mdbx_roundup2(pgno2bytes(env, growth_pgno), env->me_os_psize);
|
growth_pgno = head->mm_geo.upper;
|
||||||
if (growth_bytes > env->me_mapsize)
|
|
||||||
growth_bytes = env->me_mapsize;
|
|
||||||
growth_pgno = bytes2pgno(env, growth_bytes);
|
|
||||||
mdbx_assert(env, growth_pgno <= head->mm_geo.upper);
|
|
||||||
mdbx_assert(env, growth_pgno > txn->mt_end_pgno);
|
|
||||||
mdbx_info("growth datafile to %" PRIaPGNO " pages (+%" PRIaPGNO
|
|
||||||
"), %" PRIuPTR " bytes",
|
|
||||||
growth_pgno, growth_pgno - txn->mt_end_pgno, growth_bytes);
|
|
||||||
|
|
||||||
rc = mdbx_mresize(env->me_flags, &env->me_dxb_mmap, env->me_dbgeo.now,
|
mdbx_info("try growth datafile to %" PRIaPGNO " pages (+%" PRIaPGNO ")",
|
||||||
growth_bytes);
|
growth_pgno, growth_pgno - txn->mt_end_pgno);
|
||||||
if (rc == MDBX_SUCCESS) {
|
rc = mdbx_mapresize(env, growth_pgno, head->mm_geo.upper);
|
||||||
txn->mt_end_pgno = growth_pgno;
|
if (rc == MDBX_SUCCESS)
|
||||||
env->me_dbgeo.now = growth_bytes;
|
continue;
|
||||||
continue;
|
|
||||||
}
|
mdbx_warning("unable growth datafile to %" PRIaPGNO "pages (+%" PRIaPGNO
|
||||||
mdbx_error("error while growth datafile to %" PRIaPGNO
|
"), errcode %d",
|
||||||
"pages (+%" PRIaPGNO "), %" PRIuPTR " bytes, errcode %d",
|
growth_pgno, growth_pgno - txn->mt_end_pgno, rc);
|
||||||
growth_pgno, growth_pgno - txn->mt_end_pgno, growth_bytes,
|
|
||||||
rc);
|
|
||||||
} else if (next < head->mm_geo.upper)
|
|
||||||
rc = MDBX_MAP_RESIZED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -2267,6 +2303,7 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
|||||||
return MDBX_PANIC;
|
return MDBX_PANIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pgno_t upper_pgno = 0;
|
||||||
if (flags & MDBX_TXN_RDONLY) {
|
if (flags & MDBX_TXN_RDONLY) {
|
||||||
txn->mt_flags = MDBX_TXN_RDONLY;
|
txn->mt_flags = MDBX_TXN_RDONLY;
|
||||||
MDBX_reader *r = txn->mt_ro_reader;
|
MDBX_reader *r = txn->mt_ro_reader;
|
||||||
@ -2364,6 +2401,7 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
|||||||
txn->mt_txnid = snap;
|
txn->mt_txnid = snap;
|
||||||
txn->mt_next_pgno = meta->mm_geo.next;
|
txn->mt_next_pgno = meta->mm_geo.next;
|
||||||
txn->mt_end_pgno = meta->mm_geo.now;
|
txn->mt_end_pgno = meta->mm_geo.now;
|
||||||
|
upper_pgno = meta->mm_geo.upper;
|
||||||
memcpy(txn->mt_dbs, meta->mm_dbs, CORE_DBS * sizeof(MDBX_db));
|
memcpy(txn->mt_dbs, meta->mm_dbs, CORE_DBS * sizeof(MDBX_db));
|
||||||
txn->mt_canary = meta->mm_canary;
|
txn->mt_canary = meta->mm_canary;
|
||||||
|
|
||||||
@ -2417,6 +2455,7 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
|||||||
/* Moved to here to avoid a data race in read TXNs */
|
/* Moved to here to avoid a data race in read TXNs */
|
||||||
txn->mt_next_pgno = meta->mm_geo.next;
|
txn->mt_next_pgno = meta->mm_geo.next;
|
||||||
txn->mt_end_pgno = meta->mm_geo.now;
|
txn->mt_end_pgno = meta->mm_geo.now;
|
||||||
|
upper_pgno = meta->mm_geo.upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup db info */
|
/* Setup db info */
|
||||||
@ -2433,9 +2472,18 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
|||||||
if (unlikely(env->me_flags & MDBX_FATAL_ERROR)) {
|
if (unlikely(env->me_flags & MDBX_FATAL_ERROR)) {
|
||||||
mdbx_debug("environment had fatal error, must shutdown!");
|
mdbx_debug("environment had fatal error, must shutdown!");
|
||||||
rc = MDBX_PANIC;
|
rc = MDBX_PANIC;
|
||||||
} else if (unlikely(env->me_mapsize < pgno2bytes(env, txn->mt_next_pgno))) {
|
|
||||||
rc = MDBX_MAP_RESIZED;
|
|
||||||
} else {
|
} else {
|
||||||
|
const size_t size = pgno2bytes(env, txn->mt_end_pgno);
|
||||||
|
if (unlikely(size > env->me_mapsize)) {
|
||||||
|
if (upper_pgno > MAX_PAGENO ||
|
||||||
|
bytes2pgno(env, pgno2bytes(env, upper_pgno)) != upper_pgno) {
|
||||||
|
rc = MDBX_MAP_RESIZED;
|
||||||
|
goto bailout;
|
||||||
|
}
|
||||||
|
rc = mdbx_mapresize(env, txn->mt_end_pgno, upper_pgno);
|
||||||
|
if (rc != MDBX_SUCCESS)
|
||||||
|
goto bailout;
|
||||||
|
}
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
bailout:
|
bailout:
|
||||||
@ -3801,10 +3849,8 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
|
|||||||
/* Windows is unable shrinking a mapped file */
|
/* Windows is unable shrinking a mapped file */
|
||||||
#else
|
#else
|
||||||
/* LY: check conditions to shrink datafile */
|
/* LY: check conditions to shrink datafile */
|
||||||
|
pgno_t shrink_pgno_delta = 0;
|
||||||
const pgno_t shrink_pgno = pending->mm_geo.next /* + pending->mm_geo.grow */;
|
const pgno_t shrink_pgno = pending->mm_geo.next /* + pending->mm_geo.grow */;
|
||||||
const size_t shrink_bytes =
|
|
||||||
mdbx_roundup2(pgno2bytes(env, shrink_pgno), env->me_os_psize);
|
|
||||||
size_t shrink_pgno_delta = 0;
|
|
||||||
if (pending->mm_geo.now > shrink_pgno && pending->mm_geo.shrink &&
|
if (pending->mm_geo.now > shrink_pgno && pending->mm_geo.shrink &&
|
||||||
unlikely(pending->mm_geo.now - pending->mm_geo.shrink >= shrink_pgno)) {
|
unlikely(pending->mm_geo.now - pending->mm_geo.shrink >= shrink_pgno)) {
|
||||||
if (pending->mm_geo.now > shrink_pgno &&
|
if (pending->mm_geo.now > shrink_pgno &&
|
||||||
@ -3965,12 +4011,9 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
|
|||||||
/* Windows is unable shrinking a mapped file */
|
/* Windows is unable shrinking a mapped file */
|
||||||
#else
|
#else
|
||||||
/* LY: shrink datafile if needed */
|
/* LY: shrink datafile if needed */
|
||||||
if (shrink_pgno_delta) {
|
if (unlikely(shrink_pgno_delta)) {
|
||||||
rc = mdbx_mresize(env->me_flags, &env->me_dxb_mmap, env->me_dbgeo.now,
|
rc = mdbx_mapresize(env, pending->mm_geo.now, pending->mm_geo.upper);
|
||||||
shrink_bytes);
|
if (MDBX_IS_ERROR(rc))
|
||||||
if (rc == MDBX_SUCCESS)
|
|
||||||
env->me_dbgeo.now = shrink_bytes;
|
|
||||||
else if (rc != MDBX_RESULT_TRUE)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
#endif /* not a Windows */
|
#endif /* not a Windows */
|
||||||
@ -4079,7 +4122,7 @@ bailout:
|
|||||||
|
|
||||||
static int __cold mdbx_env_map(MDBX_env *env, size_t usedsize) {
|
static int __cold mdbx_env_map(MDBX_env *env, size_t usedsize) {
|
||||||
int rc = mdbx_mmap(env->me_flags, &env->me_dxb_mmap, env->me_dbgeo.now,
|
int rc = mdbx_mmap(env->me_flags, &env->me_dxb_mmap, env->me_dbgeo.now,
|
||||||
env->me_mapsize);
|
env->me_dbgeo.upper);
|
||||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
env->me_map = NULL;
|
env->me_map = NULL;
|
||||||
return rc;
|
return rc;
|
||||||
@ -4304,7 +4347,7 @@ LIBMDBX_API int mdbx_env_set_geometry(MDBX_env *env, ssize_t size_lower,
|
|||||||
if (bytes2pgno(env, shrink_threshold) > UINT16_MAX)
|
if (bytes2pgno(env, shrink_threshold) > UINT16_MAX)
|
||||||
shrink_threshold = pgno2bytes(env, UINT16_MAX);
|
shrink_threshold = pgno2bytes(env, UINT16_MAX);
|
||||||
|
|
||||||
/* save params for future open/create */
|
/* save user's geo-params for future open/create */
|
||||||
env->me_dbgeo.lower = size_lower;
|
env->me_dbgeo.lower = size_lower;
|
||||||
env->me_dbgeo.now = size_now;
|
env->me_dbgeo.now = size_now;
|
||||||
env->me_dbgeo.upper = size_upper;
|
env->me_dbgeo.upper = size_upper;
|
||||||
@ -4337,27 +4380,9 @@ LIBMDBX_API int mdbx_env_set_geometry(MDBX_env *env, ssize_t size_lower,
|
|||||||
meta.mm_geo.shrink == bytes2pgno(env, env->me_dbgeo.shrink));
|
meta.mm_geo.shrink == bytes2pgno(env, env->me_dbgeo.shrink));
|
||||||
|
|
||||||
if (memcmp(&meta.mm_geo, &head->mm_geo, sizeof(meta.mm_geo))) {
|
if (memcmp(&meta.mm_geo, &head->mm_geo, sizeof(meta.mm_geo))) {
|
||||||
if (meta.mm_geo.upper != head->mm_geo.upper) {
|
if (meta.mm_geo.now != head->mm_geo.now ||
|
||||||
const size_t size =
|
meta.mm_geo.upper != head->mm_geo.upper) {
|
||||||
mdbx_roundup2(pgno2bytes(env, meta.mm_geo.upper), env->me_os_psize);
|
rc = mdbx_mapresize(env, meta.mm_geo.now, meta.mm_geo.upper);
|
||||||
|
|
||||||
rc = mdbx_mremap(env->me_flags, &env->me_dxb_mmap, env->me_mapsize,
|
|
||||||
size);
|
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
|
||||||
goto bailout;
|
|
||||||
env->me_mapsize = size;
|
|
||||||
#ifdef USE_VALGRIND
|
|
||||||
VALGRIND_DISCARD(env->me_valgrind_handle);
|
|
||||||
env->me_valgrind_handle =
|
|
||||||
VALGRIND_CREATE_BLOCK(env->me_map, env->me_mapsize, "mdbx");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (meta.mm_geo.now != head->mm_geo.now) {
|
|
||||||
const size_t size =
|
|
||||||
mdbx_roundup2(pgno2bytes(env, meta.mm_geo.now), env->me_os_psize);
|
|
||||||
|
|
||||||
rc = mdbx_mresize(env->me_flags, &env->me_dxb_mmap,
|
|
||||||
pgno2bytes(env, head->mm_geo.now), size);
|
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
@ -4503,7 +4528,6 @@ static int __cold mdbx_setup_dxb(MDBX_env *env, int lck_rc) {
|
|||||||
meta.mm_geo.shrink = (uint16_t)bytes2pgno(env, env->me_dbgeo.shrink);
|
meta.mm_geo.shrink = (uint16_t)bytes2pgno(env, env->me_dbgeo.shrink);
|
||||||
mdbx_ensure(env, meta.mm_geo.now >= meta.mm_geo.next);
|
mdbx_ensure(env, meta.mm_geo.now >= meta.mm_geo.next);
|
||||||
}
|
}
|
||||||
env->me_mapsize = env->me_dbgeo.upper;
|
|
||||||
|
|
||||||
uint64_t filesize;
|
uint64_t filesize;
|
||||||
err = mdbx_filesize(env->me_fd, &filesize);
|
err = mdbx_filesize(env->me_fd, &filesize);
|
||||||
@ -4541,7 +4565,7 @@ static int __cold mdbx_setup_dxb(MDBX_env *env, int lck_rc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mdbx_env_map(env, env->me_mapsize);
|
err = mdbx_env_map(env, expected_bytes);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -4997,7 +5021,7 @@ static void __cold mdbx_env_close0(MDBX_env *env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (env->me_map) {
|
if (env->me_map) {
|
||||||
mdbx_munmap(&env->me_dxb_mmap, env->me_mapsize);
|
mdbx_munmap(&env->me_dxb_mmap);
|
||||||
#ifdef USE_VALGRIND
|
#ifdef USE_VALGRIND
|
||||||
VALGRIND_DISCARD(env->me_valgrind_handle);
|
VALGRIND_DISCARD(env->me_valgrind_handle);
|
||||||
env->me_valgrind_handle = -1;
|
env->me_valgrind_handle = -1;
|
||||||
@ -5009,9 +5033,7 @@ static void __cold mdbx_env_close0(MDBX_env *env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (env->me_lck) {
|
if (env->me_lck) {
|
||||||
mdbx_munmap(&env->me_lck_mmap,
|
mdbx_munmap(&env->me_lck_mmap);
|
||||||
(env->me_maxreaders - 1) * sizeof(MDBX_reader) +
|
|
||||||
sizeof(MDBX_lockinfo));
|
|
||||||
env->me_lck = nullptr;
|
env->me_lck = nullptr;
|
||||||
}
|
}
|
||||||
env->me_pid = 0;
|
env->me_pid = 0;
|
||||||
@ -9607,44 +9629,44 @@ int __cold mdbx_env_info(MDBX_env *env, MDBX_envinfo *arg, size_t bytes) {
|
|||||||
const MDBX_meta *meta;
|
const MDBX_meta *meta;
|
||||||
do {
|
do {
|
||||||
meta = mdbx_meta_head(env);
|
meta = mdbx_meta_head(env);
|
||||||
arg->me_recent_txnid = mdbx_meta_txnid_fluid(env, meta);
|
arg->mi_recent_txnid = mdbx_meta_txnid_fluid(env, meta);
|
||||||
arg->me_meta0_txnid = mdbx_meta_txnid_fluid(env, meta0);
|
arg->mi_meta0_txnid = mdbx_meta_txnid_fluid(env, meta0);
|
||||||
arg->me_meta0_sign = meta0->mm_datasync_sign;
|
arg->mi_meta0_sign = meta0->mm_datasync_sign;
|
||||||
arg->me_meta1_txnid = mdbx_meta_txnid_fluid(env, meta1);
|
arg->mi_meta1_txnid = mdbx_meta_txnid_fluid(env, meta1);
|
||||||
arg->me_meta1_sign = meta1->mm_datasync_sign;
|
arg->mi_meta1_sign = meta1->mm_datasync_sign;
|
||||||
arg->me_meta2_txnid = mdbx_meta_txnid_fluid(env, meta2);
|
arg->mi_meta2_txnid = mdbx_meta_txnid_fluid(env, meta2);
|
||||||
arg->me_meta2_sign = meta2->mm_datasync_sign;
|
arg->mi_meta2_sign = meta2->mm_datasync_sign;
|
||||||
arg->me_last_pgno = meta->mm_geo.next - 1;
|
arg->mi_last_pgno = meta->mm_geo.next - 1;
|
||||||
arg->me_geo.lower = pgno2bytes(env, meta->mm_geo.lower);
|
arg->mi_geo.lower = pgno2bytes(env, meta->mm_geo.lower);
|
||||||
arg->me_geo.upper = pgno2bytes(env, meta->mm_geo.upper);
|
arg->mi_geo.upper = pgno2bytes(env, meta->mm_geo.upper);
|
||||||
arg->me_geo.current = pgno2bytes(env, meta->mm_geo.now);
|
arg->mi_geo.current = pgno2bytes(env, meta->mm_geo.now);
|
||||||
arg->me_geo.shrink = pgno2bytes(env, meta->mm_geo.shrink);
|
arg->mi_geo.shrink = pgno2bytes(env, meta->mm_geo.shrink);
|
||||||
arg->me_geo.grow = pgno2bytes(env, meta->mm_geo.grow);
|
arg->mi_geo.grow = pgno2bytes(env, meta->mm_geo.grow);
|
||||||
arg->me_mapsize = env->me_mapsize;
|
arg->mi_mapsize = env->me_mapsize;
|
||||||
mdbx_compiler_barrier();
|
mdbx_compiler_barrier();
|
||||||
} while (unlikely(arg->me_meta0_txnid != mdbx_meta_txnid_fluid(env, meta0) ||
|
} while (unlikely(arg->mi_meta0_txnid != mdbx_meta_txnid_fluid(env, meta0) ||
|
||||||
arg->me_meta0_sign != meta0->mm_datasync_sign ||
|
arg->mi_meta0_sign != meta0->mm_datasync_sign ||
|
||||||
arg->me_meta1_txnid != mdbx_meta_txnid_fluid(env, meta1) ||
|
arg->mi_meta1_txnid != mdbx_meta_txnid_fluid(env, meta1) ||
|
||||||
arg->me_meta1_sign != meta1->mm_datasync_sign ||
|
arg->mi_meta1_sign != meta1->mm_datasync_sign ||
|
||||||
arg->me_meta2_txnid != mdbx_meta_txnid_fluid(env, meta2) ||
|
arg->mi_meta2_txnid != mdbx_meta_txnid_fluid(env, meta2) ||
|
||||||
arg->me_meta2_sign != meta2->mm_datasync_sign ||
|
arg->mi_meta2_sign != meta2->mm_datasync_sign ||
|
||||||
meta != mdbx_meta_head(env) ||
|
meta != mdbx_meta_head(env) ||
|
||||||
arg->me_recent_txnid != mdbx_meta_txnid_fluid(env, meta)));
|
arg->mi_recent_txnid != mdbx_meta_txnid_fluid(env, meta)));
|
||||||
|
|
||||||
arg->me_maxreaders = env->me_maxreaders;
|
arg->mi_maxreaders = env->me_maxreaders;
|
||||||
arg->me_numreaders = env->me_lck ? env->me_lck->mti_numreaders : INT32_MAX;
|
arg->mi_numreaders = env->me_lck ? env->me_lck->mti_numreaders : INT32_MAX;
|
||||||
arg->me_dxb_pagesize = env->me_psize;
|
arg->mi_dxb_pagesize = env->me_psize;
|
||||||
arg->me_sys_pagesize = env->me_os_psize;
|
arg->mi_sys_pagesize = env->me_os_psize;
|
||||||
|
|
||||||
arg->me_latter_reader_txnid = 0;
|
arg->mi_latter_reader_txnid = 0;
|
||||||
if (env->me_lck) {
|
if (env->me_lck) {
|
||||||
MDBX_reader *r = env->me_lck->mti_readers;
|
MDBX_reader *r = env->me_lck->mti_readers;
|
||||||
arg->me_latter_reader_txnid = arg->me_recent_txnid;
|
arg->mi_latter_reader_txnid = arg->mi_recent_txnid;
|
||||||
for (unsigned i = 0; i < arg->me_numreaders; ++i) {
|
for (unsigned i = 0; i < arg->mi_numreaders; ++i) {
|
||||||
if (r[i].mr_pid) {
|
if (r[i].mr_pid) {
|
||||||
const txnid_t txnid = r[i].mr_txnid;
|
const txnid_t txnid = r[i].mr_txnid;
|
||||||
if (arg->me_latter_reader_txnid > txnid)
|
if (arg->mi_latter_reader_txnid > txnid)
|
||||||
arg->me_latter_reader_txnid = txnid;
|
arg->mi_latter_reader_txnid = txnid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10451,9 +10473,10 @@ int mdbx_txn_straggler(MDBX_txn *txn, int *percent)
|
|||||||
return MDBX_THREAD_MISMATCH;
|
return MDBX_THREAD_MISMATCH;
|
||||||
|
|
||||||
MDBX_env *env = txn->mt_env;
|
MDBX_env *env = txn->mt_env;
|
||||||
pgno_t maxpg = bytes2pgno(env, env->me_mapsize);
|
|
||||||
if (unlikely((txn->mt_flags & MDBX_RDONLY) == 0)) {
|
if (unlikely((txn->mt_flags & MDBX_RDONLY) == 0)) {
|
||||||
*percent = (int)((txn->mt_next_pgno * UINT64_C(100) + maxpg / 2) / maxpg);
|
*percent =
|
||||||
|
(int)((txn->mt_next_pgno * UINT64_C(100) + txn->mt_end_pgno / 2) /
|
||||||
|
txn->mt_end_pgno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10462,8 +10485,10 @@ int mdbx_txn_straggler(MDBX_txn *txn, int *percent)
|
|||||||
do {
|
do {
|
||||||
meta = mdbx_meta_head(env);
|
meta = mdbx_meta_head(env);
|
||||||
recent = mdbx_meta_txnid_fluid(env, meta);
|
recent = mdbx_meta_txnid_fluid(env, meta);
|
||||||
if (percent)
|
if (percent) {
|
||||||
|
const pgno_t maxpg = meta->mm_geo.now;
|
||||||
*percent = (int)((meta->mm_geo.next * UINT64_C(100) + maxpg / 2) / maxpg);
|
*percent = (int)((meta->mm_geo.next * UINT64_C(100) + maxpg / 2) / maxpg);
|
||||||
|
}
|
||||||
} while (unlikely(recent != mdbx_meta_txnid_fluid(env, meta)));
|
} while (unlikely(recent != mdbx_meta_txnid_fluid(env, meta)));
|
||||||
|
|
||||||
txnid_t lag = recent - txn->mt_ro_reader->mr_txnid;
|
txnid_t lag = recent - txn->mt_ro_reader->mr_txnid;
|
||||||
|
104
src/osal.c
104
src/osal.c
@ -773,9 +773,12 @@ int mdbx_msync(mdbx_mmap_t *map, size_t offset, size_t length, int async) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdbx_mmap(int flags, mdbx_mmap_t *map, size_t length, size_t limit) {
|
int mdbx_mmap(int flags, mdbx_mmap_t *map, size_t must, size_t limit) {
|
||||||
|
assert(must <= limit);
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
map->section = 0;
|
map->length = 0;
|
||||||
|
map->current = 0;
|
||||||
|
map->section = NULL;
|
||||||
map->address = MAP_FAILED;
|
map->address = MAP_FAILED;
|
||||||
|
|
||||||
if (GetFileType(map->fd) != FILE_TYPE_DISK)
|
if (GetFileType(map->fd) != FILE_TYPE_DISK)
|
||||||
@ -870,11 +873,11 @@ int mdbx_mmap(int flags, mdbx_mmap_t *map, size_t length, size_t limit) {
|
|||||||
return ntstatus2errcode(rc);
|
return ntstatus2errcode(rc);
|
||||||
|
|
||||||
map->address = NULL;
|
map->address = NULL;
|
||||||
SIZE_T ViewSize = limit;
|
SIZE_T ViewSize = (flags & MDBX_RDONLY) ? must : limit;
|
||||||
rc = NtMapViewOfSection(
|
rc = NtMapViewOfSection(
|
||||||
map->section, GetCurrentProcess(), &map->address,
|
map->section, GetCurrentProcess(), &map->address,
|
||||||
/* ZeroBits */ 0,
|
/* ZeroBits */ 0,
|
||||||
/* CommitSize */ length,
|
/* CommitSize */ must,
|
||||||
/* SectionOffset */ NULL, &ViewSize,
|
/* SectionOffset */ NULL, &ViewSize,
|
||||||
/* InheritDisposition */ ViewUnmap,
|
/* InheritDisposition */ ViewUnmap,
|
||||||
/* AllocationType */ (flags & MDBX_RDONLY) ? 0 : MEM_RESERVE,
|
/* AllocationType */ (flags & MDBX_RDONLY) ? 0 : MEM_RESERVE,
|
||||||
@ -889,26 +892,40 @@ int mdbx_mmap(int flags, mdbx_mmap_t *map, size_t length, size_t limit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(map->address != MAP_FAILED);
|
assert(map->address != MAP_FAILED);
|
||||||
|
map->current = must;
|
||||||
|
map->length = ViewSize;
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
#else
|
#else
|
||||||
(void)length;
|
(void)must;
|
||||||
map->address = mmap(
|
map->address = mmap(
|
||||||
NULL, limit, (flags & MDBX_WRITEMAP) ? PROT_READ | PROT_WRITE : PROT_READ,
|
NULL, limit, (flags & MDBX_WRITEMAP) ? PROT_READ | PROT_WRITE : PROT_READ,
|
||||||
MAP_SHARED, map->fd, 0);
|
MAP_SHARED, map->fd, 0);
|
||||||
return (map->address != MAP_FAILED) ? MDBX_SUCCESS : errno;
|
if (likely(map->address != MAP_FAILED)) {
|
||||||
|
map->length = limit;
|
||||||
|
return MDBX_SUCCESS;
|
||||||
|
}
|
||||||
|
map->length = 0;
|
||||||
|
return errno;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdbx_munmap(mdbx_mmap_t *map, size_t length) {
|
int mdbx_munmap(mdbx_mmap_t *map) {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
(void)length;
|
|
||||||
if (map->section)
|
if (map->section)
|
||||||
NtClose(map->section);
|
NtClose(map->section);
|
||||||
NTSTATUS rc = NtUnmapViewOfSection(GetCurrentProcess(), map->address);
|
NTSTATUS rc = NtUnmapViewOfSection(GetCurrentProcess(), map->address);
|
||||||
return NT_SUCCESS(rc) ? MDBX_SUCCESS : ntstatus2errcode(rc);
|
if (!NT_SUCCESS(rc))
|
||||||
|
ntstatus2errcode(rc);
|
||||||
|
map->length = 0;
|
||||||
|
map->current = 0;
|
||||||
|
map->address = nullptr;
|
||||||
#else
|
#else
|
||||||
return (munmap(map->address, length) == 0) ? MDBX_SUCCESS : errno;
|
if (unlikely(munmap(map->address, map->length)))
|
||||||
|
return errno;
|
||||||
|
map->length = 0;
|
||||||
|
map->address = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdbx_mlock(mdbx_mmap_t *map, size_t length) {
|
int mdbx_mlock(mdbx_mmap_t *map, size_t length) {
|
||||||
@ -919,45 +936,46 @@ int mdbx_mlock(mdbx_mmap_t *map, size_t length) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t current, size_t wanna) {
|
int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t must, size_t limit) {
|
||||||
|
assert(must <= limit);
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
if (wanna > current) {
|
if (limit < map->length) {
|
||||||
/* growth */
|
|
||||||
uint8_t *ptr = (uint8_t *)map->address + current;
|
|
||||||
return (ptr == VirtualAlloc(ptr, wanna - current, MEM_COMMIT,
|
|
||||||
(flags & MDBX_WRITEMAP) ? PAGE_READWRITE
|
|
||||||
: PAGE_READONLY))
|
|
||||||
? MDBX_SUCCESS
|
|
||||||
: GetLastError();
|
|
||||||
}
|
|
||||||
/* Windows is unable shrinking a mapped file */
|
|
||||||
return MDBX_RESULT_TRUE;
|
|
||||||
#else
|
|
||||||
(void)flags;
|
|
||||||
(void)current;
|
|
||||||
return mdbx_ftruncate(map->fd, wanna);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int mdbx_mremap(int flags, mdbx_mmap_t *map, size_t old_limit,
|
|
||||||
size_t new_limit) {
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
|
||||||
(void)flags;
|
|
||||||
if (old_limit > new_limit) {
|
|
||||||
/* Windows is unable shrinking a mapped section */
|
/* Windows is unable shrinking a mapped section */
|
||||||
return ERROR_USER_MAPPED_FILE;
|
return ERROR_USER_MAPPED_FILE;
|
||||||
}
|
}
|
||||||
LARGE_INTEGER new_size;
|
if (limit > map->length) {
|
||||||
new_size.QuadPart = new_limit;
|
/* extend */
|
||||||
NTSTATUS rc = NtExtendSection(map->section, &new_size);
|
LARGE_INTEGER new_size;
|
||||||
return NT_SUCCESS(rc) ? MDBX_SUCCESS : ntstatus2errcode(rc);
|
new_size.QuadPart = limit;
|
||||||
|
NTSTATUS rc = NtExtendSection(map->section, &new_size);
|
||||||
|
if (!NT_SUCCESS(rc))
|
||||||
|
return ntstatus2errcode(rc);
|
||||||
|
map->length = limit;
|
||||||
|
}
|
||||||
|
if (must < map->current) {
|
||||||
|
/* Windows is unable shrinking a mapped file */
|
||||||
|
return MDBX_RESULT_TRUE;
|
||||||
|
}
|
||||||
|
if (must > map->current) {
|
||||||
|
/* growth */
|
||||||
|
uint8_t *ptr = (uint8_t *)map->address + map->current;
|
||||||
|
if (ptr !=
|
||||||
|
VirtualAlloc(ptr, must - map->current, MEM_COMMIT,
|
||||||
|
(flags & MDBX_WRITEMAP) ? PAGE_READWRITE : PAGE_READONLY))
|
||||||
|
return GetLastError();
|
||||||
|
map->current = must;
|
||||||
|
}
|
||||||
|
return MDBX_SUCCESS;
|
||||||
#else
|
#else
|
||||||
(void)flags;
|
(void)flags;
|
||||||
void *ptr = mremap(map->address, old_limit, new_limit, 0);
|
if (limit != map->length) {
|
||||||
if (ptr == MAP_FAILED)
|
void *ptr = mremap(map->address, map->length, limit, MREMAP_MAYMOVE);
|
||||||
return errno;
|
if (ptr == MAP_FAILED)
|
||||||
map->address = ptr;
|
return errno;
|
||||||
return MDBX_SUCCESS;
|
map->address = ptr;
|
||||||
|
map->length = limit;
|
||||||
|
}
|
||||||
|
return mdbx_ftruncate(map->fd, must);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/osal.h
10
src/osal.h
@ -444,17 +444,19 @@ typedef struct mdbx_mmap_param {
|
|||||||
struct MDBX_lockinfo *lck;
|
struct MDBX_lockinfo *lck;
|
||||||
};
|
};
|
||||||
mdbx_filehandle_t fd;
|
mdbx_filehandle_t fd;
|
||||||
|
size_t length; /* mapping length, but NOT a size of file or DB */
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
size_t current; /* mapped region size, e.g. file and DB */
|
||||||
|
#endif
|
||||||
#ifdef MDBX_OSAL_SECTION
|
#ifdef MDBX_OSAL_SECTION
|
||||||
MDBX_OSAL_SECTION section;
|
MDBX_OSAL_SECTION section;
|
||||||
#endif
|
#endif
|
||||||
} mdbx_mmap_t;
|
} mdbx_mmap_t;
|
||||||
|
|
||||||
int mdbx_mmap(int flags, mdbx_mmap_t *map, size_t length, size_t limit);
|
int mdbx_mmap(int flags, mdbx_mmap_t *map, size_t must, size_t limit);
|
||||||
int mdbx_munmap(mdbx_mmap_t *map, size_t length);
|
int mdbx_munmap(mdbx_mmap_t *map);
|
||||||
int mdbx_mlock(mdbx_mmap_t *map, size_t length);
|
int mdbx_mlock(mdbx_mmap_t *map, size_t length);
|
||||||
int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t current, size_t wanna);
|
int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t current, size_t wanna);
|
||||||
int mdbx_mremap(int flags, mdbx_mmap_t *map, size_t old_limit,
|
|
||||||
size_t new_limit);
|
|
||||||
int mdbx_msync(mdbx_mmap_t *map, size_t offset, size_t length, int async);
|
int mdbx_msync(mdbx_mmap_t *map, size_t offset, size_t length, int async);
|
||||||
|
|
||||||
static __inline mdbx_pid_t mdbx_getpid(void) {
|
static __inline mdbx_pid_t mdbx_getpid(void) {
|
||||||
|
@ -335,7 +335,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
|
|||||||
if (key->iov_len != sizeof(txnid_t))
|
if (key->iov_len != sizeof(txnid_t))
|
||||||
problem_add("entry", record_number, "wrong txn-id size",
|
problem_add("entry", record_number, "wrong txn-id size",
|
||||||
"key-size %" PRIiPTR "", key->iov_len);
|
"key-size %" PRIiPTR "", key->iov_len);
|
||||||
else if (txnid < 1 || txnid > envinfo.me_recent_txnid)
|
else if (txnid < 1 || txnid > envinfo.mi_recent_txnid)
|
||||||
problem_add("entry", record_number, "wrong txn-id", "%" PRIaTXN "", txnid);
|
problem_add("entry", record_number, "wrong txn-id", "%" PRIaTXN "", txnid);
|
||||||
|
|
||||||
if (data->iov_len < sizeof(pgno_t) || data->iov_len % sizeof(pgno_t))
|
if (data->iov_len < sizeof(pgno_t) || data->iov_len % sizeof(pgno_t))
|
||||||
@ -352,14 +352,14 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
|
|||||||
data->iov_len);
|
data->iov_len);
|
||||||
else {
|
else {
|
||||||
freedb_pages += number;
|
freedb_pages += number;
|
||||||
if (envinfo.me_latter_reader_txnid > txnid)
|
if (envinfo.mi_latter_reader_txnid > txnid)
|
||||||
reclaimable_pages += number;
|
reclaimable_pages += number;
|
||||||
for (i = number, prev = 1; --i >= 0;) {
|
for (i = number, prev = 1; --i >= 0;) {
|
||||||
pg = iptr[i];
|
pg = iptr[i];
|
||||||
if (pg < NUM_METAS || pg > envinfo.me_last_pgno)
|
if (pg < NUM_METAS || pg > envinfo.mi_last_pgno)
|
||||||
problem_add("entry", record_number, "wrong idl entry",
|
problem_add("entry", record_number, "wrong idl entry",
|
||||||
"%u < %" PRIiPTR " < %" PRIiPTR "", NUM_METAS, pg,
|
"%u < %" PRIiPTR " < %" PRIiPTR "", NUM_METAS, pg,
|
||||||
envinfo.me_last_pgno);
|
envinfo.mi_last_pgno);
|
||||||
else if (pg <= prev) {
|
else if (pg <= prev) {
|
||||||
bad = " [bad sequence]";
|
bad = " [bad sequence]";
|
||||||
problem_add("entry", record_number, "bad sequence",
|
problem_add("entry", record_number, "bad sequence",
|
||||||
@ -636,16 +636,16 @@ static __inline bool meta_eq(txnid_t txn_a, uint64_t sign_a, txnid_t txn_b,
|
|||||||
|
|
||||||
static __inline int meta_recent(const bool roolback2steady) {
|
static __inline int meta_recent(const bool roolback2steady) {
|
||||||
|
|
||||||
if (meta_ot(envinfo.me_meta0_txnid, envinfo.me_meta0_sign,
|
if (meta_ot(envinfo.mi_meta0_txnid, envinfo.mi_meta0_sign,
|
||||||
envinfo.me_meta1_txnid, envinfo.me_meta1_sign, roolback2steady))
|
envinfo.mi_meta1_txnid, envinfo.mi_meta1_sign, roolback2steady))
|
||||||
return meta_ot(envinfo.me_meta2_txnid, envinfo.me_meta2_sign,
|
return meta_ot(envinfo.mi_meta2_txnid, envinfo.mi_meta2_sign,
|
||||||
envinfo.me_meta1_txnid, envinfo.me_meta1_sign,
|
envinfo.mi_meta1_txnid, envinfo.mi_meta1_sign,
|
||||||
roolback2steady)
|
roolback2steady)
|
||||||
? 1
|
? 1
|
||||||
: 2;
|
: 2;
|
||||||
|
|
||||||
return meta_ot(envinfo.me_meta0_txnid, envinfo.me_meta0_sign,
|
return meta_ot(envinfo.mi_meta0_txnid, envinfo.mi_meta0_sign,
|
||||||
envinfo.me_meta2_txnid, envinfo.me_meta2_sign, roolback2steady)
|
envinfo.mi_meta2_txnid, envinfo.mi_meta2_sign, roolback2steady)
|
||||||
? 2
|
? 2
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
@ -653,18 +653,18 @@ static __inline int meta_recent(const bool roolback2steady) {
|
|||||||
static __inline int meta_tail(int head) {
|
static __inline int meta_tail(int head) {
|
||||||
|
|
||||||
if (head == 0)
|
if (head == 0)
|
||||||
return meta_ot(envinfo.me_meta1_txnid, envinfo.me_meta1_sign,
|
return meta_ot(envinfo.mi_meta1_txnid, envinfo.mi_meta1_sign,
|
||||||
envinfo.me_meta2_txnid, envinfo.me_meta2_sign, true)
|
envinfo.mi_meta2_txnid, envinfo.mi_meta2_sign, true)
|
||||||
? 1
|
? 1
|
||||||
: 2;
|
: 2;
|
||||||
if (head == 1)
|
if (head == 1)
|
||||||
return meta_ot(envinfo.me_meta0_txnid, envinfo.me_meta0_sign,
|
return meta_ot(envinfo.mi_meta0_txnid, envinfo.mi_meta0_sign,
|
||||||
envinfo.me_meta2_txnid, envinfo.me_meta2_sign, true)
|
envinfo.mi_meta2_txnid, envinfo.mi_meta2_sign, true)
|
||||||
? 0
|
? 0
|
||||||
: 2;
|
: 2;
|
||||||
if (head == 2)
|
if (head == 2)
|
||||||
return meta_ot(envinfo.me_meta0_txnid, envinfo.me_meta0_sign,
|
return meta_ot(envinfo.mi_meta0_txnid, envinfo.mi_meta0_sign,
|
||||||
envinfo.me_meta1_txnid, envinfo.me_meta1_sign, true)
|
envinfo.mi_meta1_txnid, envinfo.mi_meta1_sign, true)
|
||||||
? 0
|
? 0
|
||||||
: 1;
|
: 1;
|
||||||
assert(false);
|
assert(false);
|
||||||
@ -698,10 +698,10 @@ void verbose_meta(int num, txnid_t txnid, uint64_t sign) {
|
|||||||
if (stay)
|
if (stay)
|
||||||
print(", stay");
|
print(", stay");
|
||||||
|
|
||||||
if (txnid > envinfo.me_recent_txnid &&
|
if (txnid > envinfo.mi_recent_txnid &&
|
||||||
(exclusive || (envflags & MDBX_RDONLY) == 0))
|
(exclusive || (envflags & MDBX_RDONLY) == 0))
|
||||||
print(", rolled-back %" PRIu64 " (%" PRIu64 " >>> %" PRIu64 ")",
|
print(", rolled-back %" PRIu64 " (%" PRIu64 " >>> %" PRIu64 ")",
|
||||||
txnid - envinfo.me_recent_txnid, txnid, envinfo.me_recent_txnid);
|
txnid - envinfo.mi_recent_txnid, txnid, envinfo.mi_recent_txnid);
|
||||||
print("\n");
|
print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -712,26 +712,26 @@ static int check_meta_head(bool steady) {
|
|||||||
error(" - unexpected internal error (%s)\n",
|
error(" - unexpected internal error (%s)\n",
|
||||||
steady ? "meta_steady_head" : "meta_weak_head");
|
steady ? "meta_steady_head" : "meta_weak_head");
|
||||||
case 0:
|
case 0:
|
||||||
if (envinfo.me_meta0_txnid != envinfo.me_recent_txnid) {
|
if (envinfo.mi_meta0_txnid != envinfo.mi_recent_txnid) {
|
||||||
print(" - meta-%d txn-id mismatch recent-txn-id (%" PRIi64 " != %" PRIi64
|
print(" - meta-%d txn-id mismatch recent-txn-id (%" PRIi64 " != %" PRIi64
|
||||||
")\n",
|
")\n",
|
||||||
0, envinfo.me_meta0_txnid, envinfo.me_recent_txnid);
|
0, envinfo.mi_meta0_txnid, envinfo.mi_recent_txnid);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (envinfo.me_meta1_txnid != envinfo.me_recent_txnid) {
|
if (envinfo.mi_meta1_txnid != envinfo.mi_recent_txnid) {
|
||||||
print(" - meta-%d txn-id mismatch recent-txn-id (%" PRIi64 " != %" PRIi64
|
print(" - meta-%d txn-id mismatch recent-txn-id (%" PRIi64 " != %" PRIi64
|
||||||
")\n",
|
")\n",
|
||||||
1, envinfo.me_meta1_txnid, envinfo.me_recent_txnid);
|
1, envinfo.mi_meta1_txnid, envinfo.mi_recent_txnid);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (envinfo.me_meta2_txnid != envinfo.me_recent_txnid) {
|
if (envinfo.mi_meta2_txnid != envinfo.mi_recent_txnid) {
|
||||||
print(" - meta-%d txn-id mismatch recent-txn-id (%" PRIi64 " != %" PRIi64
|
print(" - meta-%d txn-id mismatch recent-txn-id (%" PRIi64 " != %" PRIi64
|
||||||
")\n",
|
")\n",
|
||||||
2, envinfo.me_meta2_txnid, envinfo.me_recent_txnid);
|
2, envinfo.mi_meta2_txnid, envinfo.mi_recent_txnid);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -890,50 +890,50 @@ int main(int argc, char *argv[]) {
|
|||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastpgno = envinfo.me_last_pgno + 1;
|
lastpgno = envinfo.mi_last_pgno + 1;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
print(" - pagesize %u (%u system), max keysize %" PRIuPTR
|
print(" - pagesize %u (%u system), max keysize %" PRIuPTR
|
||||||
", max readers %u\n",
|
", max readers %u\n",
|
||||||
envinfo.me_dxb_pagesize, envinfo.me_sys_pagesize, maxkeysize,
|
envinfo.mi_dxb_pagesize, envinfo.mi_sys_pagesize, maxkeysize,
|
||||||
envinfo.me_maxreaders);
|
envinfo.mi_maxreaders);
|
||||||
print_size(" - mapsize ", envinfo.me_mapsize, "\n");
|
print_size(" - mapsize ", envinfo.mi_mapsize, "\n");
|
||||||
if (envinfo.me_geo.lower == envinfo.me_geo.upper)
|
if (envinfo.mi_geo.lower == envinfo.mi_geo.upper)
|
||||||
print_size(" - fixed datafile: ", envinfo.me_geo.current, "");
|
print_size(" - fixed datafile: ", envinfo.mi_geo.current, "");
|
||||||
else {
|
else {
|
||||||
print_size(" - dynamic datafile: ", envinfo.me_geo.lower, "");
|
print_size(" - dynamic datafile: ", envinfo.mi_geo.lower, "");
|
||||||
print_size(" .. ", envinfo.me_geo.upper, ", ");
|
print_size(" .. ", envinfo.mi_geo.upper, ", ");
|
||||||
print_size("+", envinfo.me_geo.grow, ", ");
|
print_size("+", envinfo.mi_geo.grow, ", ");
|
||||||
print_size("-", envinfo.me_geo.shrink, "\n");
|
print_size("-", envinfo.mi_geo.shrink, "\n");
|
||||||
print_size(" - current datafile: ", envinfo.me_geo.current, "");
|
print_size(" - current datafile: ", envinfo.mi_geo.current, "");
|
||||||
}
|
}
|
||||||
printf(", %" PRIu64 " pages\n",
|
printf(", %" PRIu64 " pages\n",
|
||||||
envinfo.me_geo.current / envinfo.me_dxb_pagesize);
|
envinfo.mi_geo.current / envinfo.mi_dxb_pagesize);
|
||||||
print(" - transactions: recent %" PRIu64 ", latter reader %" PRIu64
|
print(" - transactions: recent %" PRIu64 ", latter reader %" PRIu64
|
||||||
", lag %" PRIi64 "\n",
|
", lag %" PRIi64 "\n",
|
||||||
envinfo.me_recent_txnid, envinfo.me_latter_reader_txnid,
|
envinfo.mi_recent_txnid, envinfo.mi_latter_reader_txnid,
|
||||||
envinfo.me_recent_txnid - envinfo.me_latter_reader_txnid);
|
envinfo.mi_recent_txnid - envinfo.mi_latter_reader_txnid);
|
||||||
|
|
||||||
verbose_meta(0, envinfo.me_meta0_txnid, envinfo.me_meta0_sign);
|
verbose_meta(0, envinfo.mi_meta0_txnid, envinfo.mi_meta0_sign);
|
||||||
verbose_meta(1, envinfo.me_meta1_txnid, envinfo.me_meta1_sign);
|
verbose_meta(1, envinfo.mi_meta1_txnid, envinfo.mi_meta1_sign);
|
||||||
verbose_meta(2, envinfo.me_meta2_txnid, envinfo.me_meta2_sign);
|
verbose_meta(2, envinfo.mi_meta2_txnid, envinfo.mi_meta2_sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
print(" - performs check for meta-pages clashes\n");
|
print(" - performs check for meta-pages clashes\n");
|
||||||
if (meta_eq(envinfo.me_meta0_txnid, envinfo.me_meta0_sign,
|
if (meta_eq(envinfo.mi_meta0_txnid, envinfo.mi_meta0_sign,
|
||||||
envinfo.me_meta1_txnid, envinfo.me_meta1_sign)) {
|
envinfo.mi_meta1_txnid, envinfo.mi_meta1_sign)) {
|
||||||
print(" - meta-%d and meta-%d are clashed\n", 0, 1);
|
print(" - meta-%d and meta-%d are clashed\n", 0, 1);
|
||||||
++problems_meta;
|
++problems_meta;
|
||||||
}
|
}
|
||||||
if (meta_eq(envinfo.me_meta1_txnid, envinfo.me_meta1_sign,
|
if (meta_eq(envinfo.mi_meta1_txnid, envinfo.mi_meta1_sign,
|
||||||
envinfo.me_meta2_txnid, envinfo.me_meta2_sign)) {
|
envinfo.mi_meta2_txnid, envinfo.mi_meta2_sign)) {
|
||||||
print(" - meta-%d and meta-%d are clashed\n", 1, 2);
|
print(" - meta-%d and meta-%d are clashed\n", 1, 2);
|
||||||
++problems_meta;
|
++problems_meta;
|
||||||
}
|
}
|
||||||
if (meta_eq(envinfo.me_meta2_txnid, envinfo.me_meta2_sign,
|
if (meta_eq(envinfo.mi_meta2_txnid, envinfo.mi_meta2_sign,
|
||||||
envinfo.me_meta0_txnid, envinfo.me_meta0_sign)) {
|
envinfo.mi_meta0_txnid, envinfo.mi_meta0_sign)) {
|
||||||
print(" - meta-%d and meta-%d are clashed\n", 2, 0);
|
print(" - meta-%d and meta-%d are clashed\n", 2, 0);
|
||||||
++problems_meta;
|
++problems_meta;
|
||||||
}
|
}
|
||||||
@ -1042,15 +1042,15 @@ int main(int argc, char *argv[]) {
|
|||||||
problems_freedb = process_db(FREE_DBI, "free", handle_freedb, false);
|
problems_freedb = process_db(FREE_DBI, "free", handle_freedb, false);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
uint64_t value = envinfo.me_mapsize / envstat.ms_psize;
|
uint64_t value = envinfo.mi_mapsize / envstat.ms_psize;
|
||||||
double percent = value / 100.0;
|
double percent = value / 100.0;
|
||||||
print(" - pages info: %" PRIu64 " total", value);
|
print(" - pages info: %" PRIu64 " total", value);
|
||||||
value = envinfo.me_geo.current / envinfo.me_dxb_pagesize;
|
value = envinfo.mi_geo.current / envinfo.mi_dxb_pagesize;
|
||||||
print(", backed %" PRIu64 " (%.1f%%)", value, value / percent);
|
print(", backed %" PRIu64 " (%.1f%%)", value, value / percent);
|
||||||
print(", allocated %" PRIu64 " (%.1f%%)", lastpgno, lastpgno / percent);
|
print(", allocated %" PRIu64 " (%.1f%%)", lastpgno, lastpgno / percent);
|
||||||
|
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
value = envinfo.me_mapsize / envstat.ms_psize - lastpgno;
|
value = envinfo.mi_mapsize / envstat.ms_psize - lastpgno;
|
||||||
print(", remained %" PRIu64 " (%.1f%%)", value, value / percent);
|
print(", remained %" PRIu64 " (%.1f%%)", value, value / percent);
|
||||||
|
|
||||||
value = lastpgno - freedb_pages;
|
value = lastpgno - freedb_pages;
|
||||||
@ -1066,7 +1066,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
value =
|
value =
|
||||||
envinfo.me_mapsize / envstat.ms_psize - lastpgno + reclaimable_pages;
|
envinfo.mi_mapsize / envstat.ms_psize - lastpgno + reclaimable_pages;
|
||||||
print(", available %" PRIu64 " (%.1f%%)\n", value, value / percent);
|
print(", available %" PRIu64 " (%.1f%%)\n", value, value / percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,8 +122,8 @@ static int dumpit(MDBX_txn *txn, MDBX_dbi dbi, char *name) {
|
|||||||
if (name)
|
if (name)
|
||||||
printf("database=%s\n", name);
|
printf("database=%s\n", name);
|
||||||
printf("type=btree\n");
|
printf("type=btree\n");
|
||||||
printf("mapsize=%" PRIu64 "\n", info.me_mapsize);
|
printf("mapsize=%" PRIu64 "\n", info.mi_mapsize);
|
||||||
printf("maxreaders=%u\n", info.me_maxreaders);
|
printf("maxreaders=%u\n", info.mi_maxreaders);
|
||||||
|
|
||||||
for (i = 0; dbflags[i].bit; i++)
|
for (i = 0; dbflags[i].bit; i++)
|
||||||
if (flags & dbflags[i].bit)
|
if (flags & dbflags[i].bit)
|
||||||
|
@ -137,7 +137,7 @@ static void readhdr(void) {
|
|||||||
if (ptr)
|
if (ptr)
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
i = sscanf((char *)dbuf.iov_base + STRLENOF("mapsize="), "%" PRIu64 "",
|
i = sscanf((char *)dbuf.iov_base + STRLENOF("mapsize="), "%" PRIu64 "",
|
||||||
&envinfo.me_mapsize);
|
&envinfo.mi_mapsize);
|
||||||
if (i != 1) {
|
if (i != 1) {
|
||||||
fprintf(stderr, "%s: line %" PRIiPTR ": invalid mapsize %s\n", prog,
|
fprintf(stderr, "%s: line %" PRIiPTR ": invalid mapsize %s\n", prog,
|
||||||
lineno, (char *)dbuf.iov_base + STRLENOF("mapsize="));
|
lineno, (char *)dbuf.iov_base + STRLENOF("mapsize="));
|
||||||
@ -150,7 +150,7 @@ static void readhdr(void) {
|
|||||||
if (ptr)
|
if (ptr)
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
i = sscanf((char *)dbuf.iov_base + STRLENOF("maxreaders="), "%u",
|
i = sscanf((char *)dbuf.iov_base + STRLENOF("maxreaders="), "%u",
|
||||||
&envinfo.me_maxreaders);
|
&envinfo.mi_maxreaders);
|
||||||
if (i != 1) {
|
if (i != 1) {
|
||||||
fprintf(stderr, "%s: line %" PRIiPTR ": invalid maxreaders %s\n", prog,
|
fprintf(stderr, "%s: line %" PRIiPTR ": invalid maxreaders %s\n", prog,
|
||||||
lineno, (char *)dbuf.iov_base + STRLENOF("maxreaders="));
|
lineno, (char *)dbuf.iov_base + STRLENOF("maxreaders="));
|
||||||
@ -393,20 +393,20 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
mdbx_env_set_maxdbs(env, 2);
|
mdbx_env_set_maxdbs(env, 2);
|
||||||
|
|
||||||
if (envinfo.me_maxreaders)
|
if (envinfo.mi_maxreaders)
|
||||||
mdbx_env_set_maxreaders(env, envinfo.me_maxreaders);
|
mdbx_env_set_maxreaders(env, envinfo.mi_maxreaders);
|
||||||
|
|
||||||
if (envinfo.me_mapsize) {
|
if (envinfo.mi_mapsize) {
|
||||||
if (envinfo.me_mapsize > SIZE_MAX) {
|
if (envinfo.mi_mapsize > SIZE_MAX) {
|
||||||
fprintf(stderr, "mdbx_env_set_mapsize failed, error %d %s\n", rc,
|
fprintf(stderr, "mdbx_env_set_mapsize failed, error %d %s\n", rc,
|
||||||
mdbx_strerror(MDBX_TOO_LARGE));
|
mdbx_strerror(MDBX_TOO_LARGE));
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
mdbx_env_set_mapsize(env, (size_t)envinfo.me_mapsize);
|
mdbx_env_set_mapsize(env, (size_t)envinfo.mi_mapsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MDBX_FIXEDMAP
|
#ifdef MDBX_FIXEDMAP
|
||||||
if (info.me_mapaddr)
|
if (info.mi_mapaddr)
|
||||||
envflags |= MDBX_FIXEDMAP;
|
envflags |= MDBX_FIXEDMAP;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -157,29 +157,29 @@ int main(int argc, char *argv[]) {
|
|||||||
(void)mdbx_env_info(env, &mei, sizeof(mei));
|
(void)mdbx_env_info(env, &mei, sizeof(mei));
|
||||||
printf("Environment Info\n");
|
printf("Environment Info\n");
|
||||||
printf(" Pagesize: %u\n", mst.ms_psize);
|
printf(" Pagesize: %u\n", mst.ms_psize);
|
||||||
if (mei.me_geo.lower != mei.me_geo.upper) {
|
if (mei.mi_geo.lower != mei.mi_geo.upper) {
|
||||||
printf(" Dynamic datafile: %" PRIu64 "..%" PRIu64 " bytes (+%" PRIu64
|
printf(" Dynamic datafile: %" PRIu64 "..%" PRIu64 " bytes (+%" PRIu64
|
||||||
"/-%" PRIu64 "), %" PRIu64 "..%" PRIu64 " pages (+%" PRIu64
|
"/-%" PRIu64 "), %" PRIu64 "..%" PRIu64 " pages (+%" PRIu64
|
||||||
"/-%" PRIu64 ")\n",
|
"/-%" PRIu64 ")\n",
|
||||||
mei.me_geo.lower, mei.me_geo.upper, mei.me_geo.grow,
|
mei.mi_geo.lower, mei.mi_geo.upper, mei.mi_geo.grow,
|
||||||
mei.me_geo.shrink, mei.me_geo.lower / mst.ms_psize,
|
mei.mi_geo.shrink, mei.mi_geo.lower / mst.ms_psize,
|
||||||
mei.me_geo.upper / mst.ms_psize, mei.me_geo.grow / mst.ms_psize,
|
mei.mi_geo.upper / mst.ms_psize, mei.mi_geo.grow / mst.ms_psize,
|
||||||
mei.me_geo.shrink / mst.ms_psize);
|
mei.mi_geo.shrink / mst.ms_psize);
|
||||||
printf(" Current datafile: %" PRIu64 " bytes, %" PRIu64 " pages\n",
|
printf(" Current datafile: %" PRIu64 " bytes, %" PRIu64 " pages\n",
|
||||||
mei.me_geo.current, mei.me_geo.current / mst.ms_psize);
|
mei.mi_geo.current, mei.mi_geo.current / mst.ms_psize);
|
||||||
} else {
|
} else {
|
||||||
printf(" Fixed datafile: %" PRIu64 " bytes, %" PRIu64 " pages\n",
|
printf(" Fixed datafile: %" PRIu64 " bytes, %" PRIu64 " pages\n",
|
||||||
mei.me_geo.current, mei.me_geo.current / mst.ms_psize);
|
mei.mi_geo.current, mei.mi_geo.current / mst.ms_psize);
|
||||||
}
|
}
|
||||||
printf(" Current mapsize: %" PRIu64 " bytes, %" PRIu64 " pages \n",
|
printf(" Current mapsize: %" PRIu64 " bytes, %" PRIu64 " pages \n",
|
||||||
mei.me_mapsize, mei.me_mapsize / mst.ms_psize);
|
mei.mi_mapsize, mei.mi_mapsize / mst.ms_psize);
|
||||||
printf(" Number of pages used: %" PRIu64 "\n", mei.me_last_pgno + 1);
|
printf(" Number of pages used: %" PRIu64 "\n", mei.mi_last_pgno + 1);
|
||||||
printf(" Last transaction ID: %" PRIu64 "\n", mei.me_recent_txnid);
|
printf(" Last transaction ID: %" PRIu64 "\n", mei.mi_recent_txnid);
|
||||||
printf(" Tail transaction ID: %" PRIu64 " (%" PRIi64 ")\n",
|
printf(" Tail transaction ID: %" PRIu64 " (%" PRIi64 ")\n",
|
||||||
mei.me_latter_reader_txnid,
|
mei.mi_latter_reader_txnid,
|
||||||
mei.me_latter_reader_txnid - mei.me_recent_txnid);
|
mei.mi_latter_reader_txnid - mei.mi_recent_txnid);
|
||||||
printf(" Max readers: %u\n", mei.me_maxreaders);
|
printf(" Max readers: %u\n", mei.mi_maxreaders);
|
||||||
printf(" Number of readers used: %u\n", mei.me_numreaders);
|
printf(" Number of readers used: %u\n", mei.mi_numreaders);
|
||||||
} else {
|
} else {
|
||||||
/* LY: zap warnings from gcc */
|
/* LY: zap warnings from gcc */
|
||||||
memset(&mst, 0, sizeof(mst));
|
memset(&mst, 0, sizeof(mst));
|
||||||
@ -234,7 +234,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
iptr = data.iov_base;
|
iptr = data.iov_base;
|
||||||
pages += *iptr;
|
pages += *iptr;
|
||||||
if (envinfo && mei.me_latter_reader_txnid > *(size_t *)key.iov_base)
|
if (envinfo && mei.mi_latter_reader_txnid > *(size_t *)key.iov_base)
|
||||||
reclaimable += *iptr;
|
reclaimable += *iptr;
|
||||||
if (freinfo > 1) {
|
if (freinfo > 1) {
|
||||||
char *bad = "";
|
char *bad = "";
|
||||||
@ -268,18 +268,18 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
mdbx_cursor_close(cursor);
|
mdbx_cursor_close(cursor);
|
||||||
if (envinfo) {
|
if (envinfo) {
|
||||||
uint64_t value = mei.me_mapsize / mst.ms_psize;
|
uint64_t value = mei.mi_mapsize / mst.ms_psize;
|
||||||
double percent = value / 100.0;
|
double percent = value / 100.0;
|
||||||
printf("Page Allocation Info\n");
|
printf("Page Allocation Info\n");
|
||||||
printf(" Max pages: %" PRIu64 " 100%%\n", value);
|
printf(" Max pages: %" PRIu64 " 100%%\n", value);
|
||||||
|
|
||||||
value = mei.me_last_pgno + 1;
|
value = mei.mi_last_pgno + 1;
|
||||||
printf(" Pages used: %" PRIu64 " %.1f%%\n", value, value / percent);
|
printf(" Pages used: %" PRIu64 " %.1f%%\n", value, value / percent);
|
||||||
|
|
||||||
value = mei.me_mapsize / mst.ms_psize - (mei.me_last_pgno + 1);
|
value = mei.mi_mapsize / mst.ms_psize - (mei.mi_last_pgno + 1);
|
||||||
printf(" Remained: %" PRIu64 " %.1f%%\n", value, value / percent);
|
printf(" Remained: %" PRIu64 " %.1f%%\n", value, value / percent);
|
||||||
|
|
||||||
value = mei.me_last_pgno + 1 - pages;
|
value = mei.mi_last_pgno + 1 - pages;
|
||||||
printf(" Used now: %" PRIu64 " %.1f%%\n", value, value / percent);
|
printf(" Used now: %" PRIu64 " %.1f%%\n", value, value / percent);
|
||||||
|
|
||||||
value = pages;
|
value = pages;
|
||||||
@ -292,7 +292,7 @@ int main(int argc, char *argv[]) {
|
|||||||
printf(" Reclaimable: %" PRIu64 " %.1f%%\n", value, value / percent);
|
printf(" Reclaimable: %" PRIu64 " %.1f%%\n", value, value / percent);
|
||||||
|
|
||||||
value =
|
value =
|
||||||
mei.me_mapsize / mst.ms_psize - (mei.me_last_pgno + 1) + reclaimable;
|
mei.mi_mapsize / mst.ms_psize - (mei.mi_last_pgno + 1) + reclaimable;
|
||||||
printf(" Available: %" PRIu64 " %.1f%%\n", value, value / percent);
|
printf(" Available: %" PRIu64 " %.1f%%\n", value, value / percent);
|
||||||
} else
|
} else
|
||||||
printf(" Free pages: %" PRIaPGNO "\n", pages);
|
printf(" Free pages: %" PRIaPGNO "\n", pages);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user