mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-20 05:18:21 +08:00
mdbx: truncate clk-file when DB closed in sync-state.
Change-Id: I2e2438606118e3aa3fa9d60811fea99994403d32
This commit is contained in:
parent
86a4085bf9
commit
a2bdbc97dc
@ -477,8 +477,10 @@ MDBX_INTERNAL_FUNC int __cold mdbx_lck_destroy(MDBX_env *env,
|
|||||||
|
|
||||||
mdbx_assert(env, rc == 0);
|
mdbx_assert(env, rc == 0);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
|
const bool synced = env->me_lck_mmap.lck->mti_unsynced_pages == 0;
|
||||||
mdbx_munmap(&env->me_lck_mmap);
|
mdbx_munmap(&env->me_lck_mmap);
|
||||||
rc = ftruncate(env->me_lfd, 0) ? errno : 0;
|
if (synced)
|
||||||
|
rc = ftruncate(env->me_lfd, 0) ? errno : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mdbx_jitter4testing(false);
|
mdbx_jitter4testing(false);
|
||||||
|
@ -344,13 +344,6 @@ mdbx_resume_threads_after_remap(mdbx_handle_array_t *array) {
|
|||||||
* i.e. free/shared/exclusive x free/shared/exclusive == 9.
|
* i.e. free/shared/exclusive x free/shared/exclusive == 9.
|
||||||
* Only 6 states of FSM are used, which 2 of ones are transitive.
|
* Only 6 states of FSM are used, which 2 of ones are transitive.
|
||||||
*
|
*
|
||||||
* The mdbx_lck_seize() moves the locking-FSM from the initial free/unlocked
|
|
||||||
* state to the "exclusive write" (and returns MDBX_RESULT_TRUE) if possible,
|
|
||||||
* or to the "used" (and returns MDBX_RESULT_FALSE).
|
|
||||||
*
|
|
||||||
* The mdbx_lck_downgrade() moves the locking-FSM from "exclusive write"
|
|
||||||
* state to the "used" (i.e. shared) state.
|
|
||||||
*
|
|
||||||
* States:
|
* States:
|
||||||
* ?-? = free, i.e. unlocked
|
* ?-? = free, i.e. unlocked
|
||||||
* S-? = used, i.e. shared lock
|
* S-? = used, i.e. shared lock
|
||||||
@ -361,6 +354,16 @@ mdbx_resume_threads_after_remap(mdbx_handle_array_t *array) {
|
|||||||
* S-E = locked (transitive state)
|
* S-E = locked (transitive state)
|
||||||
* E-S
|
* E-S
|
||||||
* E-E = exclusive-write, i.e. exclusive due (re)initialization
|
* E-E = exclusive-write, i.e. exclusive due (re)initialization
|
||||||
|
*
|
||||||
|
* The mdbx_lck_seize() moves the locking-FSM from the initial free/unlocked
|
||||||
|
* state to the "exclusive write" (and returns MDBX_RESULT_TRUE) if possible,
|
||||||
|
* or to the "used" (and returns MDBX_RESULT_FALSE).
|
||||||
|
*
|
||||||
|
* The mdbx_lck_downgrade() moves the locking-FSM from "exclusive write"
|
||||||
|
* state to the "used" (i.e. shared) state.
|
||||||
|
*
|
||||||
|
* The mdbx_lck_upgrade() moves the locking-FSM from "used" (i.e. shared)
|
||||||
|
* state to the "exclusive write" state.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void lck_unlock(MDBX_env *env) {
|
static void lck_unlock(MDBX_env *env) {
|
||||||
@ -406,30 +409,6 @@ static void lck_unlock(MDBX_env *env) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MDBX_INTERNAL_FUNC int mdbx_lck_init(MDBX_env *env,
|
|
||||||
MDBX_env *inprocess_neighbor,
|
|
||||||
int global_uniqueness_flag) {
|
|
||||||
(void)env;
|
|
||||||
(void)inprocess_neighbor;
|
|
||||||
(void)global_uniqueness_flag;
|
|
||||||
return MDBX_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
MDBX_INTERNAL_FUNC int mdbx_lck_destroy(MDBX_env *env,
|
|
||||||
MDBX_env *inprocess_neighbor) {
|
|
||||||
(void)inprocess_neighbor;
|
|
||||||
|
|
||||||
/* LY: should unmap before releasing the locks to avoid race condition and
|
|
||||||
* STATUS_USER_MAPPED_FILE/ERROR_USER_MAPPED_FILE */
|
|
||||||
if (env->me_map)
|
|
||||||
mdbx_munmap(&env->me_dxb_mmap);
|
|
||||||
if (env->me_lck)
|
|
||||||
mdbx_munmap(&env->me_lck_mmap);
|
|
||||||
|
|
||||||
lck_unlock(env);
|
|
||||||
return MDBX_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Seize state as 'exclusive-write' (E-E and returns MDBX_RESULT_TRUE)
|
/* Seize state as 'exclusive-write' (E-E and returns MDBX_RESULT_TRUE)
|
||||||
* or as 'used' (S-? and returns MDBX_RESULT_FALSE).
|
* or as 'used' (S-? and returns MDBX_RESULT_FALSE).
|
||||||
* Oherwise returns an error. */
|
* Oherwise returns an error. */
|
||||||
@ -553,6 +532,66 @@ MDBX_INTERNAL_FUNC int mdbx_lck_downgrade(MDBX_env *env) {
|
|||||||
return MDBX_SUCCESS /* 5) now at S-? (used), done */;
|
return MDBX_SUCCESS /* 5) now at S-? (used), done */;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MDBX_INTERNAL_FUNC int mdbx_lck_upgrade(MDBX_env *env) {
|
||||||
|
/* Transite from used state (S-?) to exclusive-write (E-E) */
|
||||||
|
assert(env->me_lfd != INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
|
if (env->me_flags & MDBX_EXCLUSIVE)
|
||||||
|
return MDBX_SUCCESS /* nope since files were must be opened non-shareable */
|
||||||
|
;
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
/* 1) now on S-? (used), try S-E (locked) */
|
||||||
|
mdbx_jitter4testing(false);
|
||||||
|
if (!flock(env->me_lfd, LCK_EXCLUSIVE | LCK_DONTWAIT, LCK_UPPER)) {
|
||||||
|
rc = GetLastError() /* 2) something went wrong, give up */;
|
||||||
|
mdbx_verbose("%s, err %u", "S-?(used) >> S-E(locked)", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3) now on S-E (locked), transite to ?-E (middle) */
|
||||||
|
if (!funlock(env->me_lfd, LCK_LOWER))
|
||||||
|
mdbx_panic("%s(%s) failed: err %u", __func__, "S-E(locked) >> ?-E(middle)",
|
||||||
|
GetLastError());
|
||||||
|
|
||||||
|
/* 4) now on ?-E (middle), try E-E (exclusive-write) */
|
||||||
|
mdbx_jitter4testing(false);
|
||||||
|
if (!flock(env->me_lfd, LCK_EXCLUSIVE | LCK_DONTWAIT, LCK_LOWER)) {
|
||||||
|
rc = GetLastError() /* 5) something went wrong, give up */;
|
||||||
|
mdbx_verbose("%s, err %u", "?-E(middle) >> E-E(exclusive-write)", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MDBX_SUCCESS /* 6) now at E-E (exclusive-write), done */;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDBX_INTERNAL_FUNC int mdbx_lck_init(MDBX_env *env,
|
||||||
|
MDBX_env *inprocess_neighbor,
|
||||||
|
int global_uniqueness_flag) {
|
||||||
|
(void)env;
|
||||||
|
(void)inprocess_neighbor;
|
||||||
|
(void)global_uniqueness_flag;
|
||||||
|
return MDBX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDBX_INTERNAL_FUNC int mdbx_lck_destroy(MDBX_env *env,
|
||||||
|
MDBX_env *inprocess_neighbor) {
|
||||||
|
/* LY: should unmap before releasing the locks to avoid race condition and
|
||||||
|
* STATUS_USER_MAPPED_FILE/ERROR_USER_MAPPED_FILE */
|
||||||
|
if (env->me_map)
|
||||||
|
mdbx_munmap(&env->me_dxb_mmap);
|
||||||
|
if (env->me_lck) {
|
||||||
|
const bool synced = env->me_lck_mmap.lck->mti_unsynced_pages == 0;
|
||||||
|
mdbx_munmap(&env->me_lck_mmap);
|
||||||
|
if (synced && !inprocess_neighbor && env->me_lfd != INVALID_HANDLE_VALUE &&
|
||||||
|
mdbx_lck_upgrade(env) == MDBX_SUCCESS)
|
||||||
|
/* this will fail if LCK is used/mmapped by other process(es) */
|
||||||
|
mdbx_ftruncate(env->me_lfd, 0);
|
||||||
|
}
|
||||||
|
lck_unlock(env);
|
||||||
|
return MDBX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/* reader checking (by pid) */
|
/* reader checking (by pid) */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user