summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dist/api_data.py7
-rw-r--r--dist/stat_data.py1
-rw-r--r--examples/c/ex_sync.c21
-rw-r--r--lang/java/java_doc.i1
-rw-r--r--src/config/config_def.c11
-rw-r--r--src/include/config.h43
-rw-r--r--src/include/extern.h3
-rw-r--r--src/include/stat.h1
-rw-r--r--src/include/wiredtiger.in140
-rw-r--r--src/log/log.c64
-rw-r--r--src/session/session_api.c39
-rw-r--r--src/support/stat.c3
-rw-r--r--src/txn/txn_log.c4
13 files changed, 246 insertions, 92 deletions
diff --git a/dist/api_data.py b/dist/api_data.py
index 3a700cf886b..f3dd779b58b 100644
--- a/dist/api_data.py
+++ b/dist/api_data.py
@@ -725,6 +725,13 @@ methods = {
type='boolean'),
]),
+'WT_SESSION.log_flush' : Method([
+ Config('sync', '', r'''
+ forcibly flush the log and wait for it to achieve the synchronization
+ level specified''',
+ choices=['background', 'sync', 'write']),
+]),
+
'WT_SESSION.log_printf' : Method([]),
'WT_SESSION.open_cursor' : Method(cursor_runtime_config + [
diff --git a/dist/stat_data.py b/dist/stat_data.py
index c91fc921380..db828a7dec6 100644
--- a/dist/stat_data.py
+++ b/dist/stat_data.py
@@ -248,6 +248,7 @@ connection_stats = [
LogStat('log_compress_small', 'log records too small to compress'),
LogStat('log_compress_write_fails', 'log records not compressed'),
LogStat('log_compress_writes', 'log records compressed'),
+ LogStat('log_flush', 'log flush calls'),
LogStat('log_max_filesize', 'maximum log file size', 'no_clear,no_scale'),
LogStat('log_prealloc_files', 'pre-allocated log files prepared'),
LogStat('log_prealloc_max',
diff --git a/examples/c/ex_sync.c b/examples/c/ex_sync.c
index 46317f3112c..0c293341e74 100644
--- a/examples/c/ex_sync.c
+++ b/examples/c/ex_sync.c
@@ -125,7 +125,28 @@ main(void)
fprintf(stderr,
"Unexpected error %d from WT_SESSION::transaction_sync\n",
ret);
+ /*
+ * Demonstrate using log_flush to force the log to disk.
+ */
+ for (i = 0; i < MAX_KEYS; i++, record_count++) {
+ snprintf(k, sizeof(k), "key%d", record_count);
+ snprintf(v, sizeof(v), "value%d", record_count);
+ cursor->set_key(cursor, k);
+ cursor->set_value(cursor, v);
+ ret = cursor->insert(cursor);
+ }
+ session->log_flush(session, "sync=sync");
+
+ for (i = 0; i < MAX_KEYS; i++, record_count++) {
+ snprintf(k, sizeof(k), "key%d", record_count);
+ snprintf(v, sizeof(v), "value%d", record_count);
+ cursor->set_key(cursor, k);
+ cursor->set_value(cursor, v);
+ ret = cursor->insert(cursor);
+ }
ret = cursor->close(cursor);
+ session->log_flush(session, "sync=write");
+ session->log_flush(session, "sync=sync");
ret = wt_conn->close(wt_conn, NULL);
return (ret);
diff --git a/lang/java/java_doc.i b/lang/java/java_doc.i
index d0bfc6b21d1..75c14dbfe8f 100644
--- a/lang/java/java_doc.i
+++ b/lang/java/java_doc.i
@@ -33,6 +33,7 @@ COPYDOC(__wt_session, WT_SESSION, open_cursor)
COPYDOC(__wt_session, WT_SESSION, create)
COPYDOC(__wt_session, WT_SESSION, compact)
COPYDOC(__wt_session, WT_SESSION, drop)
+COPYDOC(__wt_session, WT_SESSION, log_flush)
COPYDOC(__wt_session, WT_SESSION, log_printf)
COPYDOC(__wt_session, WT_SESSION, rename)
COPYDOC(__wt_session, WT_SESSION, reset)
diff --git a/src/config/config_def.c b/src/config/config_def.c
index 91cfcedfcaf..8913571f793 100644
--- a/src/config/config_def.c
+++ b/src/config/config_def.c
@@ -277,6 +277,13 @@ static const WT_CONFIG_CHECK confchk_WT_SESSION_drop[] = {
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
+static const WT_CONFIG_CHECK confchk_WT_SESSION_log_flush[] = {
+ { "sync", "string",
+ NULL, "choices=[\"background\",\"sync\",\"write\"]",
+ NULL, 0 },
+ { NULL, NULL, NULL, NULL, NULL, 0 }
+};
+
static const WT_CONFIG_CHECK confchk_WT_SESSION_open_cursor[] = {
{ "append", "boolean", NULL, NULL, NULL, 0 },
{ "bulk", "string", NULL, NULL, NULL, 0 },
@@ -864,6 +871,10 @@ static const WT_CONFIG_ENTRY config_entries[] = {
"force=0,remove_files=",
confchk_WT_SESSION_drop, 2
},
+ { "WT_SESSION.log_flush",
+ "sync=",
+ confchk_WT_SESSION_log_flush, 1
+ },
{ "WT_SESSION.log_printf",
"",
NULL, 0
diff --git a/src/include/config.h b/src/include/config.h
index 45aa87fcdc5..408639ab2a9 100644
--- a/src/include/config.h
+++ b/src/include/config.h
@@ -68,27 +68,28 @@ struct __wt_config_parser_impl {
#define WT_CONFIG_ENTRY_WT_SESSION_compact 16
#define WT_CONFIG_ENTRY_WT_SESSION_create 17
#define WT_CONFIG_ENTRY_WT_SESSION_drop 18
-#define WT_CONFIG_ENTRY_WT_SESSION_log_printf 19
-#define WT_CONFIG_ENTRY_WT_SESSION_open_cursor 20
-#define WT_CONFIG_ENTRY_WT_SESSION_reconfigure 21
-#define WT_CONFIG_ENTRY_WT_SESSION_rename 22
-#define WT_CONFIG_ENTRY_WT_SESSION_reset 23
-#define WT_CONFIG_ENTRY_WT_SESSION_rollback_transaction 24
-#define WT_CONFIG_ENTRY_WT_SESSION_salvage 25
-#define WT_CONFIG_ENTRY_WT_SESSION_snapshot 26
-#define WT_CONFIG_ENTRY_WT_SESSION_strerror 27
-#define WT_CONFIG_ENTRY_WT_SESSION_transaction_sync 28
-#define WT_CONFIG_ENTRY_WT_SESSION_truncate 29
-#define WT_CONFIG_ENTRY_WT_SESSION_upgrade 30
-#define WT_CONFIG_ENTRY_WT_SESSION_verify 31
-#define WT_CONFIG_ENTRY_colgroup_meta 32
-#define WT_CONFIG_ENTRY_file_meta 33
-#define WT_CONFIG_ENTRY_index_meta 34
-#define WT_CONFIG_ENTRY_table_meta 35
-#define WT_CONFIG_ENTRY_wiredtiger_open 36
-#define WT_CONFIG_ENTRY_wiredtiger_open_all 37
-#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 38
-#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 39
+#define WT_CONFIG_ENTRY_WT_SESSION_log_flush 19
+#define WT_CONFIG_ENTRY_WT_SESSION_log_printf 20
+#define WT_CONFIG_ENTRY_WT_SESSION_open_cursor 21
+#define WT_CONFIG_ENTRY_WT_SESSION_reconfigure 22
+#define WT_CONFIG_ENTRY_WT_SESSION_rename 23
+#define WT_CONFIG_ENTRY_WT_SESSION_reset 24
+#define WT_CONFIG_ENTRY_WT_SESSION_rollback_transaction 25
+#define WT_CONFIG_ENTRY_WT_SESSION_salvage 26
+#define WT_CONFIG_ENTRY_WT_SESSION_snapshot 27
+#define WT_CONFIG_ENTRY_WT_SESSION_strerror 28
+#define WT_CONFIG_ENTRY_WT_SESSION_transaction_sync 29
+#define WT_CONFIG_ENTRY_WT_SESSION_truncate 30
+#define WT_CONFIG_ENTRY_WT_SESSION_upgrade 31
+#define WT_CONFIG_ENTRY_WT_SESSION_verify 32
+#define WT_CONFIG_ENTRY_colgroup_meta 33
+#define WT_CONFIG_ENTRY_file_meta 34
+#define WT_CONFIG_ENTRY_index_meta 35
+#define WT_CONFIG_ENTRY_table_meta 36
+#define WT_CONFIG_ENTRY_wiredtiger_open 37
+#define WT_CONFIG_ENTRY_wiredtiger_open_all 38
+#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 39
+#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 40
/*
* configuration section: END
* DO NOT EDIT: automatically built by dist/flags.py.
diff --git a/src/include/extern.h b/src/include/extern.h
index 2e447bcfffe..e88fffde120 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -325,7 +325,7 @@ extern int __wt_cache_dump(WT_SESSION_IMPL *session, const char *ofile);
extern int __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, int closing);
extern int __wt_evict_page_clean_update(WT_SESSION_IMPL *session, WT_REF *ref, int closing);
extern int __wt_log_ckpt(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn);
-extern int __wt_log_ckpt_lsn(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn);
+extern int __wt_log_flush_lsn(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn, int start);
extern int __wt_log_background(WT_SESSION_IMPL *session, WT_LSN *lsn);
extern int __wt_log_force_sync(WT_SESSION_IMPL *session, WT_LSN *min_lsn);
extern int __wt_log_needs_recovery(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn, int *rec);
@@ -343,6 +343,7 @@ extern int __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
extern int __wt_log_force_write(WT_SESSION_IMPL *session, int retry);
extern int __wt_log_write(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, uint32_t flags);
extern int __wt_log_vprintf(WT_SESSION_IMPL *session, const char *fmt, va_list ap);
+extern int __wt_log_flush(WT_SESSION_IMPL *session, uint32_t flags);
extern int __wt_logrec_alloc(WT_SESSION_IMPL *session, size_t size, WT_ITEM **logrecp);
extern void __wt_logrec_free(WT_SESSION_IMPL *session, WT_ITEM **logrecp);
extern int __wt_logrec_read(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *rectypep);
diff --git a/src/include/stat.h b/src/include/stat.h
index cd2c149bc94..2f975b70c40 100644
--- a/src/include/stat.h
+++ b/src/include/stat.h
@@ -316,6 +316,7 @@ struct __wt_connection_stats {
int64_t log_compress_small;
int64_t log_compress_write_fails;
int64_t log_compress_writes;
+ int64_t log_flush;
int64_t log_max_filesize;
int64_t log_prealloc_files;
int64_t log_prealloc_max;
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index 71ba3f41a44..e4f2fdfc761 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -1236,6 +1236,20 @@ struct __wt_session {
const char *name, const char *config);
/*!
+ * Flush the log.
+ *
+ * @param session the session handle
+ * @configstart{WT_SESSION.log_flush, see dist/api_data.py}
+ * @config{sync, forcibly flush the log and wait for it to achieve the
+ * synchronization level specified., a string\, chosen from the
+ * following options: \c "background"\, \c "sync"\, \c "write"; default
+ * empty.}
+ * @configend
+ * @errors
+ */
+ int __F(log_flush)(WT_SESSION *session, const char *config);
+
+ /*!
* Insert a ::WT_LOGREC_MESSAGE type record in the database log files
* (the database must be configured for logging when this method is
* called).
@@ -3727,130 +3741,132 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1087
/*! log: log records compressed */
#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1088
+/*! log: log flush calls */
+#define WT_STAT_CONN_LOG_FLUSH 1089
/*! log: maximum log file size */
-#define WT_STAT_CONN_LOG_MAX_FILESIZE 1089
+#define WT_STAT_CONN_LOG_MAX_FILESIZE 1090
/*! log: pre-allocated log files prepared */
-#define WT_STAT_CONN_LOG_PREALLOC_FILES 1090
+#define WT_STAT_CONN_LOG_PREALLOC_FILES 1091
/*! log: number of pre-allocated log files to create */
-#define WT_STAT_CONN_LOG_PREALLOC_MAX 1091
+#define WT_STAT_CONN_LOG_PREALLOC_MAX 1092
/*! log: pre-allocated log files used */
-#define WT_STAT_CONN_LOG_PREALLOC_USED 1092
+#define WT_STAT_CONN_LOG_PREALLOC_USED 1093
/*! log: log release advances write LSN */
-#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1093
+#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1094
/*! log: records processed by log scan */
-#define WT_STAT_CONN_LOG_SCAN_RECORDS 1094
+#define WT_STAT_CONN_LOG_SCAN_RECORDS 1095
/*! log: log scan records requiring two reads */
-#define WT_STAT_CONN_LOG_SCAN_REREADS 1095
+#define WT_STAT_CONN_LOG_SCAN_REREADS 1096
/*! log: log scan operations */
-#define WT_STAT_CONN_LOG_SCANS 1096
+#define WT_STAT_CONN_LOG_SCANS 1097
/*! log: consolidated slot closures */
-#define WT_STAT_CONN_LOG_SLOT_CLOSES 1097
+#define WT_STAT_CONN_LOG_SLOT_CLOSES 1098
/*! log: written slots coalesced */
-#define WT_STAT_CONN_LOG_SLOT_COALESCED 1098
+#define WT_STAT_CONN_LOG_SLOT_COALESCED 1099
/*! log: logging bytes consolidated */
-#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1099
+#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1100
/*! log: consolidated slot joins */
-#define WT_STAT_CONN_LOG_SLOT_JOINS 1100
+#define WT_STAT_CONN_LOG_SLOT_JOINS 1101
/*! log: consolidated slot join races */
-#define WT_STAT_CONN_LOG_SLOT_RACES 1101
+#define WT_STAT_CONN_LOG_SLOT_RACES 1102
/*! log: busy returns attempting to switch slots */
-#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1102
+#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1103
/*! log: consolidated slot join transitions */
-#define WT_STAT_CONN_LOG_SLOT_TRANSITIONS 1103
+#define WT_STAT_CONN_LOG_SLOT_TRANSITIONS 1104
/*! log: consolidated slot unbuffered writes */
-#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1104
+#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1105
/*! log: log sync operations */
-#define WT_STAT_CONN_LOG_SYNC 1105
+#define WT_STAT_CONN_LOG_SYNC 1106
/*! log: log sync_dir operations */
-#define WT_STAT_CONN_LOG_SYNC_DIR 1106
+#define WT_STAT_CONN_LOG_SYNC_DIR 1107
/*! log: log server thread advances write LSN */
-#define WT_STAT_CONN_LOG_WRITE_LSN 1107
+#define WT_STAT_CONN_LOG_WRITE_LSN 1108
/*! log: log write operations */
-#define WT_STAT_CONN_LOG_WRITES 1108
+#define WT_STAT_CONN_LOG_WRITES 1109
/*! LSM: sleep for LSM checkpoint throttle */
-#define WT_STAT_CONN_LSM_CHECKPOINT_THROTTLE 1109
+#define WT_STAT_CONN_LSM_CHECKPOINT_THROTTLE 1110
/*! LSM: sleep for LSM merge throttle */
-#define WT_STAT_CONN_LSM_MERGE_THROTTLE 1110
+#define WT_STAT_CONN_LSM_MERGE_THROTTLE 1111
/*! LSM: rows merged in an LSM tree */
-#define WT_STAT_CONN_LSM_ROWS_MERGED 1111
+#define WT_STAT_CONN_LSM_ROWS_MERGED 1112
/*! LSM: application work units currently queued */
-#define WT_STAT_CONN_LSM_WORK_QUEUE_APP 1112
+#define WT_STAT_CONN_LSM_WORK_QUEUE_APP 1113
/*! LSM: merge work units currently queued */
-#define WT_STAT_CONN_LSM_WORK_QUEUE_MANAGER 1113
+#define WT_STAT_CONN_LSM_WORK_QUEUE_MANAGER 1114
/*! LSM: tree queue hit maximum */
-#define WT_STAT_CONN_LSM_WORK_QUEUE_MAX 1114
+#define WT_STAT_CONN_LSM_WORK_QUEUE_MAX 1115
/*! LSM: switch work units currently queued */
-#define WT_STAT_CONN_LSM_WORK_QUEUE_SWITCH 1115
+#define WT_STAT_CONN_LSM_WORK_QUEUE_SWITCH 1116
/*! LSM: tree maintenance operations scheduled */
-#define WT_STAT_CONN_LSM_WORK_UNITS_CREATED 1116
+#define WT_STAT_CONN_LSM_WORK_UNITS_CREATED 1117
/*! LSM: tree maintenance operations discarded */
-#define WT_STAT_CONN_LSM_WORK_UNITS_DISCARDED 1117
+#define WT_STAT_CONN_LSM_WORK_UNITS_DISCARDED 1118
/*! LSM: tree maintenance operations executed */
-#define WT_STAT_CONN_LSM_WORK_UNITS_DONE 1118
+#define WT_STAT_CONN_LSM_WORK_UNITS_DONE 1119
/*! connection: memory allocations */
-#define WT_STAT_CONN_MEMORY_ALLOCATION 1119
+#define WT_STAT_CONN_MEMORY_ALLOCATION 1120
/*! connection: memory frees */
-#define WT_STAT_CONN_MEMORY_FREE 1120
+#define WT_STAT_CONN_MEMORY_FREE 1121
/*! connection: memory re-allocations */
-#define WT_STAT_CONN_MEMORY_GROW 1121
+#define WT_STAT_CONN_MEMORY_GROW 1122
/*! thread-yield: page acquire busy blocked */
-#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1122
+#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1123
/*! thread-yield: page acquire eviction blocked */
-#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1123
+#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1124
/*! thread-yield: page acquire locked blocked */
-#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1124
+#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1125
/*! thread-yield: page acquire read blocked */
-#define WT_STAT_CONN_PAGE_READ_BLOCKED 1125
+#define WT_STAT_CONN_PAGE_READ_BLOCKED 1126
/*! thread-yield: page acquire time sleeping (usecs) */
-#define WT_STAT_CONN_PAGE_SLEEP 1126
+#define WT_STAT_CONN_PAGE_SLEEP 1127
/*! connection: total read I/Os */
-#define WT_STAT_CONN_READ_IO 1127
+#define WT_STAT_CONN_READ_IO 1128
/*! reconciliation: page reconciliation calls */
-#define WT_STAT_CONN_REC_PAGES 1128
+#define WT_STAT_CONN_REC_PAGES 1129
/*! reconciliation: page reconciliation calls for eviction */
-#define WT_STAT_CONN_REC_PAGES_EVICTION 1129
+#define WT_STAT_CONN_REC_PAGES_EVICTION 1130
/*! reconciliation: split bytes currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1130
+#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1131
/*! reconciliation: split objects currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1131
+#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1132
/*! connection: pthread mutex shared lock read-lock calls */
-#define WT_STAT_CONN_RWLOCK_READ 1132
+#define WT_STAT_CONN_RWLOCK_READ 1133
/*! connection: pthread mutex shared lock write-lock calls */
-#define WT_STAT_CONN_RWLOCK_WRITE 1133
+#define WT_STAT_CONN_RWLOCK_WRITE 1134
/*! session: open cursor count */
-#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1134
+#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1135
/*! session: open session count */
-#define WT_STAT_CONN_SESSION_OPEN 1135
+#define WT_STAT_CONN_SESSION_OPEN 1136
/*! transaction: transaction begins */
-#define WT_STAT_CONN_TXN_BEGIN 1136
+#define WT_STAT_CONN_TXN_BEGIN 1137
/*! transaction: transaction checkpoints */
-#define WT_STAT_CONN_TXN_CHECKPOINT 1137
+#define WT_STAT_CONN_TXN_CHECKPOINT 1138
/*! transaction: transaction checkpoint generation */
-#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1138
+#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1139
/*! transaction: transaction checkpoint currently running */
-#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1139
+#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1140
/*! transaction: transaction checkpoint max time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1140
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1141
/*! transaction: transaction checkpoint min time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1141
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1142
/*! transaction: transaction checkpoint most recent time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1142
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1143
/*! transaction: transaction checkpoint total time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1143
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1144
/*! transaction: transactions committed */
-#define WT_STAT_CONN_TXN_COMMIT 1144
+#define WT_STAT_CONN_TXN_COMMIT 1145
/*! transaction: transaction failures due to cache overflow */
-#define WT_STAT_CONN_TXN_FAIL_CACHE 1145
+#define WT_STAT_CONN_TXN_FAIL_CACHE 1146
/*! transaction: transaction range of IDs currently pinned by a checkpoint */
-#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1146
+#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1147
/*! transaction: transaction range of IDs currently pinned */
-#define WT_STAT_CONN_TXN_PINNED_RANGE 1147
+#define WT_STAT_CONN_TXN_PINNED_RANGE 1148
/*! transaction: transactions rolled back */
-#define WT_STAT_CONN_TXN_ROLLBACK 1148
+#define WT_STAT_CONN_TXN_ROLLBACK 1149
/*! transaction: transaction sync calls */
-#define WT_STAT_CONN_TXN_SYNC 1149
+#define WT_STAT_CONN_TXN_SYNC 1150
/*! connection: total write I/Os */
-#define WT_STAT_CONN_WRITE_IO 1150
+#define WT_STAT_CONN_WRITE_IO 1151
/*!
* @}
diff --git a/src/log/log.c b/src/log/log.c
index 4041761d062..b5e23c4cff5 100644
--- a/src/log/log.c
+++ b/src/log/log.c
@@ -34,11 +34,12 @@ __wt_log_ckpt(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn)
}
/*
- * __wt_log_ckpt_lsn --
- * Force out buffered records and return an LSN for checkpoint.
+ * __wt_log_flush_lsn --
+ * Force out buffered records and return the LSN, either the
+ * write_start_lsn or write_lsn depending on the argument.
*/
int
-__wt_log_ckpt_lsn(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn)
+__wt_log_flush_lsn(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn, int start)
{
WT_CONNECTION_IMPL *conn;
WT_LOG *log;
@@ -47,7 +48,10 @@ __wt_log_ckpt_lsn(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn)
log = conn->log;
WT_RET(__wt_log_force_write(session, 1));
WT_RET(__wt_log_wrlsn(session));
- *ckp_lsn = log->write_start_lsn;
+ if (start)
+ *ckp_lsn = log->write_start_lsn;
+ else
+ *ckp_lsn = log->write_lsn;
return (0);
}
@@ -64,6 +68,11 @@ __wt_log_background(WT_SESSION_IMPL *session, WT_LSN *lsn)
conn = S2C(session);
log = conn->log;
+ /*
+ * If a thread already set the LSN to a bigger LSN, we're done.
+ */
+ if (__wt_log_cmp(&session->bg_sync_lsn, lsn) > 0)
+ return (0);
session->bg_sync_lsn = *lsn;
/*
@@ -1878,8 +1887,7 @@ __log_write_internal(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp,
/*
* Advance the background sync LSN if needed.
*/
- if (LF_ISSET(WT_LOG_BACKGROUND) &&
- __wt_log_cmp(&session->bg_sync_lsn, &lsn) <= 0)
+ if (LF_ISSET(WT_LOG_BACKGROUND))
WT_ERR(__wt_log_background(session, &lsn));
err:
@@ -1948,3 +1956,47 @@ __wt_log_vprintf(WT_SESSION_IMPL *session, const char *fmt, va_list ap)
err: __wt_scr_free(session, &logrec);
return (ret);
}
+
+/*
+ * __wt_log_flush --
+ * Forcibly flush the log to the synchronization level specified.
+ * Wait until it has been completed.
+ */
+int
+__wt_log_flush(WT_SESSION_IMPL *session, uint32_t flags)
+{
+ WT_CONNECTION_IMPL *conn;
+ WT_DECL_RET;
+ WT_LOG *log;
+ WT_LSN last_lsn, lsn;
+
+ conn = S2C(session);
+ WT_ASSERT(session, FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED));
+ log = conn->log;
+ last_lsn = log->alloc_lsn;
+ lsn = log->write_lsn;
+ /*
+ * Wait until all current outstanding writes have been written
+ * to the file system.
+ */
+ while (__wt_log_cmp(&last_lsn, &lsn) > 0)
+ WT_RET(__wt_log_flush_lsn(session, &lsn, 0));
+
+ /*
+ * If the user wants only write-no-sync, then we're done.
+ */
+ if (LF_ISSET(WT_LOG_FLUSH))
+ return (0);
+ /*
+ * If the user wants background sync, set the LSN and we're done.
+ */
+ if (LF_ISSET(WT_LOG_BACKGROUND))
+ return (__wt_log_background(session, &lsn));
+
+ /*
+ * If the user wants sync, force it now.
+ */
+ WT_ASSERT(session, LF_ISSET(WT_LOG_FSYNC));
+ WT_RET(__wt_log_force_sync(session, &lsn));
+ return (ret);
+}
diff --git a/src/session/session_api.c b/src/session/session_api.c
index a1f5618a317..dcf60945e2c 100644
--- a/src/session/session_api.c
+++ b/src/session/session_api.c
@@ -445,6 +445,44 @@ err: API_END_RET_NOTFOUND_MAP(session, ret);
}
/*
+ * __session_log_flush --
+ * WT_SESSION->log_flush method.
+ */
+static int
+__session_log_flush(WT_SESSION *wt_session, const char *config)
+{
+ WT_CONFIG_ITEM cval;
+ WT_CONNECTION_IMPL *conn;
+ WT_DECL_RET;
+ WT_LOG *log;
+ WT_SESSION_IMPL *session;
+ uint32_t flags;
+
+ session = (WT_SESSION_IMPL *)wt_session;
+ SESSION_API_CALL(session, log_flush, config, cfg);
+ WT_STAT_FAST_CONN_INCR(session, log_flush);
+
+ conn = S2C(session);
+ /*
+ * If logging is not enabled there is nothing to do.
+ */
+ if (!FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED))
+ WT_ERR_MSG(session, EINVAL, "logging not enabled");
+
+ log = conn->log;
+ WT_ERR(__wt_config_gets_def(session, cfg, "sync", 0, &cval));
+ if (WT_STRING_MATCH("background", cval.str, cval.len))
+ flags = WT_LOG_BACKGROUND;
+ else if (WT_STRING_MATCH("sync", cval.str, cval.len))
+ flags = WT_LOG_FSYNC;
+ else if (WT_STRING_MATCH("write", cval.str, cval.len))
+ flags = WT_LOG_FLUSH;
+ ret = __wt_log_flush(session, flags);
+
+err: API_END_RET(session, ret);
+}
+
+/*
* __session_log_printf --
* WT_SESSION->log_printf method.
*/
@@ -1152,6 +1190,7 @@ __wt_open_session(WT_CONNECTION_IMPL *conn,
__session_create,
__session_compact,
__session_drop,
+ __session_log_flush,
__session_log_printf,
__session_rename,
__session_reset,
diff --git a/src/support/stat.c b/src/support/stat.c
index 79248b0652c..bbe8cb22582 100644
--- a/src/support/stat.c
+++ b/src/support/stat.c
@@ -573,6 +573,7 @@ static const char * const __stats_connection_desc[] = {
"log: log records too small to compress",
"log: log records not compressed",
"log: log records compressed",
+ "log: log flush calls",
"log: maximum log file size",
"log: pre-allocated log files prepared",
"log: number of pre-allocated log files to create",
@@ -758,6 +759,7 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
stats->log_slot_unbuffered = 0;
stats->log_bytes_payload = 0;
stats->log_bytes_written = 0;
+ stats->log_flush = 0;
stats->log_compress_writes = 0;
stats->log_compress_write_fails = 0;
stats->log_compress_small = 0;
@@ -940,6 +942,7 @@ __wt_stat_connection_aggregate(
to->log_slot_unbuffered += WT_STAT_READ(from, log_slot_unbuffered);
to->log_bytes_payload += WT_STAT_READ(from, log_bytes_payload);
to->log_bytes_written += WT_STAT_READ(from, log_bytes_written);
+ to->log_flush += WT_STAT_READ(from, log_flush);
to->log_compress_writes += WT_STAT_READ(from, log_compress_writes);
to->log_compress_write_fails +=
WT_STAT_READ(from, log_compress_write_fails);
diff --git a/src/txn/txn_log.c b/src/txn/txn_log.c
index 0966558b177..7a53fb65b1f 100644
--- a/src/txn/txn_log.c
+++ b/src/txn/txn_log.c
@@ -307,7 +307,7 @@ __wt_txn_checkpoint_log(
switch (flags) {
case WT_TXN_LOG_CKPT_PREPARE:
txn->full_ckpt = 1;
- WT_ERR(__wt_log_ckpt_lsn(session, ckpt_lsn));
+ WT_ERR(__wt_log_flush_lsn(session, ckpt_lsn, 1));
/*
* We need to make sure that the log records in the checkpoint
* LSN are on disk. In particular to make sure that the
@@ -336,7 +336,7 @@ __wt_txn_checkpoint_log(
txn->ckpt_nsnapshot = 0;
WT_CLEAR(empty);
ckpt_snapshot = &empty;
- WT_ERR(__wt_log_ckpt_lsn(session, ckpt_lsn));
+ WT_ERR(__wt_log_flush_lsn(session, ckpt_lsn, 1));
} else
ckpt_snapshot = txn->ckpt_snapshot;