mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
ITS#8704 add MDB_PREVMETA flag to mdb_env_open
used to open the previous meta page, in case the latest one is corrupted From https://github.com/LMDB/lmdb/pull/12
This commit is contained in:
parent
47ca2f7095
commit
3daab3be73
2 changed files with 14 additions and 7 deletions
|
|
@ -332,6 +332,8 @@ typedef void (MDB_rel_func)(MDB_val *item, void *oldptr, void *newptr, void *rel
|
||||||
#define MDB_NORDAHEAD 0x800000
|
#define MDB_NORDAHEAD 0x800000
|
||||||
/** don't initialize malloc'd memory before writing to datafile */
|
/** don't initialize malloc'd memory before writing to datafile */
|
||||||
#define MDB_NOMEMINIT 0x1000000
|
#define MDB_NOMEMINIT 0x1000000
|
||||||
|
/** use the previous meta page rather than the latest one */
|
||||||
|
#define MDB_PREVMETA 0x2000000
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** @defgroup mdb_dbi_open Database Flags
|
/** @defgroup mdb_dbi_open Database Flags
|
||||||
|
|
@ -646,6 +648,10 @@ int mdb_env_create(MDB_env **env);
|
||||||
* caller is expected to overwrite all of the memory that was
|
* caller is expected to overwrite all of the memory that was
|
||||||
* reserved in that case.
|
* reserved in that case.
|
||||||
* This flag may be changed at any time using #mdb_env_set_flags().
|
* 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
|
||||||
|
* one. This loses the latest transaction, but may help work around some
|
||||||
|
* types of corruption.
|
||||||
* </ul>
|
* </ul>
|
||||||
* @param[in] mode The UNIX permissions to set on created files and semaphores.
|
* @param[in] mode The UNIX permissions to set on created files and semaphores.
|
||||||
* This parameter is ignored on Windows.
|
* This parameter is ignored on Windows.
|
||||||
|
|
|
||||||
|
|
@ -1582,7 +1582,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 */
|
||||||
|
|
@ -3985,11 +3985,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;
|
||||||
|
|
@ -4040,7 +4041,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;
|
||||||
|
|
@ -4670,7 +4671,7 @@ mdb_fopen(const MDB_env *env, MDB_name *fname,
|
||||||
/** 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;
|
||||||
|
|
@ -4733,7 +4734,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");
|
||||||
|
|
@ -5332,7 +5333,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_PREVMETA)
|
||||||
|
|
||||||
#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"
|
||||||
|
|
@ -5432,7 +5433,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rc = mdb_env_open2(env)) == MDB_SUCCESS) {
|
if ((rc = mdb_env_open2(env, flags & MDB_PREVMETA)) == MDB_SUCCESS) {
|
||||||
if (!(flags & (MDB_RDONLY|MDB_WRITEMAP))) {
|
if (!(flags & (MDB_RDONLY|MDB_WRITEMAP))) {
|
||||||
/* Synchronous fd for meta writes. Needed even with
|
/* Synchronous fd for meta writes. Needed even with
|
||||||
* MDB_NOSYNC/MDB_NOMETASYNC, in case these get reset.
|
* MDB_NOSYNC/MDB_NOMETASYNC, in case these get reset.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue