mdbx: provide additional info via mdbx_env_info_ex().

Change-Id: Icfc751da73f090833800ad5429a9b296b4e34700
This commit is contained in:
Leonid Yuriev 2019-10-01 17:09:57 +03:00
parent f918d89408
commit e1e2e2e935
3 changed files with 57 additions and 7 deletions

25
mdbx.h
View File

@ -1606,6 +1606,31 @@ typedef struct MDBX_envinfo {
uint32_t mi_numreaders; /* max reader slots used in the environment */
uint32_t mi_dxb_pagesize; /* database pagesize */
uint32_t mi_sys_pagesize; /* system pagesize */
uint64_t
mi_bootid[2]; /* A mostly unique ID that is regenerated on each boot.
As such it can be used to identify the local
machine's current boot. MDBX uses such when open
the database to determine whether rollback required
to the last steady sync point or not. I.e. if current
bootid is differ from the value within a database then
the system was rebooted and all changes since last steady
sync must be reverted for data integrity. Zeros mean that
no relevant information is available from the system. */
uint64_t mi_unsync_volume; /* bytes not explicitly synchronized to disk */
uint64_t mi_autosync_threshold; /* current auto-sync threshold, see
mdbx_env_set_syncbytes(). */
uint32_t mi_since_sync_seconds16dot16; /* time since the last steady sync in
1/65536 of second */
uint32_t mi_autosync_period_seconds16dot16 /* current auto-sync period in
1/65536 of second, see
mdbx_env_set_syncperiod(). */
;
uint32_t mi_since_reader_check_seconds16dot16; /* time since the last readers
check in 1/65536 of second,
see mdbx_reader_check(). */
uint32_t mi_mode; /* current environment mode, the same as
mdbx_env_get_flags() returns. */
} MDBX_envinfo;
/* Return information about the MDBX environment.

View File

@ -13027,12 +13027,14 @@ int __cold mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
env = txn->mt_env;
}
if (unlikely(bytes != sizeof(MDBX_envinfo)))
const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid);
if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid)
return MDBX_EINVAL;
const MDBX_meta *const meta0 = METAPAGE(env, 0);
const MDBX_meta *const meta1 = METAPAGE(env, 1);
const MDBX_meta *const meta2 = METAPAGE(env, 2);
pgno_t unsynced_pages;
while (1) {
if (unlikely(env->me_flags & MDBX_FATAL_ERROR))
return MDBX_PANIC;
@ -13063,6 +13065,8 @@ int __cold mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
arg->mi_geo.upper = pgno2bytes(env, txn_meta->mm_geo.upper);
arg->mi_geo.shrink = pgno2bytes(env, txn_meta->mm_geo.shrink);
arg->mi_geo.grow = pgno2bytes(env, txn_meta->mm_geo.grow);
unsynced_pages = *env->me_unsynced_pages +
(*env->me_meta_sync_txnid != (uint32_t)arg->mi_last_pgno);
arg->mi_mapsize = env->me_mapsize;
mdbx_compiler_barrier();
@ -13082,15 +13086,32 @@ int __cold mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
arg->mi_dxb_pagesize = env->me_psize;
arg->mi_sys_pagesize = env->me_os_psize;
const MDBX_lockinfo *const lck = env->me_lck;
if (likely(bytes > size_before_bootid)) {
arg->mi_unsync_volume = pgno2bytes(env, unsynced_pages);
const uint64_t monotime_now = mdbx_osal_monotime();
arg->mi_since_sync_seconds16dot16 =
mdbx_osal_monotime_to_16dot16(monotime_now - *env->me_sync_timestamp);
arg->mi_since_reader_check_seconds16dot16 =
lck ? mdbx_osal_monotime_to_16dot16(monotime_now -
lck->mti_reader_check_timestamp)
: 0;
arg->mi_autosync_threshold = pgno2bytes(env, *env->me_autosync_threshold);
arg->mi_autosync_period_seconds16dot16 =
mdbx_osal_monotime_to_16dot16(*env->me_autosync_period);
arg->mi_bootid[0] = lck ? lck->mti_bootid[0] : 0;
arg->mi_bootid[1] = lck ? lck->mti_bootid[1] : 0;
arg->mi_mode = lck ? lck->mti_envmode : env->me_flags;
}
arg->mi_self_latter_reader_txnid = arg->mi_latter_reader_txnid = 0;
if (env->me_lck) {
MDBX_reader *rlt = env->me_lck->mti_readers;
if (lck) {
arg->mi_self_latter_reader_txnid = arg->mi_latter_reader_txnid =
arg->mi_recent_txnid;
for (unsigned i = 0; i < arg->mi_numreaders; ++i) {
const uint32_t pid = rlt[i].mr_pid;
const uint32_t pid = lck->mti_readers[i].mr_pid;
if (pid) {
const txnid_t txnid = safe64_read(&rlt[i].mr_txnid);
const txnid_t txnid = safe64_read(&lck->mti_readers[i].mr_txnid);
if (arg->mi_latter_reader_txnid > txnid)
arg->mi_latter_reader_txnid = txnid;
if (pid == env->me_pid && arg->mi_self_latter_reader_txnid > txnid)

View File

@ -535,8 +535,12 @@ typedef struct MDBX_lockinfo {
/* Marker to distinguish uniqueness of DB/CLK.*/
volatile uint64_t mti_bait_uniqueness;
/* the hash of /proc/sys/kernel/random/boot_id or analogue */
volatile uint64_t mti_boot_id;
/* The analogue /proc/sys/kernel/random/boot_id or similar to determine
* whether the system was rebooted after the last use of the database files.
* If there was no reboot, but there is no need to rollback to the last
* steady sync point. Zeros mean that no relevant information is available
* from the system. */
volatile uint64_t mti_bootid[2];
alignas(MDBX_CACHELINE_SIZE) /* cacheline ---------------------------------*/
#ifdef MDBX_OSAL_LOCK