mirror of
https://github.com/isar/libmdbx.git
synced 2025-04-23 05:17:47 +08:00
mdbx: добавление mdbx_preopen_snapinfo()
в API.
https://gitflic.ru/project/erthink/libmdbx/issue/15
This commit is contained in:
parent
0b87ddc6d4
commit
1c174e84c4
12
mdbx.h
12
mdbx.h
@ -5714,6 +5714,18 @@ LIBMDBX_API int mdbx_env_open_for_recoveryW(MDBX_env *env,
|
|||||||
* leg(s). */
|
* leg(s). */
|
||||||
LIBMDBX_API int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target_meta);
|
LIBMDBX_API int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target_meta);
|
||||||
|
|
||||||
|
/** \brief FIXME
|
||||||
|
*/
|
||||||
|
LIBMDBX_API int mdbx_preopen_snapinfo(const char *pathname, MDBX_envinfo *arg,
|
||||||
|
size_t bytes);
|
||||||
|
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
||||||
|
/** \copydoc mdbx_preopen_snapinfo()
|
||||||
|
* \note Available only on Windows.
|
||||||
|
* \see mdbx_preopen_snapinfo() */
|
||||||
|
LIBMDBX_API int mdbx_preopen_snapinfoW(const wchar_t *pathname,
|
||||||
|
MDBX_envinfo *arg, size_t bytes);
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
/** \brief Флаги/опции для проверки целостности БД.
|
/** \brief Флаги/опции для проверки целостности БД.
|
||||||
* \see mdbx_env_chk() */
|
* \see mdbx_env_chk() */
|
||||||
enum MDBX_chk_flags_t {
|
enum MDBX_chk_flags_t {
|
||||||
|
83
src/core.c
83
src/core.c
@ -23396,6 +23396,89 @@ __cold int env_info(const MDBX_env *env, const MDBX_txn *txn, MDBX_envinfo *out,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__cold int mdbx_preopen_snapinfo(const char *pathname, MDBX_envinfo *out,
|
||||||
|
size_t bytes) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
wchar_t *pathnameW = nullptr;
|
||||||
|
int rc = osal_mb2w(pathname, &pathnameW);
|
||||||
|
if (likely(rc == MDBX_SUCCESS)) {
|
||||||
|
rc = mdbx_preopen_snapinfoW(pathnameW, out, bytes);
|
||||||
|
osal_free(pathnameW);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
__cold int mdbx_preopen_snapinfoW(const wchar_t *pathname, MDBX_envinfo *out,
|
||||||
|
size_t bytes) {
|
||||||
|
#endif /* Windows */
|
||||||
|
if (unlikely(!out))
|
||||||
|
return MDBX_EINVAL;
|
||||||
|
|
||||||
|
const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid);
|
||||||
|
const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat);
|
||||||
|
if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid &&
|
||||||
|
bytes != size_before_pgop_stat)
|
||||||
|
return MDBX_EINVAL;
|
||||||
|
|
||||||
|
memset(out, 0, bytes);
|
||||||
|
if (likely(bytes > size_before_bootid)) {
|
||||||
|
out->mi_bootid.current.x = bootid.x;
|
||||||
|
out->mi_bootid.current.y = bootid.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDBX_env env;
|
||||||
|
memset(&env, 0, sizeof(env));
|
||||||
|
env.me_pid = osal_getpid();
|
||||||
|
const size_t os_psize = osal_syspagesize();
|
||||||
|
if (unlikely(!is_powerof2(os_psize) || os_psize < MIN_PAGESIZE)) {
|
||||||
|
ERROR("unsuitable system pagesize %" PRIuPTR, os_psize);
|
||||||
|
return MDBX_INCOMPATIBLE;
|
||||||
|
}
|
||||||
|
out->mi_sys_pagesize = env.me_os_psize = (unsigned)os_psize;
|
||||||
|
env.me_flags = MDBX_RDONLY | MDBX_NORDAHEAD | MDBX_ACCEDE | MDBX_VALIDATION;
|
||||||
|
env.me_stuck_meta = -1;
|
||||||
|
env.me_lfd = INVALID_HANDLE_VALUE;
|
||||||
|
env.me_lazy_fd = INVALID_HANDLE_VALUE;
|
||||||
|
env.me_dsync_fd = INVALID_HANDLE_VALUE;
|
||||||
|
env.me_fd4meta = INVALID_HANDLE_VALUE;
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
env.me_data_lock_event = INVALID_HANDLE_VALUE;
|
||||||
|
env.me_overlapped_fd = INVALID_HANDLE_VALUE;
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
|
int rc = env_handle_pathname(&env, pathname, 0);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
goto bailout;
|
||||||
|
rc = osal_openfile(MDBX_OPEN_DXB_READ, &env, env.me_pathname.dxb,
|
||||||
|
&env.me_lazy_fd, 0);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
goto bailout;
|
||||||
|
|
||||||
|
MDBX_meta header;
|
||||||
|
rc = read_header(&env, &header, 0, 0);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
goto bailout;
|
||||||
|
|
||||||
|
setup_pagesize(&env, header.mm_psize);
|
||||||
|
out->mi_dxb_pagesize = env.me_psize;
|
||||||
|
out->mi_geo.lower = pgno2bytes(&env, header.mm_geo.lower);
|
||||||
|
out->mi_geo.upper = pgno2bytes(&env, header.mm_geo.upper);
|
||||||
|
out->mi_geo.shrink = pgno2bytes(&env, pv2pages(header.mm_geo.shrink_pv));
|
||||||
|
out->mi_geo.grow = pgno2bytes(&env, pv2pages(header.mm_geo.grow_pv));
|
||||||
|
out->mi_geo.current = pgno2bytes(&env, header.mm_geo.now);
|
||||||
|
out->mi_last_pgno = header.mm_geo.next - 1;
|
||||||
|
|
||||||
|
const unsigned n = 0;
|
||||||
|
out->mi_recent_txnid = constmeta_txnid(&header);
|
||||||
|
out->mi_meta_sign[n] = unaligned_peek_u64(4, &header.mm_sign);
|
||||||
|
if (likely(bytes > size_before_bootid))
|
||||||
|
memcpy(&out->mi_bootid.meta[n], &header.mm_bootid, 16);
|
||||||
|
|
||||||
|
bailout:
|
||||||
|
env_close(&env, false);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
__cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
|
__cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
|
||||||
MDBX_envinfo *arg, size_t bytes) {
|
MDBX_envinfo *arg, size_t bytes) {
|
||||||
if (unlikely((env == NULL && txn == NULL) || arg == NULL))
|
if (unlikely((env == NULL && txn == NULL) || arg == NULL))
|
||||||
|
@ -743,6 +743,14 @@ int main(int argc, char *const argv[]) {
|
|||||||
log_trace("=== done...");
|
log_trace("=== done...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!failed) {
|
||||||
|
MDBX_envinfo info;
|
||||||
|
int err =
|
||||||
|
mdbx_preopen_snapinfo(params.pathname_db.c_str(), &info, sizeof(info));
|
||||||
|
if (err != MDBX_SUCCESS)
|
||||||
|
failure_perror("mdbx_preopen_snapinfo()", err);
|
||||||
|
}
|
||||||
|
|
||||||
log_notice("RESULT: %s\n", failed ? "Failed" : "Successful");
|
log_notice("RESULT: %s\n", failed ? "Failed" : "Successful");
|
||||||
if (global::config::cleanup_after) {
|
if (global::config::cleanup_after) {
|
||||||
if (failed)
|
if (failed)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user