diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2016-11-16 21:10:29 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2016-11-16 21:10:29 +1100 |
commit | fb4ae3792065e98696e391ac1c4602216b8502cb (patch) | |
tree | 7d6ab84b45c4eb26bbe59e73a3950e9aa2233f41 /src/third_party/wiredtiger/src/log/log.c | |
parent | 6904d0ac5ea4bba1822103eb4e7a623cc81de641 (diff) | |
download | mongo-fb4ae3792065e98696e391ac1c4602216b8502cb.tar.gz |
Import wiredtiger: ca6eee06ffdacc8e191987e64b3791740dad21e1 from branch mongodb-3.4
ref: 74430da40c..ca6eee06ff
for: 3.4.0
WT-2962 Provide a way to configure builtin extensions
WT-2984 Search of metadata for recently created collection gets WT_NOTFOUND
WT-3000 Missing log records in recovery when crashing after a log file switch
WT-3002 Allow applications to exempt threads from eviction.
WT-3004 lint: declare functions that don't return a value as void
WT-3011 __wt_curjoin_open() saves the wrong URI in the cursor.
WT-3012 Test format hanging on LSM configurations
WT-3015 Test format stuck with 2mb cache
WT-3016 Tests needed for systems without ftruncate
WT-3017 Hazard pointer race with page replace causes error
WT-3018 lint
WT-3020 LSM primary changes impact parallel-pop-lsm load time
WT-3022 LSM operations get stuck in __wt_clsm_await_switch waiting for switch on tree to complete
WT-3023 Test format hang on zSeries
WT-3024 wtperf medium-lsm-compact test can hang
Diffstat (limited to 'src/third_party/wiredtiger/src/log/log.c')
-rw-r--r-- | src/third_party/wiredtiger/src/log/log.c | 80 |
1 files changed, 57 insertions, 23 deletions
diff --git a/src/third_party/wiredtiger/src/log/log.c b/src/third_party/wiredtiger/src/log/log.c index 00e4ea5f441..8b6c8b2c490 100644 --- a/src/third_party/wiredtiger/src/log/log.c +++ b/src/third_party/wiredtiger/src/log/log.c @@ -21,6 +21,60 @@ static int __log_write_internal( #define WT_LOG_OPEN_VERIFY 0x02 /* + * __log_wait_for_earlier_slot -- + * Wait for write_lsn to catch up to this slot. + */ +static void +__log_wait_for_earlier_slot(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) +{ + WT_CONNECTION_IMPL *conn; + WT_LOG *log; + int yield_count; + + conn = S2C(session); + log = conn->log; + yield_count = 0; + + while (__wt_log_cmp(&log->write_lsn, &slot->slot_release_lsn) != 0) { + /* + * If we're on a locked path and the write LSN is not advancing, + * unlock in case an earlier thread is trying to switch its + * slot and complete its operation. + */ + if (F_ISSET(session, WT_SESSION_LOCKED_SLOT)) + __wt_spin_unlock(session, &log->log_slot_lock); + __wt_cond_auto_signal(session, conn->log_wrlsn_cond); + if (++yield_count < WT_THOUSAND) + __wt_yield(); + else + __wt_cond_wait(session, log->log_write_cond, 200); + if (F_ISSET(session, WT_SESSION_LOCKED_SLOT)) + __wt_spin_lock(session, &log->log_slot_lock); + } +} + +/* + * __log_fs_write -- + * Wrapper when writing to a log file. If we're writing to a new log + * file for the first time wait for writes to the previous log file. + */ +static int +__log_fs_write(WT_SESSION_IMPL *session, + WT_LOGSLOT *slot, wt_off_t offset, size_t len, const void *buf) +{ + /* + * If we're writing into a new log file, we have to wait for all + * writes to the previous log file to complete otherwise there could + * be a hole at the end of the previous log file that we cannot detect. + */ + if (slot->slot_release_lsn.l.file < slot->slot_start_lsn.l.file) { + __log_wait_for_earlier_slot(session, slot); + WT_RET(__wt_log_force_sync(session, &slot->slot_release_lsn)); + } + return (__wt_write(session, slot->slot_fh, offset, len, buf)); +} + +/* * __wt_log_ckpt -- * Record the given LSN as the checkpoint LSN and signal the archive * thread as needed. @@ -371,8 +425,6 @@ __wt_log_extract_lognum( { const char *p; - WT_UNUSED(session); - if (id == NULL || name == NULL) return (WT_ERROR); if ((p = strrchr(name, '.')) == NULL || @@ -576,7 +628,7 @@ __log_fill(WT_SESSION_IMPL *session, /* * If this is a force or unbuffered write, write it now. */ - WT_ERR(__wt_write(session, myslot->slot->slot_fh, + WT_ERR(__log_fs_write(session, myslot->slot, myslot->offset + myslot->slot->slot_start_offset, record->size, record->mem)); @@ -1352,13 +1404,11 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) WT_LSN sync_lsn; int64_t release_buffered, release_bytes; uint64_t fsync_duration_usecs; - int yield_count; bool locked; conn = S2C(session); log = conn->log; locked = false; - yield_count = 0; if (freep != NULL) *freep = 1; release_buffered = WT_LOG_SLOT_RELEASED_BUFFERED(slot->slot_state); @@ -1379,8 +1429,7 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) /* Write the buffered records */ if (release_buffered != 0) - WT_ERR(__wt_write(session, - slot->slot_fh, slot->slot_start_offset, + WT_ERR(__log_fs_write(session, slot, slot->slot_start_offset, (size_t)release_buffered, slot->slot_buf.mem)); /* @@ -1411,22 +1460,7 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) * be holes in the log file. */ WT_STAT_CONN_INCR(session, log_release_write_lsn); - while (__wt_log_cmp(&log->write_lsn, &slot->slot_release_lsn) != 0) { - /* - * If we're on a locked path and the write LSN is not advancing, - * unlock in case an earlier thread is trying to switch its - * slot and complete its operation. - */ - if (F_ISSET(session, WT_SESSION_LOCKED_SLOT)) - __wt_spin_unlock(session, &log->log_slot_lock); - __wt_cond_auto_signal(session, conn->log_wrlsn_cond); - if (++yield_count < WT_THOUSAND) - __wt_yield(); - else - __wt_cond_wait(session, log->log_write_cond, 200); - if (F_ISSET(session, WT_SESSION_LOCKED_SLOT)) - __wt_spin_lock(session, &log->log_slot_lock); - } + __log_wait_for_earlier_slot(session, slot); log->write_start_lsn = slot->slot_start_lsn; log->write_lsn = slot->slot_end_lsn; |