mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-02 04:59:39 -05:00
ITS#8704 Fix PREVMETA, rename to PREVSNAPSHOT
and enforce exclusive access to environment. Also fix txn_begin/pick_meta to use correct meta page, and reset the flag after successful commit.
This commit is contained in:
parent
ce83455904
commit
af2f8cc814
5 changed files with 35 additions and 17 deletions
|
|
@ -332,8 +332,8 @@ typedef void (MDB_rel_func)(MDB_val *item, void *oldptr, void *newptr, void *rel
|
|||
#define MDB_NORDAHEAD 0x800000
|
||||
/** don't initialize malloc'd memory before writing to datafile */
|
||||
#define MDB_NOMEMINIT 0x1000000
|
||||
/** use the previous meta page rather than the latest one */
|
||||
#define MDB_PREVMETA 0x2000000
|
||||
/** use the previous snapshot rather than the latest one */
|
||||
#define MDB_PREVSNAPSHOT 0x2000000
|
||||
/** @} */
|
||||
|
||||
/** @defgroup mdb_dbi_open Database Flags
|
||||
|
|
@ -648,10 +648,12 @@ int mdb_env_create(MDB_env **env);
|
|||
* caller is expected to overwrite all of the memory that was
|
||||
* reserved in that case.
|
||||
* This flag may be changed at any time using #mdb_env_set_flags().
|
||||
* <li>#MDB_PREVMETA
|
||||
* Open the environment with the previous meta page rather than the latest
|
||||
* <li>#MDB_PREVSNAPSHOT
|
||||
* Open the environment with the previous snapshot rather than the latest
|
||||
* one. This loses the latest transaction, but may help work around some
|
||||
* types of corruption.
|
||||
* types of corruption. If opened with write access, this must be the
|
||||
* only process using the environment. This flag is automatically reset
|
||||
* after a write transaction is successfully committed.
|
||||
* </ul>
|
||||
* @param[in] mode The UNIX permissions to set on created files and semaphores.
|
||||
* This parameter is ignored on Windows.
|
||||
|
|
|
|||
|
|
@ -3793,6 +3793,8 @@ done:
|
|||
return MDB_SUCCESS;
|
||||
}
|
||||
|
||||
static int ESECT mdb_env_share_locks(MDB_env *env, int *excl);
|
||||
|
||||
int
|
||||
mdb_txn_commit(MDB_txn *txn)
|
||||
{
|
||||
|
|
@ -4015,6 +4017,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);
|
||||
|
|
@ -4296,7 +4307,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
|
||||
|
|
@ -4868,6 +4880,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);
|
||||
|
|
@ -4967,9 +4982,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
|
||||
{
|
||||
|
|
@ -5391,7 +5403,7 @@ fail:
|
|||
*/
|
||||
#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_WRITEMAP|MDB_NOTLS|MDB_NOLOCK|MDB_NORDAHEAD|MDB_PREVSNAPSHOT)
|
||||
|
||||
#if VALID_FLAGS & PERSISTENT_FLAGS & (CHANGEABLE|CHANGELESS)
|
||||
# error "Persistent DB flags & env flags overlap, but both go in mm_flags"
|
||||
|
|
@ -5477,6 +5489,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,
|
||||
|
|
@ -5491,7 +5507,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.
|
||||
|
|
@ -5501,7 +5517,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;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ int main(int argc,char * argv[])
|
|||
if (argv[1][1] == 'n' && argv[1][2] == '\0')
|
||||
flags |= MDB_NOSUBDIR;
|
||||
else if (argv[1][1] == 'v' && argv[1][2] == '\0')
|
||||
flags |= MDB_PREVMETA;
|
||||
flags |= MDB_PREVSNAPSHOT;
|
||||
else if (argv[1][1] == 'c' && argv[1][2] == '\0')
|
||||
cpflags |= MDB_CP_COMPACT;
|
||||
else if (argv[1][1] == 'V' && argv[1][2] == '\0') {
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ int main(int argc, char *argv[])
|
|||
* -n: use NOSUBDIR flag on env_open
|
||||
* -p: use printable characters
|
||||
* -f: write to file instead of stdout
|
||||
* -v: use previous metapage
|
||||
* -v: use previous snapshot
|
||||
* -V: print version and exit
|
||||
* (default) dump only the main DB
|
||||
*/
|
||||
|
|
@ -204,7 +204,7 @@ int main(int argc, char *argv[])
|
|||
envflags |= MDB_NOSUBDIR;
|
||||
break;
|
||||
case 'v':
|
||||
envflags |= MDB_PREVMETA;
|
||||
envflags |= MDB_PREVSNAPSHOT;
|
||||
break;
|
||||
case 'p':
|
||||
mode |= PRINT;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ int main(int argc, char *argv[])
|
|||
* -f: print freelist info
|
||||
* -r: print reader info
|
||||
* -n: use NOSUBDIR flag on env_open
|
||||
* -v: use previous metapage
|
||||
* -v: use previous snapshot
|
||||
* -V: print version and exit
|
||||
* (default) print stat of only the main DB
|
||||
*/
|
||||
|
|
@ -86,7 +86,7 @@ int main(int argc, char *argv[])
|
|||
envflags |= MDB_NOSUBDIR;
|
||||
break;
|
||||
case 'v':
|
||||
envflags |= MDB_PREVMETA;
|
||||
envflags |= MDB_PREVSNAPSHOT;
|
||||
break;
|
||||
case 'r':
|
||||
rdrinfo++;
|
||||
|
|
|
|||
Loading…
Reference in a new issue