summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2015-09-18 17:17:34 +1000
committerMichael Cahill <michael.cahill@mongodb.com>2015-09-18 17:17:34 +1000
commit881f00984ce2692b81154d5ea3d5fb589b484c70 (patch)
tree5a9b5aeaf3c6023457dd08dbb9e26150b45a7f14 /src/third_party/wiredtiger/src
parent250b05a6184b559dc5c2e3ee53c3183a70f47fd2 (diff)
downloadmongo-881f00984ce2692b81154d5ea3d5fb589b484c70.tar.gz
Import wiredtiger-wiredtiger-2.6.1-1119-g16e3e48.tar.gz from wiredtiger branch mongodb-3.2
Diffstat (limited to 'src/third_party/wiredtiger/src')
-rw-r--r--src/third_party/wiredtiger/src/async/async_op.c16
-rw-r--r--src/third_party/wiredtiger/src/block/block_addr.c10
-rw-r--r--src/third_party/wiredtiger/src/block/block_mgr.c28
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_curnext.c12
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_curprev.c12
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_delete.c4
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_slvg.c73
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_split.c7
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_vrfy_dsk.c84
-rw-r--r--src/third_party/wiredtiger/src/btree/row_srch.c16
-rw-r--r--src/third_party/wiredtiger/src/config/config_def.c13
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_cache.c5
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_log.c3
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_lru.c45
-rw-r--r--src/third_party/wiredtiger/src/include/block.h3
-rw-r--r--src/third_party/wiredtiger/src/include/cache.h2
-rw-r--r--src/third_party/wiredtiger/src/include/cell.i26
-rw-r--r--src/third_party/wiredtiger/src/include/config.h43
-rw-r--r--src/third_party/wiredtiger/src/include/error.h32
-rw-r--r--src/third_party/wiredtiger/src/include/extern.h9
-rw-r--r--src/third_party/wiredtiger/src/include/intpack.i32
-rw-r--r--src/third_party/wiredtiger/src/include/packing.i40
-rw-r--r--src/third_party/wiredtiger/src/include/serial.i27
-rw-r--r--src/third_party/wiredtiger/src/include/stat.h1
-rw-r--r--src/third_party/wiredtiger/src/include/wiredtiger.in156
-rw-r--r--src/third_party/wiredtiger/src/log/log.c115
-rw-r--r--src/third_party/wiredtiger/src/log/log_slot.c59
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_track.c2
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_write.c7
-rw-r--r--src/third_party/wiredtiger/src/session/session_api.c38
-rw-r--r--src/third_party/wiredtiger/src/support/stat.c3
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_log.c12
32 files changed, 513 insertions, 422 deletions
diff --git a/src/third_party/wiredtiger/src/async/async_op.c b/src/third_party/wiredtiger/src/async/async_op.c
index 469dbc8e615..7661a4383d6 100644
--- a/src/third_party/wiredtiger/src/async/async_op.c
+++ b/src/third_party/wiredtiger/src/async/async_op.c
@@ -31,18 +31,16 @@ static void
__async_set_key(WT_ASYNC_OP *asyncop, ...)
{
WT_CURSOR *c;
- WT_DECL_RET;
va_list ap;
c = &asyncop->c;
va_start(ap, asyncop);
__wt_cursor_set_keyv(c, c->flags, ap);
if (!WT_DATA_IN_ITEM(&c->key) && !WT_CURSOR_RECNO(c))
- WT_ERR(__wt_buf_set(O2S((WT_ASYNC_OP_IMPL *)asyncop), &c->key,
- c->key.data, c->key.size));
+ c->saved_err = __wt_buf_set(
+ O2S((WT_ASYNC_OP_IMPL *)asyncop),
+ &c->key, c->key.data, c->key.size);
va_end(ap);
- if (0)
-err: c->saved_err = ret;
}
/*
@@ -69,7 +67,6 @@ static void
__async_set_value(WT_ASYNC_OP *asyncop, ...)
{
WT_CURSOR *c;
- WT_DECL_RET;
va_list ap;
c = &asyncop->c;
@@ -77,11 +74,10 @@ __async_set_value(WT_ASYNC_OP *asyncop, ...)
__wt_cursor_set_valuev(c, ap);
/* Copy the data, if it is pointing at data elsewhere. */
if (!WT_DATA_IN_ITEM(&c->value))
- WT_ERR(__wt_buf_set(O2S((WT_ASYNC_OP_IMPL *)asyncop),
- &c->value, c->value.data, c->value.size));
+ c->saved_err = __wt_buf_set(
+ O2S((WT_ASYNC_OP_IMPL *)asyncop),
+ &c->value, c->value.data, c->value.size);
va_end(ap);
- if (0)
-err: c->saved_err = ret;
}
/*
diff --git a/src/third_party/wiredtiger/src/block/block_addr.c b/src/third_party/wiredtiger/src/block/block_addr.c
index 6b5610eb17c..3099f5ba8dc 100644
--- a/src/third_party/wiredtiger/src/block/block_addr.c
+++ b/src/third_party/wiredtiger/src/block/block_addr.c
@@ -84,11 +84,11 @@ __wt_block_buffer_to_addr(WT_BLOCK *block,
}
/*
- * __wt_block_addr_valid --
- * Return if an address cookie is valid.
+ * __wt_block_addr_invalid --
+ * Return an error code if an address cookie is invalid.
*/
int
-__wt_block_addr_valid(WT_SESSION_IMPL *session,
+__wt_block_addr_invalid(WT_SESSION_IMPL *session,
WT_BLOCK *block, const uint8_t *addr, size_t addr_size, int live)
{
wt_off_t offset;
@@ -110,8 +110,8 @@ __wt_block_addr_valid(WT_SESSION_IMPL *session,
session, block, "addr-valid", offset, size, live));
#endif
- /* Check if it's past the end of the file. */
- return (offset + size > block->fh->size ? 0 : 1);
+ /* Check if the address is past the end of the file. */
+ return (offset + size > block->fh->size ? EINVAL : 0);
}
/*
diff --git a/src/third_party/wiredtiger/src/block/block_mgr.c b/src/third_party/wiredtiger/src/block/block_mgr.c
index 558008ee7b0..015c574da8c 100644
--- a/src/third_party/wiredtiger/src/block/block_mgr.c
+++ b/src/third_party/wiredtiger/src/block/block_mgr.c
@@ -23,27 +23,27 @@ __bm_readonly(WT_BM *bm, WT_SESSION_IMPL *session)
}
/*
- * __bm_addr_string --
- * Return a printable string representation of an address cookie.
+ * __bm_addr_invalid --
+ * Return an error code if an address cookie is invalid.
*/
static int
-__bm_addr_string(WT_BM *bm, WT_SESSION_IMPL *session,
- WT_ITEM *buf, const uint8_t *addr, size_t addr_size)
+__bm_addr_invalid(WT_BM *bm,
+ WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size)
{
- return (
- __wt_block_addr_string(session, bm->block, buf, addr, addr_size));
+ return (__wt_block_addr_invalid(
+ session, bm->block, addr, addr_size, bm->is_live));
}
/*
- * __bm_addr_valid --
- * Return if an address cookie is valid.
+ * __bm_addr_string --
+ * Return a printable string representation of an address cookie.
*/
static int
-__bm_addr_valid(WT_BM *bm,
- WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size)
+__bm_addr_string(WT_BM *bm, WT_SESSION_IMPL *session,
+ WT_ITEM *buf, const uint8_t *addr, size_t addr_size)
{
- return (__wt_block_addr_valid(
- session, bm->block, addr, addr_size, bm->is_live));
+ return (
+ __wt_block_addr_string(session, bm->block, buf, addr, addr_size));
}
/*
@@ -337,8 +337,8 @@ static void
__bm_method_set(WT_BM *bm, int readonly)
{
if (readonly) {
+ bm->addr_invalid = __bm_addr_invalid;
bm->addr_string = __bm_addr_string;
- bm->addr_valid = __bm_addr_valid;
bm->block_header = __bm_block_header;
bm->checkpoint = (int (*)(WT_BM *,
WT_SESSION_IMPL *, WT_ITEM *, WT_CKPT *, int))__bm_readonly;
@@ -378,8 +378,8 @@ __bm_method_set(WT_BM *bm, int readonly)
bm->write_size = (int (*)
(WT_BM *, WT_SESSION_IMPL *, size_t *))__bm_readonly;
} else {
+ bm->addr_invalid = __bm_addr_invalid;
bm->addr_string = __bm_addr_string;
- bm->addr_valid = __bm_addr_valid;
bm->block_header = __bm_block_header;
bm->checkpoint = __bm_checkpoint;
bm->checkpoint_load = __bm_checkpoint_load;
diff --git a/src/third_party/wiredtiger/src/btree/bt_curnext.c b/src/third_party/wiredtiger/src/btree/bt_curnext.c
index c4cbde25d12..49650efcdd4 100644
--- a/src/third_party/wiredtiger/src/btree/bt_curnext.c
+++ b/src/third_party/wiredtiger/src/btree/bt_curnext.c
@@ -144,7 +144,8 @@ new_page: if (cbt->ins == NULL)
if ((upd = __wt_txn_read(session, cbt->ins->upd)) == NULL)
continue;
if (WT_UPDATE_DELETED_ISSET(upd)) {
- ++cbt->page_deleted_count;
+ if (__wt_txn_visible_all(session, upd->txnid))
+ ++cbt->page_deleted_count;
continue;
}
val->data = WT_UPDATE_DATA(upd);
@@ -205,7 +206,8 @@ new_page: /* Find the matching WT_COL slot. */
NULL : __wt_txn_read(session, cbt->ins->upd);
if (upd != NULL) {
if (WT_UPDATE_DELETED_ISSET(upd)) {
- ++cbt->page_deleted_count;
+ if (__wt_txn_visible_all(session, upd->txnid))
+ ++cbt->page_deleted_count;
continue;
}
@@ -323,7 +325,8 @@ new_insert: if ((ins = cbt->ins) != NULL) {
if ((upd = __wt_txn_read(session, ins->upd)) == NULL)
continue;
if (WT_UPDATE_DELETED_ISSET(upd)) {
- ++cbt->page_deleted_count;
+ if (__wt_txn_visible_all(session, upd->txnid))
+ ++cbt->page_deleted_count;
continue;
}
key->data = WT_INSERT_KEY(ins);
@@ -355,7 +358,8 @@ new_insert: if ((ins = cbt->ins) != NULL) {
rip = &page->pg_row_d[cbt->slot];
upd = __wt_txn_read(session, WT_ROW_UPDATE(page, rip));
if (upd != NULL && WT_UPDATE_DELETED_ISSET(upd)) {
- ++cbt->page_deleted_count;
+ if (__wt_txn_visible_all(session, upd->txnid))
+ ++cbt->page_deleted_count;
continue;
}
diff --git a/src/third_party/wiredtiger/src/btree/bt_curprev.c b/src/third_party/wiredtiger/src/btree/bt_curprev.c
index 3ff020510f9..b514d9b8bb6 100644
--- a/src/third_party/wiredtiger/src/btree/bt_curprev.c
+++ b/src/third_party/wiredtiger/src/btree/bt_curprev.c
@@ -281,7 +281,8 @@ new_page: if (cbt->ins == NULL)
if ((upd = __wt_txn_read(session, cbt->ins->upd)) == NULL)
continue;
if (WT_UPDATE_DELETED_ISSET(upd)) {
- ++cbt->page_deleted_count;
+ if (__wt_txn_visible_all(session, upd->txnid))
+ ++cbt->page_deleted_count;
continue;
}
val->data = WT_UPDATE_DATA(upd);
@@ -343,7 +344,8 @@ new_page: if (cbt->recno < page->pg_var_recno)
NULL : __wt_txn_read(session, cbt->ins->upd);
if (upd != NULL) {
if (WT_UPDATE_DELETED_ISSET(upd)) {
- ++cbt->page_deleted_count;
+ if (__wt_txn_visible_all(session, upd->txnid))
+ ++cbt->page_deleted_count;
continue;
}
@@ -471,7 +473,8 @@ new_insert: if ((ins = cbt->ins) != NULL) {
if ((upd = __wt_txn_read(session, ins->upd)) == NULL)
continue;
if (WT_UPDATE_DELETED_ISSET(upd)) {
- ++cbt->page_deleted_count;
+ if (__wt_txn_visible_all(session, upd->txnid))
+ ++cbt->page_deleted_count;
continue;
}
key->data = WT_INSERT_KEY(ins);
@@ -505,7 +508,8 @@ new_insert: if ((ins = cbt->ins) != NULL) {
rip = &page->pg_row_d[cbt->slot];
upd = __wt_txn_read(session, WT_ROW_UPDATE(page, rip));
if (upd != NULL && WT_UPDATE_DELETED_ISSET(upd)) {
- ++cbt->page_deleted_count;
+ if (__wt_txn_visible_all(session, upd->txnid))
+ ++cbt->page_deleted_count;
continue;
}
diff --git a/src/third_party/wiredtiger/src/btree/bt_delete.c b/src/third_party/wiredtiger/src/btree/bt_delete.c
index 0d512b13c5e..c3c7afa1450 100644
--- a/src/third_party/wiredtiger/src/btree/bt_delete.c
+++ b/src/third_party/wiredtiger/src/btree/bt_delete.c
@@ -245,8 +245,8 @@ __wt_delete_page_skip(WT_SESSION_IMPL *session, WT_REF *ref)
if (!__wt_atomic_casv32(&ref->state, WT_REF_DELETED, WT_REF_LOCKED))
return (false);
- skip = (ref->page_del == NULL ||
- __wt_txn_visible(session, ref->page_del->txnid));
+ skip = ref->page_del == NULL ||
+ __wt_txn_visible(session, ref->page_del->txnid);
WT_PUBLISH(ref->state, WT_REF_DELETED);
return (skip);
diff --git a/src/third_party/wiredtiger/src/btree/bt_slvg.c b/src/third_party/wiredtiger/src/btree/bt_slvg.c
index c2a211bdd2d..0edbe75ba60 100644
--- a/src/third_party/wiredtiger/src/btree/bt_slvg.c
+++ b/src/third_party/wiredtiger/src/btree/bt_slvg.c
@@ -153,7 +153,6 @@ static int __slvg_trk_leaf_ovfl(
WT_SESSION_IMPL *, const WT_PAGE_HEADER *, WT_TRACK *);
static int __slvg_trk_ovfl(WT_SESSION_IMPL *,
const WT_PAGE_HEADER *, uint8_t *, size_t, WT_STUFF *);
-static int __slvg_trk_split(WT_SESSION_IMPL *, WT_TRACK *, WT_TRACK **);
/*
* __wt_bt_salvage --
@@ -512,26 +511,6 @@ err: __wt_free(session, trk->trk_addr);
}
/*
- * __slvg_trk_split --
- * Split a tracked chunk.
- */
-static int
-__slvg_trk_split(WT_SESSION_IMPL *session, WT_TRACK *orig, WT_TRACK **newp)
-{
- WT_TRACK *trk;
-
- WT_RET(__wt_calloc_one(session, &trk));
-
- trk->shared = orig->shared;
- trk->ss = orig->ss;
-
- ++orig->shared->ref;
-
- *newp = trk;
- return (0);
-}
-
-/*
* __slvg_trk_leaf --
* Track a leaf page.
*/
@@ -872,6 +851,7 @@ static int
__slvg_col_range_overlap(
WT_SESSION_IMPL *session, uint32_t a_slot, uint32_t b_slot, WT_STUFF *ss)
{
+ WT_DECL_RET;
WT_TRACK *a_trk, *b_trk, *new;
uint32_t i;
@@ -1016,16 +996,29 @@ delete_b: /*
* Case #5: b_trk is more desirable and is a middle chunk of a_trk.
* Split a_trk into two parts, the key range before b_trk and the
* key range after b_trk.
+ *
+ * Allocate a new WT_TRACK object, and extend the array of pages as
+ * necessary.
*/
- WT_RET(__slvg_trk_split(session, a_trk, &new));
+ WT_RET(__wt_calloc_one(session, &new));
+ if ((ret = __wt_realloc_def(session,
+ &ss->pages_allocated, ss->pages_next + 1, &ss->pages)) != 0) {
+ __wt_free(session, new);
+ return (ret);
+ }
/*
- * Second, reallocate the array of pages if necessary, and then insert
- * the new element into the array after the existing element (that's
- * probably wrong, but we'll fix it up in a second).
+ * First, set up the track share (we do this after the allocation to
+ * ensure the shared reference count is never incorrect).
+ */
+ new->shared = a_trk->shared;
+ new->ss = a_trk->ss;
+ ++new->shared->ref;
+
+ /*
+ * Second, insert the new element into the array after the existing
+ * element (that's probably wrong, but we'll fix it up in a second).
*/
- WT_RET(__wt_realloc_def(
- session, &ss->pages_allocated, ss->pages_next + 1, &ss->pages));
memmove(ss->pages + a_slot + 1, ss->pages + a_slot,
(ss->pages_next - a_slot) * sizeof(*ss->pages));
ss->pages[a_slot + 1] = new;
@@ -1489,6 +1482,7 @@ __slvg_row_range_overlap(
WT_SESSION_IMPL *session, uint32_t a_slot, uint32_t b_slot, WT_STUFF *ss)
{
WT_BTREE *btree;
+ WT_DECL_RET;
WT_TRACK *a_trk, *b_trk, *new;
uint32_t i;
int start_cmp, stop_cmp;
@@ -1649,16 +1643,29 @@ delete_b: /*
* Case #5: b_trk is more desirable and is a middle chunk of a_trk.
* Split a_trk into two parts, the key range before b_trk and the
* key range after b_trk.
+ *
+ * Allocate a new WT_TRACK object, and extend the array of pages as
+ * necessary.
*/
- WT_RET(__slvg_trk_split(session, a_trk, &new));
+ WT_RET(__wt_calloc_one(session, &new));
+ if ((ret = __wt_realloc_def(session,
+ &ss->pages_allocated, ss->pages_next + 1, &ss->pages)) != 0) {
+ __wt_free(session, new);
+ return (ret);
+ }
/*
- * Second, reallocate the array of pages if necessary, and then insert
- * the new element into the array after the existing element (that's
- * probably wrong, but we'll fix it up in a second).
+ * First, set up the track share (we do this after the allocation to
+ * ensure the shared reference count is never incorrect).
+ */
+ new->shared = a_trk->shared;
+ new->ss = a_trk->ss;
+ ++new->shared->ref;
+
+ /*
+ * Second, insert the new element into the array after the existing
+ * element (that's probably wrong, but we'll fix it up in a second).
*/
- WT_RET(__wt_realloc_def(
- session, &ss->pages_allocated, ss->pages_next + 1, &ss->pages));
memmove(ss->pages + a_slot + 1, ss->pages + a_slot,
(ss->pages_next - a_slot) * sizeof(*ss->pages));
ss->pages[a_slot + 1] = new;
diff --git a/src/third_party/wiredtiger/src/btree/bt_split.c b/src/third_party/wiredtiger/src/btree/bt_split.c
index 4b9ab45c678..3753747c358 100644
--- a/src/third_party/wiredtiger/src/btree/bt_split.c
+++ b/src/third_party/wiredtiger/src/btree/bt_split.c
@@ -1180,9 +1180,12 @@ __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref)
* Assert splitting makes sense; specifically assert the page is dirty,
* we depend on that, otherwise the page might be evicted based on its
* last reconciliation which no longer matches reality after the split.
+ *
+ * Note this page has already been through an in-memory split.
*/
WT_ASSERT(session, __wt_page_can_split(session, page));
WT_ASSERT(session, __wt_page_is_modified(page));
+ F_SET_ATOMIC(page, WT_PAGE_SPLIT_INSERT);
/* Find the last item on the page. */
ins_head = page->pg_row_entries == 0 ?
@@ -1190,10 +1193,6 @@ __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref)
WT_ROW_INSERT_SLOT(page, page->pg_row_entries - 1);
moved_ins = WT_SKIP_LAST(ins_head);
- /* Mark that this page has already been through an in-memory split. */
- WT_ASSERT(session, !F_ISSET_ATOMIC(page, WT_PAGE_SPLIT_INSERT));
- F_SET_ATOMIC(page, WT_PAGE_SPLIT_INSERT);
-
/*
* The first page in the split is the current page, but we still have
* to create a replacement WT_REF, the original WT_REF will be set to
diff --git a/src/third_party/wiredtiger/src/btree/bt_vrfy_dsk.c b/src/third_party/wiredtiger/src/btree/bt_vrfy_dsk.c
index 38396facc3d..cf86ca9bec3 100644
--- a/src/third_party/wiredtiger/src/btree/bt_vrfy_dsk.c
+++ b/src/third_party/wiredtiger/src/btree/bt_vrfy_dsk.c
@@ -8,10 +8,10 @@
#include "wt_internal.h"
-static int __err_cell_corrupted(WT_SESSION_IMPL *, uint32_t, const char *);
+static int __err_cell_corrupt(WT_SESSION_IMPL *, uint32_t, const char *);
+static int __err_cell_corrupt_or_eof(WT_SESSION_IMPL *, uint32_t, const char *);
static int __err_cell_type(
WT_SESSION_IMPL *, uint32_t, const char *, uint8_t, uint8_t);
-static int __err_eof(WT_SESSION_IMPL *, uint32_t, const char *);
static int __verify_dsk_chunk(
WT_SESSION_IMPL *, const char *, const WT_PAGE_HEADER *, uint32_t);
static int __verify_dsk_col_fix(
@@ -223,8 +223,8 @@ __verify_dsk_row(
++cell_num;
/* Carefully unpack the cell. */
- if (__wt_cell_unpack_safe(cell, unpack, end) != 0) {
- ret = __err_cell_corrupted(session, cell_num, tag);
+ if (__wt_cell_unpack_safe(cell, unpack, dsk, end) != 0) {
+ ret = __err_cell_corrupt(session, cell_num, tag);
goto err;
}
@@ -285,7 +285,7 @@ __verify_dsk_row(
break;
}
- /* Check if any referenced item has a valid address. */
+ /* Check if any referenced item has an invalid address. */
switch (cell_type) {
case WT_CELL_ADDR_DEL:
case WT_CELL_ADDR_INT:
@@ -293,9 +293,14 @@ __verify_dsk_row(
case WT_CELL_ADDR_LEAF_NO:
case WT_CELL_KEY_OVFL:
case WT_CELL_VALUE_OVFL:
- if (!bm->addr_valid(bm,
- session, unpack->data, unpack->size))
- goto eof;
+ ret = bm->addr_invalid(
+ bm, session, unpack->data, unpack->size);
+ WT_RET_ERROR_OK(ret, EINVAL);
+ if (ret == EINVAL) {
+ ret = __err_cell_corrupt_or_eof(
+ session, cell_num, tag);
+ goto err;
+ }
break;
}
@@ -452,10 +457,6 @@ key_compare: /*
tag, key_cnt, dsk->u.entries);
if (0) {
-eof: ret = __err_eof(session, cell_num, tag);
- }
-
- if (0) {
err: if (ret == 0)
ret = WT_ERROR;
}
@@ -477,6 +478,7 @@ __verify_dsk_col_int(
WT_BTREE *btree;
WT_CELL *cell;
WT_CELL_UNPACK *unpack, _unpack;
+ WT_DECL_RET;
uint32_t cell_num, i;
uint8_t *end;
@@ -490,8 +492,8 @@ __verify_dsk_col_int(
++cell_num;
/* Carefully unpack the cell. */
- if (__wt_cell_unpack_safe(cell, unpack, end) != 0)
- return (__err_cell_corrupted(session, cell_num, tag));
+ if (__wt_cell_unpack_safe(cell, unpack, dsk, end) != 0)
+ return (__err_cell_corrupt(session, cell_num, tag));
/* Check the raw and collapsed cell types. */
WT_RET(__err_cell_type(
@@ -500,8 +502,11 @@ __verify_dsk_col_int(
session, cell_num, tag, unpack->type, dsk->type));
/* Check if any referenced item is entirely in the file. */
- if (!bm->addr_valid(bm, session, unpack->data, unpack->size))
- return (__err_eof(session, cell_num, tag));
+ ret = bm->addr_invalid(bm, session, unpack->data, unpack->size);
+ WT_RET_ERROR_OK(ret, EINVAL);
+ if (ret == EINVAL)
+ return (
+ __err_cell_corrupt_or_eof(session, cell_num, tag));
}
WT_RET(__verify_dsk_memsize(session, tag, dsk, cell));
@@ -537,6 +542,7 @@ __verify_dsk_col_var(
WT_BTREE *btree;
WT_CELL *cell;
WT_CELL_UNPACK *unpack, _unpack;
+ WT_DECL_RET;
size_t last_size;
uint32_t cell_num, cell_type, i;
int last_deleted;
@@ -557,8 +563,8 @@ __verify_dsk_col_var(
++cell_num;
/* Carefully unpack the cell. */
- if (__wt_cell_unpack_safe(cell, unpack, end) != 0)
- return (__err_cell_corrupted(session, cell_num, tag));
+ if (__wt_cell_unpack_safe(cell, unpack, dsk, end) != 0)
+ return (__err_cell_corrupt(session, cell_num, tag));
/* Check the raw and collapsed cell types. */
WT_RET(__err_cell_type(
@@ -568,9 +574,14 @@ __verify_dsk_col_var(
cell_type = unpack->type;
/* Check if any referenced item is entirely in the file. */
- if (cell_type == WT_CELL_VALUE_OVFL &&
- !bm->addr_valid(bm, session, unpack->data, unpack->size))
- return (__err_eof(session, cell_num, tag));
+ if (cell_type == WT_CELL_VALUE_OVFL) {
+ ret = bm->addr_invalid(
+ bm, session, unpack->data, unpack->size);
+ WT_RET_ERROR_OK(ret, EINVAL);
+ if (ret == EINVAL)
+ return (__err_cell_corrupt_or_eof(
+ session, cell_num, tag));
+ }
/*
* Compare the last two items and see if reconciliation missed
@@ -671,11 +682,11 @@ __verify_dsk_chunk(WT_SESSION_IMPL *session,
}
/*
- * __err_cell_corrupted --
+ * __err_cell_corrupt --
* Generic corrupted cell, we couldn't read it.
*/
static int
-__err_cell_corrupted(
+__err_cell_corrupt(
WT_SESSION_IMPL *session, uint32_t entry_num, const char *tag)
{
WT_RET_VRFY(session,
@@ -684,6 +695,20 @@ __err_cell_corrupted(
}
/*
+ * __err_cell_corrupt_or_eof --
+ * Generic corrupted cell or item references non-existent file pages error.
+ */
+static int
+__err_cell_corrupt_or_eof(
+ WT_SESSION_IMPL *session, uint32_t entry_num, const char *tag)
+{
+ WT_RET_VRFY(session,
+ "item %" PRIu32 " on page at %s is a corrupted cell or references "
+ "non-existent file pages",
+ entry_num, tag);
+}
+
+/*
* __err_cell_type --
* Generic illegal cell type for a particular page type error.
*/
@@ -741,16 +766,3 @@ __err_cell_type(WT_SESSION_IMPL *session,
entry_num, tag,
__wt_cell_type_string(cell_type), __wt_page_type_string(dsk_type));
}
-
-/*
- * __err_eof --
- * Generic item references non-existent file pages error.
- */
-static int
-__err_eof(WT_SESSION_IMPL *session, uint32_t entry_num, const char *tag)
-{
- WT_RET_VRFY(session,
- "off-page item %" PRIu32
- " on page at %s references non-existent file pages",
- entry_num, tag);
-}
diff --git a/src/third_party/wiredtiger/src/btree/row_srch.c b/src/third_party/wiredtiger/src/btree/row_srch.c
index d83d3253c44..6f2856301a6 100644
--- a/src/third_party/wiredtiger/src/btree/row_srch.c
+++ b/src/third_party/wiredtiger/src/btree/row_srch.c
@@ -509,20 +509,14 @@ restart:
}
if (page->pg_row_entries != 0) {
- /*
- * The use case for this call is finding a place to split the
- * tree. Cheat (it's not like this is "random", anyway), and
- * make things easier by returning the first key on the page.
- * If the caller is attempting to split a newly created tree,
- * or a tree with just one big page, that's not going to work,
- * check for that.
- */
cbt->ref = current;
cbt->compare = 0;
- WT_INTL_INDEX_GET(session, btree->root.page, pindex);
- cbt->slot = pindex->entries < 2 ?
- __wt_random(&session->rnd) % page->pg_row_entries : 0;
+ cbt->slot = __wt_random(&session->rnd) % page->pg_row_entries;
+ /*
+ * The real row-store search function builds the key, so we
+ * have to as well.
+ */
return (__wt_row_leaf_key(session,
page, page->pg_row_d + cbt->slot, cbt->tmp, 0));
}
diff --git a/src/third_party/wiredtiger/src/config/config_def.c b/src/third_party/wiredtiger/src/config/config_def.c
index 91cfcedfcaf..a3dc24fafc4 100644
--- a/src/third_party/wiredtiger/src/config/config_def.c
+++ b/src/third_party/wiredtiger/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\",\"off\",\"on\"]",
+ 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=on",
+ confchk_WT_SESSION_log_flush, 1
+ },
{ "WT_SESSION.log_printf",
"",
NULL, 0
@@ -902,7 +913,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {
NULL, 0
},
{ "WT_SESSION.transaction_sync",
- "timeout_ms=",
+ "timeout_ms=1200000",
confchk_WT_SESSION_transaction_sync, 1
},
{ "WT_SESSION.truncate",
diff --git a/src/third_party/wiredtiger/src/conn/conn_cache.c b/src/third_party/wiredtiger/src/conn/conn_cache.c
index 85e4074d15b..8f62c7140c7 100644
--- a/src/third_party/wiredtiger/src/conn/conn_cache.c
+++ b/src/third_party/wiredtiger/src/conn/conn_cache.c
@@ -156,7 +156,8 @@ __wt_cache_create(WT_SESSION_IMPL *session, const char *cfg[])
/* Allocate the LRU eviction queue. */
cache->evict_slots = WT_EVICT_WALK_BASE + WT_EVICT_WALK_INCR;
- WT_ERR(__wt_calloc_def(session, cache->evict_slots, &cache->evict));
+ WT_ERR(__wt_calloc_def(session,
+ cache->evict_slots, &cache->evict_queue));
/*
* We get/set some values in the cache statistics (rather than have
@@ -250,7 +251,7 @@ __wt_cache_destroy(WT_SESSION_IMPL *session)
__wt_spin_destroy(session, &cache->evict_lock);
__wt_spin_destroy(session, &cache->evict_walk_lock);
- __wt_free(session, cache->evict);
+ __wt_free(session, cache->evict_queue);
__wt_free(session, conn->cache);
return (ret);
}
diff --git a/src/third_party/wiredtiger/src/conn/conn_log.c b/src/third_party/wiredtiger/src/conn/conn_log.c
index 2b115190b06..f4baf6962ef 100644
--- a/src/third_party/wiredtiger/src/conn/conn_log.c
+++ b/src/third_party/wiredtiger/src/conn/conn_log.c
@@ -145,10 +145,9 @@ __log_archive_once(WT_SESSION_IMPL *session, uint32_t backup_file)
for (i = 0; i < logcount; i++) {
WT_ERR(__wt_log_extract_lognum(
session, logfiles[i], &lognum));
- if (lognum < min_lognum) {
+ if (lognum < min_lognum)
WT_ERR(__wt_log_remove(
session, WT_LOG_FILENAME, lognum));
- }
}
}
WT_ERR(__wt_readunlock(session, conn->hot_backup_lock));
diff --git a/src/third_party/wiredtiger/src/evict/evict_lru.c b/src/third_party/wiredtiger/src/evict/evict_lru.c
index b16621d1e6f..e0866521c7c 100644
--- a/src/third_party/wiredtiger/src/evict/evict_lru.c
+++ b/src/third_party/wiredtiger/src/evict/evict_lru.c
@@ -106,7 +106,7 @@ __wt_evict_list_clear_page(WT_SESSION_IMPL *session, WT_REF *ref)
__wt_spin_lock(session, &cache->evict_lock);
elem = cache->evict_max;
- for (i = 0, evict = cache->evict; i < elem; i++, evict++)
+ for (i = 0, evict = cache->evict_queue; i < elem; i++, evict++)
if (evict->ref == ref) {
__evict_list_clear(session, evict);
break;
@@ -739,7 +739,7 @@ __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session, int *evict_resetp)
* clear it.
*/
elem = cache->evict_max;
- for (i = 0, evict = cache->evict; i < elem; i++, evict++)
+ for (i = 0, evict = cache->evict_queue; i < elem; i++, evict++)
if (evict->btree == btree)
__evict_list_clear(session, evict);
__wt_spin_unlock(session, &cache->evict_lock);
@@ -811,10 +811,10 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
__wt_spin_lock(session, &cache->evict_lock);
entries = cache->evict_entries;
- qsort(cache->evict,
+ qsort(cache->evict_queue,
entries, sizeof(WT_EVICT_ENTRY), __evict_lru_cmp);
- while (entries > 0 && cache->evict[entries - 1].ref == NULL)
+ while (entries > 0 && cache->evict_queue[entries - 1].ref == NULL)
--entries;
cache->evict_entries = entries;
@@ -831,10 +831,10 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
return (0);
}
- WT_ASSERT(session, cache->evict[0].ref != NULL);
+ WT_ASSERT(session, cache->evict_queue[0].ref != NULL);
/* Track the oldest read generation we have in the queue. */
- cache->read_gen_oldest = cache->evict[0].ref->page->read_gen;
+ cache->read_gen_oldest = cache->evict_queue[0].ref->page->read_gen;
if (FLD_ISSET(cache->state,
WT_EVICT_PASS_AGGRESSIVE | WT_EVICT_PASS_WOULD_BLOCK))
@@ -845,8 +845,8 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
cache->evict_candidates = entries;
else {
/* Find the bottom 25% of read generations. */
- cutoff = (3 * __evict_read_gen(&cache->evict[0]) +
- __evict_read_gen(&cache->evict[entries - 1])) / 4;
+ cutoff = (3 * __evict_read_gen(&cache->evict_queue[0]) +
+ __evict_read_gen(&cache->evict_queue[entries - 1])) / 4;
/*
* Don't take less than 10% or more than 50% of entries,
* regardless. That said, if there is only one entry, which is
@@ -856,21 +856,21 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
candidates < entries / 2;
candidates++)
if (__evict_read_gen(
- &cache->evict[candidates]) > cutoff)
+ &cache->evict_queue[candidates]) > cutoff)
break;
cache->evict_candidates = candidates;
}
/* If we have more than the minimum number of entries, clear them. */
if (cache->evict_entries > WT_EVICT_WALK_BASE) {
- for (i = WT_EVICT_WALK_BASE, evict = cache->evict + i;
+ for (i = WT_EVICT_WALK_BASE, evict = cache->evict_queue + i;
i < cache->evict_entries;
i++, evict++)
__evict_list_clear(session, evict);
cache->evict_entries = WT_EVICT_WALK_BASE;
}
- cache->evict_current = cache->evict;
+ cache->evict_current = cache->evict_queue;
__wt_spin_unlock(session, &cache->evict_lock);
/*
@@ -1105,7 +1105,7 @@ __evict_init_candidate(
cache = S2C(session)->cache;
/* Keep track of the maximum slot we are using. */
- slot = (u_int)(evict - cache->evict);
+ slot = (u_int)(evict - cache->evict_queue);
if (slot >= cache->evict_max)
cache->evict_max = slot + 1;
@@ -1140,9 +1140,9 @@ __evict_walk_file(WT_SESSION_IMPL *session, u_int *slotp)
conn = S2C(session);
btree = S2BT(session);
cache = conn->cache;
- start = cache->evict + *slotp;
+ start = cache->evict_queue + *slotp;
end = WT_MIN(start + WT_EVICT_WALK_PER_FILE,
- cache->evict + cache->evict_slots);
+ cache->evict_queue + cache->evict_slots);
enough = internal_pages = restarts = 0;
walk_flags = WT_READ_CACHE | WT_READ_NO_EVICT |
@@ -1333,7 +1333,7 @@ __evict_get_ref(
/* Get the next page queued for eviction. */
while ((evict = cache->evict_current) != NULL &&
- evict < cache->evict + candidates && evict->ref != NULL) {
+ evict < cache->evict_queue + candidates && evict->ref != NULL) {
WT_ASSERT(session, evict->btree != NULL);
/* Move to the next item. */
@@ -1368,7 +1368,7 @@ __evict_get_ref(
}
/* Clear the current pointer if there are no more candidates. */
- if (evict >= cache->evict + cache->evict_candidates)
+ if (evict >= cache->evict_queue + cache->evict_candidates)
cache->evict_current = NULL;
__wt_spin_unlock(session, &cache->evict_lock);
@@ -1529,19 +1529,6 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, int busy, u_int pct_full)
if (q_found)
continue;
- /*
- * The cache is still full and no pages were found in the queue
- * to evict. If this transaction is the one holding back the
- * oldest ID, we can't wait forever. We'll block next time we
- * are not busy.
- */
- if (busy) {
- __wt_txn_update_oldest(session, 0);
- if (txn_state->id == txn_global->oldest_id ||
- txn_state->snap_min == txn_global->oldest_id)
- return (0);
- }
-
/* Wait for the queue to re-populate before trying again. */
WT_RET(
__wt_cond_wait(session, cache->evict_waiter_cond, 100000));
diff --git a/src/third_party/wiredtiger/src/include/block.h b/src/third_party/wiredtiger/src/include/block.h
index ce33b331e76..a7cdaba8b9f 100644
--- a/src/third_party/wiredtiger/src/include/block.h
+++ b/src/third_party/wiredtiger/src/include/block.h
@@ -155,9 +155,10 @@ struct __wt_block_ckpt {
*/
struct __wt_bm {
/* Methods */
+ int (*addr_invalid)
+ (WT_BM *, WT_SESSION_IMPL *, const uint8_t *, size_t);
int (*addr_string)
(WT_BM *, WT_SESSION_IMPL *, WT_ITEM *, const uint8_t *, size_t);
- int (*addr_valid)(WT_BM *, WT_SESSION_IMPL *, const uint8_t *, size_t);
u_int (*block_header)(WT_BM *);
int (*checkpoint)
(WT_BM *, WT_SESSION_IMPL *, WT_ITEM *, WT_CKPT *, int);
diff --git a/src/third_party/wiredtiger/src/include/cache.h b/src/third_party/wiredtiger/src/include/cache.h
index f98483a215f..f199372ea5e 100644
--- a/src/third_party/wiredtiger/src/include/cache.h
+++ b/src/third_party/wiredtiger/src/include/cache.h
@@ -91,7 +91,7 @@ struct __wt_cache {
/*
* LRU eviction list information.
*/
- WT_EVICT_ENTRY *evict; /* LRU pages being tracked */
+ WT_EVICT_ENTRY *evict_queue; /* LRU pages being tracked */
WT_EVICT_ENTRY *evict_current; /* LRU current page to be evicted */
uint32_t evict_candidates; /* LRU list pages to evict */
uint32_t evict_entries; /* LRU entries in the queue */
diff --git a/src/third_party/wiredtiger/src/include/cell.i b/src/third_party/wiredtiger/src/include/cell.i
index d7ecfd3bda4..a517ac4a523 100644
--- a/src/third_party/wiredtiger/src/include/cell.i
+++ b/src/third_party/wiredtiger/src/include/cell.i
@@ -547,7 +547,8 @@ __wt_cell_leaf_value_parse(WT_PAGE *page, WT_CELL *cell)
* Unpack a WT_CELL into a structure during verification.
*/
static inline int
-__wt_cell_unpack_safe(WT_CELL *cell, WT_CELL_UNPACK *unpack, uint8_t *end)
+__wt_cell_unpack_safe(
+ WT_CELL *cell, WT_CELL_UNPACK *unpack, const void *start, const void *end)
{
struct {
uint32_t len;
@@ -560,14 +561,15 @@ __wt_cell_unpack_safe(WT_CELL *cell, WT_CELL_UNPACK *unpack, uint8_t *end)
copy.v = 0; /* -Werror=maybe-uninitialized */
/*
- * The verification code specifies an end argument, a pointer to 1 past
- * the end-of-page. In that case, make sure we don't go past the end
- * of the page when reading. If an error occurs, we simply return the
- * error code, the verification code takes care of complaining (and, in
- * the case of salvage, it won't complain at all, it's OK to fail).
+ * The verification code specifies start/end arguments, pointers to the
+ * start of the page and to 1 past the end-of-page. In which case, make
+ * sure all reads are inside the page image. If an error occurs, return
+ * an error code but don't output messages, our caller handles that.
*/
-#define WT_CELL_LEN_CHK(p, len) do { \
- if (end != NULL && (((uint8_t *)p) + (len)) > end) \
+#define WT_CELL_LEN_CHK(t, len) do { \
+ if (start != NULL && \
+ ((uint8_t *)t < (uint8_t *)start || \
+ (((uint8_t *)t) + (len)) > (uint8_t *)end)) \
return (WT_ERROR); \
} while (0)
@@ -630,7 +632,7 @@ restart:
*/
if (cell->__chunk[0] & WT_CELL_64V) /* skip value */
WT_RET(__wt_vunpack_uint(
- &p, end == NULL ? 0 : (size_t)(end - p), &unpack->v));
+ &p, end == NULL ? 0 : WT_PTRDIFF(end, p), &unpack->v));
/*
* Handle special actions for a few different cell types and set the
@@ -647,7 +649,7 @@ restart:
* earlier cell.
*/
WT_RET(__wt_vunpack_uint(
- &p, end == NULL ? 0 : (size_t)(end - p), &v));
+ &p, end == NULL ? 0 : WT_PTRDIFF(end, p), &v));
copy.len = WT_PTRDIFF32(p, cell);
copy.v = unpack->v;
cell = (WT_CELL *)((uint8_t *)cell - v);
@@ -675,7 +677,7 @@ restart:
* data.
*/
WT_RET(__wt_vunpack_uint(
- &p, end == NULL ? 0 : (size_t)(end - p), &v));
+ &p, end == NULL ? 0 : WT_PTRDIFF(end, p), &v));
if (unpack->raw == WT_CELL_KEY ||
unpack->raw == WT_CELL_KEY_PFX ||
@@ -716,7 +718,7 @@ done: WT_CELL_LEN_CHK(cell, unpack->__len);
static inline void
__wt_cell_unpack(WT_CELL *cell, WT_CELL_UNPACK *unpack)
{
- (void)__wt_cell_unpack_safe(cell, unpack, NULL);
+ (void)__wt_cell_unpack_safe(cell, unpack, NULL, NULL);
}
/*
diff --git a/src/third_party/wiredtiger/src/include/config.h b/src/third_party/wiredtiger/src/include/config.h
index 45aa87fcdc5..408639ab2a9 100644
--- a/src/third_party/wiredtiger/src/include/config.h
+++ b/src/third_party/wiredtiger/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/third_party/wiredtiger/src/include/error.h b/src/third_party/wiredtiger/src/include/error.h
index abffc02945e..e721855ce7c 100644
--- a/src/third_party/wiredtiger/src/include/error.h
+++ b/src/third_party/wiredtiger/src/include/error.h
@@ -35,10 +35,10 @@
} else \
ret = 0; \
} while (0)
-#define WT_ERR_BUSY_OK(a) \
- WT_ERR_TEST((ret = (a)) != 0 && ret != EBUSY, ret)
-#define WT_ERR_NOTFOUND_OK(a) \
- WT_ERR_TEST((ret = (a)) != 0 && ret != WT_NOTFOUND, ret)
+#define WT_ERR_ERROR_OK(a, e) \
+ WT_ERR_TEST((ret = (a)) != 0 && ret != (e), ret)
+#define WT_ERR_BUSY_OK(a) WT_ERR_ERROR_OK(a, EBUSY)
+#define WT_ERR_NOTFOUND_OK(a) WT_ERR_ERROR_OK(a, WT_NOTFOUND)
/* Return tests. */
#define WT_RET(a) do { \
@@ -55,14 +55,13 @@
if (a) \
return (v); \
} while (0)
-#define WT_RET_BUSY_OK(a) do { \
+#define WT_RET_ERROR_OK(a, e) do { \
int __ret = (a); \
- WT_RET_TEST(__ret != 0 && __ret != EBUSY, __ret); \
-} while (0)
-#define WT_RET_NOTFOUND_OK(a) do { \
- int __ret = (a); \
- WT_RET_TEST(__ret != 0 && __ret != WT_NOTFOUND, __ret); \
+ WT_RET_TEST(__ret != 0 && __ret != (e), __ret); \
} while (0)
+#define WT_RET_BUSY_OK(a) WT_RET_ERROR_OK(a, EBUSY)
+#define WT_RET_NOTFOUND_OK(a) WT_RET_ERROR_OK(a, WT_NOTFOUND)
+
/* Set "ret" if not already set. */
#define WT_TRET(a) do { \
int __ret; \
@@ -71,20 +70,15 @@
ret == 0 || ret == WT_DUPLICATE_KEY || ret == WT_NOTFOUND)) \
ret = __ret; \
} while (0)
-#define WT_TRET_BUSY_OK(a) do { \
- int __ret; \
- if ((__ret = (a)) != 0 && __ret != EBUSY && \
- (__ret == WT_PANIC || \
- ret == 0 || ret == WT_DUPLICATE_KEY || ret == WT_NOTFOUND)) \
- ret = __ret; \
-} while (0)
-#define WT_TRET_NOTFOUND_OK(a) do { \
+#define WT_TRET_ERROR_OK(a, e) do { \
int __ret; \
- if ((__ret = (a)) != 0 && __ret != WT_NOTFOUND && \
+ if ((__ret = (a)) != 0 && __ret != (e) && \
(__ret == WT_PANIC || \
ret == 0 || ret == WT_DUPLICATE_KEY || ret == WT_NOTFOUND)) \
ret = __ret; \
} while (0)
+#define WT_TRET_BUSY_OK(a) WT_TRET_ERROR_OK(a, EBUSY)
+#define WT_TRET_NOTFOUND_OK(a) WT_TRET_ERROR_OK(a, WT_NOTFOUND)
/* Return and branch-to-err-label cases for switch statements. */
#define WT_ILLEGAL_VALUE(session) \
diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h
index e5c5a72fe02..609dc1b7894 100644
--- a/src/third_party/wiredtiger/src/include/extern.h
+++ b/src/third_party/wiredtiger/src/include/extern.h
@@ -11,7 +11,7 @@ extern int __wt_async_op_init(WT_SESSION_IMPL *session);
extern WT_THREAD_RET __wt_async_worker(void *arg);
extern int __wt_block_addr_to_buffer(WT_BLOCK *block, uint8_t **pp, wt_off_t offset, uint32_t size, uint32_t cksum);
extern int __wt_block_buffer_to_addr(WT_BLOCK *block, const uint8_t *p, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump);
-extern int __wt_block_addr_valid(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, int live);
+extern int __wt_block_addr_invalid(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, int live);
extern int __wt_block_addr_string(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, const uint8_t *addr, size_t addr_size);
extern int __wt_block_buffer_to_ckpt(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *p, WT_BLOCK_CKPT *ci);
extern int __wt_block_ckpt_to_buffer(WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t **pp, WT_BLOCK_CKPT *ci);
@@ -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 *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);
@@ -338,10 +338,12 @@ extern int __wt_log_allocfile( WT_SESSION_IMPL *session, uint32_t lognum, const
extern int __wt_log_remove(WT_SESSION_IMPL *session, const char *file_prefix, uint32_t lognum);
extern int __wt_log_open(WT_SESSION_IMPL *session);
extern int __wt_log_close(WT_SESSION_IMPL *session);
+extern int __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, int *freep);
extern int __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, int (*func)(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, WT_LSN *next_lsnp, void *cookie, int firstrecord), void *cookie);
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);
@@ -367,8 +369,7 @@ extern int __wt_logop_row_truncate_print( WT_SESSION_IMPL *session, const uint8_
extern int __wt_txn_op_printlog( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, FILE *out);
extern void __wt_log_slot_activate(WT_SESSION_IMPL *session, WT_LOGSLOT *slot);
extern int __wt_log_slot_close( WT_SESSION_IMPL *session, WT_LOGSLOT *slot, int *releasep, int forced);
-extern int __wt_log_slot_switch_internal(WT_SESSION_IMPL *session, WT_MYSLOT *myslot);
-extern int __wt_log_slot_switch(WT_SESSION_IMPL *session, WT_MYSLOT *myslot);
+extern int __wt_log_slot_switch( WT_SESSION_IMPL *session, WT_MYSLOT *myslot, int retry, int forced);
extern int __wt_log_slot_new(WT_SESSION_IMPL *session);
extern int __wt_log_slot_init(WT_SESSION_IMPL *session);
extern int __wt_log_slot_destroy(WT_SESSION_IMPL *session);
diff --git a/src/third_party/wiredtiger/src/include/intpack.i b/src/third_party/wiredtiger/src/include/intpack.i
index d3fdfeaf1a6..0830704fb6d 100644
--- a/src/third_party/wiredtiger/src/include/intpack.i
+++ b/src/third_party/wiredtiger/src/include/intpack.i
@@ -47,8 +47,14 @@
#define GET_BITS(x, start, end) \
(((uint64_t)(x) & ((1U << (start)) - 1U)) >> (end))
-#define WT_SIZE_CHECK(l, maxl) \
+/*
+ * Size checks: return ENOMEM if not enough room when writing, EINVAL if the
+ * length is wrong when reading (presumably the value is corrupted).
+ */
+#define WT_SIZE_CHECK_PACK(l, maxl) \
WT_RET_TEST((maxl) != 0 && (size_t)(l) > (maxl), ENOMEM)
+#define WT_SIZE_CHECK_UNPACK(l, maxl) \
+ WT_RET_TEST((maxl) != 0 && (size_t)(l) > (maxl), EINVAL)
/* Count the leading zero bytes. */
#if defined(__GNUC__)
@@ -84,7 +90,7 @@ __wt_vpack_posint(uint8_t **pp, size_t maxlen, uint64_t x)
WT_LEADING_ZEROS(x, lz);
len = (int)sizeof (x) - lz;
- WT_SIZE_CHECK(len + 1, maxlen);
+ WT_SIZE_CHECK_PACK(len + 1, maxlen);
p = *pp;
/* There are four bits we can use in the first byte. */
@@ -109,7 +115,7 @@ __wt_vpack_negint(uint8_t **pp, size_t maxlen, uint64_t x)
WT_LEADING_ZEROS(~x, lz);
len = (int)sizeof (x) - lz;
- WT_SIZE_CHECK(len + 1, maxlen);
+ WT_SIZE_CHECK_PACK(len + 1, maxlen);
p = *pp;
/*
@@ -141,7 +147,7 @@ __wt_vunpack_posint(const uint8_t **pp, size_t maxlen, uint64_t *retp)
/* There are four length bits in the first byte. */
p = *pp;
len = (*p++ & 0xf);
- WT_SIZE_CHECK(len + 1, maxlen);
+ WT_SIZE_CHECK_UNPACK(len + 1, maxlen);
for (x = 0; len != 0; --len)
x = (x << 8) | *p++;
@@ -165,7 +171,7 @@ __wt_vunpack_negint(const uint8_t **pp, size_t maxlen, uint64_t *retp)
/* There are four length bits in the first byte. */
p = *pp;
len = (int)sizeof (x) - (*p++ & 0xf);
- WT_SIZE_CHECK(len + 1, maxlen);
+ WT_SIZE_CHECK_UNPACK(len + 1, maxlen);
for (x = UINT64_MAX; len != 0; --len)
x = (x << 8) | *p++;
@@ -184,12 +190,12 @@ __wt_vpack_uint(uint8_t **pp, size_t maxlen, uint64_t x)
{
uint8_t *p;
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_PACK(1, maxlen);
p = *pp;
if (x <= POS_1BYTE_MAX)
*p++ = POS_1BYTE_MARKER | GET_BITS(x, 6, 0);
else if (x <= POS_2BYTE_MAX) {
- WT_SIZE_CHECK(2, maxlen);
+ WT_SIZE_CHECK_PACK(2, maxlen);
x -= POS_1BYTE_MAX + 1;
*p++ = POS_2BYTE_MARKER | GET_BITS(x, 13, 8);
*p++ = GET_BITS(x, 8, 0);
@@ -220,13 +226,13 @@ __wt_vpack_int(uint8_t **pp, size_t maxlen, int64_t x)
{
uint8_t *p;
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_PACK(1, maxlen);
p = *pp;
if (x < NEG_2BYTE_MIN) {
*p = NEG_MULTI_MARKER;
return (__wt_vpack_negint(pp, maxlen, (uint64_t)x));
} else if (x < NEG_1BYTE_MIN) {
- WT_SIZE_CHECK(2, maxlen);
+ WT_SIZE_CHECK_PACK(2, maxlen);
x -= NEG_2BYTE_MIN;
*p++ = NEG_2BYTE_MARKER | GET_BITS(x, 13, 8);
*p++ = GET_BITS(x, 8, 0);
@@ -250,7 +256,7 @@ __wt_vunpack_uint(const uint8_t **pp, size_t maxlen, uint64_t *xp)
{
const uint8_t *p;
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_UNPACK(1, maxlen);
p = *pp;
switch (*p & 0xf0) {
case POS_1BYTE_MARKER:
@@ -262,7 +268,7 @@ __wt_vunpack_uint(const uint8_t **pp, size_t maxlen, uint64_t *xp)
break;
case POS_2BYTE_MARKER:
case POS_2BYTE_MARKER | 0x10:
- WT_SIZE_CHECK(2, maxlen);
+ WT_SIZE_CHECK_UNPACK(2, maxlen);
*xp = GET_BITS(*p++, 5, 0) << 8;
*xp |= *p++;
*xp += POS_1BYTE_MAX + 1;
@@ -288,7 +294,7 @@ __wt_vunpack_int(const uint8_t **pp, size_t maxlen, int64_t *xp)
{
const uint8_t *p;
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_UNPACK(1, maxlen);
p = *pp;
switch (*p & 0xf0) {
case NEG_MULTI_MARKER:
@@ -296,7 +302,7 @@ __wt_vunpack_int(const uint8_t **pp, size_t maxlen, int64_t *xp)
return (0);
case NEG_2BYTE_MARKER:
case NEG_2BYTE_MARKER | 0x10:
- WT_SIZE_CHECK(2, maxlen);
+ WT_SIZE_CHECK_UNPACK(2, maxlen);
*xp = (int64_t)(GET_BITS(*p++, 5, 0) << 8);
*xp |= *p++;
*xp += NEG_2BYTE_MIN;
diff --git a/src/third_party/wiredtiger/src/include/packing.i b/src/third_party/wiredtiger/src/include/packing.i
index bf6b5abce67..da0ca54e6c2 100644
--- a/src/third_party/wiredtiger/src/include/packing.i
+++ b/src/third_party/wiredtiger/src/include/packing.i
@@ -318,12 +318,12 @@ __pack_write(
switch (pv->type) {
case 'x':
- WT_SIZE_CHECK(pv->size, maxlen);
+ WT_SIZE_CHECK_PACK(pv->size, maxlen);
memset(*pp, 0, pv->size);
*pp += pv->size;
break;
case 's':
- WT_SIZE_CHECK(pv->size, maxlen);
+ WT_SIZE_CHECK_PACK(pv->size, maxlen);
memcpy(*pp, pv->u.s, pv->size);
*pp += pv->size;
break;
@@ -337,7 +337,7 @@ __pack_write(
pad = pv->size - s;
} else
pad = 1;
- WT_SIZE_CHECK(s + pad, maxlen);
+ WT_SIZE_CHECK_PACK(s + pad, maxlen);
if (s > 0)
memcpy(*pp, pv->u.s, s);
*pp += s;
@@ -363,7 +363,7 @@ __pack_write(
maxlen -= (size_t)(*pp - oldp);
}
if (pad > 0) {
- WT_SIZE_CHECK(pad, maxlen);
+ WT_SIZE_CHECK_PACK(pad, maxlen);
memset(*pp, 0, pad);
*pp += pad;
}
@@ -382,11 +382,11 @@ __pack_write(
* Check that there is at least one byte available: the
* low-level routines treat zero length as unchecked.
*/
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_PACK(1, maxlen);
WT_RET(__wt_vpack_uint(pp, maxlen, s + pad));
maxlen -= (size_t)(*pp - oldp);
}
- WT_SIZE_CHECK(s + pad, maxlen);
+ WT_SIZE_CHECK_PACK(s + pad, maxlen);
if (s > 0)
memcpy(*pp, pv->u.item.data, s);
*pp += s;
@@ -397,13 +397,13 @@ __pack_write(
break;
case 'b':
/* Translate to maintain ordering with the sign bit. */
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_PACK(1, maxlen);
**pp = (uint8_t)(pv->u.i + 0x80);
*pp += 1;
break;
case 'B':
case 't':
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_PACK(1, maxlen);
**pp = (uint8_t)pv->u.u;
*pp += 1;
break;
@@ -415,7 +415,7 @@ __pack_write(
* Check that there is at least one byte available: the
* low-level routines treat zero length as unchecked.
*/
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_PACK(1, maxlen);
WT_RET(__wt_vpack_int(pp, maxlen, pv->u.i));
break;
case 'H':
@@ -427,11 +427,11 @@ __pack_write(
* Check that there is at least one byte available: the
* low-level routines treat zero length as unchecked.
*/
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_PACK(1, maxlen);
WT_RET(__wt_vpack_uint(pp, maxlen, pv->u.u));
break;
case 'R':
- WT_SIZE_CHECK(sizeof(uint64_t), maxlen);
+ WT_SIZE_CHECK_PACK(sizeof(uint64_t), maxlen);
*(uint64_t *)*pp = pv->u.u;
*pp += sizeof(uint64_t);
break;
@@ -455,7 +455,7 @@ __unpack_read(WT_SESSION_IMPL *session,
switch (pv->type) {
case 'x':
- WT_SIZE_CHECK(pv->size, maxlen);
+ WT_SIZE_CHECK_UNPACK(pv->size, maxlen);
*pp += pv->size;
break;
case 's':
@@ -466,7 +466,7 @@ __unpack_read(WT_SESSION_IMPL *session,
s = strlen((const char *)*pp) + 1;
if (s > 0)
pv->u.s = (const char *)*pp;
- WT_SIZE_CHECK(s, maxlen);
+ WT_SIZE_CHECK_UNPACK(s, maxlen);
*pp += s;
break;
case 'U':
@@ -474,7 +474,7 @@ __unpack_read(WT_SESSION_IMPL *session,
* Check that there is at least one byte available: the
* low-level routines treat zero length as unchecked.
*/
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_UNPACK(1, maxlen);
WT_RET(__wt_vunpack_uint(pp, maxlen, &pv->u.u));
/* FALLTHROUGH */
case 'u':
@@ -484,19 +484,19 @@ __unpack_read(WT_SESSION_IMPL *session,
s = (size_t)pv->u.u;
else
s = maxlen;
- WT_SIZE_CHECK(s, maxlen);
+ WT_SIZE_CHECK_UNPACK(s, maxlen);
pv->u.item.data = *pp;
pv->u.item.size = s;
*pp += s;
break;
case 'b':
/* Translate to maintain ordering with the sign bit. */
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_UNPACK(1, maxlen);
pv->u.i = (int8_t)(*(*pp)++ - 0x80);
break;
case 'B':
case 't':
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_UNPACK(1, maxlen);
pv->u.u = *(*pp)++;
break;
case 'h':
@@ -507,7 +507,7 @@ __unpack_read(WT_SESSION_IMPL *session,
* Check that there is at least one byte available: the
* low-level routines treat zero length as unchecked.
*/
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_UNPACK(1, maxlen);
WT_RET(__wt_vunpack_int(pp, maxlen, &pv->u.i));
break;
case 'H':
@@ -519,11 +519,11 @@ __unpack_read(WT_SESSION_IMPL *session,
* Check that there is at least one byte available: the
* low-level routines treat zero length as unchecked.
*/
- WT_SIZE_CHECK(1, maxlen);
+ WT_SIZE_CHECK_UNPACK(1, maxlen);
WT_RET(__wt_vunpack_uint(pp, maxlen, &pv->u.u));
break;
case 'R':
- WT_SIZE_CHECK(sizeof(uint64_t), maxlen);
+ WT_SIZE_CHECK_UNPACK(sizeof(uint64_t), maxlen);
pv->u.u = *(uint64_t *)*pp;
*pp += sizeof(uint64_t);
break;
diff --git a/src/third_party/wiredtiger/src/include/serial.i b/src/third_party/wiredtiger/src/include/serial.i
index d90b29c2133..fd6ede46c69 100644
--- a/src/third_party/wiredtiger/src/include/serial.i
+++ b/src/third_party/wiredtiger/src/include/serial.i
@@ -256,6 +256,7 @@ __wt_update_serial(WT_SESSION_IMPL *session, WT_PAGE *page,
{
WT_DECL_RET;
WT_UPDATE *obsolete, *upd = *updp;
+ uint64_t txn;
/* Check for page write generation wrap. */
WT_RET(__page_write_gen_wrapped_check(page));
@@ -296,33 +297,33 @@ __wt_update_serial(WT_SESSION_IMPL *session, WT_PAGE *page,
*/
if (upd->next == NULL)
return (0);
+
/*
* We would like to call __wt_txn_update_oldest only in the event that
* there are further updates to this page, the check against WT_TXN_NONE
* is used as an indicator of there being further updates on this page.
*/
- if (page->modify->obsolete_check_txn != WT_TXN_NONE) {
- if (!__wt_txn_visible_all(session,
- page->modify->obsolete_check_txn)) {
- /* Try to move the oldest ID forward and re-check */
- __wt_txn_update_oldest(session,0);
- }
- if (!__wt_txn_visible_all(session,
- page->modify->obsolete_check_txn)) {
- page->modify->obsolete_check_txn = WT_TXN_NONE;
- return (0);
+ if ((txn = page->modify->obsolete_check_txn) != WT_TXN_NONE) {
+ if (!__wt_txn_visible_all(session, txn)) {
+ /* Try to move the oldest ID forward and re-check. */
+ __wt_txn_update_oldest(session, 0);
+
+ if (!__wt_txn_visible_all(session, txn))
+ return (0);
}
+
+ page->modify->obsolete_check_txn = WT_TXN_NONE;
}
- F_CAS_ATOMIC(page, WT_PAGE_RECONCILIATION, ret);
/* If we can't lock it, don't scan, that's okay. */
+ F_CAS_ATOMIC(page, WT_PAGE_RECONCILIATION, ret);
if (ret != 0)
return (0);
+
obsolete = __wt_update_obsolete_check(session, page, upd->next);
F_CLR_ATOMIC(page, WT_PAGE_RECONCILIATION);
- if (obsolete != NULL) {
+ if (obsolete != NULL)
__wt_update_obsolete_free(session, page, obsolete);
- }
return (0);
}
diff --git a/src/third_party/wiredtiger/src/include/stat.h b/src/third_party/wiredtiger/src/include/stat.h
index cd2c149bc94..2f975b70c40 100644
--- a/src/third_party/wiredtiger/src/include/stat.h
+++ b/src/third_party/wiredtiger/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/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in
index 71ba3f41a44..e9ef7ac5ff4 100644
--- a/src/third_party/wiredtiger/src/include/wiredtiger.in
+++ b/src/third_party/wiredtiger/src/include/wiredtiger.in
@@ -1236,6 +1236,24 @@ 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. The \c background setting initiates
+ * a background synchronization intended to be used with a later call to
+ * WT_SESSION::transaction_sync. The \c off setting forces any buffered
+ * log records to be written to the file system. The \c on setting
+ * forces log records to be written to the storage device., a string\,
+ * chosen from the following options: \c "background"\, \c "off"\, \c
+ * "on"; default \c on.}
+ * @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).
@@ -1442,8 +1460,13 @@ struct __wt_session {
* @configstart{WT_SESSION.commit_transaction, see dist/api_data.py}
* @config{sync, override whether to sync log records when the
* transaction commits\, inherited from ::wiredtiger_open \c
- * transaction_sync., a string\, chosen from the following options: \c
- * "background"\, \c "off"\, \c "on"; default empty.}
+ * transaction_sync. The \c background setting initiates a background
+ * synchronization intended to be used with a later call to
+ * WT_SESSION::transaction_sync. The \c off setting does not wait for
+ * record to be written or synchronized. The \c on setting forces log
+ * records to be written to the storage device., a string\, chosen from
+ * the following options: \c "background"\, \c "off"\, \c "on"; default
+ * empty.}
* @configend
* @errors
*/
@@ -1552,8 +1575,7 @@ struct __wt_session {
* @configstart{WT_SESSION.transaction_sync, see dist/api_data.py}
* @config{timeout_ms, maximum amount of time to wait for background
* sync to complete in milliseconds. A value of zero disables the
- * timeout and returns immediately. The default waits forever., an
- * integer; default \c .}
+ * timeout and returns immediately., an integer; default \c 1200000.}
* @configend
* @errors
*/
@@ -3727,130 +3749,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 operations */
+#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/third_party/wiredtiger/src/log/log.c b/src/third_party/wiredtiger/src/log/log.c
index 574442f645c..79513944a1c 100644
--- a/src/third_party/wiredtiger/src/log/log.c
+++ b/src/third_party/wiredtiger/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 *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)
+ *lsn = log->write_start_lsn;
+ else
+ *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;
/*
@@ -542,7 +551,7 @@ __log_file_header(
/*
* We may recursively call __wt_log_acquire to allocate log space for
* the log descriptor record. Call __log_fill to write it, but we
- * do not need to call __log_release because we're not waiting for
+ * do not need to call __wt_log_release because we're not waiting for
* any earlier operations to complete.
*/
if (prealloc) {
@@ -1170,11 +1179,11 @@ err:
}
/*
- * __log_release --
+ * __wt_log_release --
* Release a log slot.
*/
-static int
-__log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, int *freep)
+int
+__wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, int *freep)
{
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
@@ -1624,40 +1633,6 @@ err: WT_STAT_FAST_CONN_INCR(session, log_scans);
}
/*
- * __log_force_write_internal --
- * Force a switch and release and write of the current slot.
- * Must be called with the slot lock held.
- */
-static int
-__log_force_write_internal(WT_SESSION_IMPL *session)
-{
- WT_DECL_RET;
- WT_LOG *log;
- WT_LOGSLOT *slot;
- int free_slot, release;
-
- log = S2C(session)->log;
- slot = log->active_slot;
- WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_SLOT));
- /*
- * If closing the slot returns WT_NOTFOUND, it means that someone else
- * is processing the slot change: we're done. If we get EBUSY (or any
- * other error), return that so the caller can decide what to do.
- */
- ret = __wt_log_slot_close(session, slot, &release, 1);
- if (ret == WT_NOTFOUND)
- return (0);
- WT_RET(ret);
- if (release) {
- WT_RET(__log_release(session, slot, &free_slot));
- if (free_slot)
- __wt_log_slot_free(session, slot);
- }
- WT_RET(__wt_log_slot_new(session));
- return (0);
-}
-
-/*
* __wt_log_force_write --
* Force a switch and release and write of the current slot.
* Wrapper function that takes the lock.
@@ -1665,14 +1640,13 @@ __log_force_write_internal(WT_SESSION_IMPL *session)
int
__wt_log_force_write(WT_SESSION_IMPL *session, int retry)
{
- WT_DECL_RET;
-
- do {
- WT_WITH_SLOT_LOCK(session, S2C(session)->log,
- ret = __log_force_write_internal(session));
- } while (retry && ret == EBUSY);
+ WT_LOG *log;
+ WT_MYSLOT myslot;
- return (ret);
+ log = S2C(session)->log;
+ memset(&myslot, 0, sizeof(myslot));
+ myslot.slot = log->active_slot;
+ return (__wt_log_slot_switch(session, &myslot, retry, 1));
}
/*
@@ -1866,7 +1840,7 @@ __log_write_internal(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp,
ret = 0;
if (myslot.end_offset >= WT_LOG_SLOT_BUF_MAX ||
F_ISSET(&myslot, WT_MYSLOT_UNBUFFERED) || force)
- ret = __wt_log_slot_switch(session, &myslot);
+ ret = __wt_log_slot_switch(session, &myslot, 1, 0);
if (ret == 0)
ret = __log_fill(session, &myslot, 0, record, &lsn);
release_size = __wt_log_slot_release(
@@ -1880,7 +1854,7 @@ __log_write_internal(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp,
myslot.slot->slot_error = ret;
WT_ASSERT(session, ret == 0);
if (WT_LOG_SLOT_DONE(release_size)) {
- WT_ERR(__log_release(session, myslot.slot, &free_slot));
+ WT_ERR(__wt_log_release(session, myslot.slot, &free_slot));
if (free_slot)
__wt_log_slot_free(session, myslot.slot);
} else if (force) {
@@ -1913,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:
@@ -1983,3 +1956,39 @@ __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_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 write-no-sync, there is nothing more to do.
+ * If the user wants background sync, set the LSN and we're done.
+ * If the user wants sync, force it now.
+ */
+ if (LF_ISSET(WT_LOG_BACKGROUND))
+ WT_RET(__wt_log_background(session, &lsn));
+ else if (LF_ISSET(WT_LOG_FSYNC))
+ WT_RET(__wt_log_force_sync(session, &lsn));
+ return (0);
+}
diff --git a/src/third_party/wiredtiger/src/log/log_slot.c b/src/third_party/wiredtiger/src/log/log_slot.c
index a1a68557f93..0d6555f8973 100644
--- a/src/third_party/wiredtiger/src/log/log_slot.c
+++ b/src/third_party/wiredtiger/src/log/log_slot.c
@@ -100,22 +100,21 @@ retry:
}
/*
- * __wt_log_slot_switch_internal --
+ * __log_slot_switch_internal --
* Switch out the current slot and set up a new one.
*/
-int
-__wt_log_slot_switch_internal(WT_SESSION_IMPL *session, WT_MYSLOT *myslot)
+static int
+__log_slot_switch_internal(
+ WT_SESSION_IMPL *session, WT_MYSLOT *myslot, int forced)
{
WT_DECL_RET;
WT_LOG *log;
- int release;
-#ifdef HAVE_DIAGNOSTIC
- int64_t r, state;
- int32_t j;
-#endif
+ WT_LOGSLOT *slot;
+ int free_slot, release;
log = S2C(session)->log;
release = 0;
+ slot = myslot->slot;
WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_SLOT));
@@ -123,7 +122,7 @@ __wt_log_slot_switch_internal(WT_SESSION_IMPL *session, WT_MYSLOT *myslot)
* If someone else raced us to closing this specific slot, we're
* done here.
*/
- if (myslot->slot != log->active_slot)
+ if (slot != log->active_slot)
return (0);
/*
@@ -133,31 +132,23 @@ __wt_log_slot_switch_internal(WT_SESSION_IMPL *session, WT_MYSLOT *myslot)
* someone else and we need to try setting up a new slot again.
*/
if (!F_ISSET(myslot, WT_MYSLOT_CLOSE)) {
- ret = __wt_log_slot_close(session, myslot->slot, &release, 0);
+ ret = __wt_log_slot_close(session, slot, &release, forced);
if (ret == WT_NOTFOUND)
return (0);
+ WT_RET(ret);
+ if (release) {
+ WT_RET(__wt_log_release(session, slot, &free_slot));
+ if (free_slot)
+ __wt_log_slot_free(session, slot);
+ }
}
-
- /*
- * Only mainline callers use switch. Our size should be in join
- * and we have not yet released, so we should never think release
- * should be done now.
- */
- WT_ASSERT(session, release == 0);
- WT_ASSERT(session, ret == 0);
-
/*
* Set that we have closed this slot because we may call in here
* multiple times if we retry creating a new slot.
*/
F_SET(myslot, WT_MYSLOT_CLOSE);
-#ifdef HAVE_DIAGNOSTIC
- state = myslot->slot->slot_state;
- j = WT_LOG_SLOT_JOINED(state);
- r = WT_LOG_SLOT_RELEASED(state);
- WT_ASSERT(session, j > r);
-#endif
WT_RET(__wt_log_slot_new(session));
+ F_CLR(myslot, WT_MYSLOT_CLOSE);
return (0);
}
@@ -166,7 +157,8 @@ __wt_log_slot_switch_internal(WT_SESSION_IMPL *session, WT_MYSLOT *myslot)
* Switch out the current slot and set up a new one.
*/
int
-__wt_log_slot_switch(WT_SESSION_IMPL *session, WT_MYSLOT *myslot)
+__wt_log_slot_switch(
+ WT_SESSION_IMPL *session, WT_MYSLOT *myslot, int retry, int forced)
{
WT_DECL_RET;
WT_LOG *log;
@@ -177,15 +169,14 @@ __wt_log_slot_switch(WT_SESSION_IMPL *session, WT_MYSLOT *myslot)
* compiler does not like it combined directly with the while loop
* here.
*/
- WT_WITH_SLOT_LOCK(session, log,
- ret = __wt_log_slot_switch_internal(session, myslot));
- while (ret == EBUSY) {
- WT_STAT_FAST_CONN_INCR(session, log_slot_switch_busy);
- __wt_yield();
+ do {
WT_WITH_SLOT_LOCK(session, log,
- ret = __wt_log_slot_switch_internal(session, myslot));
- }
- WT_ASSERT(session, ret == 0);
+ ret = __log_slot_switch_internal(session, myslot, forced));
+ if (ret == EBUSY) {
+ WT_STAT_FAST_CONN_INCR(session, log_slot_switch_busy);
+ __wt_yield();
+ }
+ } while (F_ISSET(myslot, WT_MYSLOT_CLOSE) || (retry && ret == EBUSY));
return (ret);
}
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_track.c b/src/third_party/wiredtiger/src/reconcile/rec_track.c
index 73be1f5c4e9..5d8870dc5ae 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_track.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_track.c
@@ -473,7 +473,7 @@ __wt_ovfl_reuse_search(WT_SESSION_IMPL *session, WT_PAGE *page,
if (WT_VERBOSE_ISSET(session, WT_VERB_OVERFLOW))
WT_RET(__ovfl_reuse_verbose(session, page, reuse, "reclaim"));
- return (1);
+ return (0);
}
/*
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_write.c b/src/third_party/wiredtiger/src/reconcile/rec_write.c
index 10daa8b717c..8a374a1a559 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_write.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_write.c
@@ -5907,10 +5907,11 @@ __rec_cell_build_ovfl(WT_SESSION_IMPL *session,
/*
* See if this overflow record has already been written and reuse it if
- * possible. Else, write a new overflow record.
+ * possible, otherwise write a new overflow record.
*/
- if (!__wt_ovfl_reuse_search(session, page,
- &addr, &size, kv->buf.data, kv->buf.size)) {
+ WT_RET(__wt_ovfl_reuse_search(
+ session, page, &addr, &size, kv->buf.data, kv->buf.size));
+ if (addr == NULL) {
/* Allocate a buffer big enough to write the overflow record. */
size = kv->buf.size;
WT_RET(bm->write_size(bm, session, &size));
diff --git a/src/third_party/wiredtiger/src/session/session_api.c b/src/third_party/wiredtiger/src/session/session_api.c
index a1f5618a317..37a1f895589 100644
--- a/src/third_party/wiredtiger/src/session/session_api.c
+++ b/src/third_party/wiredtiger/src/session/session_api.c
@@ -445,6 +445,43 @@ 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_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);
+ flags = 0;
+ /*
+ * 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");
+
+ 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("off", cval.str, cval.len))
+ flags = WT_LOG_FLUSH;
+ else if (WT_STRING_MATCH("on", cval.str, cval.len))
+ flags = WT_LOG_FSYNC;
+ ret = __wt_log_flush(session, flags);
+
+err: API_END_RET(session, ret);
+}
+
+/*
* __session_log_printf --
* WT_SESSION->log_printf method.
*/
@@ -1152,6 +1189,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/third_party/wiredtiger/src/support/stat.c b/src/third_party/wiredtiger/src/support/stat.c
index 79248b0652c..b6b9dd71b3b 100644
--- a/src/third_party/wiredtiger/src/support/stat.c
+++ b/src/third_party/wiredtiger/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 operations",
"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/third_party/wiredtiger/src/txn/txn_log.c b/src/third_party/wiredtiger/src/txn/txn_log.c
index a63720d736f..7a53fb65b1f 100644
--- a/src/third_party/wiredtiger/src/txn/txn_log.c
+++ b/src/third_party/wiredtiger/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;
@@ -358,9 +358,13 @@ __wt_txn_checkpoint_log(
/*
* If this full checkpoint completed successfully and there is
* no hot backup in progress, tell the logging subsystem the
- * checkpoint LSN so that it can archive.
+ * checkpoint LSN so that it can archive. Do not update the
+ * logging checkpoint LSN if this is during a clean connection
+ * close, only during a full checkpoint. A clean close may not
+ * update any metadata LSN and we do not want to archive in
+ * that case.
*/
- if (!S2C(session)->hot_backup)
+ if (!S2C(session)->hot_backup && txn->full_ckpt)
WT_ERR(__wt_log_ckpt(session, ckpt_lsn));
/* FALLTHROUGH */