mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-01 23:54:12 +08:00
lmdb: added mdb_env_open_ex() and exclusive/monopoly mode for mdb_chk.
Change-Id: I867e7f17924ffecb744440e95db96c0a7411d6ef
This commit is contained in:
parent
59b74d5df0
commit
96d69e3fa1
2
lmdb.h
2
lmdb.h
@ -616,7 +616,7 @@ int mdb_env_create(MDB_env **env);
|
||||
* </ul>
|
||||
*/
|
||||
int mdb_env_open(MDB_env *env, const char *path, unsigned flags, mode_t mode);
|
||||
|
||||
int mdb_env_open_ex(MDB_env *env, const char *path, unsigned flags, mode_t mode, int *exclusive);
|
||||
/** @brief Copy an LMDB environment to the specified path.
|
||||
*
|
||||
* This function may be used to make a backup of an existing environment.
|
||||
|
22
mdb.c
22
mdb.c
@ -4345,8 +4345,6 @@ mdb_env_share_locks(MDB_env *env, int *excl, MDB_meta *meta)
|
||||
struct flock lock_info;
|
||||
int rc = 0;
|
||||
|
||||
env->me_txns->mti_txnid = meta->mm_txnid;
|
||||
|
||||
/* The shared lock replaces the existing lock */
|
||||
memset((void *)&lock_info, 0, sizeof(lock_info));
|
||||
lock_info.l_type = F_RDLCK;
|
||||
@ -4600,6 +4598,12 @@ fail:
|
||||
|
||||
int ESECT
|
||||
mdb_env_open(MDB_env *env, const char *path, unsigned flags, mode_t mode)
|
||||
{
|
||||
return mdb_env_open_ex(env, path, flags, mode, NULL);
|
||||
}
|
||||
|
||||
int ESECT
|
||||
mdb_env_open_ex(MDB_env *env, const char *path, unsigned flags, mode_t mode, int *exclusive)
|
||||
{
|
||||
int oflags, rc, len, excl = -1;
|
||||
char *lpath, *dpath;
|
||||
@ -4678,9 +4682,17 @@ mdb_env_open(MDB_env *env, const char *path, unsigned flags, mode_t mode)
|
||||
if ((rc = mdb_env_open2(env, &meta)) == MDB_SUCCESS) {
|
||||
mdb_debug("opened dbenv %p", (void *) env);
|
||||
if (excl > 0) {
|
||||
rc = mdb_env_share_locks(env, &excl, &meta);
|
||||
if (rc)
|
||||
goto leave;
|
||||
env->me_txns->mti_txnid = meta.mm_txnid;
|
||||
if (exclusive == NULL || *exclusive < 2) {
|
||||
/* LY: downgrade lock only if exclusive access not requested.
|
||||
* in case exclusive==1, just leave value as is. */
|
||||
rc = mdb_env_share_locks(env, &excl, &meta);
|
||||
if (rc)
|
||||
goto leave;
|
||||
}
|
||||
} else if (exclusive) {
|
||||
/* LY: just indicate that is not an exclusive access. */
|
||||
*exclusive = 0;
|
||||
}
|
||||
if (!(flags & MDB_RDONLY)) {
|
||||
MDB_txn *txn;
|
||||
|
39
mdb_chk.c
39
mdb_chk.c
@ -61,6 +61,7 @@ size_t dbi_payload_bytes[MAX_DBI];
|
||||
short *pagemap;
|
||||
size_t pgcount;
|
||||
size_t total_payload_bytes, total_unused_bytes;
|
||||
int exclusive = 2;
|
||||
|
||||
MDB_env *env;
|
||||
MDB_txn *txn, *locktxn;
|
||||
@ -458,7 +459,8 @@ static void usage(char *prog)
|
||||
" -v\tmore verbose, could be used multiple times\n"
|
||||
" -n\tNOSUBDIR mode for open\n"
|
||||
" -q\tbe quiet\n"
|
||||
" -w\tstart write-txn to lock db\n", prog);
|
||||
" -w\tstart write-txn to lock db\n"
|
||||
" -c\tforce cooperative mode (don't try exclusive)\n", prog);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -474,7 +476,7 @@ const char* meta_synctype(size_t sign) {
|
||||
}
|
||||
|
||||
int meta_lt(size_t txn1, size_t sign1, size_t txn2, size_t sign2) {
|
||||
return ((sign1 > 1) == (sign2 > 1)) ? txn1 < txn2 : sign2 > 1;
|
||||
return ((sign1 > 1) == (sign2 > 1)) ? txn1 < txn2 : txn2 && sign2 > 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -491,7 +493,7 @@ int main(int argc, char *argv[])
|
||||
usage(prog);
|
||||
}
|
||||
|
||||
while ((i = getopt(argc, argv, "Vvqnw")) != EOF) {
|
||||
while ((i = getopt(argc, argv, "Vvqnwc")) != EOF) {
|
||||
switch(i) {
|
||||
case 'V':
|
||||
printf("%s\n", MDB_VERSION_STRING);
|
||||
@ -509,6 +511,9 @@ int main(int argc, char *argv[])
|
||||
case 'w':
|
||||
envflags &= ~MDB_RDONLY;
|
||||
break;
|
||||
case 'c':
|
||||
exclusive = 0;
|
||||
break;
|
||||
default:
|
||||
usage(prog);
|
||||
}
|
||||
@ -545,11 +550,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
mdb_env_set_maxdbs(env, 3);
|
||||
|
||||
rc = mdb_env_open(env, envname, envflags, 0664);
|
||||
rc = mdb_env_open_ex(env, envname, envflags, 0664, &exclusive);
|
||||
if (rc) {
|
||||
error("mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
||||
goto bailout;
|
||||
}
|
||||
if (verbose)
|
||||
print(" - %s mode\n", exclusive ? "monopolistic" : "cooperative");
|
||||
|
||||
rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
|
||||
if (rc) {
|
||||
@ -619,18 +626,20 @@ int main(int argc, char *argv[])
|
||||
info.me_meta2_txnid, info.me_last_txnid);
|
||||
}
|
||||
|
||||
if (! meta_lt(info.me_meta1_txnid, info.me_meta1_sign,
|
||||
info.me_meta2_txnid, info.me_meta2_sign)
|
||||
&& info.me_meta1_txnid != info.me_last_txnid) {
|
||||
print(" - meta-1 txn-id mismatch\n");
|
||||
++problems_meta;
|
||||
}
|
||||
if (exclusive > 1) {
|
||||
if (! meta_lt(info.me_meta1_txnid, info.me_meta1_sign,
|
||||
info.me_meta2_txnid, info.me_meta2_sign)
|
||||
&& info.me_meta1_txnid != info.me_last_txnid) {
|
||||
print(" - meta-1 txn-id mismatch\n");
|
||||
++problems_meta;
|
||||
}
|
||||
|
||||
if (! meta_lt(info.me_meta2_txnid, info.me_meta2_sign,
|
||||
info.me_meta1_txnid, info.me_meta1_sign)
|
||||
&& info.me_meta2_txnid != info.me_last_txnid) {
|
||||
print(" - meta-2 txn-id mismatch\n");
|
||||
++problems_meta;
|
||||
if (! meta_lt(info.me_meta2_txnid, info.me_meta2_sign,
|
||||
info.me_meta1_txnid, info.me_meta1_sign)
|
||||
&& info.me_meta2_txnid != info.me_last_txnid) {
|
||||
print(" - meta-2 txn-id mismatch\n");
|
||||
++problems_meta;
|
||||
}
|
||||
}
|
||||
|
||||
print("Walking b-tree...\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user