diff options
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_split.c | 8 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/conn/conn_log.c | 4 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/log/log.c | 61 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/txn/txn_log.c | 4 |
4 files changed, 63 insertions, 14 deletions
diff --git a/src/third_party/wiredtiger/src/btree/bt_split.c b/src/third_party/wiredtiger/src/btree/bt_split.c index ca7f2266f2a..4041bbb71b0 100644 --- a/src/third_party/wiredtiger/src/btree/bt_split.c +++ b/src/third_party/wiredtiger/src/btree/bt_split.c @@ -719,6 +719,14 @@ __split_multi_inmem( */ page->modify->first_dirty_txn = WT_TXN_FIRST; + /* + * XXX Don't allow this page to be evicted immediately. + * + * In some cases involving forced eviction during truncates, a reader + * ends up looking at an evicted page. This is a temporary workaround. + */ + page->modify->inmem_split_txn = __wt_txn_new_id(session); + err: /* Free any resources that may have been cached in the cursor. */ WT_TRET(__wt_btcur_close(&cbt)); diff --git a/src/third_party/wiredtiger/src/conn/conn_log.c b/src/third_party/wiredtiger/src/conn/conn_log.c index 2799a58f327..d15b27f9bc9 100644 --- a/src/third_party/wiredtiger/src/conn/conn_log.c +++ b/src/third_party/wiredtiger/src/conn/conn_log.c @@ -126,11 +126,13 @@ __log_archive_once(WT_SESSION_IMPL *session, uint32_t backup_file) /* * If we're coming from a backup cursor we want the smaller of * the last full log file copied in backup or the checkpoint LSN. + * Otherwise we want the minimum of the last log file written to + * disk and the checkpoint LSN. */ if (backup_file != 0) min_lognum = WT_MIN(log->ckpt_lsn.file, backup_file); else - min_lognum = log->ckpt_lsn.file; + min_lognum = WT_MIN(log->ckpt_lsn.file, log->sync_lsn.file); WT_RET(__wt_verbose(session, WT_VERB_LOG, "log_archive: archive to log number %" PRIu32, min_lognum)); diff --git a/src/third_party/wiredtiger/src/log/log.c b/src/third_party/wiredtiger/src/log/log.c index 944e748a6a8..181e77128a9 100644 --- a/src/third_party/wiredtiger/src/log/log.c +++ b/src/third_party/wiredtiger/src/log/log.c @@ -859,7 +859,7 @@ __log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) WT_DECL_RET; WT_FH *close_fh; WT_LOG *log; - WT_LSN sync_lsn; + WT_LSN close_end_lsn, close_lsn, sync_lsn; size_t write_size; int locked; WT_DECL_SPINLOCK_ID(id); /* Must appear last */ @@ -873,8 +873,22 @@ __log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) * of the file handle structure. */ close_fh = NULL; + WT_INIT_LSN(&close_lsn); + WT_INIT_LSN(&close_end_lsn); if (F_ISSET(slot, SLOT_CLOSEFH)) { close_fh = log->log_close_fh; + /* + * Set the close_end_lsn to the LSN immediately after ours. + * That is, the beginning of the next log file. We need to + * know the LSN file number of our own close in case earlier + * calls are still in progress and the next one to move the + * sync_lsn into the next file for later syncs. + */ + WT_ERR(__wt_log_extract_lognum(session, close_fh->name, + &close_lsn.file)); + close_lsn.offset = 0; + close_end_lsn = close_lsn; + close_end_lsn.file++; log->log_close_fh = NULL; F_CLR(slot, SLOT_CLOSEFH); } @@ -896,12 +910,45 @@ __log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) log->write_lsn = slot->slot_end_lsn; /* + * If we have a file to close, close it now. First fsync so + * that a later sync will be assured all earlier transactions + * in earlier log files are also on disk. We have to do this + * before potentially syncing our own operation. + */ + if (close_fh) { + WT_ERR(__wt_fsync(session, close_fh)); + /* + * This loop guarantees sync_lsn is updated in file order + * so that when sync_lsn is updated, we know all earlier files + * have already been fully processed. + */ + while (log->sync_lsn.file < close_lsn.file || + __wt_spin_trylock(session, &log->log_sync_lock, &id) != 0) { + WT_ERR(__wt_cond_wait( + session, log->log_sync_cond, 10000)); + continue; + } + locked = 1; + WT_ERR(__wt_close(session, close_fh)); + log->sync_lsn = close_end_lsn; + WT_ERR(__wt_cond_signal(session, log->log_sync_cond)); + locked = 0; + __wt_spin_unlock(session, &log->log_sync_lock); + } + + /* * Try to consolidate calls to fsync to wait less. Acquire a spin lock * so that threads finishing writing to the log will wait while the * current fsync completes and advance log->sync_lsn. */ while (F_ISSET(slot, SLOT_SYNC | SLOT_SYNC_DIR)) { - if (__wt_spin_trylock(session, &log->log_sync_lock, &id) != 0) { + /* + * We have to wait until earlier log files have finished their + * sync operations. The most recent one will set the LSN to the + * beginning of our file. + */ + if (log->sync_lsn.file < slot->slot_end_lsn.file || + __wt_spin_trylock(session, &log->log_sync_lock, &id) != 0) { WT_ERR(__wt_cond_wait( session, log->log_sync_cond, 10000)); continue; @@ -956,16 +1003,6 @@ __log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) WT_ERR(__wt_buf_grow(session, &slot->slot_buf, slot->slot_buf.memsize * 2)); } - /* - * If we have a file to close, close it now. First fsync so - * that a later sync will be assured all earlier transactions - * in earlier log files are also on disk. - */ - if (close_fh) { - WT_ERR(__wt_fsync(session, close_fh)); - WT_ERR(__wt_close(session, close_fh)); - } - err: if (locked) __wt_spin_unlock(session, &log->log_sync_lock); if (ret != 0 && slot->slot_error == 0) diff --git a/src/third_party/wiredtiger/src/txn/txn_log.c b/src/third_party/wiredtiger/src/txn/txn_log.c index f706efa8a70..789be2ceef4 100644 --- a/src/third_party/wiredtiger/src/txn/txn_log.c +++ b/src/third_party/wiredtiger/src/txn/txn_log.c @@ -337,7 +337,9 @@ __wt_txn_checkpoint_log( rectype, ckpt_lsn->file, ckpt_lsn->offset, txn->ckpt_nsnapshot, ckpt_snapshot)); logrec->size += (uint32_t)recsize; - WT_ERR(__wt_log_write(session, logrec, lsnp, 0)); + WT_ERR(__wt_log_write(session, logrec, lsnp, + F_ISSET(S2C(session), WT_CONN_CKPT_SYNC) ? + WT_LOG_FSYNC : 0)); /* * If this full checkpoint completed successfully and there is |