|
|
@ -1468,7 +1468,7 @@ static int mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst);
|
|
|
|
static int mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata,
|
|
|
|
static int mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata,
|
|
|
|
pgno_t newpgno, unsigned int nflags);
|
|
|
|
pgno_t newpgno, unsigned int nflags);
|
|
|
|
|
|
|
|
|
|
|
|
static int mdb_env_read_header(MDB_env *env, MDB_meta *meta);
|
|
|
|
static int mdb_env_read_header(MDB_env *env, int prev, MDB_meta *meta);
|
|
|
|
static MDB_meta *mdb_env_pick_meta(const MDB_env *env);
|
|
|
|
static MDB_meta *mdb_env_pick_meta(const MDB_env *env);
|
|
|
|
static int mdb_env_write_meta(MDB_txn *txn);
|
|
|
|
static int mdb_env_write_meta(MDB_txn *txn);
|
|
|
|
#ifdef MDB_USE_POSIX_MUTEX /* Drop unused excl arg */
|
|
|
|
#ifdef MDB_USE_POSIX_MUTEX /* Drop unused excl arg */
|
|
|
@ -3632,6 +3632,8 @@ done:
|
|
|
|
return MDB_SUCCESS;
|
|
|
|
return MDB_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int ESECT mdb_env_share_locks(MDB_env *env, int *excl);
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
int
|
|
|
|
mdb_txn_commit(MDB_txn *txn)
|
|
|
|
mdb_txn_commit(MDB_txn *txn)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -3854,6 +3856,15 @@ mdb_txn_commit(MDB_txn *txn)
|
|
|
|
if ((rc = mdb_env_write_meta(txn)))
|
|
|
|
if ((rc = mdb_env_write_meta(txn)))
|
|
|
|
goto fail;
|
|
|
|
goto fail;
|
|
|
|
end_mode = MDB_END_COMMITTED|MDB_END_UPDATE;
|
|
|
|
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:
|
|
|
|
done:
|
|
|
|
mdb_txn_end(txn, end_mode);
|
|
|
|
mdb_txn_end(txn, end_mode);
|
|
|
@ -3867,11 +3878,12 @@ fail:
|
|
|
|
/** Read the environment parameters of a DB environment before
|
|
|
|
/** Read the environment parameters of a DB environment before
|
|
|
|
* mapping it into memory.
|
|
|
|
* mapping it into memory.
|
|
|
|
* @param[in] env the environment handle
|
|
|
|
* @param[in] env the environment handle
|
|
|
|
|
|
|
|
* @param[in] prev whether to read the backup meta page
|
|
|
|
* @param[out] meta address of where to store the meta information
|
|
|
|
* @param[out] meta address of where to store the meta information
|
|
|
|
* @return 0 on success, non-zero on failure.
|
|
|
|
* @return 0 on success, non-zero on failure.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static int ESECT
|
|
|
|
static int ESECT
|
|
|
|
mdb_env_read_header(MDB_env *env, MDB_meta *meta)
|
|
|
|
mdb_env_read_header(MDB_env *env, int prev, MDB_meta *meta)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
MDB_metabuf pbuf;
|
|
|
|
MDB_metabuf pbuf;
|
|
|
|
MDB_page *p;
|
|
|
|
MDB_page *p;
|
|
|
@ -3922,7 +3934,7 @@ mdb_env_read_header(MDB_env *env, MDB_meta *meta)
|
|
|
|
return MDB_VERSION_MISMATCH;
|
|
|
|
return MDB_VERSION_MISMATCH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (off == 0 || m->mm_txnid > meta->mm_txnid)
|
|
|
|
if (off == 0 || (prev ? m->mm_txnid < meta->mm_txnid : m->mm_txnid > meta->mm_txnid))
|
|
|
|
*meta = *m;
|
|
|
|
*meta = *m;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
@ -4131,7 +4143,8 @@ static MDB_meta *
|
|
|
|
mdb_env_pick_meta(const MDB_env *env)
|
|
|
|
mdb_env_pick_meta(const MDB_env *env)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
MDB_meta *const *metas = env->me_metas;
|
|
|
|
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
|
|
|
|
int ESECT
|
|
|
@ -4366,7 +4379,7 @@ mdb_fsize(HANDLE fd, mdb_size_t *size)
|
|
|
|
/** Further setup required for opening an LMDB environment
|
|
|
|
/** Further setup required for opening an LMDB environment
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static int ESECT
|
|
|
|
static int ESECT
|
|
|
|
mdb_env_open2(MDB_env *env)
|
|
|
|
mdb_env_open2(MDB_env *env, int prev)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
unsigned int flags = env->me_flags;
|
|
|
|
unsigned int flags = env->me_flags;
|
|
|
|
int i, newenv = 0, rc;
|
|
|
|
int i, newenv = 0, rc;
|
|
|
@ -4429,7 +4442,7 @@ mdb_env_open2(MDB_env *env)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if ((i = mdb_env_read_header(env, &meta)) != 0) {
|
|
|
|
if ((i = mdb_env_read_header(env, prev, &meta)) != 0) {
|
|
|
|
if (i != ENOENT)
|
|
|
|
if (i != ENOENT)
|
|
|
|
return i;
|
|
|
|
return i;
|
|
|
|
DPUTS("new mdbenv");
|
|
|
|
DPUTS("new mdbenv");
|
|
|
@ -4505,6 +4518,9 @@ mdb_env_open2(MDB_env *env)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
env->me_maxpg = env->me_mapsize / env->me_psize;
|
|
|
|
env->me_maxpg = env->me_mapsize / env->me_psize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (env->me_txns)
|
|
|
|
|
|
|
|
env->me_txns->mti_txnid = meta.mm_txnid;
|
|
|
|
|
|
|
|
|
|
|
|
#if MDB_DEBUG
|
|
|
|
#if MDB_DEBUG
|
|
|
|
{
|
|
|
|
{
|
|
|
|
MDB_meta *meta = mdb_env_pick_meta(env);
|
|
|
|
MDB_meta *meta = mdb_env_pick_meta(env);
|
|
|
@ -4600,9 +4616,6 @@ static int ESECT
|
|
|
|
mdb_env_share_locks(MDB_env *env, int *excl)
|
|
|
|
mdb_env_share_locks(MDB_env *env, int *excl)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int rc = 0;
|
|
|
|
int rc = 0;
|
|
|
|
MDB_meta *meta = mdb_env_pick_meta(env);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
env->me_txns->mti_txnid = meta->mm_txnid;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#ifdef _WIN32
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -5056,7 +5069,7 @@ fail:
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#define CHANGEABLE (MDB_NOSYNC|MDB_NOMETASYNC|MDB_MAPASYNC|MDB_NOMEMINIT)
|
|
|
|
#define CHANGEABLE (MDB_NOSYNC|MDB_NOMETASYNC|MDB_MAPASYNC|MDB_NOMEMINIT)
|
|
|
|
#define CHANGELESS (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY| \
|
|
|
|
#define CHANGELESS (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY| \
|
|
|
|
MDB_WRITEMAP|MDB_NOTLS|MDB_NOLOCK|MDB_NORDAHEAD)
|
|
|
|
MDB_WRITEMAP|MDB_NOTLS|MDB_NOLOCK|MDB_NORDAHEAD|MDB_PREVSNAPSHOT)
|
|
|
|
|
|
|
|
|
|
|
|
#if VALID_FLAGS & PERSISTENT_FLAGS & (CHANGEABLE|CHANGELESS)
|
|
|
|
#if VALID_FLAGS & PERSISTENT_FLAGS & (CHANGEABLE|CHANGELESS)
|
|
|
|
# error "Persistent DB flags & env flags overlap, but both go in mm_flags"
|
|
|
|
# error "Persistent DB flags & env flags overlap, but both go in mm_flags"
|
|
|
@ -5178,9 +5191,13 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
|
|
|
|
rc = mdb_env_setup_locks(env, lpath, mode, &excl);
|
|
|
|
rc = mdb_env_setup_locks(env, lpath, mode, &excl);
|
|
|
|
if (rc)
|
|
|
|
if (rc)
|
|
|
|
goto leave;
|
|
|
|
goto leave;
|
|
|
|
|
|
|
|
if ((flags & MDB_PREVSNAPSHOT) && !excl) {
|
|
|
|
|
|
|
|
rc = EAGAIN;
|
|
|
|
|
|
|
|
goto leave;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((rc = mdb_env_open2(env)) == MDB_SUCCESS) {
|
|
|
|
if ((rc = mdb_env_open2(env, flags & MDB_PREVSNAPSHOT)) == MDB_SUCCESS) {
|
|
|
|
if (flags & (MDB_RDONLY|MDB_WRITEMAP)) {
|
|
|
|
if (flags & (MDB_RDONLY|MDB_WRITEMAP)) {
|
|
|
|
env->me_mfd = env->me_fd;
|
|
|
|
env->me_mfd = env->me_fd;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -5206,7 +5223,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DPRINTF(("opened dbenv %p", (void *) env));
|
|
|
|
DPRINTF(("opened dbenv %p", (void *) env));
|
|
|
|
if (excl > 0) {
|
|
|
|
if (excl > 0 && !(flags & MDB_PREVSNAPSHOT)) {
|
|
|
|
rc = mdb_env_share_locks(env, &excl);
|
|
|
|
rc = mdb_env_share_locks(env, &excl);
|
|
|
|
if (rc)
|
|
|
|
if (rc)
|
|
|
|
goto leave;
|
|
|
|
goto leave;
|
|
|
|