diff --git a/src/mdbx_chk.c b/src/mdbx_chk.c index d2dea1e3..311695c8 100644 --- a/src/mdbx_chk.c +++ b/src/mdbx_chk.c @@ -930,21 +930,24 @@ bailout: } static void usage(char *prog) { - fprintf(stderr, - "usage: %s [-V] [-v] [-q] [-c] [-0|1|2] [-w] [-d] [-i] [-s subdb] " - "dbpath\n" - " -V\t\tprint version and exit\n" - " -v\t\tmore verbose, could be used multiple times\n" - " -q\t\tbe quiet\n" - " -c\t\tforce cooperative mode (don't try exclusive)\n" - " -w\t\twrite-mode checking\n" - " -d\t\tdisable page-by-page traversal of B-tree\n" - " -i\t\tignore wrong order errors (for custom comparators case)\n" - " -s subdb\tprocess a specific subdatabase only\n" - " -0|1|2\tforce using specific meta-page 0, or 2 for checking\n" - " -t\t\tturn to a specified meta-page on successful check\n" - " -T\t\tturn to a specified meta-page EVEN ON UNSUCCESSFUL CHECK!\n", - prog); + fprintf( + stderr, + "usage: %s " + "[-V] [-v] [-q] [-c] [-0|1|2] [-w] [-d] [-i] [-s subdb] [-u|U] dbpath\n" + " -V\t\tprint version and exit\n" + " -v\t\tmore verbose, could be used multiple times\n" + " -q\t\tbe quiet\n" + " -c\t\tforce cooperative mode (don't try exclusive)\n" + " -w\t\twrite-mode checking\n" + " -d\t\tdisable page-by-page traversal of B-tree\n" + " -i\t\tignore wrong order errors (for custom comparators case)\n" + " -s subdb\tprocess a specific subdatabase only\n" + " -u\t\twarmup database before checking\n" + " -U\t\twarmup and try lock database pages in memory before checking\n" + " -0|1|2\tforce using specific meta-page 0, or 2 for checking\n" + " -t\t\tturn to a specified meta-page on successful check\n" + " -T\t\tturn to a specified meta-page EVEN ON UNSUCCESSFUL CHECK!\n", + prog); exit(EXIT_INTERRUPTED); } @@ -1083,6 +1086,8 @@ int main(int argc, char *argv[]) { bool write_locked = false; bool turn_meta = false; bool force_turn_meta = false; + bool warmup = false; + MDBX_warmup_flags_t warmup_flags = MDBX_warmup_default; double elapsed; #if defined(_WIN32) || defined(_WIN64) @@ -1106,6 +1111,7 @@ int main(int argc, char *argv[]) { usage(prog); for (int i; (i = getopt(argc, argv, + "uU" "0" "1" "2" @@ -1183,6 +1189,14 @@ int main(int argc, char *argv[]) { case 'i': ignore_wrong_order = true; break; + case 'u': + warmup = true; + break; + case 'U': + warmup = true; + warmup_flags = + MDBX_warmup_force | MDBX_warmup_touchlimit | MDBX_warmup_lock; + break; default: usage(prog); } @@ -1284,14 +1298,35 @@ int main(int argc, char *argv[]) { (envflags & MDBX_EXCLUSIVE) ? "monopolistic" : "cooperative"); if ((envflags & (MDBX_RDONLY | MDBX_EXCLUSIVE)) == 0) { + if (verbose) { + print(" - taking write lock..."); + fflush(nullptr); + } rc = mdbx_txn_lock(env, false); if (rc != MDBX_SUCCESS) { error("mdbx_txn_lock() failed, error %d %s\n", rc, mdbx_strerror(rc)); goto bailout; } + if (verbose) + print(" done\n"); write_locked = true; } + if (warmup) { + if (verbose) { + print(" - warming up..."); + fflush(nullptr); + } + rc = mdbx_env_warmup(env, nullptr, warmup_flags, 3600 * 65536); + if (MDBX_IS_ERROR(rc)) { + error("mdbx_env_warmup(flags %u) failed, error %d %s\n", warmup_flags, rc, + mdbx_strerror(rc)); + goto bailout; + } + if (verbose) + print(" %s\n", rc ? "timeout" : "done"); + } + rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_RDONLY, &txn); if (rc) { error("mdbx_txn_begin() failed, error %d %s\n", rc, mdbx_strerror(rc)); diff --git a/src/mdbx_copy.c b/src/mdbx_copy.c index 18eafca0..b070449b 100644 --- a/src/mdbx_copy.c +++ b/src/mdbx_copy.c @@ -44,14 +44,17 @@ static void signal_handler(int sig) { #endif /* !WINDOWS */ static void usage(const char *prog) { - fprintf(stderr, - "usage: %s [-V] [-q] [-c] src_path [dest_path]\n" - " -V\t\tprint version and exit\n" - " -q\t\tbe quiet\n" - " -c\t\tenable compactification (skip unused pages)\n" - " src_path\tsource database\n" - " dest_path\tdestination (stdout if not specified)\n", - prog); + fprintf( + stderr, + "usage: %s [-V] [-q] [-c] [-u|U] src_path [dest_path]\n" + " -V\t\tprint version and exit\n" + " -q\t\tbe quiet\n" + " -c\t\tenable compactification (skip unused pages)\n" + " -u\t\twarmup database before copying\n" + " -U\t\twarmup and try lock database pages in memory before copying\n" + " src_path\tsource database\n" + " dest_path\tdestination (stdout if not specified)\n", + prog); exit(EXIT_FAILURE); } @@ -62,6 +65,8 @@ int main(int argc, char *argv[]) { unsigned flags = MDBX_RDONLY; unsigned cpflags = 0; bool quiet = false; + bool warmup = false; + MDBX_warmup_flags_t warmup_flags = MDBX_warmup_default; for (; argc > 1 && argv[1][0] == '-'; argc--, argv++) { if (argv[1][1] == 'n' && argv[1][2] == '\0') @@ -70,8 +75,14 @@ int main(int argc, char *argv[]) { cpflags |= MDBX_CP_COMPACT; else if (argv[1][1] == 'q' && argv[1][2] == '\0') quiet = true; - else if ((argv[1][1] == 'h' && argv[1][2] == '\0') || - strcmp(argv[1], "--help") == 0) + else if (argv[1][1] == 'u' && argv[1][2] == '\0') + warmup = true; + else if (argv[1][1] == 'U' && argv[1][2] == '\0') { + warmup = true; + warmup_flags = + MDBX_warmup_force | MDBX_warmup_touchlimit | MDBX_warmup_lock; + } else if ((argv[1][1] == 'h' && argv[1][2] == '\0') || + strcmp(argv[1], "--help") == 0) usage(progname); else if (argv[1][1] == 'V' && argv[1][2] == '\0') { printf("mdbx_copy version %d.%d.%d.%d\n" @@ -120,7 +131,12 @@ int main(int argc, char *argv[]) { if (rc == MDBX_SUCCESS) rc = mdbx_env_open(env, argv[1], flags, 0); - if (rc == MDBX_SUCCESS) { + if (rc == MDBX_SUCCESS && warmup) { + act = "warming up"; + rc = mdbx_env_warmup(env, nullptr, warmup_flags, 3600 * 65536); + } + + if (!MDBX_IS_ERROR(rc)) { act = "copying"; if (argc == 2) { mdbx_filehandle_t fd; diff --git a/src/mdbx_dump.c b/src/mdbx_dump.c index 364e03ab..f710d33d 100644 --- a/src/mdbx_dump.c +++ b/src/mdbx_dump.c @@ -217,19 +217,23 @@ static int dump_sdb(MDBX_txn *txn, MDBX_dbi dbi, char *name) { } static void usage(void) { - fprintf(stderr, - "usage: %s [-V] [-q] [-f file] [-l] [-p] [-r] [-a|-s subdb] " - "dbpath\n" - " -V\t\tprint version and exit\n" - " -q\t\tbe quiet\n" - " -f\t\twrite to file instead of stdout\n" - " -l\t\tlist subDBs and exit\n" - " -p\t\tuse printable characters\n" - " -r\t\trescue mode (ignore errors to dump corrupted DB)\n" - " -a\t\tdump main DB and all subDBs\n" - " -s name\tdump only the specified named subDB\n" - " \t\tby default dump only the main DB\n", - prog); + fprintf( + stderr, + "usage: %s " + "[-V] [-q] [-f file] [-l] [-p] [-r] [-a|-s subdb] [-u|U] " + "dbpath\n" + " -V\t\tprint version and exit\n" + " -q\t\tbe quiet\n" + " -f\t\twrite to file instead of stdout\n" + " -l\t\tlist subDBs and exit\n" + " -p\t\tuse printable characters\n" + " -r\t\trescue mode (ignore errors to dump corrupted DB)\n" + " -a\t\tdump main DB and all subDBs\n" + " -s name\tdump only the specified named subDB\n" + " -u\t\twarmup database before dumping\n" + " -U\t\twarmup and try lock database pages in memory before dumping\n" + " \t\tby default dump only the main DB\n", + prog); exit(EXIT_FAILURE); } @@ -250,11 +254,14 @@ int main(int argc, char *argv[]) { char *subname = nullptr, *buf4free = nullptr; unsigned envflags = 0; bool alldbs = false, list = false; + bool warmup = false; + MDBX_warmup_flags_t warmup_flags = MDBX_warmup_default; if (argc < 2) usage(); while ((i = getopt(argc, argv, + "uU" "a" "f:" "l" @@ -311,6 +318,14 @@ int main(int argc, char *argv[]) { case 'r': rescue = true; break; + case 'u': + warmup = true; + break; + case 'U': + warmup = true; + warmup_flags = + MDBX_warmup_force | MDBX_warmup_touchlimit | MDBX_warmup_lock; + break; default: usage(); } @@ -364,6 +379,14 @@ int main(int argc, char *argv[]) { goto env_close; } + if (warmup) { + rc = mdbx_env_warmup(env, nullptr, warmup_flags, 3600 * 65536); + if (MDBX_IS_ERROR(rc)) { + error("mdbx_env_warmup", rc); + goto env_close; + } + } + rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_RDONLY, &txn); if (unlikely(rc != MDBX_SUCCESS)) { error("mdbx_txn_begin", rc);