diff options
Diffstat (limited to 'src/third_party/wiredtiger/test/format/backup.c')
-rw-r--r-- | src/third_party/wiredtiger/test/format/backup.c | 268 |
1 files changed, 127 insertions, 141 deletions
diff --git a/src/third_party/wiredtiger/test/format/backup.c b/src/third_party/wiredtiger/test/format/backup.c index ba858a28d5b..9d2bb241efc 100644 --- a/src/third_party/wiredtiger/test/format/backup.c +++ b/src/third_party/wiredtiger/test/format/backup.c @@ -30,165 +30,151 @@ /* * check_copy -- - * Confirm the backup worked. + * Confirm the backup worked. */ static void check_copy(void) { - WT_CONNECTION *conn; - WT_DECL_RET; - WT_SESSION *session; - - wts_open(g.home_backup, false, &conn); - - testutil_checkfmt( - conn->open_session(conn, NULL, NULL, &session), - "%s", g.home_backup); - - /* - * Verify can return EBUSY if the handle isn't available. Don't yield - * and retry, in the case of LSM, the handle may not be available for - * a long time. - */ - ret = session->verify(session, g.uri, NULL); - testutil_assertfmt(ret == 0 || ret == EBUSY, - "WT_SESSION.verify: %s: %s", g.home_backup, g.uri); - - testutil_checkfmt(conn->close(conn, NULL), "%s", g.home_backup); + WT_CONNECTION *conn; + WT_DECL_RET; + WT_SESSION *session; + + wts_open(g.home_backup, false, &conn); + + testutil_checkfmt(conn->open_session(conn, NULL, NULL, &session), "%s", g.home_backup); + + /* + * Verify can return EBUSY if the handle isn't available. Don't yield and retry, in the case of + * LSM, the handle may not be available for a long time. + */ + ret = session->verify(session, g.uri, NULL); + testutil_assertfmt(ret == 0 || ret == EBUSY, "WT_SESSION.verify: %s: %s", g.home_backup, g.uri); + + testutil_checkfmt(conn->close(conn, NULL), "%s", g.home_backup); } /* * copy_file -- - * Copy a single file into the backup directories. + * Copy a single file into the backup directories. */ static void copy_file(WT_SESSION *session, const char *name) { - size_t len; - char *first, *second; - - len = strlen("BACKUP") + strlen(name) + 10; - first = dmalloc(len); - testutil_check(__wt_snprintf(first, len, "BACKUP/%s", name)); - testutil_check(__wt_copy_and_sync(session, name, first)); - - /* - * Save another copy of the original file to make debugging recovery - * errors easier. - */ - len = strlen("BACKUP_COPY") + strlen(name) + 10; - second = dmalloc(len); - testutil_check(__wt_snprintf(second, len, "BACKUP_COPY/%s", name)); - testutil_check(__wt_copy_and_sync(session, first, second)); - - free(first); - free(second); + size_t len; + char *first, *second; + + len = strlen("BACKUP") + strlen(name) + 10; + first = dmalloc(len); + testutil_check(__wt_snprintf(first, len, "BACKUP/%s", name)); + testutil_check(__wt_copy_and_sync(session, name, first)); + + /* + * Save another copy of the original file to make debugging recovery errors easier. + */ + len = strlen("BACKUP_COPY") + strlen(name) + 10; + second = dmalloc(len); + testutil_check(__wt_snprintf(second, len, "BACKUP_COPY/%s", name)); + testutil_check(__wt_copy_and_sync(session, first, second)); + + free(first); + free(second); } /* * backup -- - * Periodically do a backup and verify it. + * Periodically do a backup and verify it. */ WT_THREAD_RET backup(void *arg) { - WT_CONNECTION *conn; - WT_CURSOR *backup_cursor; - WT_DECL_RET; - WT_SESSION *session; - u_int incremental, period; - const char *config, *key; - bool full; - - (void)(arg); - - conn = g.wts_conn; - - /* Open a session. */ - testutil_check(conn->open_session(conn, NULL, NULL, &session)); - - /* - * Perform a full backup at somewhere under 10 seconds (that way there's - * at least one), then at larger intervals, optionally do incremental - * backups between full backups. - */ - incremental = 0; - for (period = mmrand(NULL, 1, 10);; period = mmrand(NULL, 20, 45)) { - /* Sleep for short periods so we don't make the run wait. */ - while (period > 0 && !g.workers_finished) { - --period; - __wt_sleep(1, 0); - } - - /* - * We can't drop named checkpoints while there's a backup in - * progress, serialize backups with named checkpoints. Wait - * for the checkpoint to complete, otherwise backups might be - * starved out. - */ - testutil_check(pthread_rwlock_wrlock(&g.backup_lock)); - if (g.workers_finished) { - testutil_check(pthread_rwlock_unlock(&g.backup_lock)); - break; - } - - if (incremental) { - config = "target=(\"log:\")"; - full = false; - } else { - /* Re-create the backup directory. */ - testutil_checkfmt( - system(g.home_backup_init), - "%s", "backup directory creation failed"); - - config = NULL; - full = true; - } - - /* - * open_cursor can return EBUSY if concurrent with a metadata - * operation, retry in that case. - */ - while ((ret = session->open_cursor( - session, "backup:", NULL, config, &backup_cursor)) == EBUSY) - __wt_yield(); - if (ret != 0) - testutil_die(ret, "session.open_cursor: backup"); - - while ((ret = backup_cursor->next(backup_cursor)) == 0) { - testutil_check( - backup_cursor->get_key(backup_cursor, &key)); - copy_file(session, key); - } - if (ret != WT_NOTFOUND) - testutil_die(ret, "backup-cursor"); - - /* After an incremental backup, truncate the log files. */ - if (incremental) - testutil_check(session->truncate( - session, "log:", backup_cursor, NULL, NULL)); - - testutil_check(backup_cursor->close(backup_cursor)); - testutil_check(pthread_rwlock_unlock(&g.backup_lock)); - - /* - * If automatic log archival isn't configured, optionally do - * incremental backups after each full backup. If we're not - * doing any more incrementals, verify the backup (we can't - * verify intermediate states, once we perform recovery on the - * backup database, we can't do any more incremental backups). - */ - if (full) - incremental = - g.c_logging_archive ? 1 : mmrand(NULL, 1, 5); - if (--incremental == 0) - check_copy(); - } - - if (incremental != 0) - check_copy(); - - testutil_check(session->close(session, NULL)); - - return (WT_THREAD_RET_VALUE); + WT_CONNECTION *conn; + WT_CURSOR *backup_cursor; + WT_DECL_RET; + WT_SESSION *session; + u_int incremental, period; + const char *config, *key; + bool full; + + (void)(arg); + + conn = g.wts_conn; + + /* Open a session. */ + testutil_check(conn->open_session(conn, NULL, NULL, &session)); + + /* + * Perform a full backup at somewhere under 10 seconds (that way there's at least one), then at + * larger intervals, optionally do incremental backups between full backups. + */ + incremental = 0; + for (period = mmrand(NULL, 1, 10);; period = mmrand(NULL, 20, 45)) { + /* Sleep for short periods so we don't make the run wait. */ + while (period > 0 && !g.workers_finished) { + --period; + __wt_sleep(1, 0); + } + + /* + * We can't drop named checkpoints while there's a backup in progress, serialize backups + * with named checkpoints. Wait for the checkpoint to complete, otherwise backups might be + * starved out. + */ + testutil_check(pthread_rwlock_wrlock(&g.backup_lock)); + if (g.workers_finished) { + testutil_check(pthread_rwlock_unlock(&g.backup_lock)); + break; + } + + if (incremental) { + config = "target=(\"log:\")"; + full = false; + } else { + /* Re-create the backup directory. */ + testutil_checkfmt(system(g.home_backup_init), "%s", "backup directory creation failed"); + + config = NULL; + full = true; + } + + /* + * open_cursor can return EBUSY if concurrent with a metadata operation, retry in that case. + */ + while ( + (ret = session->open_cursor(session, "backup:", NULL, config, &backup_cursor)) == EBUSY) + __wt_yield(); + if (ret != 0) + testutil_die(ret, "session.open_cursor: backup"); + + while ((ret = backup_cursor->next(backup_cursor)) == 0) { + testutil_check(backup_cursor->get_key(backup_cursor, &key)); + copy_file(session, key); + } + if (ret != WT_NOTFOUND) + testutil_die(ret, "backup-cursor"); + + /* After an incremental backup, truncate the log files. */ + if (incremental) + testutil_check(session->truncate(session, "log:", backup_cursor, NULL, NULL)); + + testutil_check(backup_cursor->close(backup_cursor)); + testutil_check(pthread_rwlock_unlock(&g.backup_lock)); + + /* + * If automatic log archival isn't configured, optionally do incremental backups after each + * full backup. If we're not doing any more incrementals, verify the backup (we can't verify + * intermediate states, once we perform recovery on the backup database, we can't do any + * more incremental backups). + */ + if (full) + incremental = g.c_logging_archive ? 1 : mmrand(NULL, 1, 5); + if (--incremental == 0) + check_copy(); + } + + if (incremental != 0) + check_copy(); + + testutil_check(session->close(session, NULL)); + + return (WT_THREAD_RET_VALUE); } |