summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/log/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/log/log.c')
-rw-r--r--src/third_party/wiredtiger/src/log/log.c78
1 files changed, 73 insertions, 5 deletions
diff --git a/src/third_party/wiredtiger/src/log/log.c b/src/third_party/wiredtiger/src/log/log.c
index ca0b81c4cf6..efe4d22eeca 100644
--- a/src/third_party/wiredtiger/src/log/log.c
+++ b/src/third_party/wiredtiger/src/log/log.c
@@ -357,6 +357,67 @@ __wt_log_extract_lognum(
}
/*
+ * __log_zero --
+ * Zero a log file.
+ */
+static int
+__log_zero(WT_SESSION_IMPL *session,
+ WT_FH *fh, wt_off_t start_off, wt_off_t len)
+{
+ WT_CONNECTION_IMPL *conn;
+ WT_DECL_ITEM(zerobuf);
+ WT_DECL_RET;
+ WT_LOG *log;
+ uint32_t allocsize, bufsz, off, partial, wrlen;
+
+ conn = S2C(session);
+ log = conn->log;
+ allocsize = log->allocsize;
+ zerobuf = NULL;
+ if (allocsize < WT_MEGABYTE)
+ bufsz = WT_MEGABYTE;
+ else
+ bufsz = allocsize;
+ /*
+ * If they're using smaller log files, cap it at the file size.
+ */
+ if (conn->log_file_max < bufsz)
+ bufsz = (uint32_t)conn->log_file_max;
+ WT_RET(__wt_scr_alloc(session, bufsz, &zerobuf));
+ memset(zerobuf->mem, 0, zerobuf->memsize);
+ WT_STAT_FAST_CONN_INCR(session, log_zero_fills);
+
+ /*
+ * Read in a chunk starting at the end of the file. Keep going until
+ * we reach the beginning or we find a chunk that contains any non-zero
+ * bytes. Compare against a known zero byte chunk.
+ */
+ off = (uint32_t)start_off;
+ while (off < (uint32_t)len) {
+ /*
+ * Typically we start to zero the file after the log header
+ * and the bufsz is a sector-aligned size. So we want to
+ * align our writes when we can.
+ */
+ partial = off % bufsz;
+ if (partial != 0)
+ wrlen = bufsz - partial;
+ else
+ wrlen = bufsz;
+ /*
+ * Check if we're writing a partial amount at the end too.
+ */
+ if ((uint32_t)len - off < bufsz)
+ wrlen = (uint32_t)len - off;
+ WT_ERR(__wt_write(session,
+ fh, (wt_off_t)off, wrlen, zerobuf->mem));
+ off += wrlen;
+ }
+err: __wt_scr_free(session, &zerobuf);
+ return (ret);
+}
+
+/*
* __log_prealloc --
* Pre-allocate a log file.
*/
@@ -370,7 +431,15 @@ __log_prealloc(WT_SESSION_IMPL *session, WT_FH *fh)
conn = S2C(session);
log = conn->log;
ret = 0;
- if (fh->fallocate_available == WT_FALLOCATE_NOT_AVAILABLE ||
+ /*
+ * If the user configured zero filling, pre-allocate the log file
+ * manually. Otherwise use either fallocate or ftruncate to create
+ * and zero the log file based on what is available.
+ */
+ if (FLD_ISSET(conn->log_flags, WT_CONN_LOG_ZERO_FILL))
+ ret = __log_zero(session, fh,
+ WT_LOG_FIRST_RECORD, conn->log_file_max);
+ else if (fh->fallocate_available == WT_FALLOCATE_NOT_AVAILABLE ||
(ret = __wt_fallocate(session, fh,
WT_LOG_FIRST_RECORD, conn->log_file_max)) == ENOTSUP)
ret = __wt_ftruncate(session, fh,
@@ -753,7 +822,7 @@ __log_newfile(WT_SESSION_IMPL *session, bool conn_open, bool *created)
if (create_log) {
log->prep_missed++;
WT_RET(__wt_log_allocfile(
- session, log->fileid, WT_LOG_FILENAME, true));
+ session, log->fileid, WT_LOG_FILENAME));
}
WT_RET(__log_openfile(session,
false, &log->log_fh, WT_LOG_FILENAME, log->fileid));
@@ -904,7 +973,7 @@ err: WT_TRET(__wt_close(session, &log_fh));
*/
int
__wt_log_allocfile(
- WT_SESSION_IMPL *session, uint32_t lognum, const char *dest, bool prealloc)
+ WT_SESSION_IMPL *session, uint32_t lognum, const char *dest)
{
WT_CONNECTION_IMPL *conn;
WT_DECL_ITEM(from_path);
@@ -936,8 +1005,7 @@ __wt_log_allocfile(
WT_ERR(__log_openfile(session, true, &log_fh, WT_LOG_TMPNAME, tmp_id));
WT_ERR(__log_file_header(session, log_fh, NULL, true));
WT_ERR(__wt_ftruncate(session, log_fh, WT_LOG_FIRST_RECORD));
- if (prealloc)
- WT_ERR(__log_prealloc(session, log_fh));
+ WT_ERR(__log_prealloc(session, log_fh));
WT_ERR(__wt_fsync(session, log_fh));
WT_ERR(__wt_close(session, &log_fh));
WT_ERR(__wt_verbose(session, WT_VERB_LOG,