mdbx-dump: add -r (rescue) and -q (quiet) options.

Change-Id: I35b32a61fbf301651099009d818722b3b893a039
This commit is contained in:
Leonid Yuriev 2019-11-27 22:02:01 +03:00
parent 01ae72a570
commit e25daab399

View File

@ -173,7 +173,7 @@ int main(int argc, char *argv[]) {
char *prog = argv[0]; char *prog = argv[0];
char *envname; char *envname;
char *subname = NULL; char *subname = NULL;
int alldbs = 0, envflags = 0, list = 0; int alldbs = 0, envflags = 0, list = 0, quiet = 0, rescue = 0;
if (argc < 2) if (argc < 2)
usage(prog); usage(prog);
@ -186,7 +186,7 @@ int main(int argc, char *argv[]) {
* -V: print version and exit * -V: print version and exit
* (default) dump only the main DB * (default) dump only the main DB
*/ */
while ((i = getopt(argc, argv, "af:lnps:V")) != EOF) { while ((i = getopt(argc, argv, "af:lnps:Vrq")) != EOF) {
switch (i) { switch (i) {
case 'V': case 'V':
printf("mdbx_dump version %d.%d.%d.%d\n" printf("mdbx_dump version %d.%d.%d.%d\n"
@ -229,6 +229,12 @@ int main(int argc, char *argv[]) {
usage(prog); usage(prog);
subname = optarg; subname = optarg;
break; break;
case 'q':
quiet = 1;
break;
case 'r':
rescue = 1;
break;
default: default:
usage(prog); usage(prog);
} }
@ -251,10 +257,12 @@ int main(int argc, char *argv[]) {
#endif /* !WINDOWS */ #endif /* !WINDOWS */
envname = argv[optind]; envname = argv[optind];
fprintf(stderr, "mdbx_dump %s (%s, T-%s)\nRunning for %s...\n", if (!quiet) {
mdbx_version.git.describe, mdbx_version.git.datetime, fprintf(stderr, "mdbx_dump %s (%s, T-%s)\nRunning for %s...\n",
mdbx_version.git.tree, envname); mdbx_version.git.describe, mdbx_version.git.datetime,
fflush(NULL); mdbx_version.git.tree, envname);
fflush(NULL);
}
rc = mdbx_env_create(&env); rc = mdbx_env_create(&env);
if (rc) { if (rc) {
@ -267,7 +275,9 @@ int main(int argc, char *argv[]) {
mdbx_env_set_maxdbs(env, 2); mdbx_env_set_maxdbs(env, 2);
} }
rc = mdbx_env_open(env, envname, envflags | MDBX_RDONLY, 0664); rc = mdbx_env_open(
env, envname,
envflags | (rescue ? MDBX_RDONLY | MDBX_EXCLUSIVE : MDBX_RDONLY), 0);
if (rc) { if (rc) {
fprintf(stderr, "mdbx_env_open failed, error %d %s\n", rc, fprintf(stderr, "mdbx_env_open failed, error %d %s\n", rc,
mdbx_strerror(rc)); mdbx_strerror(rc));
@ -318,8 +328,32 @@ int main(int argc, char *argv[]) {
list++; list++;
} else { } else {
rc = dumpit(txn, db2, str); rc = dumpit(txn, db2, str);
if (rc) if (rc) {
break; if (!rescue)
break;
fprintf(stderr, "%s: %s: ignore %s for `%s` and continue\n", prog,
envname, mdbx_strerror(rc), str);
/* Here is a hack for rescue mode, don't do that:
* - we should restart transaction in case error due
* database corruption;
* - but we won't close cursor, reopen and re-positioning it
* for new a transaction;
* - this is possible since DB is opened in read-only exclusive
* mode and transaction is the same, i.e. has the same address
* and so on. */
rc = mdbx_txn_reset(txn);
if (rc) {
fprintf(stderr, "mdbx_txn_reset failed, error %d %s\n", rc,
mdbx_strerror(rc));
goto env_close;
}
rc = mdbx_txn_renew(txn);
if (rc) {
fprintf(stderr, "mdbx_txn_renew failed, error %d %s\n", rc,
mdbx_strerror(rc));
goto env_close;
}
}
} }
mdbx_dbi_close(env, db2); mdbx_dbi_close(env, db2);
} }