mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-30 02:04:12 +08:00
mdbx-windows: more safety/robustness for DB shriking.
This commit is contained in:
parent
35f95e8ca2
commit
f55e1ec5cc
43
src/mdbx.c
43
src/mdbx.c
@ -3349,6 +3349,13 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
txn->mt_owner = mdbx_thread_self();
|
txn->mt_owner = mdbx_thread_self();
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
if ((txn->mt_flags & MDBX_TXN_RDONLY) != 0 && size > env->me_dbgeo.lower &&
|
||||||
|
env->me_dbgeo.shrink) {
|
||||||
|
txn->mt_flags |= MDBX_SHRINK_ALLOWED;
|
||||||
|
mdbx_srwlock_AcquireShared(&env->me_remap_guard);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
bailout:
|
bailout:
|
||||||
@ -3516,8 +3523,8 @@ int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, unsigned flags,
|
|||||||
if (txn != env->me_txn0)
|
if (txn != env->me_txn0)
|
||||||
mdbx_free(txn);
|
mdbx_free(txn);
|
||||||
} else {
|
} else {
|
||||||
mdbx_assert(env,
|
mdbx_assert(env, (txn->mt_flags & ~(MDBX_TXN_RDONLY | MDBX_TXN_WRITEMAP |
|
||||||
(txn->mt_flags & ~(MDBX_TXN_RDONLY | MDBX_TXN_WRITEMAP)) == 0);
|
MDBX_SHRINK_ALLOWED)) == 0);
|
||||||
txn->mt_signature = MDBX_MT_SIGNATURE;
|
txn->mt_signature = MDBX_MT_SIGNATURE;
|
||||||
*ret = txn;
|
*ret = txn;
|
||||||
mdbx_debug("begin txn %" PRIaTXN "%c %p on env %p, root page %" PRIaPGNO
|
mdbx_debug("begin txn %" PRIaTXN "%c %p on env %p, root page %" PRIaPGNO
|
||||||
@ -3610,6 +3617,10 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode) {
|
|||||||
txn->mt_dbs[FREE_DBI].md_root);
|
txn->mt_dbs[FREE_DBI].md_root);
|
||||||
|
|
||||||
if (F_ISSET(txn->mt_flags, MDBX_TXN_RDONLY)) {
|
if (F_ISSET(txn->mt_flags, MDBX_TXN_RDONLY)) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
if (txn->mt_flags & MDBX_SHRINK_ALLOWED)
|
||||||
|
mdbx_srwlock_ReleaseShared(&env->me_remap_guard);
|
||||||
|
#endif
|
||||||
if (txn->mt_ro_reader) {
|
if (txn->mt_ro_reader) {
|
||||||
txn->mt_ro_reader->mr_txnid = ~(txnid_t)0;
|
txn->mt_ro_reader->mr_txnid = ~(txnid_t)0;
|
||||||
env->me_lck->mti_readers_refresh_flag = true;
|
env->me_lck->mti_readers_refresh_flag = true;
|
||||||
@ -5843,6 +5854,34 @@ LIBMDBX_API int mdbx_env_set_geometry(MDBX_env *env, intptr_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 defined(_WIN32) || defined(_WIN64)
|
||||||
|
/* Was DB shrinking disabled before and now it will be enabled? */
|
||||||
|
if (meta.mm_geo.lower < meta.mm_geo.upper && meta.mm_geo.shrink &&
|
||||||
|
!(head->mm_geo.lower < head->mm_geo.upper && head->mm_geo.shrink)) {
|
||||||
|
rc = mdbx_rdt_lock(env);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
goto bailout;
|
||||||
|
|
||||||
|
/* Check if there are any reading threads that do not use the SRWL */
|
||||||
|
const mdbx_pid_t CurrentTid = GetCurrentThreadId();
|
||||||
|
const MDBX_reader *const begin = env->me_lck->mti_readers;
|
||||||
|
const MDBX_reader *const end = begin + env->me_lck->mti_numreaders;
|
||||||
|
for (const MDBX_reader *reader = begin; reader < end; ++reader) {
|
||||||
|
if (reader->mr_pid == env->me_pid && reader->mr_tid &&
|
||||||
|
reader->mr_tid != CurrentTid) {
|
||||||
|
/* At least one thread may don't use SRWL */
|
||||||
|
rc = MDBX_EPERM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mdbx_rdt_unlock(env);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
goto bailout;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (meta.mm_geo.now != head->mm_geo.now ||
|
if (meta.mm_geo.now != head->mm_geo.now ||
|
||||||
meta.mm_geo.upper != head->mm_geo.upper) {
|
meta.mm_geo.upper != head->mm_geo.upper) {
|
||||||
rc = mdbx_mapresize(env, meta.mm_geo.now, meta.mm_geo.upper);
|
rc = mdbx_mapresize(env, meta.mm_geo.now, meta.mm_geo.upper);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user