|
|
|
@ -4047,6 +4047,8 @@ done: |
|
|
|
|
return MDB_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int ESECT mdb_env_share_locks(MDB_env *env, int *excl); |
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
mdb_txn_commit(MDB_txn *txn) |
|
|
|
|
{ |
|
|
|
@ -4274,6 +4276,15 @@ mdb_txn_commit(MDB_txn *txn) |
|
|
|
|
if ((rc = mdb_env_write_meta(txn))) |
|
|
|
|
goto fail; |
|
|
|
|
end_mode = MDB_END_COMMITTED|MDB_END_UPDATE; |
|
|
|
|
if (env->me_flags & MDB_PREVSNAPSHOT) { |
|
|
|
|
if (!(env->me_flags & MDB_NOLOCK)) { |
|
|
|
|
int excl; |
|
|
|
|
rc = mdb_env_share_locks(env, &excl); |
|
|
|
|
if (rc) |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
env->me_flags ^= MDB_PREVSNAPSHOT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
done: |
|
|
|
|
mdb_txn_end(txn, end_mode); |
|
|
|
@ -4564,7 +4575,8 @@ static MDB_meta * |
|
|
|
|
mdb_env_pick_meta(const MDB_env *env) |
|
|
|
|
{ |
|
|
|
|
MDB_meta *const *metas = env->me_metas; |
|
|
|
|
return metas[ metas[0]->mm_txnid < metas[1]->mm_txnid ]; |
|
|
|
|
return metas[ (metas[0]->mm_txnid < metas[1]->mm_txnid) ^ |
|
|
|
|
((env->me_flags & MDB_PREVSNAPSHOT) != 0) ]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int ESECT |
|
|
|
@ -5139,6 +5151,9 @@ mdb_env_open2(MDB_env *env, int prev) |
|
|
|
|
#endif |
|
|
|
|
env->me_maxpg = env->me_mapsize / env->me_psize; |
|
|
|
|
|
|
|
|
|
if (env->me_txns) |
|
|
|
|
env->me_txns->mti_txnid = meta.mm_txnid; |
|
|
|
|
|
|
|
|
|
#if MDB_DEBUG |
|
|
|
|
{ |
|
|
|
|
MDB_meta *meta = mdb_env_pick_meta(env); |
|
|
|
@ -5238,9 +5253,6 @@ static int ESECT |
|
|
|
|
mdb_env_share_locks(MDB_env *env, int *excl) |
|
|
|
|
{ |
|
|
|
|
int rc = 0; |
|
|
|
|
MDB_meta *meta = mdb_env_pick_meta(env); |
|
|
|
|
|
|
|
|
|
env->me_txns->mti_txnid = meta->mm_txnid; |
|
|
|
|
|
|
|
|
|
#ifdef _WIN32 |
|
|
|
|
{ |
|
|
|
@ -5684,7 +5696,7 @@ mdb_env_envflags(MDB_env *env) |
|
|
|
|
/*f*/ MDB_FIXEDMAP, /*h*/ MDB_NORDAHEAD, /*i*/ MDB_NOMEMINIT, |
|
|
|
|
/*l*/ MDB_NOLOCK, /*m*/ MDB_NOMETASYNC, /*n*/ MDB_NOSUBDIR, |
|
|
|
|
/*r*/ MDB_RDONLY, /*s*/ MDB_NOSYNC, /*t*/ MDB_NOTLS, |
|
|
|
|
/*v*/ MDB_PREVMETA, /*w*/ MDB_WRITEMAP, |
|
|
|
|
/*v*/ MDB_PREVSNAPSHOT, /*w*/ MDB_WRITEMAP, |
|
|
|
|
}; |
|
|
|
|
unsigned flags = 0; |
|
|
|
|
const char *s, *opts = getenv("LMDB_FLAGS"); |
|
|
|
@ -5724,7 +5736,7 @@ mdb_env_envflags(MDB_env *env) |
|
|
|
|
*/ |
|
|
|
|
#define CHANGEABLE (MDB_NOSYNC|MDB_NOMETASYNC|MDB_MAPASYNC|MDB_NOMEMINIT) |
|
|
|
|
#define CHANGELESS (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY| \ |
|
|
|
|
MDB_WRITEMAP|MDB_NOTLS|MDB_NOLOCK|MDB_NORDAHEAD|MDB_PREVMETA|MDB_REMAP_CHUNKS) |
|
|
|
|
MDB_WRITEMAP|MDB_NOTLS|MDB_NOLOCK|MDB_NORDAHEAD|MDB_PREVSNAPSHOT|MDB_REMAP_CHUNKS) |
|
|
|
|
#define EXPOSED (CHANGEABLE|CHANGELESS | MDB_ENCRYPT) |
|
|
|
|
|
|
|
|
|
#if VALID_FLAGS & PERSISTENT_FLAGS & EXPOSED |
|
|
|
@ -5823,6 +5835,10 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode |
|
|
|
|
rc = mdb_env_setup_locks(env, &fname, mode, &excl); |
|
|
|
|
if (rc) |
|
|
|
|
goto leave; |
|
|
|
|
if ((flags & MDB_PREVSNAPSHOT) && !excl) { |
|
|
|
|
rc = EAGAIN; |
|
|
|
|
goto leave; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rc = mdb_fopen(env, &fname, |
|
|
|
@ -5837,7 +5853,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode |
|
|
|
|
goto leave; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((rc = mdb_env_open2(env, flags & MDB_PREVMETA)) == MDB_SUCCESS) { |
|
|
|
|
if ((rc = mdb_env_open2(env, flags & MDB_PREVSNAPSHOT)) == MDB_SUCCESS) { |
|
|
|
|
if (!(flags & (MDB_RDONLY|MDB_WRITEMAP))) { |
|
|
|
|
/* Synchronous fd for meta writes. Needed even with
|
|
|
|
|
* MDB_NOSYNC/MDB_NOMETASYNC, in case these get reset. |
|
|
|
@ -5847,7 +5863,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode |
|
|
|
|
goto leave; |
|
|
|
|
} |
|
|
|
|
DPRINTF(("opened dbenv %p", (void *) env)); |
|
|
|
|
if (excl > 0) { |
|
|
|
|
if (excl > 0 && !(flags & MDB_PREVSNAPSHOT)) { |
|
|
|
|
rc = mdb_env_share_locks(env, &excl); |
|
|
|
|
if (rc) |
|
|
|
|
goto leave; |
|
|
|
|