diff options
author | Susan LoVerso <sue@wiredtiger.com> | 2015-09-15 13:35:11 -0400 |
---|---|---|
committer | Susan LoVerso <sue@wiredtiger.com> | 2015-09-15 13:35:11 -0400 |
commit | 366fc17e0bf9d5bad887f14b2c9e40d8fa13c4bd (patch) | |
tree | 362556f5e737fb950310f71c7f66cf15c0c4c739 | |
parent | 41db2ee37d11b0a885fc883dbcb2a92394e598d1 (diff) | |
download | mongo-366fc17e0bf9d5bad887f14b2c9e40d8fa13c4bd.tar.gz |
WT-2104 New log_flush API to control the flushing or syncing of the log.
-rw-r--r-- | dist/api_data.py | 7 | ||||
-rw-r--r-- | dist/stat_data.py | 1 | ||||
-rw-r--r-- | examples/c/ex_sync.c | 21 | ||||
-rw-r--r-- | lang/java/java_doc.i | 1 | ||||
-rw-r--r-- | src/config/config_def.c | 11 | ||||
-rw-r--r-- | src/include/config.h | 43 | ||||
-rw-r--r-- | src/include/extern.h | 3 | ||||
-rw-r--r-- | src/include/stat.h | 1 | ||||
-rw-r--r-- | src/include/wiredtiger.in | 140 | ||||
-rw-r--r-- | src/log/log.c | 64 | ||||
-rw-r--r-- | src/session/session_api.c | 39 | ||||
-rw-r--r-- | src/support/stat.c | 3 | ||||
-rw-r--r-- | src/txn/txn_log.c | 4 |
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 = ∅ - 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; |