summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/api.h48
-rw-r--r--src/include/bitstring.i2
-rw-r--r--src/include/btmem.h132
-rw-r--r--src/include/btree.h40
-rw-r--r--src/include/btree.i151
-rw-r--r--src/include/buf.i37
-rw-r--r--src/include/cache.h11
-rw-r--r--src/include/cache.i17
-rw-r--r--src/include/cell.i16
-rw-r--r--src/include/column.i27
-rw-r--r--src/include/connection.h29
-rw-r--r--src/include/cursor.h12
-rw-r--r--src/include/cursor.i60
-rw-r--r--src/include/dhandle.h20
-rw-r--r--src/include/error.h6
-rw-r--r--src/include/extern.h64
-rw-r--r--src/include/extern_posix.h7
-rw-r--r--src/include/extern_win.h7
-rw-r--r--src/include/flags.h92
-rw-r--r--src/include/intpack.i30
-rw-r--r--src/include/lint.h14
-rw-r--r--src/include/log.h18
-rw-r--r--src/include/lsm.h12
-rw-r--r--src/include/misc.h19
-rw-r--r--src/include/misc.i96
-rw-r--r--src/include/mutex.h50
-rw-r--r--src/include/mutex.i42
-rw-r--r--src/include/os.h10
-rw-r--r--src/include/os_windows.h22
-rw-r--r--src/include/packing.i57
-rw-r--r--src/include/schema.h167
-rw-r--r--src/include/session.h29
-rw-r--r--src/include/stat.h14
-rw-r--r--src/include/thread_group.h2
-rw-r--r--src/include/txn.h4
-rw-r--r--src/include/txn.i3
-rw-r--r--src/include/verify_build.h1
-rw-r--r--src/include/wiredtiger.in611
-rw-r--r--src/include/wt_internal.h6
39 files changed, 1128 insertions, 857 deletions
diff --git a/src/include/api.h b/src/include/api.h
index 2783d17f825..a3636eb8040 100644
--- a/src/include/api.h
+++ b/src/include/api.h
@@ -7,22 +7,21 @@
*/
/* Standard entry points to the API: declares/initializes local variables. */
-#define API_SESSION_INIT(s, h, n, cur, dh) \
+#define API_SESSION_INIT(s, h, n, dh) \
WT_DATA_HANDLE *__olddh = (s)->dhandle; \
const char *__oldname = (s)->name; \
- (s)->cursor = (cur); \
(s)->dhandle = (dh); \
(s)->name = (s)->lastop = #h "." #n; \
-#define API_CALL_NOCONF(s, h, n, cur, dh) do { \
- API_SESSION_INIT(s, h, n, cur, dh); \
+#define API_CALL_NOCONF(s, h, n, dh) do { \
+ API_SESSION_INIT(s, h, n, dh); \
WT_ERR(WT_SESSION_CHECK_PANIC(s)); \
__wt_verbose((s), WT_VERB_API, "CALL: " #h ":" #n)
-#define API_CALL(s, h, n, cur, dh, config, cfg) do { \
- const char *cfg[] = \
+#define API_CALL(s, h, n, dh, config, cfg) do { \
+ const char *(cfg)[] = \
{ WT_CONFIG_BASE(s, h##_##n), config, NULL }; \
- API_SESSION_INIT(s, h, n, cur, dh); \
+ API_SESSION_INIT(s, h, n, dh); \
WT_ERR(WT_SESSION_CHECK_PANIC(s)); \
if ((config) != NULL) \
WT_ERR(__wt_config_check((s), \
@@ -42,17 +41,17 @@
} while (0)
/* An API call wrapped in a transaction if necessary. */
-#define TXN_API_CALL(s, h, n, cur, bt, config, cfg) do { \
+#define TXN_API_CALL(s, h, n, bt, config, cfg) do { \
bool __autotxn = false; \
- API_CALL(s, h, n, bt, cur, config, cfg); \
+ API_CALL(s, h, n, bt, config, cfg); \
__autotxn = !F_ISSET(&(s)->txn, WT_TXN_AUTOCOMMIT | WT_TXN_RUNNING);\
if (__autotxn) \
F_SET(&(s)->txn, WT_TXN_AUTOCOMMIT)
/* An API call wrapped in a transaction if necessary. */
-#define TXN_API_CALL_NOCONF(s, h, n, cur, bt) do { \
+#define TXN_API_CALL_NOCONF(s, h, n, bt) do { \
bool __autotxn = false; \
- API_CALL_NOCONF(s, h, n, cur, bt); \
+ API_CALL_NOCONF(s, h, n, bt); \
__autotxn = !F_ISSET(&(s)->txn, WT_TXN_AUTOCOMMIT | WT_TXN_RUNNING);\
if (__autotxn) \
F_SET(&(s)->txn, WT_TXN_AUTOCOMMIT)
@@ -63,15 +62,16 @@
if (__autotxn) { \
if (F_ISSET(&(s)->txn, WT_TXN_AUTOCOMMIT)) \
F_CLR(&(s)->txn, WT_TXN_AUTOCOMMIT); \
- else if (ret == 0 && !F_ISSET(&(s)->txn, WT_TXN_ERROR)) \
- ret = __wt_txn_commit((s), NULL); \
+ else if ((ret) == 0 && \
+ !F_ISSET(&(s)->txn, WT_TXN_ERROR)) \
+ (ret) = __wt_txn_commit((s), NULL); \
else { \
if (retry) \
WT_TRET(__wt_session_copy_values(s)); \
WT_TRET(__wt_txn_rollback((s), NULL)); \
- if ((ret == 0 || ret == WT_ROLLBACK) && \
+ if (((ret) == 0 || (ret) == WT_ROLLBACK) && \
(retry)) { \
- ret = 0; \
+ (ret) = 0; \
continue; \
} \
WT_TRET(__wt_session_reset_cursors(s, false)); \
@@ -98,24 +98,24 @@
#define CONNECTION_API_CALL(conn, s, n, config, cfg) \
s = (conn)->default_session; \
- API_CALL(s, WT_CONNECTION, n, NULL, NULL, config, cfg)
+ API_CALL(s, WT_CONNECTION, n, NULL, config, cfg)
#define CONNECTION_API_CALL_NOCONF(conn, s, n) \
s = (conn)->default_session; \
- API_CALL_NOCONF(s, WT_CONNECTION, n, NULL, NULL)
+ API_CALL_NOCONF(s, WT_CONNECTION, n, NULL)
#define SESSION_API_CALL(s, n, config, cfg) \
- API_CALL(s, WT_SESSION, n, NULL, NULL, config, cfg)
+ API_CALL(s, WT_SESSION, n, NULL, config, cfg)
#define SESSION_API_CALL_NOCONF(s, n) \
- API_CALL_NOCONF(s, WT_SESSION, n, NULL, NULL)
+ API_CALL_NOCONF(s, WT_SESSION, n, NULL)
#define SESSION_TXN_API_CALL(s, n, config, cfg) \
- TXN_API_CALL(s, WT_SESSION, n, NULL, NULL, config, cfg)
+ TXN_API_CALL(s, WT_SESSION, n, NULL, config, cfg)
#define CURSOR_API_CALL(cur, s, n, bt) \
(s) = (WT_SESSION_IMPL *)(cur)->session; \
- API_CALL_NOCONF(s, WT_CURSOR, n, cur, \
+ API_CALL_NOCONF(s, WT_CURSOR, n, \
((bt) == NULL) ? NULL : ((WT_BTREE *)(bt))->dhandle)
#define JOINABLE_CURSOR_CALL_CHECK(cur) \
@@ -128,7 +128,7 @@
#define CURSOR_REMOVE_API_CALL(cur, s, bt) \
(s) = (WT_SESSION_IMPL *)(cur)->session; \
- TXN_API_CALL_NOCONF(s, WT_CURSOR, remove, cur, \
+ TXN_API_CALL_NOCONF(s, WT_CURSOR, remove, \
((bt) == NULL) ? NULL : ((WT_BTREE *)(bt))->dhandle);
#define JOINABLE_CURSOR_REMOVE_API_CALL(cur, s, bt) \
@@ -137,7 +137,7 @@
#define CURSOR_UPDATE_API_CALL(cur, s, n, bt) \
(s) = (WT_SESSION_IMPL *)(cur)->session; \
- TXN_API_CALL_NOCONF(s, WT_CURSOR, n, cur, \
+ TXN_API_CALL_NOCONF(s, WT_CURSOR, n, \
((bt) == NULL) ? NULL : ((WT_BTREE *)(bt))->dhandle); \
if (F_ISSET(S2C(s), WT_CONN_IN_MEMORY) && \
!F_ISSET((WT_BTREE *)(bt), WT_BTREE_IGNORE_CACHE) && \
@@ -153,4 +153,4 @@
#define ASYNCOP_API_CALL(conn, s, n) \
s = (conn)->default_session; \
- API_CALL_NOCONF(s, asyncop, n, NULL, NULL)
+ API_CALL_NOCONF(s, asyncop, n, NULL)
diff --git a/src/include/bitstring.i b/src/include/bitstring.i
index 08746beb9b9..118dc0bba01 100644
--- a/src/include/bitstring.i
+++ b/src/include/bitstring.i
@@ -230,7 +230,7 @@ __bit_getv(uint8_t *bitf, uint64_t entry, uint8_t width)
#define __BIT_GET(len, mask) \
case len: \
if (__bit_test(bitf, bit)) \
- value |= mask; \
+ value |= (mask); \
++bit \
/* FALLTHROUGH */
diff --git a/src/include/btmem.h b/src/include/btmem.h
index 9bd835f5d09..f1bb08d2699 100644
--- a/src/include/btmem.h
+++ b/src/include/btmem.h
@@ -435,6 +435,19 @@ struct __wt_page_modify {
};
/*
+ * WT_COL_RLE --
+ * Variable-length column-store pages have an array of page entries with RLE
+ * counts greater than 1 when reading the page, so it's not necessary to walk
+ * the page counting records to find a specific entry. We can do a binary search
+ * in this array, then an offset calculation to find the cell.
+ */
+WT_PACKED_STRUCT_BEGIN(__wt_col_rle)
+ uint64_t recno; /* Record number of first repeat. */
+ uint64_t rle; /* Repeat count. */
+ uint32_t indx; /* Slot of entry in col_var. */
+WT_PACKED_STRUCT_END
+
+/*
* WT_PAGE --
* The WT_PAGE structure describes the in-memory page information.
*/
@@ -470,6 +483,7 @@ struct __wt_page {
*/
struct {
WT_REF *parent_ref; /* Parent reference */
+ uint64_t split_gen; /* Generation of last split */
struct __wt_page_index {
uint32_t entries;
@@ -479,6 +493,8 @@ struct __wt_page {
} intl;
#undef pg_intl_parent_ref
#define pg_intl_parent_ref u.intl.parent_ref
+#undef pg_intl_split_gen
+#define pg_intl_split_gen u.intl.split_gen
/*
* Macros to copy/set the index because the name is obscured to ensure
@@ -491,7 +507,7 @@ struct __wt_page {
#define WT_INTL_INDEX_GET_SAFE(page) \
((page)->u.intl.__index)
#define WT_INTL_INDEX_GET(session, page, pindex) do { \
- WT_ASSERT(session, session->split_gen != 0); \
+ WT_ASSERT(session, (session)->split_gen != 0); \
(pindex) = WT_INTL_INDEX_GET_SAFE(page); \
} while (0)
#define WT_INTL_INDEX_SET(page, v) do { \
@@ -515,53 +531,54 @@ struct __wt_page {
} while (0)
/* Row-store leaf page. */
- struct {
- WT_ROW *d; /* Key/value pairs */
- uint32_t entries; /* Entries */
- } row;
-#undef pg_row_d
-#define pg_row_d u.row.d
-#undef pg_row_entries
-#define pg_row_entries u.row.entries
+ WT_ROW *row; /* Key/value pairs */
+#undef pg_row
+#define pg_row u.row
/* Fixed-length column-store leaf page. */
- struct {
- uint8_t *bitf; /* Values */
- uint32_t entries; /* Entries */
- } col_fix;
+ uint8_t *fix_bitf; /* Values */
#undef pg_fix_bitf
-#define pg_fix_bitf u.col_fix.bitf
-#undef pg_fix_entries
-#define pg_fix_entries u.col_fix.entries
+#define pg_fix_bitf u.fix_bitf
/* Variable-length column-store leaf page. */
struct {
- WT_COL *d; /* Values */
+ WT_COL *col_var; /* Values */
/*
- * Variable-length column-store files maintain a list of
- * RLE entries on the page so it's unnecessary to walk
- * the page counting records to find a specific entry.
+ * Variable-length column-store pages have an array
+ * of page entries with RLE counts greater than 1 when
+ * reading the page, so it's not necessary to walk the
+ * page counting records to find a specific entry. We
+ * can do a binary search in this array, then an offset
+ * calculation to find the cell.
+ *
+ * It's a separate structure to keep the page structure
+ * as small as possible.
*/
- WT_COL_RLE *repeats; /* RLE array for lookups */
- uint32_t nrepeats; /* Number of repeat slots */
-
- uint32_t entries; /* Entries */
+ struct __wt_col_var_repeat {
+ uint32_t nrepeats; /* repeat slots */
+ WT_COL_RLE repeats[0]; /* lookup RLE array */
+ } *repeats;
+#define WT_COL_VAR_REPEAT_SET(page) \
+ ((page)->u.col_var.repeats != NULL)
} col_var;
-#undef pg_var_d
-#define pg_var_d u.col_var.d
+#undef pg_var
+#define pg_var u.col_var.col_var
#undef pg_var_repeats
-#define pg_var_repeats u.col_var.repeats
+#define pg_var_repeats u.col_var.repeats->repeats
#undef pg_var_nrepeats
-#define pg_var_nrepeats u.col_var.nrepeats
-#undef pg_var_entries
-#define pg_var_entries u.col_var.entries
+#define pg_var_nrepeats u.col_var.repeats->nrepeats
} u;
/*
- * The page's type and flags are positioned at the end of the WT_PAGE
- * union, it reduces cache misses in the row-store search function.
+ * Page entries, type and flags are positioned at the end of the WT_PAGE
+ * union to reduce cache misses in the row-store search function.
+ *
+ * The entries field only applies to leaf pages, internal pages use the
+ * page-index entries instead.
*/
+ uint32_t entries; /* Leaf page entries */
+
#define WT_PAGE_IS_INTERNAL(page) \
((page)->type == WT_PAGE_COL_INT || (page)->type == WT_PAGE_ROW_INT)
#define WT_PAGE_INVALID 0 /* Invalid page */
@@ -579,9 +596,8 @@ struct __wt_page {
#define WT_PAGE_DISK_MAPPED 0x04 /* Disk image in mapped memory */
#define WT_PAGE_EVICT_LRU 0x08 /* Page is on the LRU queue */
#define WT_PAGE_OVERFLOW_KEYS 0x10 /* Page has overflow keys */
-#define WT_PAGE_SPLIT_BLOCK 0x20 /* Split blocking eviction and splits */
-#define WT_PAGE_SPLIT_INSERT 0x40 /* A leaf page was split for append */
-#define WT_PAGE_UPDATE_IGNORE 0x80 /* Ignore updates on page discard */
+#define WT_PAGE_SPLIT_INSERT 0x20 /* A leaf page was split for append */
+#define WT_PAGE_UPDATE_IGNORE 0x40 /* Ignore updates on page discard */
uint8_t flags_atomic; /* Atomic flags, use F_*_ATOMIC */
uint8_t unused[2]; /* Unused padding */
@@ -618,8 +634,8 @@ struct __wt_page {
#define WT_READGEN_START_VALUE 100
#define WT_READGEN_STEP 100
uint64_t read_gen;
- /* The evict pass generation for the page */
- uint64_t evict_pass_gen;
+
+ uint64_t evict_pass_gen; /* Eviction pass generation */
size_t memory_footprint; /* Memory attached to the page */
@@ -792,11 +808,11 @@ struct __wt_row { /* On-page key, on-page cell, or off-page WT_IKEY */
* Walk the entries of an in-memory row-store leaf page.
*/
#define WT_ROW_FOREACH(page, rip, i) \
- for ((i) = (page)->pg_row_entries, \
- (rip) = (page)->pg_row_d; (i) > 0; ++(rip), --(i))
+ for ((i) = (page)->entries, \
+ (rip) = (page)->pg_row; (i) > 0; ++(rip), --(i))
#define WT_ROW_FOREACH_REVERSE(page, rip, i) \
- for ((i) = (page)->pg_row_entries, \
- (rip) = (page)->pg_row_d + ((page)->pg_row_entries - 1); \
+ for ((i) = (page)->entries, \
+ (rip) = (page)->pg_row + ((page)->entries - 1); \
(i) > 0; --(rip), --(i))
/*
@@ -804,7 +820,7 @@ struct __wt_row { /* On-page key, on-page cell, or off-page WT_IKEY */
* Return the 0-based array offset based on a WT_ROW reference.
*/
#define WT_ROW_SLOT(page, rip) \
- ((uint32_t)(((WT_ROW *)(rip)) - (page)->pg_row_d))
+ ((uint32_t)(((WT_ROW *)(rip)) - (page)->pg_row))
/*
* WT_COL --
@@ -829,18 +845,6 @@ struct __wt_col {
};
/*
- * WT_COL_RLE --
- * In variable-length column store leaf pages, we build an array of entries
- * with RLE counts greater than 1 when reading the page. We can do a binary
- * search in this array, then an offset calculation to find the cell.
- */
-WT_PACKED_STRUCT_BEGIN(__wt_col_rle)
- uint64_t recno; /* Record number of first repeat. */
- uint64_t rle; /* Repeat count. */
- uint32_t indx; /* Slot of entry in col_var.d */
-WT_PACKED_STRUCT_END
-
-/*
* WT_COL_PTR, WT_COL_PTR_SET --
* Return/Set a pointer corresponding to the data offset. (If the item does
* not exist on the page, return a NULL.)
@@ -856,15 +860,15 @@ WT_PACKED_STRUCT_END
* Walk the entries of variable-length column-store leaf page.
*/
#define WT_COL_FOREACH(page, cip, i) \
- for ((i) = (page)->pg_var_entries, \
- (cip) = (page)->pg_var_d; (i) > 0; ++(cip), --(i))
+ for ((i) = (page)->entries, \
+ (cip) = (page)->pg_var; (i) > 0; ++(cip), --(i))
/*
* WT_COL_SLOT --
* Return the 0-based array offset based on a WT_COL reference.
*/
#define WT_COL_SLOT(page, cip) \
- ((uint32_t)(((WT_COL *)cip) - (page)->pg_var_d))
+ ((uint32_t)(((WT_COL *)(cip)) - (page)->pg_var))
/*
* WT_IKEY --
@@ -973,10 +977,10 @@ struct __wt_insert {
} key;
} u;
-#define WT_INSERT_KEY_SIZE(ins) (((WT_INSERT *)ins)->u.key.size)
+#define WT_INSERT_KEY_SIZE(ins) (((WT_INSERT *)(ins))->u.key.size)
#define WT_INSERT_KEY(ins) \
- ((void *)((uint8_t *)(ins) + ((WT_INSERT *)ins)->u.key.offset))
-#define WT_INSERT_RECNO(ins) (((WT_INSERT *)ins)->u.recno)
+ ((void *)((uint8_t *)(ins) + ((WT_INSERT *)(ins))->u.key.offset))
+#define WT_INSERT_RECNO(ins) (((WT_INSERT *)(ins))->u.recno)
WT_INSERT *next[0]; /* forward-linked skip list */
};
@@ -985,9 +989,9 @@ struct __wt_insert {
* Skiplist helper macros.
*/
#define WT_SKIP_FIRST(ins_head) \
- (((ins_head) == NULL) ? NULL : ((WT_INSERT_HEAD *)ins_head)->head[0])
+ (((ins_head) == NULL) ? NULL : ((WT_INSERT_HEAD *)(ins_head))->head[0])
#define WT_SKIP_LAST(ins_head) \
- (((ins_head) == NULL) ? NULL : ((WT_INSERT_HEAD *)ins_head)->tail[0])
+ (((ins_head) == NULL) ? NULL : ((WT_INSERT_HEAD *)(ins_head))->tail[0])
#define WT_SKIP_NEXT(ins) ((ins)->next[0])
#define WT_SKIP_FOREACH(ins, ins_head) \
for ((ins) = WT_SKIP_FIRST(ins_head); \
@@ -1000,7 +1004,7 @@ struct __wt_insert {
#define WT_PAGE_ALLOC_AND_SWAP(s, page, dest, v, count) do { \
if (((v) = (dest)) == NULL) { \
WT_ERR(__wt_calloc_def(s, count, &(v))); \
- if (__wt_atomic_cas_ptr(&dest, NULL, v)) \
+ if (__wt_atomic_cas_ptr(&(dest), NULL, v)) \
__wt_cache_page_inmem_incr( \
s, page, (count) * sizeof(*(v))); \
else \
@@ -1041,7 +1045,7 @@ struct __wt_insert_head {
#define WT_ROW_INSERT_SMALLEST(page) \
((page)->modify == NULL || \
(page)->modify->mod_row_insert == NULL ? \
- NULL : (page)->modify->mod_row_insert[(page)->pg_row_entries])
+ NULL : (page)->modify->mod_row_insert[(page)->entries])
/*
* The column-store leaf page update lists are arrays of pointers to structures,
diff --git a/src/include/btree.h b/src/include/btree.h
index 595afc453c8..28fe1b94b23 100644
--- a/src/include/btree.h
+++ b/src/include/btree.h
@@ -58,6 +58,12 @@
#define WT_BTREE_DELETE_THRESHOLD 1000
/*
+ * Minimum size of the chunks (in percentage of the page size) a page gets split
+ * into during reconciliation.
+ */
+#define WT_BTREE_MIN_SPLIT_PCT 50
+
+/*
* WT_BTREE --
* A btree handle.
*/
@@ -114,23 +120,26 @@ struct __wt_btree {
int split_pct; /* Split page percent */
WT_COMPRESSOR *compressor; /* Page compressor */
WT_KEYED_ENCRYPTOR *kencryptor; /* Page encryptor */
- WT_RWLOCK *ovfl_lock; /* Overflow lock */
+ WT_RWLOCK ovfl_lock; /* Overflow lock */
uint64_t last_recno; /* Column-store last record number */
- WT_REF root; /* Root page reference */
- bool modified; /* If the tree ever modified */
- bool bulk_load_ok; /* Bulk-load is a possibility */
+ WT_REF root; /* Root page reference */
+ bool modified; /* If the tree ever modified */
+ uint8_t original; /* Newly created: bulk-load possible
+ (want a bool but needs atomic cas) */
+
+ bool lsm_primary; /* Handle is/was the LSM primary */
WT_BM *bm; /* Block manager reference */
u_int block_header; /* WT_PAGE_HEADER_BYTE_SIZE */
uint64_t checkpoint_gen; /* Checkpoint generation */
- bool include_checkpoint_txn;/* ID checks include checkpoint */
uint64_t rec_max_txn; /* Maximum txn seen (clean trees) */
uint64_t write_gen; /* Write generation */
uint64_t bytes_inmem; /* Cache bytes in memory. */
+ uint64_t bytes_dirty_intl; /* Bytes in dirty internal pages. */
uint64_t bytes_dirty_leaf; /* Bytes in dirty leaf pages. */
WT_REF *evict_ref; /* Eviction thread's location */
@@ -138,10 +147,10 @@ struct __wt_btree {
u_int evict_walk_period; /* Skip this many LRU walks */
u_int evict_walk_saved; /* Saved walk skips for checkpoints */
u_int evict_walk_skips; /* Number of walks skipped */
- u_int evict_disabled; /* Eviction disabled count */
+ int evict_disabled; /* Eviction disabled count */
volatile uint32_t evict_busy; /* Count of threads in eviction */
- bool evict_walk_reverse; /* Walk direction */
-
+ int evict_start_type; /* Start position for eviction walk
+ (see WT_EVICT_WALK_START). */
enum {
WT_CKPT_OFF, WT_CKPT_PREPARE, WT_CKPT_RUNNING
} checkpointing; /* Checkpoint in progress */
@@ -154,15 +163,14 @@ struct __wt_btree {
WT_SPINLOCK flush_lock; /* Lock to flush the tree's pages */
/* Flags values up to 0xff are reserved for WT_DHANDLE_* */
-#define WT_BTREE_BULK 0x000100 /* Bulk-load handle */
-#define WT_BTREE_IGNORE_CACHE 0x000200 /* Cache-resident object */
-#define WT_BTREE_IN_MEMORY 0x000400 /* Cache-resident object */
-#define WT_BTREE_LOOKASIDE 0x000800 /* Look-aside table */
-#define WT_BTREE_LSM_PRIMARY 0x001000 /* Handle is current LSM primary */
-#define WT_BTREE_NO_CHECKPOINT 0x002000 /* Disable checkpoints */
-#define WT_BTREE_NO_EVICTION 0x004000 /* Disable eviction */
+#define WT_BTREE_ALLOW_SPLITS 0x000100 /* Allow splits, even with no evict */
+#define WT_BTREE_BULK 0x000200 /* Bulk-load handle */
+#define WT_BTREE_CLOSED 0x000400 /* Handle closed */
+#define WT_BTREE_IGNORE_CACHE 0x000800 /* Cache-resident object */
+#define WT_BTREE_IN_MEMORY 0x001000 /* Cache-resident object */
+#define WT_BTREE_LOOKASIDE 0x002000 /* Look-aside table */
+#define WT_BTREE_NO_CHECKPOINT 0x004000 /* Disable checkpoints */
#define WT_BTREE_NO_LOGGING 0x008000 /* Disable logging */
-#define WT_BTREE_NO_RECONCILE 0x010000 /* Allow splits, even with no evict */
#define WT_BTREE_REBALANCE 0x020000 /* Handle is for rebalance */
#define WT_BTREE_SALVAGE 0x040000 /* Handle is for salvage */
#define WT_BTREE_SKIP_CKPT 0x080000 /* Handle skipped checkpoint */
diff --git a/src/include/btree.i b/src/include/btree.i
index 4f69c258621..1d6fcd6272c 100644
--- a/src/include/btree.i
+++ b/src/include/btree.i
@@ -71,6 +71,47 @@ __wt_btree_bytes_inuse(WT_SESSION_IMPL *session)
}
/*
+ * __wt_btree_bytes_evictable --
+ * Return the number of bytes that can be evicted (i.e. bytes apart from
+ * the pinned root page).
+ */
+static inline uint64_t
+__wt_btree_bytes_evictable(WT_SESSION_IMPL *session)
+{
+ WT_BTREE *btree;
+ WT_CACHE *cache;
+ WT_PAGE *root_page;
+ uint64_t bytes_inmem, bytes_root;
+
+ btree = S2BT(session);
+ cache = S2C(session)->cache;
+ root_page = btree->root.page;
+
+ bytes_inmem = btree->bytes_inmem;
+ bytes_root = root_page == NULL ? 0 : root_page->memory_footprint;
+
+ return (bytes_inmem <= bytes_root ? 0 :
+ __wt_cache_bytes_plus_overhead(cache, bytes_inmem - bytes_root));
+}
+
+/*
+ * __wt_btree_dirty_inuse --
+ * Return the number of dirty bytes in use.
+ */
+static inline uint64_t
+__wt_btree_dirty_inuse(WT_SESSION_IMPL *session)
+{
+ WT_BTREE *btree;
+ WT_CACHE *cache;
+
+ btree = S2BT(session);
+ cache = S2C(session)->cache;
+
+ return (__wt_cache_bytes_plus_overhead(cache,
+ btree->bytes_dirty_intl + btree->bytes_dirty_leaf));
+}
+
+/*
* __wt_btree_dirty_leaf_inuse --
* Return the number of bytes in use by dirty leaf pages.
*/
@@ -105,11 +146,12 @@ __wt_cache_page_inmem_incr(WT_SESSION_IMPL *session, WT_PAGE *page, size_t size)
(void)__wt_atomic_addsize(&page->memory_footprint, size);
if (__wt_page_is_modified(page)) {
(void)__wt_atomic_addsize(&page->modify->bytes_dirty, size);
- if (WT_PAGE_IS_INTERNAL(page))
+ if (WT_PAGE_IS_INTERNAL(page)) {
+ (void)__wt_atomic_add64(&btree->bytes_dirty_intl, size);
(void)__wt_atomic_add64(&cache->bytes_dirty_intl, size);
- else if (!F_ISSET(btree, WT_BTREE_LSM_PRIMARY)) {
- (void)__wt_atomic_add64(&cache->bytes_dirty_leaf, size);
+ } else if (!btree->lsm_primary) {
(void)__wt_atomic_add64(&btree->bytes_dirty_leaf, size);
+ (void)__wt_atomic_add64(&cache->bytes_dirty_leaf, size);
}
}
/* Track internal size in cache. */
@@ -238,10 +280,12 @@ __wt_cache_page_byte_dirty_decr(
if (i == 5)
return;
- if (WT_PAGE_IS_INTERNAL(page))
+ if (WT_PAGE_IS_INTERNAL(page)) {
+ __wt_cache_decr_check_uint64(session, &btree->bytes_dirty_intl,
+ decr, "WT_BTREE.bytes_dirty_intl");
__wt_cache_decr_check_uint64(session, &cache->bytes_dirty_intl,
decr, "WT_CACHE.bytes_dirty_intl");
- else if (!F_ISSET(btree, WT_BTREE_LSM_PRIMARY)) {
+ } else if (!btree->lsm_primary) {
__wt_cache_decr_check_uint64(session, &btree->bytes_dirty_leaf,
decr, "WT_BTREE.bytes_dirty_leaf");
__wt_cache_decr_check_uint64(session, &cache->bytes_dirty_leaf,
@@ -297,10 +341,11 @@ __wt_cache_dirty_incr(WT_SESSION_IMPL *session, WT_PAGE *page)
*/
size = page->memory_footprint;
if (WT_PAGE_IS_INTERNAL(page)) {
+ (void)__wt_atomic_add64(&btree->bytes_dirty_intl, size);
(void)__wt_atomic_add64(&cache->bytes_dirty_intl, size);
(void)__wt_atomic_add64(&cache->pages_dirty_intl, 1);
} else {
- if (!F_ISSET(btree, WT_BTREE_LSM_PRIMARY)) {
+ if (!btree->lsm_primary) {
(void)__wt_atomic_add64(&btree->bytes_dirty_leaf, size);
(void)__wt_atomic_add64(&cache->bytes_dirty_leaf, size);
}
@@ -368,7 +413,7 @@ __wt_cache_page_image_incr(WT_SESSION_IMPL *session, uint32_t size)
* Evict pages from the cache.
*/
static inline void
-__wt_cache_page_evict(WT_SESSION_IMPL *session, WT_PAGE *page)
+__wt_cache_page_evict(WT_SESSION_IMPL *session, WT_PAGE *page, bool rewrite)
{
WT_BTREE *btree;
WT_CACHE *cache;
@@ -392,23 +437,34 @@ __wt_cache_page_evict(WT_SESSION_IMPL *session, WT_PAGE *page)
/* Update the cache's dirty-byte count. */
if (modify != NULL && modify->bytes_dirty != 0) {
- if (WT_PAGE_IS_INTERNAL(page))
+ if (WT_PAGE_IS_INTERNAL(page)) {
+ __wt_cache_decr_zero_uint64(session,
+ &btree->bytes_dirty_intl,
+ modify->bytes_dirty, "WT_BTREE.bytes_dirty_intl");
__wt_cache_decr_zero_uint64(session,
&cache->bytes_dirty_intl,
modify->bytes_dirty, "WT_CACHE.bytes_dirty_intl");
- else if (!F_ISSET(btree, WT_BTREE_LSM_PRIMARY)) {
- __wt_cache_decr_zero_uint64(session,
- &cache->bytes_dirty_leaf,
- modify->bytes_dirty, "WT_CACHE.bytes_dirty_leaf");
+ } else if (!btree->lsm_primary) {
__wt_cache_decr_zero_uint64(session,
&btree->bytes_dirty_leaf,
modify->bytes_dirty, "WT_BTREE.bytes_dirty_leaf");
+ __wt_cache_decr_zero_uint64(session,
+ &cache->bytes_dirty_leaf,
+ modify->bytes_dirty, "WT_CACHE.bytes_dirty_leaf");
}
}
/* Update pages and bytes evicted. */
(void)__wt_atomic_add64(&cache->bytes_evict, page->memory_footprint);
- (void)__wt_atomic_addv64(&cache->pages_evict, 1);
+
+ /*
+ * Don't count rewrites as eviction: there's no guarantee we are making
+ * real progress.
+ */
+ if (rewrite)
+ (void)__wt_atomic_subv64(&cache->pages_inmem, 1);
+ else
+ (void)__wt_atomic_addv64(&cache->pages_evict, 1);
}
/*
@@ -984,7 +1040,7 @@ __wt_cursor_row_leaf_key(WT_CURSOR_BTREE *cbt, WT_ITEM *key)
if (cbt->ins == NULL) {
session = (WT_SESSION_IMPL *)cbt->iface.session;
page = cbt->ref->page;
- rip = &page->u.row.d[cbt->slot];
+ rip = &page->pg_row[cbt->slot];
WT_RET(__wt_row_leaf_key(session, page, rip, key, false));
} else {
key->data = WT_INSERT_KEY(cbt->ins);
@@ -1181,11 +1237,10 @@ __wt_leaf_page_can_split(WT_SESSION_IMPL *session, WT_PAGE *page)
* data in the last skiplist on the page. Split if there are enough
* items and the skiplist does not fit within a single disk page.
*/
-
ins_head = page->type == WT_PAGE_ROW_LEAF ?
- (page->pg_row_entries == 0 ?
+ (page->entries == 0 ?
WT_ROW_INSERT_SMALLEST(page) :
- WT_ROW_INSERT_SLOT(page, page->pg_row_entries - 1)) :
+ WT_ROW_INSERT_SLOT(page, page->entries - 1)) :
WT_COL_APPEND(page);
if (ins_head == NULL)
return (false);
@@ -1299,9 +1354,14 @@ __wt_page_can_evict(
* the original parent page's index, because evicting an internal page
* discards its WT_REF array, and a thread traversing the original
* parent page index might see a freed WT_REF.
+ *
+ * One special case where we know this is safe is if the handle is
+ * locked exclusive (e.g., when the whole tree is being evicted). In
+ * that case, no readers can be looking at an old index.
*/
- if (WT_PAGE_IS_INTERNAL(page) &&
- F_ISSET_ATOMIC(page, WT_PAGE_SPLIT_BLOCK))
+ if (!F_ISSET(session->dhandle, WT_DHANDLE_EXCLUSIVE) &&
+ WT_PAGE_IS_INTERNAL(page) && !__wt_split_obsolete(
+ session, page->pg_intl_split_gen))
return (false);
/*
@@ -1353,7 +1413,7 @@ __wt_page_release(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags)
if (page->read_gen != WT_READGEN_OLDEST ||
LF_ISSET(WT_READ_NO_EVICT) ||
F_ISSET(session, WT_SESSION_NO_EVICTION) ||
- F_ISSET(btree, WT_BTREE_NO_EVICTION) ||
+ btree->evict_disabled > 0 ||
!__wt_page_can_evict(session, ref, NULL))
return (__wt_hazard_clear(session, ref));
@@ -1473,7 +1533,7 @@ __wt_btree_lsm_over_size(WT_SESSION_IMPL *session, uint64_t maxsize)
return (false);
/* A tree that can be evicted always requires a switch. */
- if (!F_ISSET(btree, WT_BTREE_NO_EVICTION))
+ if (btree->evict_disabled == 0)
return (true);
/* Check for a tree with a single leaf page. */
@@ -1498,55 +1558,6 @@ __wt_btree_lsm_over_size(WT_SESSION_IMPL *session, uint64_t maxsize)
}
/*
- * __wt_btree_lsm_switch_primary --
- * Switch a btree handle to/from the current primary chunk of an LSM tree.
- */
-static inline void
-__wt_btree_lsm_switch_primary(WT_SESSION_IMPL *session, bool on)
-{
- WT_BTREE *btree;
- WT_CACHE *cache;
- WT_PAGE *child, *root;
- WT_PAGE_INDEX *pindex;
- WT_REF *first;
- size_t size;
-
- btree = S2BT(session);
- cache = S2C(session)->cache;
- root = btree->root.page;
-
- if (!F_ISSET(btree, WT_BTREE_LSM_PRIMARY))
- F_SET(btree, WT_BTREE_LSM_PRIMARY | WT_BTREE_NO_EVICTION);
- if (!on && F_ISSET(btree, WT_BTREE_LSM_PRIMARY)) {
- pindex = WT_INTL_INDEX_GET_SAFE(root);
- if (!F_ISSET(btree, WT_BTREE_NO_EVICTION) ||
- pindex->entries != 1)
- return;
- first = pindex->index[0];
-
- /*
- * We're reaching down into the page without a hazard pointer,
- * but that's OK because we know that no-eviction is set so the
- * page can't disappear.
- *
- * While this tree was the primary, its dirty bytes were not
- * included in the cache accounting. Fix that now before we
- * open it up for eviction.
- */
- child = first->page;
- if (first->state == WT_REF_MEM &&
- child->type == WT_PAGE_ROW_LEAF &&
- __wt_page_is_modified(child)) {
- size = child->modify->bytes_dirty;
- (void)__wt_atomic_add64(&btree->bytes_dirty_leaf, size);
- (void)__wt_atomic_add64(&cache->bytes_dirty_leaf, size);
- }
-
- F_CLR(btree, WT_BTREE_LSM_PRIMARY | WT_BTREE_NO_EVICTION);
- }
-}
-
-/*
* __wt_split_descent_race --
* Return if we raced with an internal page split when descending the tree.
*/
diff --git a/src/include/buf.i b/src/include/buf.i
index ebbee6b4633..d192e292dcf 100644
--- a/src/include/buf.i
+++ b/src/include/buf.i
@@ -37,28 +37,30 @@ __wt_buf_extend(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size)
/*
* __wt_buf_init --
- * Initialize a buffer at a specific size.
+ * Create an empty buffer at a specific size.
*/
static inline int
__wt_buf_init(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size)
{
+ /*
+ * The buffer grow function does what we need, but anticipates data
+ * referenced by the buffer. Avoid any data copy by setting data to
+ * reference the buffer's allocated memory, and clearing it.
+ */
buf->data = buf->mem;
- buf->size = 0; /* Clear existing data length */
- WT_RET(__wt_buf_grow(session, buf, size));
-
- return (0);
+ buf->size = 0;
+ return (__wt_buf_grow(session, buf, size));
}
/*
* __wt_buf_initsize --
- * Initialize a buffer at a specific size, and set the data length.
+ * Create an empty buffer at a specific size, and set the data length.
*/
static inline int
__wt_buf_initsize(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size)
{
- buf->data = buf->mem;
- buf->size = 0; /* Clear existing data length */
- WT_RET(__wt_buf_grow(session, buf, size));
+ WT_RET(__wt_buf_init(session, buf, size));
+
buf->size = size; /* Set the data length. */
return (0);
@@ -72,14 +74,15 @@ static inline int
__wt_buf_set(
WT_SESSION_IMPL *session, WT_ITEM *buf, const void *data, size_t size)
{
- /* Ensure the buffer is large enough. */
- WT_RET(__wt_buf_initsize(session, buf, size));
-
- /* Copy the data, allowing for overlapping strings. */
- if (size != 0)
- memmove(buf->mem, data, size);
-
- return (0);
+ /*
+ * The buffer grow function does what we need, but expects the data to
+ * be referenced by the buffer. If we're copying data from outside the
+ * buffer, set it up so it makes sense to the buffer grow function. (No
+ * test needed, this works if WT_ITEM.data is already set to "data".)
+ */
+ buf->data = data;
+ buf->size = size;
+ return (__wt_buf_grow(session, buf, size));
}
/*
diff --git a/src/include/cache.h b/src/include/cache.h
index 70f6169200d..04920c3585a 100644
--- a/src/include/cache.h
+++ b/src/include/cache.h
@@ -18,6 +18,15 @@
#define WT_EVICT_MAX_TREES 1000 /* Maximum walk points */
+/* Ways to position when starting an eviction walk. */
+typedef enum {
+ WT_EVICT_WALK_NEXT,
+ WT_EVICT_WALK_PREV,
+ WT_EVICT_WALK_RAND_NEXT,
+ WT_EVICT_WALK_RAND_PREV
+} WT_EVICT_WALK_START;
+#define WT_EVICT_WALK_START_NUM (WT_EVICT_WALK_RAND_PREV + 1)
+
/*
* WT_EVICT_ENTRY --
* Encapsulation of an eviction candidate.
@@ -83,7 +92,7 @@ struct __wt_cache {
uint64_t worker_evicts; /* Pages evicted by worker threads */
uint64_t evict_max_page_size; /* Largest page seen at eviction */
-#ifdef HAVE_DIAGNOSTIC
+#if defined(HAVE_DIAGNOSTIC) || defined(HAVE_VERBOSE)
struct timespec stuck_ts; /* Stuck timestamp */
#endif
diff --git a/src/include/cache.i b/src/include/cache.i
index 17ab39e97d2..90dd1bcdda8 100644
--- a/src/include/cache.i
+++ b/src/include/cache.i
@@ -360,11 +360,13 @@ __wt_cache_eviction_check(WT_SESSION_IMPL *session, bool busy, bool *didworkp)
/*
* LSM sets the no-cache-check flag when holding the LSM tree lock, in
- * that case, or when holding the schema or handle list locks (which
- * block eviction), we don't want to highjack the thread for eviction.
+ * that case, or when holding the handle list, schema or table locks
+ * (which can block checkpoints and eviction), don't block the thread
+ * for eviction.
*/
if (F_ISSET(session, WT_SESSION_NO_EVICTION |
- WT_SESSION_LOCKED_HANDLE_LIST | WT_SESSION_LOCKED_SCHEMA))
+ WT_SESSION_LOCKED_HANDLE_LIST | WT_SESSION_LOCKED_SCHEMA |
+ WT_SESSION_LOCKED_TABLE))
return (0);
/* In memory configurations don't block when the cache is full. */
@@ -372,11 +374,14 @@ __wt_cache_eviction_check(WT_SESSION_IMPL *session, bool busy, bool *didworkp)
return (0);
/*
- * Threads operating on cache-resident trees are ignored because they're
- * not contributing to the problem.
+ * Threads operating on cache-resident trees are ignored because
+ * they're not contributing to the problem. We also don't block while
+ * reading metadata because we're likely to be holding some other
+ * resources that could block checkpoints or eviction.
*/
btree = S2BT_SAFE(session);
- if (btree != NULL && F_ISSET(btree, WT_BTREE_IN_MEMORY))
+ if (btree != NULL && (F_ISSET(btree, WT_BTREE_IN_MEMORY) ||
+ WT_IS_METADATA(session->dhandle)))
return (0);
/* Check if eviction is needed. */
diff --git a/src/include/cell.i b/src/include/cell.i
index c130768e595..71c2515daf0 100644
--- a/src/include/cell.i
+++ b/src/include/cell.i
@@ -361,14 +361,12 @@ __wt_cell_pack_leaf_key(WT_CELL *cell, uint8_t prefix, size_t size)
cell->__chunk[0] = (uint8_t)
((byte << WT_CELL_SHORT_SHIFT) | WT_CELL_KEY_SHORT);
return (1);
- } else {
- byte = (uint8_t)size; /* Type + length */
- cell->__chunk[0] = (uint8_t)
- ((byte << WT_CELL_SHORT_SHIFT) |
- WT_CELL_KEY_SHORT_PFX);
- cell->__chunk[1] = prefix; /* Prefix */
- return (2);
}
+ byte = (uint8_t)size; /* Type + length */
+ cell->__chunk[0] = (uint8_t)
+ ((byte << WT_CELL_SHORT_SHIFT) | WT_CELL_KEY_SHORT_PFX);
+ cell->__chunk[1] = prefix; /* Prefix */
+ return (2);
}
if (prefix == 0) {
@@ -569,8 +567,8 @@ __wt_cell_unpack_safe(
*/
#define WT_CELL_LEN_CHK(t, len) do { \
if (start != NULL && \
- ((uint8_t *)t < (uint8_t *)start || \
- (((uint8_t *)t) + (len)) > (uint8_t *)end)) \
+ ((uint8_t *)(t) < (uint8_t *)start || \
+ (((uint8_t *)(t)) + (len)) > (uint8_t *)end)) \
return (WT_ERROR); \
} while (0)
diff --git a/src/include/column.i b/src/include/column.i
index d15f874b281..07b627315e6 100644
--- a/src/include/column.i
+++ b/src/include/column.i
@@ -108,7 +108,7 @@ __col_insert_search_match(WT_INSERT_HEAD *ins_head, uint64_t recno)
/* Fast path the check for values at the end of the skiplist. */
if (recno > WT_INSERT_RECNO(ret_ins))
return (NULL);
- else if (recno == WT_INSERT_RECNO(ret_ins))
+ if (recno == WT_INSERT_RECNO(ret_ins))
return (ret_ins);
/*
@@ -127,7 +127,7 @@ __col_insert_search_match(WT_INSERT_HEAD *ins_head, uint64_t recno)
if (cmp == 0) /* Exact match: return */
return (*insp);
- else if (cmp > 0) /* Keep going at this level */
+ if (cmp > 0) /* Keep going at this level */
insp = &(*insp)->next[i];
else { /* Drop down a level */
--i;
@@ -221,13 +221,13 @@ __col_var_last_recno(WT_REF *ref)
* This function ignores those records, our callers must handle that
* explicitly, if they care.
*/
- if (page->pg_var_nrepeats == 0)
- return (page->pg_var_entries == 0 ? 0 :
- ref->ref_recno + (page->pg_var_entries - 1));
+ if (!WT_COL_VAR_REPEAT_SET(page))
+ return (page->entries == 0 ? 0 :
+ ref->ref_recno + (page->entries - 1));
repeat = &page->pg_var_repeats[page->pg_var_nrepeats - 1];
return ((repeat->recno + repeat->rle) - 1 +
- (page->pg_var_entries - (repeat->indx + 1)));
+ (page->entries - (repeat->indx + 1)));
}
/*
@@ -246,8 +246,7 @@ __col_fix_last_recno(WT_REF *ref)
* This function ignores those records, our callers must handle that
* explicitly, if they care.
*/
- return (page->pg_fix_entries == 0 ?
- 0 : ref->ref_recno + (page->pg_fix_entries - 1));
+ return (page->entries == 0 ? 0 : ref->ref_recno + (page->entries - 1));
}
/*
@@ -273,7 +272,9 @@ __col_var_search(WT_REF *ref, uint64_t recno, uint64_t *start_recnop)
* slot for this record number, because we know any intervening records
* have repeat counts of 1.
*/
- for (base = 0, limit = page->pg_var_nrepeats; limit != 0; limit >>= 1) {
+ for (base = 0,
+ limit = WT_COL_VAR_REPEAT_SET(page) ? page->pg_var_nrepeats : 0;
+ limit != 0; limit >>= 1) {
indx = base + (limit >> 1);
repeat = page->pg_var_repeats + indx;
@@ -281,7 +282,7 @@ __col_var_search(WT_REF *ref, uint64_t recno, uint64_t *start_recnop)
recno < repeat->recno + repeat->rle) {
if (start_recnop != NULL)
*start_recnop = repeat->recno;
- return (page->pg_var_d + repeat->indx);
+ return (page->pg_var + repeat->indx);
}
if (recno < repeat->recno)
continue;
@@ -306,14 +307,14 @@ __col_var_search(WT_REF *ref, uint64_t recno, uint64_t *start_recnop)
* !!!
* The test could be written more simply as:
*
- * (recno >= start_recno + (page->pg_var_entries - start_indx))
+ * (recno >= start_recno + (page->entries - start_indx))
*
* It's split into two parts because the simpler test will overflow if
* searching for large record numbers.
*/
if (recno >= start_recno &&
- recno - start_recno >= page->pg_var_entries - start_indx)
+ recno - start_recno >= page->entries - start_indx)
return (NULL);
- return (page->pg_var_d + start_indx + (uint32_t)(recno - start_recno));
+ return (page->pg_var + start_indx + (uint32_t)(recno - start_recno));
}
diff --git a/src/include/connection.h b/src/include/connection.h
index 60ce5f55234..6c23492e926 100644
--- a/src/include/connection.h
+++ b/src/include/connection.h
@@ -107,7 +107,7 @@ struct __wt_named_extractor {
* Allocate some additional slots for internal sessions so the user cannot
* configure too few sessions for us to run.
*/
-#define WT_EXTRA_INTERNAL_SESSIONS 10
+#define WT_EXTRA_INTERNAL_SESSIONS 20
/*
* WT_CONN_CHECK_PANIC --
@@ -123,15 +123,19 @@ struct __wt_named_extractor {
* main queue and the hashed queue.
*/
#define WT_CONN_DHANDLE_INSERT(conn, dhandle, bucket) do { \
+ WT_ASSERT(session, \
+ F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST_WRITE)); \
TAILQ_INSERT_HEAD(&(conn)->dhqh, dhandle, q); \
TAILQ_INSERT_HEAD(&(conn)->dhhash[bucket], dhandle, hashq); \
- ++conn->dhandle_count; \
+ ++(conn)->dhandle_count; \
} while (0)
#define WT_CONN_DHANDLE_REMOVE(conn, dhandle, bucket) do { \
+ WT_ASSERT(session, \
+ F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST_WRITE)); \
TAILQ_REMOVE(&(conn)->dhqh, dhandle, q); \
TAILQ_REMOVE(&(conn)->dhhash[bucket], dhandle, hashq); \
- --conn->dhandle_count; \
+ --(conn)->dhandle_count; \
} while (0)
/*
@@ -163,13 +167,13 @@ struct __wt_connection_impl {
WT_SPINLOCK api_lock; /* Connection API spinlock */
WT_SPINLOCK checkpoint_lock; /* Checkpoint spinlock */
- WT_SPINLOCK dhandle_lock; /* Data handle list spinlock */
WT_SPINLOCK fh_lock; /* File handle queue spinlock */
WT_SPINLOCK metadata_lock; /* Metadata update spinlock */
WT_SPINLOCK reconfig_lock; /* Single thread reconfigure */
WT_SPINLOCK schema_lock; /* Schema operation spinlock */
- WT_SPINLOCK table_lock; /* Table creation spinlock */
+ WT_RWLOCK table_lock; /* Table list lock */
WT_SPINLOCK turtle_lock; /* Turtle file spinlock */
+ WT_RWLOCK dhandle_lock; /* Data handle list lock */
/*
* We distribute the btree page locks across a set of spin locks. Don't
@@ -262,7 +266,7 @@ struct __wt_connection_impl {
WT_TXN_GLOBAL txn_global; /* Global transaction state */
- WT_RWLOCK *hot_backup_lock; /* Hot backup serialization */
+ WT_RWLOCK hot_backup_lock; /* Hot backup serialization */
bool hot_backup; /* Hot backup in progress */
char **hot_backup_list; /* Hot backup file list */
@@ -301,6 +305,15 @@ struct __wt_connection_impl {
uint32_t evict_threads_max;/* Max eviction threads */
uint32_t evict_threads_min;/* Min eviction threads */
+ uint32_t evict_tune_datapts_needed;/* Data needed to tune */
+ struct timespec evict_tune_last_action_time;/* Time of last action */
+ struct timespec evict_tune_last_time; /* Time of last check */
+ uint32_t evict_tune_num_points; /* Number of values tried */
+ uint64_t evict_tune_pgs_last; /* Number of pages evicted */
+ uint64_t evict_tune_pg_sec_max; /* Max throughput encountered */
+ bool evict_tune_stable; /* Are we stable? */
+ uint32_t evict_tune_workers_best;/* Best performing value */
+
#define WT_STATLOG_FILENAME "WiredTigerStat.%d.%H"
WT_SESSION_IMPL *stat_session; /* Statistics log session */
wt_thread_t stat_tid; /* Statistics log thread */
@@ -326,11 +339,11 @@ struct __wt_connection_impl {
bool log_tid_set; /* Log server thread set */
WT_CONDVAR *log_file_cond; /* Log file thread wait mutex */
WT_SESSION_IMPL *log_file_session;/* Log file thread session */
- wt_thread_t log_file_tid; /* Log file thread thread */
+ wt_thread_t log_file_tid; /* Log file thread */
bool log_file_tid_set;/* Log file thread set */
WT_CONDVAR *log_wrlsn_cond;/* Log write lsn thread wait mutex */
WT_SESSION_IMPL *log_wrlsn_session;/* Log write lsn thread session */
- wt_thread_t log_wrlsn_tid; /* Log write lsn thread thread */
+ wt_thread_t log_wrlsn_tid; /* Log write lsn thread */
bool log_wrlsn_tid_set;/* Log write lsn thread set */
WT_LOG *log; /* Logging structure */
WT_COMPRESSOR *log_compressor;/* Logging compressor */
diff --git a/src/include/cursor.h b/src/include/cursor.h
index d522abc2a56..f32b4250d30 100644
--- a/src/include/cursor.h
+++ b/src/include/cursor.h
@@ -52,8 +52,8 @@
{ 0 }, /* recno raw buffer */ \
NULL, /* json_private */ \
NULL, /* lang_private */ \
- { NULL, 0, 0, NULL, 0 }, /* WT_ITEM key */ \
- { NULL, 0, 0, NULL, 0 }, /* WT_ITEM value */ \
+ { NULL, 0, NULL, 0, 0 }, /* WT_ITEM key */ \
+ { NULL, 0, NULL, 0, 0 }, /* WT_ITEM value */ \
0, /* int saved_err */ \
NULL, /* internal_uri */ \
0 /* uint32_t flags */ \
@@ -73,7 +73,7 @@ struct __wt_cursor_backup {
#define WT_CURBACKUP_LOCKER 0x01 /* Hot-backup started */
uint8_t flags;
};
-#define WT_CURSOR_BACKUP_ID(cursor) (((WT_CURSOR_BACKUP *)cursor)->maxid)
+#define WT_CURSOR_BACKUP_ID(cursor) (((WT_CURSOR_BACKUP *)(cursor))->maxid)
struct __wt_cursor_btree {
WT_CURSOR iface;
@@ -474,7 +474,7 @@ struct __wt_cursor_stat {
* Return a reference to a statistic cursor's stats structures.
*/
#define WT_CURSOR_STATS(cursor) \
- (((WT_CURSOR_STAT *)cursor)->stats)
+ (((WT_CURSOR_STAT *)(cursor))->stats)
struct __wt_cursor_table {
WT_CURSOR iface;
@@ -493,7 +493,7 @@ struct __wt_cursor_table {
};
#define WT_CURSOR_PRIMARY(cursor) \
- (((WT_CURSOR_TABLE *)cursor)->cg_cursors[0])
+ (((WT_CURSOR_TABLE *)(cursor))->cg_cursors[0])
#define WT_CURSOR_RECNO(cursor) WT_STREQ((cursor)->key_format, "r")
@@ -550,4 +550,4 @@ struct __wt_cursor_table {
} while (0)
#define WT_CURSOR_RAW_OK \
- WT_CURSTD_DUMP_HEX | WT_CURSTD_DUMP_PRINT | WT_CURSTD_RAW
+ (WT_CURSTD_DUMP_HEX | WT_CURSTD_DUMP_PRINT | WT_CURSTD_RAW)
diff --git a/src/include/cursor.i b/src/include/cursor.i
index c3fcef9a13d..12044e0e228 100644
--- a/src/include/cursor.i
+++ b/src/include/cursor.i
@@ -76,34 +76,19 @@ __cursor_leave(WT_SESSION_IMPL *session)
}
/*
- * __curfile_enter --
- * Activate a file cursor.
- */
-static inline int
-__curfile_enter(WT_CURSOR_BTREE *cbt)
-{
- WT_SESSION_IMPL *session;
-
- session = (WT_SESSION_IMPL *)cbt->iface.session;
-
- if (!F_ISSET(cbt, WT_CBT_NO_TXN))
- WT_RET(__cursor_enter(session));
- F_SET(cbt, WT_CBT_ACTIVE);
- return (0);
-}
-
-/*
- * __curfile_leave --
- * Clear a file cursor's position.
+ * __cursor_reset --
+ * Reset the cursor, it no longer holds any position.
*/
static inline int
-__curfile_leave(WT_CURSOR_BTREE *cbt)
+__cursor_reset(WT_CURSOR_BTREE *cbt)
{
WT_DECL_RET;
WT_SESSION_IMPL *session;
session = (WT_SESSION_IMPL *)cbt->iface.session;
+ __cursor_pos_clear(cbt);
+
/* If the cursor was active, deactivate it. */
if (F_ISSET(cbt, WT_CBT_ACTIVE)) {
if (!F_ISSET(cbt, WT_CBT_NO_TXN))
@@ -111,12 +96,15 @@ __curfile_leave(WT_CURSOR_BTREE *cbt)
F_CLR(cbt, WT_CBT_ACTIVE);
}
+ /* If we're not holding a cursor reference, we're done. */
+ if (cbt->ref == NULL)
+ return (0);
+
/*
* If we were scanning and saw a lot of deleted records on this page,
* try to evict the page when we release it.
*/
- if (cbt->ref != NULL &&
- cbt->page_deleted_count > WT_BTREE_DELETE_THRESHOLD)
+ if (cbt->page_deleted_count > WT_BTREE_DELETE_THRESHOLD)
__wt_page_evict_soon(session, cbt->ref);
cbt->page_deleted_count = 0;
@@ -247,7 +235,7 @@ __cursor_func_init(WT_CURSOR_BTREE *cbt, bool reenter)
#ifdef HAVE_DIAGNOSTIC
__wt_cursor_key_order_reset(cbt);
#endif
- WT_RET(__curfile_leave(cbt));
+ WT_RET(__cursor_reset(cbt));
}
/*
@@ -259,8 +247,12 @@ __cursor_func_init(WT_CURSOR_BTREE *cbt, bool reenter)
/* If the transaction is idle, check that the cache isn't full. */
WT_RET(__wt_txn_idle_cache_check(session));
- if (!F_ISSET(cbt, WT_CBT_ACTIVE))
- WT_RET(__curfile_enter(cbt));
+ /* Activate the file cursor. */
+ if (!F_ISSET(cbt, WT_CBT_ACTIVE)) {
+ if (!F_ISSET(cbt, WT_CBT_NO_TXN))
+ WT_RET(__cursor_enter(session));
+ F_SET(cbt, WT_CBT_ACTIVE);
+ }
/*
* If this is an ordinary transactional cursor, make sure we are set up
@@ -272,24 +264,6 @@ __cursor_func_init(WT_CURSOR_BTREE *cbt, bool reenter)
}
/*
- * __cursor_reset --
- * Reset the cursor.
- */
-static inline int
-__cursor_reset(WT_CURSOR_BTREE *cbt)
-{
- WT_DECL_RET;
-
- /*
- * The cursor is leaving the API, and no longer holds any position,
- * generally called to clean up the cursor after an error.
- */
- ret = __curfile_leave(cbt);
- __cursor_pos_clear(cbt);
- return (ret);
-}
-
-/*
* __cursor_row_slot_return --
* Return a row-store leaf page slot's K/V pair.
*/
diff --git a/src/include/dhandle.h b/src/include/dhandle.h
index d7802bb319b..8861e96112b 100644
--- a/src/include/dhandle.h
+++ b/src/include/dhandle.h
@@ -37,12 +37,30 @@
#define WT_SESSION_META_DHANDLE(s) \
(((WT_CURSOR_BTREE *)((s)->meta_cursor))->btree->dhandle)
+#define WT_DHANDLE_ACQUIRE(dhandle) \
+ (void)__wt_atomic_add32(&(dhandle)->session_ref, 1)
+
+#define WT_DHANDLE_RELEASE(dhandle) \
+ (void)__wt_atomic_sub32(&(dhandle)->session_ref, 1)
+
+#define WT_DHANDLE_NEXT(session, dhandle, head, field) do { \
+ WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST));\
+ if ((dhandle) == NULL) \
+ (dhandle) = TAILQ_FIRST(head); \
+ else { \
+ WT_DHANDLE_RELEASE(dhandle); \
+ (dhandle) = TAILQ_NEXT(dhandle, field); \
+ } \
+ if ((dhandle) != NULL) \
+ WT_DHANDLE_ACQUIRE(dhandle); \
+} while (0)
+
/*
* WT_DATA_HANDLE --
* A handle for a generic named data source.
*/
struct __wt_data_handle {
- WT_RWLOCK *rwlock; /* Lock for shared/exclusive ops */
+ WT_RWLOCK rwlock; /* Lock for shared/exclusive ops */
TAILQ_ENTRY(__wt_data_handle) q;
TAILQ_ENTRY(__wt_data_handle) hashq;
diff --git a/src/include/error.h b/src/include/error.h
index bbb7f989332..c338acb370f 100644
--- a/src/include/error.h
+++ b/src/include/error.h
@@ -67,14 +67,16 @@
int __ret; \
if ((__ret = (a)) != 0 && \
(__ret == WT_PANIC || \
- ret == 0 || ret == WT_DUPLICATE_KEY || ret == WT_NOTFOUND)) \
+ ret == 0 || ret == WT_DUPLICATE_KEY || \
+ ret == WT_NOTFOUND || ret == WT_RESTART)) \
ret = __ret; \
} while (0)
#define WT_TRET_ERROR_OK(a, e) do { \
int __ret; \
if ((__ret = (a)) != 0 && __ret != (e) && \
(__ret == WT_PANIC || \
- ret == 0 || ret == WT_DUPLICATE_KEY || ret == WT_NOTFOUND)) \
+ ret == 0 || ret == WT_DUPLICATE_KEY || \
+ ret == WT_NOTFOUND || ret == WT_RESTART)) \
ret = __ret; \
} while (0)
#define WT_TRET_NOTFOUND_OK(a) WT_TRET_ERROR_OK(a, WT_NOTFOUND)
diff --git a/src/include/extern.h b/src/include/extern.h
index be042bcd6cb..55ba1bada7c 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -98,14 +98,14 @@ extern void __wt_cursor_key_order_reset(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_A
extern void __wt_btcur_iterate_setup(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_next(WT_CURSOR_BTREE *cbt, bool truncating) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_prev(WT_CURSOR_BTREE *cbt, bool truncating) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern bool __wt_cursor_valid(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_reset(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_search(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_search_near(WT_CURSOR_BTREE *cbt, int *exactp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_insert(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_btcur_update_check(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_btcur_insert_check(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_remove(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_update(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_btcur_next_random(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_compare(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *cmpp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_equals(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *equalp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btcur_range_truncate(WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -126,6 +126,7 @@ extern int __wt_delete_page(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp)
extern void __wt_delete_page_rollback(WT_SESSION_IMPL *session, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern bool __wt_delete_page_skip(WT_SESSION_IMPL *session, WT_REF *ref, bool visible_all) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_delete_page_instantiate(WT_SESSION_IMPL *session, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_ref_out_int(WT_SESSION_IMPL *session, WT_REF *ref, bool rewrite) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_ref_out(WT_SESSION_IMPL *session, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE **pagep) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_free_ref( WT_SESSION_IMPL *session, WT_REF *ref, int page_type, bool free_pages) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -133,10 +134,10 @@ extern void __wt_free_ref_index(WT_SESSION_IMPL *session, WT_PAGE *page, WT_PAGE
extern void __wt_free_update_list(WT_SESSION_IMPL *session, WT_UPDATE *upd) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btree_open(WT_SESSION_IMPL *session, const char *op_cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btree_close(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_btree_discard(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_root_ref_init(WT_REF *root_ref, WT_PAGE *root, bool is_recno) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btree_tree_open( WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btree_new_leaf_page(WT_SESSION_IMPL *session, WT_PAGE **pagep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_btree_evictable(WT_SESSION_IMPL *session, bool on) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_btree_huffman_open(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_btree_huffman_close(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_bt_read(WT_SESSION_IMPL *session, WT_ITEM *buf, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -150,6 +151,9 @@ extern int __wt_ovfl_cache(WT_SESSION_IMPL *session, WT_PAGE *page, void *cookie
extern int __wt_ovfl_discard(WT_SESSION_IMPL *session, WT_CELL *cell) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_page_alloc(WT_SESSION_IMPL *session, uint8_t type, uint32_t alloc_entries, bool alloc_refs, WT_PAGE **pagep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_page_inmem(WT_SESSION_IMPL *session, WT_REF *ref, const void *image, size_t memsize, uint32_t flags, WT_PAGE **pagep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_row_random_leaf(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_random_descent(WT_SESSION_IMPL *session, WT_REF **refp, bool eviction) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_btcur_next_random(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_las_remove_block(WT_SESSION_IMPL *session, WT_CURSOR *cursor, uint32_t btree_id, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int
__wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags
@@ -158,8 +162,10 @@ __wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags
#endif
) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_bt_rebalance(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_key_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_kv_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_bt_salvage(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern bool __wt_split_obsolete(WT_SESSION_IMPL *session, uint64_t split_gen) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_split_stash_discard(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_split_stash_discard_all( WT_SESSION_IMPL *session_safe, WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_multi_to_ref(WT_SESSION_IMPL *session, WT_PAGE *page, WT_MULTI *multi, WT_REF **refp, size_t *incrp, bool closing) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -192,8 +198,6 @@ extern WT_UPDATE *__wt_update_obsolete_check( WT_SESSION_IMPL *session, WT_PAGE
extern void __wt_update_obsolete_free( WT_SESSION_IMPL *session, WT_PAGE *page, WT_UPDATE *upd) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_search_insert(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_INSERT_HEAD *ins_head, WT_ITEM *srch_key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_row_search(WT_SESSION_IMPL *session, WT_ITEM *srch_key, WT_REF *leaf, WT_CURSOR_BTREE *cbt, bool insert) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_row_random_leaf(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_row_random_descent(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_las_stats_update(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_las_create(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_las_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -254,6 +258,7 @@ extern WT_THREAD_RET __wt_cache_pool_server(void *arg) WT_GCC_FUNC_DECL_ATTRIBUT
extern int __wt_checkpoint_server_create(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_checkpoint_server_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_checkpoint_signal(WT_SESSION_IMPL *session, wt_off_t logsize) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_conn_dhandle_alloc( WT_SESSION_IMPL *session, const char *uri, const char *checkpoint) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_conn_dhandle_find( WT_SESSION_IMPL *session, const char *uri, const char *checkpoint) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_conn_btree_sync_and_close(WT_SESSION_IMPL *session, bool final, bool force) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_conn_btree_open( WT_SESSION_IMPL *session, const char *cfg[], uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -262,7 +267,7 @@ extern int __wt_conn_dhandle_close_all( WT_SESSION_IMPL *session, const char *ur
extern int __wt_conn_dhandle_discard_single( WT_SESSION_IMPL *session, bool final, bool force) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_conn_dhandle_discard(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_connection_init(WT_CONNECTION_IMPL *conn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_connection_destroy(WT_CONNECTION_IMPL *conn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_connection_destroy(WT_CONNECTION_IMPL *conn) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_logmgr_reconfig(WT_SESSION_IMPL *session, const char **cfg) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_log_truncate_files( WT_SESSION_IMPL *session, WT_CURSOR *cursor, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_log_wrlsn(WT_SESSION_IMPL *session, int *yield) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -285,7 +290,7 @@ extern int __wt_curconfig_open(WT_SESSION_IMPL *session, const char *uri, const
extern int __wt_curds_open( WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_DATA_SOURCE *dsrc, WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_curdump_create(WT_CURSOR *child, WT_CURSOR *owner, WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_curfile_next_random(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_curfile_update_check(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_curfile_insert_check(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_curfile_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_curindex_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_curjoin_joined(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -294,7 +299,7 @@ extern int __wt_curjoin_join(WT_SESSION_IMPL *session, WT_CURSOR_JOIN *cjoin, WT
extern int __wt_json_alloc_unpack(WT_SESSION_IMPL *session, const void *buffer, size_t size, const char *fmt, WT_CURSOR_JSON *json, bool iskey, va_list ap) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_json_close(WT_SESSION_IMPL *session, WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern size_t __wt_json_unpack_char(u_char ch, u_char *buf, size_t bufsz, bool force_unicode) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
-extern void __wt_json_column_init(WT_CURSOR *cursor, const char *keyformat, const WT_CONFIG_ITEM *idxconf, const WT_CONFIG_ITEM *colconf) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_json_column_init(WT_CURSOR *cursor, const char *uri, const char *keyformat, const WT_CONFIG_ITEM *idxconf, const WT_CONFIG_ITEM *colconf) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_json_token(WT_SESSION *wt_session, const char *src, int *toktype, const char **tokstart, size_t *toklen) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default"))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern const char *__wt_json_tokname(int toktype) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
extern int __wt_json_to_item(WT_SESSION_IMPL *session, const char *jstr, const char *format, WT_CURSOR_JSON *json, bool iskey, WT_ITEM *item) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -315,7 +320,7 @@ extern int __wt_cursor_equals_notsup(WT_CURSOR *cursor, WT_CURSOR *other, int *e
extern int __wt_cursor_search_near_notsup(WT_CURSOR *cursor, int *exact) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_cursor_reconfigure_notsup(WT_CURSOR *cursor, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_cursor_set_notsup(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_cursor_kv_not_set(WT_CURSOR *cursor, bool key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_cursor_kv_not_set(WT_CURSOR *cursor, bool key) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_cursor_get_key(WT_CURSOR *cursor, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_cursor_set_key(WT_CURSOR *cursor, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_cursor_get_raw_key(WT_CURSOR *cursor, WT_ITEM *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -352,7 +357,7 @@ extern int __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int
extern bool __wt_page_evict_urgent(WT_SESSION_IMPL *session, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_evict_priority_set(WT_SESSION_IMPL *session, uint64_t v) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_evict_priority_clear(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_cache_dump(WT_SESSION_IMPL *session, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_verbose_dump_cache(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_page_release_evict(WT_SESSION_IMPL *session, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_curstat_cache_walk(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -399,11 +404,10 @@ extern int __wt_logop_row_truncate_unpack( WT_SESSION_IMPL *session, const uint8
extern int __wt_logop_row_truncate_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_txn_op_printlog(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_log_slot_activate(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_log_slot_switch( WT_SESSION_IMPL *session, WT_MYSLOT *myslot, bool retry, bool forced) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_log_slot_new(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_log_slot_switch(WT_SESSION_IMPL *session, WT_MYSLOT *myslot, bool retry, bool forced, bool *did_work) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_log_slot_init(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_log_slot_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_log_slot_join(WT_SESSION_IMPL *session, uint64_t mysize, uint32_t flags, WT_MYSLOT *myslot) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_log_slot_join(WT_SESSION_IMPL *session, uint64_t mysize, uint32_t flags, WT_MYSLOT *myslot) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int64_t __wt_log_slot_release(WT_SESSION_IMPL *session, WT_MYSLOT *myslot, int64_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_log_slot_free(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_clsm_request_switch(WT_CURSOR_LSM *clsm) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -453,13 +457,14 @@ extern int __wt_lsm_work_bloom(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
extern int __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, WT_LSM_CHUNK *chunk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_worker_start(WT_SESSION_IMPL *session, WT_LSM_WORKER_ARGS *args) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_lsm_worker_stop(WT_SESSION_IMPL *session, WT_LSM_WORKER_ARGS *args) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_meta_apply_all(WT_SESSION_IMPL *session, int (*file_func)(WT_SESSION_IMPL *, const char *[]), int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_meta_checkpoint(WT_SESSION_IMPL *session, const char *fname, const char *checkpoint, WT_CKPT *ckpt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_meta_checkpoint_last_name( WT_SESSION_IMPL *session, const char *fname, const char **namep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_meta_checkpoint_clear(WT_SESSION_IMPL *session, const char *fname) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_meta_ckptlist_get( WT_SESSION_IMPL *session, const char *fname, WT_CKPT **ckptbasep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_meta_ckptlist_set(WT_SESSION_IMPL *session, const char *fname, WT_CKPT *ckptbase, WT_LSN *ckptlsn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_meta_ckptlist_free(WT_SESSION_IMPL *session, WT_CKPT *ckptbase) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_meta_ckptlist_free(WT_SESSION_IMPL *session, WT_CKPT **ckptbasep) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_meta_checkpoint_free(WT_SESSION_IMPL *session, WT_CKPT *ckpt) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_ext_metadata_insert(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *key, const char *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_ext_metadata_remove( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -613,11 +618,9 @@ extern void __wt_session_close_cache(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_
extern int __wt_session_get_btree(WT_SESSION_IMPL *session, const char *uri, const char *checkpoint, const char *cfg[], uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_session_lock_checkpoint(WT_SESSION_IMPL *session, const char *checkpoint) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_salvage(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_cond_auto_alloc( WT_SESSION_IMPL *session, const char *name, bool is_signalled, uint64_t min, uint64_t max, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_cond_auto_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_cond_auto_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, bool progress, bool *signalled) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_cond_auto_wait( WT_SESSION_IMPL *session, WT_CONDVAR *cond, bool progress) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_cond_auto_destroy(WT_SESSION_IMPL *session, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_cond_auto_alloc(WT_SESSION_IMPL *session, const char *name, uint64_t min, uint64_t max, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_cond_auto_wait_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond, bool progress, bool (*run_func)(WT_SESSION_IMPL *), bool *signalled) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_cond_auto_wait(WT_SESSION_IMPL *session, WT_CONDVAR *cond, bool progress, bool (*run_func)(WT_SESSION_IMPL *)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_decrypt(WT_SESSION_IMPL *session, WT_ENCRYPTOR *encryptor, size_t skip, WT_ITEM *in, WT_ITEM *out) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_encrypt(WT_SESSION_IMPL *session, WT_KEYED_ENCRYPTOR *kencryptor, size_t skip, WT_ITEM *in, WT_ITEM *out) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_encrypt_size(WT_SESSION_IMPL *session, WT_KEYED_ENCRYPTOR *kencryptor, size_t incoming_size, size_t *sizep) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -671,16 +674,16 @@ extern void __wt_huffman_close(WT_SESSION_IMPL *session, void *huffman_arg) WT_G
extern void __wt_print_huffman_code(void *huffman_arg, uint16_t symbol) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_huffman_encode(WT_SESSION_IMPL *session, void *huffman_arg, const uint8_t *from_arg, size_t from_len, WT_ITEM *to_buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_huffman_decode(WT_SESSION_IMPL *session, void *huffman_arg, const uint8_t *from_arg, size_t from_len, WT_ITEM *to_buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_rwlock_alloc( WT_SESSION_IMPL *session, WT_RWLOCK **rwlockp, const char *name) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_try_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_readlock_spin(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_readunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_try_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_writeunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_rwlock_destroy(WT_SESSION_IMPL *session, WT_RWLOCK **rwlockp) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern bool __wt_rwlock_islocked(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_rwlock_init(WT_SESSION_IMPL *session, WT_RWLOCK *l) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_rwlock_destroy(WT_SESSION_IMPL *session, WT_RWLOCK *l) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_try_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *l) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_readlock_spin(WT_SESSION_IMPL *session, WT_RWLOCK *l) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *l) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_readunlock(WT_SESSION_IMPL *session, WT_RWLOCK *l) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_try_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *l) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *l) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_writeunlock(WT_SESSION_IMPL *session, WT_RWLOCK *l) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern bool __wt_rwlock_islocked(WT_SESSION_IMPL *session, WT_RWLOCK *l) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern uint32_t __wt_nlpo2_round(uint32_t v) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern uint32_t __wt_nlpo2(uint32_t v) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern uint32_t __wt_log2_int(uint32_t n) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -689,6 +692,7 @@ extern uint32_t __wt_rduppo2(uint32_t n, uint32_t po2) WT_GCC_FUNC_DECL_ATTRIBUT
extern void __wt_random_init(WT_RAND_STATE volatile *rnd_state) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
extern void __wt_random_init_seed( WT_SESSION_IMPL *session, WT_RAND_STATE volatile *rnd_state) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
extern uint32_t __wt_random(WT_RAND_STATE volatile *rnd_state) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
+extern uint64_t __wt_random64(WT_RAND_STATE volatile *rnd_state) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
extern int __wt_buf_grow_worker(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_buf_fmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_buf_catfmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -728,6 +732,7 @@ extern int __wt_thread_group_resize( WT_SESSION_IMPL *session, WT_THREAD_GROUP *
extern int __wt_thread_group_create( WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, const char *name, uint32_t min, uint32_t max, uint32_t flags, int (*run_func)(WT_SESSION_IMPL *session, WT_THREAD *context)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_thread_group_destroy(WT_SESSION_IMPL *session, WT_THREAD_GROUP *group) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_thread_group_start_one( WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, bool wait) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_thread_group_stop_one( WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, bool wait) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_txn_release_snapshot(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_txn_get_snapshot(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_txn_update_oldest(WT_SESSION_IMPL *session, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -740,6 +745,7 @@ extern void __wt_txn_stats_update(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATT
extern void __wt_txn_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_txn_global_init(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_txn_global_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_verbose_dump_txn(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_checkpoint_get_handles(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[], bool waiting) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
diff --git a/src/include/extern_posix.h b/src/include/extern_posix.h
index 5acb7b0ed27..57d94e392d1 100644
--- a/src/include/extern_posix.h
+++ b/src/include/extern_posix.h
@@ -12,8 +12,8 @@ extern int __wt_posix_map(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, void *mapp
extern int __wt_posix_map_preload(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, const void *map, size_t length, void *mapped_cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_posix_map_discard(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, void *map, size_t length, void *mapped_cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_posix_unmap(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, void *mapped_region, size_t len, void *mapped_cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_cond_alloc(WT_SESSION_IMPL *session, const char *name, bool is_signalled, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_cond_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs, bool *signalled) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_cond_alloc(WT_SESSION_IMPL *session, const char *name, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_cond_wait_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs, bool (*run_func)(WT_SESSION_IMPL *), bool *signalled) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_cond_destroy(WT_SESSION_IMPL *session, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_once(void (*init_routine)(void)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -24,8 +24,9 @@ extern bool __wt_has_priv(void) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")
extern void __wt_stream_set_line_buffer(FILE *fp) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
extern void __wt_stream_set_no_buffer(FILE *fp) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
extern void __wt_sleep(uint64_t seconds, uint64_t micro_seconds) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
+extern int __wt_vsnprintf_len_incr( char *buf, size_t size, size_t *retsizep, const char *fmt, va_list ap) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default"))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern int __wt_thread_create(WT_SESSION_IMPL *session, wt_thread_t *tidret, WT_THREAD_CALLBACK(*func)(void *), void *arg) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_thread_join(WT_SESSION_IMPL *session, wt_thread_t tid) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_thread_id(char *buf, size_t buflen) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
+extern int __wt_thread_id(char *buf, size_t buflen) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default"))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
extern void __wt_epoch(WT_SESSION_IMPL *session, struct timespec *tsp) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
extern void __wt_yield(void) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
diff --git a/src/include/extern_win.h b/src/include/extern_win.h
index 11b45f11304..43127a0c79f 100644
--- a/src/include/extern_win.h
+++ b/src/include/extern_win.h
@@ -10,8 +10,8 @@ extern int __wt_os_win(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((war
extern int __wt_getenv(WT_SESSION_IMPL *session, const char *variable, const char **envp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_win_map(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, void *mapped_regionp, size_t *lenp, void *mapped_cookiep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_win_unmap(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, void *mapped_region, size_t length, void *mapped_cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_cond_alloc(WT_SESSION_IMPL *session, const char *name, bool is_signalled, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_cond_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs, bool *signalled) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_cond_alloc(WT_SESSION_IMPL *session, const char *name, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern void __wt_cond_wait_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs, bool (*run_func)(WT_SESSION_IMPL *), bool *signalled) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_cond_destroy(WT_SESSION_IMPL *session, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_once(void (*init_routine)(void)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -22,9 +22,10 @@ extern bool __wt_has_priv(void) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")
extern void __wt_stream_set_line_buffer(FILE *fp) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_stream_set_no_buffer(FILE *fp) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_sleep(uint64_t seconds, uint64_t micro_seconds) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_vsnprintf_len_incr( char *buf, size_t size, size_t *retsizep, const char *fmt, va_list ap) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_thread_create(WT_SESSION_IMPL *session, wt_thread_t *tidret, WT_THREAD_CALLBACK(*func)(void *), void *arg) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_thread_join(WT_SESSION_IMPL *session, wt_thread_t tid) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern void __wt_thread_id(char *buf, size_t buflen) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_thread_id(char *buf, size_t buflen) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern void __wt_epoch(WT_SESSION_IMPL *session, struct timespec *tsp) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_to_utf16_string( WT_SESSION_IMPL *session, const char*utf8, WT_ITEM **outbuf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_to_utf8_string( WT_SESSION_IMPL *session, const wchar_t*wide, WT_ITEM **outbuf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
diff --git a/src/include/flags.h b/src/include/flags.h
index e7a5ba066df..f26a45c68f5 100644
--- a/src/include/flags.h
+++ b/src/include/flags.h
@@ -6,19 +6,19 @@
#define WT_CONN_CACHE_POOL 0x00000001
#define WT_CONN_CKPT_SYNC 0x00000002
#define WT_CONN_CLOSING 0x00000004
-#define WT_CONN_EVICTION_RUN 0x00000008
-#define WT_CONN_IN_MEMORY 0x00000010
-#define WT_CONN_LAS_OPEN 0x00000020
-#define WT_CONN_LEAK_MEMORY 0x00000040
-#define WT_CONN_LOG_SERVER_RUN 0x00000080
+#define WT_CONN_CLOSING_NO_MORE_OPENS 0x00000008
+#define WT_CONN_EVICTION_RUN 0x00000010
+#define WT_CONN_IN_MEMORY 0x00000020
+#define WT_CONN_LAS_OPEN 0x00000040
+#define WT_CONN_LEAK_MEMORY 0x00000080
#define WT_CONN_LSM_MERGE 0x00000100
#define WT_CONN_PANIC 0x00000200
#define WT_CONN_READONLY 0x00000400
#define WT_CONN_RECOVERING 0x00000800
#define WT_CONN_SERVER_ASYNC 0x00001000
#define WT_CONN_SERVER_CHECKPOINT 0x00002000
-#define WT_CONN_SERVER_LSM 0x00004000
-#define WT_CONN_SERVER_RUN 0x00008000
+#define WT_CONN_SERVER_LOG 0x00004000
+#define WT_CONN_SERVER_LSM 0x00008000
#define WT_CONN_SERVER_STATISTICS 0x00010000
#define WT_CONN_SERVER_SWEEP 0x00020000
#define WT_CONN_WAS_BACKUP 0x00040000
@@ -53,22 +53,24 @@
#define WT_SESSION_CAN_WAIT 0x00000001
#define WT_SESSION_INTERNAL 0x00000002
#define WT_SESSION_LOCKED_CHECKPOINT 0x00000004
-#define WT_SESSION_LOCKED_HANDLE_LIST 0x00000008
-#define WT_SESSION_LOCKED_METADATA 0x00000010
-#define WT_SESSION_LOCKED_PASS 0x00000020
-#define WT_SESSION_LOCKED_SCHEMA 0x00000040
-#define WT_SESSION_LOCKED_SLOT 0x00000080
-#define WT_SESSION_LOCKED_TABLE 0x00000100
-#define WT_SESSION_LOCKED_TURTLE 0x00000200
-#define WT_SESSION_LOGGING_INMEM 0x00000400
-#define WT_SESSION_LOOKASIDE_CURSOR 0x00000800
-#define WT_SESSION_NO_CACHE 0x00001000
-#define WT_SESSION_NO_DATA_HANDLES 0x00002000
-#define WT_SESSION_NO_EVICTION 0x00004000
-#define WT_SESSION_NO_LOGGING 0x00008000
-#define WT_SESSION_NO_SCHEMA_LOCK 0x00010000
-#define WT_SESSION_QUIET_CORRUPT_FILE 0x00020000
-#define WT_SESSION_SERVER_ASYNC 0x00040000
+#define WT_SESSION_LOCKED_HANDLE_LIST_READ 0x00000008
+#define WT_SESSION_LOCKED_HANDLE_LIST_WRITE 0x00000010
+#define WT_SESSION_LOCKED_METADATA 0x00000020
+#define WT_SESSION_LOCKED_PASS 0x00000040
+#define WT_SESSION_LOCKED_SCHEMA 0x00000080
+#define WT_SESSION_LOCKED_SLOT 0x00000100
+#define WT_SESSION_LOCKED_TABLE_READ 0x00000200
+#define WT_SESSION_LOCKED_TABLE_WRITE 0x00000400
+#define WT_SESSION_LOCKED_TURTLE 0x00000800
+#define WT_SESSION_LOGGING_INMEM 0x00001000
+#define WT_SESSION_LOOKASIDE_CURSOR 0x00002000
+#define WT_SESSION_NO_CACHE 0x00004000
+#define WT_SESSION_NO_DATA_HANDLES 0x00008000
+#define WT_SESSION_NO_EVICTION 0x00010000
+#define WT_SESSION_NO_LOGGING 0x00020000
+#define WT_SESSION_NO_SCHEMA_LOCK 0x00040000
+#define WT_SESSION_QUIET_CORRUPT_FILE 0x00080000
+#define WT_SESSION_SERVER_ASYNC 0x00100000
#define WT_STAT_CLEAR 0x00000001
#define WT_STAT_JSON 0x00000002
#define WT_STAT_ON_CLOSE 0x00000004
@@ -90,27 +92,29 @@
#define WT_VERB_COMPACT 0x00000008
#define WT_VERB_EVICT 0x00000010
#define WT_VERB_EVICTSERVER 0x00000020
-#define WT_VERB_FILEOPS 0x00000040
-#define WT_VERB_HANDLEOPS 0x00000080
-#define WT_VERB_LOG 0x00000100
-#define WT_VERB_LSM 0x00000200
-#define WT_VERB_LSM_MANAGER 0x00000400
-#define WT_VERB_METADATA 0x00000800
-#define WT_VERB_MUTEX 0x00001000
-#define WT_VERB_OVERFLOW 0x00002000
-#define WT_VERB_READ 0x00004000
-#define WT_VERB_REBALANCE 0x00008000
-#define WT_VERB_RECONCILE 0x00010000
-#define WT_VERB_RECOVERY 0x00020000
-#define WT_VERB_SALVAGE 0x00040000
-#define WT_VERB_SHARED_CACHE 0x00080000
-#define WT_VERB_SPLIT 0x00100000
-#define WT_VERB_TEMPORARY 0x00200000
-#define WT_VERB_THREAD_GROUP 0x00400000
-#define WT_VERB_TRANSACTION 0x00800000
-#define WT_VERB_VERIFY 0x01000000
-#define WT_VERB_VERSION 0x02000000
-#define WT_VERB_WRITE 0x04000000
+#define WT_VERB_EVICT_STUCK 0x00000040
+#define WT_VERB_FILEOPS 0x00000080
+#define WT_VERB_HANDLEOPS 0x00000100
+#define WT_VERB_LOG 0x00000200
+#define WT_VERB_LSM 0x00000400
+#define WT_VERB_LSM_MANAGER 0x00000800
+#define WT_VERB_METADATA 0x00001000
+#define WT_VERB_MUTEX 0x00002000
+#define WT_VERB_OVERFLOW 0x00004000
+#define WT_VERB_READ 0x00008000
+#define WT_VERB_REBALANCE 0x00010000
+#define WT_VERB_RECONCILE 0x00020000
+#define WT_VERB_RECOVERY 0x00040000
+#define WT_VERB_RECOVERY_PROGRESS 0x00080000
+#define WT_VERB_SALVAGE 0x00100000
+#define WT_VERB_SHARED_CACHE 0x00200000
+#define WT_VERB_SPLIT 0x00400000
+#define WT_VERB_TEMPORARY 0x00800000
+#define WT_VERB_THREAD_GROUP 0x01000000
+#define WT_VERB_TRANSACTION 0x02000000
+#define WT_VERB_VERIFY 0x04000000
+#define WT_VERB_VERSION 0x08000000
+#define WT_VERB_WRITE 0x10000000
#define WT_VISIBILITY_ERR 0x00000080
/*
* flags section: END
diff --git a/src/include/intpack.i b/src/include/intpack.i
index e8bea58cede..a534de9d9a8 100644
--- a/src/include/intpack.i
+++ b/src/include/intpack.i
@@ -59,21 +59,21 @@
/* Count the leading zero bytes. */
#if defined(__GNUC__)
#define WT_LEADING_ZEROS(x, i) \
- (i = (x == 0) ? (int)sizeof(x) : __builtin_clzll(x) >> 3)
+ ((i) = ((x) == 0) ? (int)sizeof(x) : __builtin_clzll(x) >> 3)
#elif defined(_MSC_VER)
#define WT_LEADING_ZEROS(x, i) do { \
- if (x == 0) i = (int)sizeof(x); \
+ if ((x) == 0) (i) = (int)sizeof(x); \
else { \
unsigned long __index; \
_BitScanReverse64(&__index, x); \
__index = 63 ^ __index; \
- i = (int)(__index >> 3); } \
+ (i) = (int)(__index >> 3); } \
} while (0)
#else
#define WT_LEADING_ZEROS(x, i) do { \
uint64_t __x = (x); \
uint64_t __m = (uint64_t)0xff << 56; \
- for (i = 0; !(__x & __m) && i != 8; i++) \
+ for ((i) = 0; !(__x & __m) && (i) != 8; (i)++) \
__m >>= 8; \
} while (0)
#endif
@@ -231,7 +231,8 @@ __wt_vpack_int(uint8_t **pp, size_t maxlen, int64_t x)
if (x < NEG_2BYTE_MIN) {
*p = NEG_MULTI_MARKER;
return (__wt_vpack_negint(pp, maxlen, (uint64_t)x));
- } else if (x < NEG_1BYTE_MIN) {
+ }
+ if (x < NEG_1BYTE_MIN) {
WT_SIZE_CHECK_PACK(2, maxlen);
x -= NEG_2BYTE_MIN;
*p++ = NEG_2BYTE_MARKER | GET_BITS(x, 13, 8);
@@ -358,12 +359,10 @@ __wt_vsize_uint(uint64_t x)
{
if (x <= POS_1BYTE_MAX)
return (1);
- else if (x <= POS_2BYTE_MAX + 1) {
+ if (x <= POS_2BYTE_MAX + 1)
return (2);
- } else {
- x -= POS_2BYTE_MAX + 1;
- return (__wt_vsize_posint(x));
- }
+ x -= POS_2BYTE_MAX + 1;
+ return (__wt_vsize_posint(x));
}
/*
@@ -373,13 +372,12 @@ __wt_vsize_uint(uint64_t x)
static inline size_t
__wt_vsize_int(int64_t x)
{
- if (x < NEG_2BYTE_MIN) {
+ if (x < NEG_2BYTE_MIN)
return (__wt_vsize_negint((uint64_t)x));
- } else if (x < NEG_1BYTE_MIN) {
+ if (x < NEG_1BYTE_MIN)
return (2);
- } else if (x < 0) {
+ if (x < 0)
return (1);
- } else
- /* For non-negative values, use the unsigned code above. */
- return (__wt_vsize_uint((uint64_t)x));
+ /* For non-negative values, use the unsigned code above. */
+ return (__wt_vsize_uint((uint64_t)x));
}
diff --git a/src/include/lint.h b/src/include/lint.h
index e20a83144ee..2d0f47988b7 100644
--- a/src/include/lint.h
+++ b/src/include/lint.h
@@ -29,9 +29,9 @@ __wt_atomic_fetch_add##name(type *vp, type v) \
{ \
type orig; \
\
- old = *vp; \
+ orig = *vp; \
*vp += v; \
- return (old); \
+ return (orig); \
} \
static inline ret \
__wt_atomic_store##name(type *vp, type v) \
@@ -40,7 +40,7 @@ __wt_atomic_store##name(type *vp, type v) \
\
orig = *vp; \
*vp = v; \
- return (old); \
+ return (orig); \
} \
static inline ret \
__wt_atomic_sub##name(type *vp, type v) \
@@ -49,9 +49,9 @@ __wt_atomic_sub##name(type *vp, type v) \
return (*vp); \
} \
static inline bool \
-__wt_atomic_cas##name(type *vp, type old, type new) \
+__wt_atomic_cas##name(type *vp, type orig, type new) \
{ \
- if (*vp == old) { \
+ if (*vp == orig) { \
*vp = new; \
return (true); \
} \
@@ -75,8 +75,8 @@ WT_ATOMIC_FUNC(size, size_t, size_t)
* Pointer compare and swap.
*/
static inline bool
-__wt_atomic_cas_ptr(void *vp, void *old, void *new) {
- if (*(void **)vp == old) {
+__wt_atomic_cas_ptr(void *vp, void *orig, void *new) {
+ if (*(void **)vp == orig) {
*(void **)vp = new;
return (true);
}
diff --git a/src/include/log.h b/src/include/log.h
index 3f2cb2ba8e6..fb3c961417f 100644
--- a/src/include/log.h
+++ b/src/include/log.h
@@ -86,8 +86,8 @@ union __wt_lsn {
* The high bit is reserved for the special states. If the high bit is
* set (WT_LOG_SLOT_RESERVED) then we are guaranteed to be in a special state.
*/
-#define WT_LOG_SLOT_FREE -1 /* Not in use */
-#define WT_LOG_SLOT_WRITTEN -2 /* Slot data written, not processed */
+#define WT_LOG_SLOT_FREE (-1) /* Not in use */
+#define WT_LOG_SLOT_WRITTEN (-2) /* Slot data written, not processed */
/*
* We allocate the buffer size, but trigger a slot switch when we cross
@@ -144,8 +144,8 @@ union __wt_lsn {
/* Slot is in use, but closed to new joins */
#define WT_LOG_SLOT_CLOSED(state) \
(WT_LOG_SLOT_ACTIVE(state) && \
- (FLD64_ISSET((uint64_t)state, WT_LOG_SLOT_CLOSE) && \
- !FLD64_ISSET((uint64_t)state, WT_LOG_SLOT_RESERVED)))
+ (FLD64_ISSET((uint64_t)(state), WT_LOG_SLOT_CLOSE) && \
+ !FLD64_ISSET((uint64_t)(state), WT_LOG_SLOT_RESERVED)))
/* Slot is in use, all data copied into buffer */
#define WT_LOG_SLOT_INPROGRESS(state) \
(WT_LOG_SLOT_RELEASED(state) != WT_LOG_SLOT_JOINED(state))
@@ -163,7 +163,7 @@ struct __wt_logslot {
WT_CACHE_LINE_PAD_BEGIN
volatile int64_t slot_state; /* Slot state */
int64_t slot_unbuffered; /* Unbuffered data in this slot */
- int32_t slot_error; /* Error value */
+ int slot_error; /* Error value */
wt_off_t slot_start_offset; /* Starting file offset */
wt_off_t slot_last_offset; /* Last record offset */
WT_LSN slot_release_lsn; /* Slot release LSN */
@@ -185,7 +185,7 @@ struct __wt_logslot {
#define WT_WITH_SLOT_LOCK(session, log, op) do { \
WT_ASSERT(session, !F_ISSET(session, WT_SESSION_LOCKED_SLOT)); \
WT_WITH_LOCK_WAIT(session, \
- &log->log_slot_lock, WT_SESSION_LOCKED_SLOT, op); \
+ &(log)->log_slot_lock, WT_SESSION_LOCKED_SLOT, op); \
} while (0)
struct __wt_myslot {
@@ -193,7 +193,8 @@ struct __wt_myslot {
wt_off_t end_offset; /* My end offset in buffer */
wt_off_t offset; /* Slot buffer offset */
#define WT_MYSLOT_CLOSE 0x01 /* This thread is closing the slot */
-#define WT_MYSLOT_UNBUFFERED 0x02 /* Write directly */
+#define WT_MYSLOT_NEEDS_RELEASE 0x02 /* This thread is releasing the slot */
+#define WT_MYSLOT_UNBUFFERED 0x04 /* Write directly */
uint32_t flags; /* Flags */
};
@@ -235,7 +236,7 @@ struct __wt_log {
WT_SPINLOCK log_sync_lock; /* Locked: Single-thread fsync */
WT_SPINLOCK log_writelsn_lock; /* Locked: write LSN */
- WT_RWLOCK *log_archive_lock; /* Archive and log cursors */
+ WT_RWLOCK log_archive_lock;/* Archive and log cursors */
/* Notify any waiting threads when sync_lsn is updated. */
WT_CONDVAR *log_sync_cond;
@@ -254,6 +255,7 @@ struct __wt_log {
#define WT_SLOT_POOL 128
WT_LOGSLOT *active_slot; /* Active slot */
WT_LOGSLOT slot_pool[WT_SLOT_POOL]; /* Pool of all slots */
+ int32_t pool_index; /* Index into slot pool */
size_t slot_buf_size; /* Buffer size for slots */
#ifdef HAVE_DIAGNOSTIC
uint64_t write_calls; /* Calls to log_write */
diff --git a/src/include/lsm.h b/src/include/lsm.h
index fefed9daa81..e3f6897ef9d 100644
--- a/src/include/lsm.h
+++ b/src/include/lsm.h
@@ -23,11 +23,14 @@ struct __wt_lsm_worker_cookie {
struct __wt_lsm_worker_args {
WT_SESSION_IMPL *session; /* Session */
WT_CONDVAR *work_cond; /* Owned by the manager */
+
wt_thread_t tid; /* Thread id */
+ bool tid_set; /* Thread id set */
+
u_int id; /* My manager slot id */
uint32_t type; /* Types of operations handled */
-#define WT_LSM_WORKER_RUN 0x01
- uint32_t flags; /* Worker flags */
+
+ volatile bool running; /* Worker is running */
};
/*
@@ -162,6 +165,9 @@ struct __wt_lsm_manager {
#define WT_LSM_MAX_WORKERS 20
#define WT_LSM_MIN_WORKERS 3
WT_LSM_WORKER_ARGS lsm_worker_cookies[WT_LSM_MAX_WORKERS];
+
+#define WT_LSM_MANAGER_SHUTDOWN 0x01 /* Manager has shut down */
+ uint32_t flags;
};
/*
@@ -189,7 +195,7 @@ struct __wt_lsm_tree {
#define LSM_TREE_MAX_QUEUE 100
uint32_t queue_ref;
- WT_RWLOCK *rwlock;
+ WT_RWLOCK rwlock;
TAILQ_ENTRY(__wt_lsm_tree) q;
uint64_t dsk_gen;
diff --git a/src/include/misc.h b/src/include/misc.h
index 66d43496e93..9161a215fdc 100644
--- a/src/include/misc.h
+++ b/src/include/misc.h
@@ -63,7 +63,7 @@
#define WT_MAX(a, b) ((a) < (b) ? (b) : (a))
/* Elements in an array. */
-#define WT_ELEMENTS(a) (sizeof(a) / sizeof(a[0]))
+#define WT_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
/* 10 level skip lists, 1/4 have a link to the next element. */
#define WT_SKIP_MAXDEPTH 10
@@ -140,6 +140,7 @@
#define F_CLR(p, mask) FLD_CLR((p)->flags, mask)
#define F_ISSET(p, mask) FLD_ISSET((p)->flags, mask)
+#define F_ISSET_ALL(p, mask) (FLD_MASK((p)->flags, mask) == (mask))
#define F_MASK(p, mask) FLD_MASK((p)->flags, mask)
#define F_SET(p, mask) FLD_SET((p)->flags, mask)
@@ -180,14 +181,14 @@
*/
#define WT_BINARY_SEARCH(key, arrayp, n, found) do { \
uint32_t __base, __indx, __limit; \
- found = false; \
+ (found) = false; \
for (__base = 0, __limit = (n); __limit != 0; __limit >>= 1) { \
__indx = __base + (__limit >> 1); \
- if ((arrayp)[__indx] < key) { \
+ if ((arrayp)[__indx] < (key)) { \
__base = __indx + 1; \
--__limit; \
- } else if ((arrayp)[__indx] == key) { \
- found = true; \
+ } else if ((arrayp)[__indx] == (key)) { \
+ (found) = true; \
break; \
} \
} \
@@ -206,8 +207,8 @@
/* Check if a string matches a prefix. */
#define WT_PREFIX_MATCH(str, pfx) \
- (((const char *)(str))[0] == ((const char *)pfx)[0] && \
- strncmp((str), (pfx), strlen(pfx)) == 0)
+ (((const char *)(str))[0] == ((const char *)(pfx))[0] && \
+ strncmp(str, pfx, strlen(pfx)) == 0)
/* Check if a string matches a prefix, and move past it. */
#define WT_PREFIX_SKIP(str, pfx) \
@@ -224,8 +225,8 @@
/* Check if a string matches a byte string of len bytes. */
#define WT_STRING_MATCH(str, bytes, len) \
- (((const char *)str)[0] == ((const char *)bytes)[0] && \
- strncmp(str, bytes, len) == 0 && (str)[(len)] == '\0')
+ (((const char *)(str))[0] == ((const char *)(bytes))[0] && \
+ strncmp(str, bytes, len) == 0 && (str)[len] == '\0')
/*
* Macro that produces a string literal that isn't wrapped in quotes, to avoid
diff --git a/src/include/misc.i b/src/include/misc.i
index f36be32d6a2..7040886cf82 100644
--- a/src/include/misc.i
+++ b/src/include/misc.i
@@ -11,11 +11,12 @@
* Wait on a mutex, optionally timing out.
*/
static inline void
-__wt_cond_wait(WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs)
+__wt_cond_wait(WT_SESSION_IMPL *session,
+ WT_CONDVAR *cond, uint64_t usecs, bool (*run_func)(WT_SESSION_IMPL *))
{
bool notused;
- __wt_cond_wait_signal(session, cond, usecs, &notused);
+ __wt_cond_wait_signal(session, cond, usecs, run_func, &notused);
}
/*
@@ -85,3 +86,94 @@ __wt_verbose(WT_SESSION_IMPL *session, int flag, const char *fmt, ...)
WT_UNUSED(fmt);
#endif
}
+
+/*
+ * __wt_snprintf --
+ * snprintf convenience function, ignoring the returned size.
+ */
+static inline int
+__wt_snprintf(char *buf, size_t size, const char *fmt, ...)
+ WT_GCC_FUNC_ATTRIBUTE((format (printf, 3, 4)))
+{
+ WT_DECL_RET;
+ size_t len;
+ va_list ap;
+
+ len = 0;
+
+ va_start(ap, fmt);
+ ret = __wt_vsnprintf_len_incr(buf, size, &len, fmt, ap);
+ va_end(ap);
+ WT_RET(ret);
+
+ /* It's an error if the buffer couldn't hold everything. */
+ return (len >= size ? ERANGE : 0);
+}
+
+/*
+ * __wt_vsnprintf --
+ * vsnprintf convenience function, ignoring the returned size.
+ */
+static inline int
+__wt_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
+{
+ size_t len;
+
+ len = 0;
+
+ WT_RET(__wt_vsnprintf_len_incr(buf, size, &len, fmt, ap));
+
+ /* It's an error if the buffer couldn't hold everything. */
+ return (len >= size ? ERANGE : 0);
+}
+
+/*
+ * __wt_snprintf_len_set --
+ * snprintf convenience function, setting the returned size.
+ */
+static inline int
+__wt_snprintf_len_set(
+ char *buf, size_t size, size_t *retsizep, const char *fmt, ...)
+ WT_GCC_FUNC_ATTRIBUTE((format (printf, 4, 5)))
+{
+ WT_DECL_RET;
+ va_list ap;
+
+ *retsizep = 0;
+
+ va_start(ap, fmt);
+ ret = __wt_vsnprintf_len_incr(buf, size, retsizep, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
+
+/*
+ * __wt_vsnprintf_len_set --
+ * vsnprintf convenience function, setting the returned size.
+ */
+static inline int
+__wt_vsnprintf_len_set(
+ char *buf, size_t size, size_t *retsizep, const char *fmt, va_list ap)
+{
+ *retsizep = 0;
+
+ return (__wt_vsnprintf_len_incr(buf, size, retsizep, fmt, ap));
+}
+
+/*
+ * __wt_snprintf_len_incr --
+ * snprintf convenience function, incrementing the returned size.
+ */
+static inline int
+__wt_snprintf_len_incr(
+ char *buf, size_t size, size_t *retsizep, const char *fmt, ...)
+ WT_GCC_FUNC_ATTRIBUTE((format (printf, 4, 5)))
+{
+ WT_DECL_RET;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = __wt_vsnprintf_len_incr(buf, size, retsizep, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/src/include/mutex.h b/src/include/mutex.h
index 6b81b1a6265..910eb7af5b9 100644
--- a/src/include/mutex.h
+++ b/src/include/mutex.h
@@ -21,8 +21,8 @@ struct __wt_condvar {
int waiters; /* Numbers of waiters, or
-1 if signalled with no waiters. */
/*
- * The following fields are only used for automatically adjusting
- * condition variables. They could be in a separate structure.
+ * The following fields are used for automatically adjusting condition
+ * variable wait times.
*/
uint64_t min_wait; /* Minimum wait duration */
uint64_t max_wait; /* Maximum wait duration */
@@ -30,11 +30,14 @@ struct __wt_condvar {
};
/*
+ * Read/write locks:
+ *
+ * WiredTiger uses read/write locks for shared/exclusive access to resources.
* !!!
* Don't modify this structure without understanding the read/write locking
* functions.
*/
-typedef union { /* Read/write lock */
+union __wt_rwlock { /* Read/write lock */
uint64_t u;
struct {
uint32_t wr; /* Writers and readers */
@@ -45,19 +48,6 @@ typedef union { /* Read/write lock */
uint16_t next; /* Next available ticket number */
uint16_t writers_active;/* Count of active writers */
} s;
-} wt_rwlock_t;
-
-/*
- * Read/write locks:
- *
- * WiredTiger uses read/write locks for shared/exclusive access to resources.
- */
-struct __wt_rwlock {
- WT_CACHE_LINE_PAD_BEGIN
- const char *name; /* Lock name for debugging */
-
- wt_rwlock_t rwlock; /* Read/write lock */
- WT_CACHE_LINE_PAD_END
};
/*
@@ -72,31 +62,17 @@ struct __wt_rwlock {
#define SPINLOCK_PTHREAD_MUTEX 2
#define SPINLOCK_PTHREAD_MUTEX_ADAPTIVE 3
-#if SPINLOCK_TYPE == SPINLOCK_GCC
-
struct __wt_spinlock {
WT_CACHE_LINE_PAD_BEGIN
+#if SPINLOCK_TYPE == SPINLOCK_GCC
volatile int lock;
-
- /*
- * We track acquisitions and time spent waiting for some locks. For
- * performance reasons and to make it possible to write generic code
- * that tracks statistics for different locks, we store the offset
- * of the statistics fields to be updated during lock acquisition.
- */
- int16_t stat_count_off; /* acquisitions offset */
- int16_t stat_app_usecs_off; /* waiting application threads offset */
- int16_t stat_int_usecs_off; /* waiting server threads offset */
- WT_CACHE_LINE_PAD_END
-};
-
#elif SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX ||\
SPINLOCK_TYPE == SPINLOCK_PTHREAD_MUTEX_ADAPTIVE ||\
SPINLOCK_TYPE == SPINLOCK_MSVC
-
-struct __wt_spinlock {
- WT_CACHE_LINE_PAD_BEGIN
wt_mutex_t lock;
+#else
+#error Unknown spinlock type
+#endif
const char *name; /* Mutex name */
@@ -113,9 +89,3 @@ struct __wt_spinlock {
int8_t initialized; /* Lock initialized, for cleanup */
WT_CACHE_LINE_PAD_END
};
-
-#else
-
-#error Unknown spinlock type
-
-#endif
diff --git a/src/include/mutex.i b/src/include/mutex.i
index a6309e0976b..2d483972ed2 100644
--- a/src/include/mutex.i
+++ b/src/include/mutex.i
@@ -14,6 +14,18 @@
* of instructions.
*/
+/*
+ * __spin_init_internal --
+ * Initialize the WT portion of a spinlock.
+ */
+static inline void
+__spin_init_internal(WT_SPINLOCK *t, const char *name)
+{
+ t->name = name;
+ t->stat_count_off = t->stat_app_usecs_off = t->stat_int_usecs_off = -1;
+ t->initialized = 1;
+}
+
#if SPINLOCK_TYPE == SPINLOCK_GCC
/* Default to spinning 1000 times before yielding. */
@@ -29,10 +41,9 @@ static inline int
__wt_spin_init(WT_SESSION_IMPL *session, WT_SPINLOCK *t, const char *name)
{
WT_UNUSED(session);
- WT_UNUSED(name);
t->lock = 0;
- t->stat_count_off = t->stat_app_usecs_off = t->stat_int_usecs_off = -1;
+ __spin_init_internal(t, name);
return (0);
}
@@ -110,10 +121,7 @@ __wt_spin_init(WT_SESSION_IMPL *session, WT_SPINLOCK *t, const char *name)
#else
WT_RET(pthread_mutex_init(&t->lock, NULL));
#endif
-
- t->name = name;
- t->stat_count_off = t->stat_app_usecs_off = t->stat_int_usecs_off = -1;
- t->initialized = 1;
+ __spin_init_internal(t, name);
WT_UNUSED(session);
return (0);
@@ -195,8 +203,7 @@ __wt_spin_init(WT_SESSION_IMPL *session, WT_SPINLOCK *t, const char *name)
return (__wt_map_windows_error(windows_error));
}
- t->name = name;
- t->initialized = 1;
+ __spin_init_internal(t, name);
return (0);
}
@@ -300,3 +307,22 @@ __wt_spin_lock_track(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
} else
__wt_spin_lock(session, t);
}
+
+/*
+ * __wt_spin_trylock_track --
+ * Try to lock a spinlock or fail immediately if it is busy.
+ * Track if successful.
+ */
+static inline int
+__wt_spin_trylock_track(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
+{
+ int64_t **stats;
+
+ if (t->stat_count_off != -1 && WT_STAT_ENABLED(session)) {
+ WT_RET(__wt_spin_trylock(session, t));
+ stats = (int64_t **)S2C(session)->stats;
+ stats[session->stat_bucket][t->stat_count_off]++;
+ return (0);
+ }
+ return (__wt_spin_trylock(session, t));
+}
diff --git a/src/include/os.h b/src/include/os.h
index 7a8e47ed81f..73d89268392 100644
--- a/src/include/os.h
+++ b/src/include/os.h
@@ -11,8 +11,14 @@
* A call returning 0 indicates success; any call where \
* 0 is not the only successful return must provide an \
* expression evaluating to 0 in all successful cases. \
+ * \
+ * XXX \
+ * Casting the call's return to int is because CentOS 7.3.1611 \
+ * complains about syscall returning a long and the loss of \
+ * integer precision in the assignment to ret. The cast should \
+ * be a no-op everywhere. \
*/ \
- if (((ret) = (call)) == 0) \
+ if (((ret) = (int)(call)) == 0) \
break; \
/* \
* The call's error was either returned by the call or \
@@ -61,7 +67,7 @@
#define WT_TIMECMP(t1, t2) \
((t1).tv_sec < (t2).tv_sec ? -1 : \
- (t1).tv_sec == (t2.tv_sec) ? \
+ (t1).tv_sec == (t2).tv_sec ? \
(t1).tv_nsec < (t2).tv_nsec ? -1 : \
(t1).tv_nsec == (t2).tv_nsec ? 0 : 1 : 1)
diff --git a/src/include/os_windows.h b/src/include/os_windows.h
index 65938ac9f17..c1e5f788dc6 100644
--- a/src/include/os_windows.h
+++ b/src/include/os_windows.h
@@ -43,16 +43,6 @@ typedef uint32_t u_int;
typedef unsigned char u_char;
typedef uint64_t u_long;
-/* <= VS 2013 is not C99 compat */
-#if _MSC_VER < 1900
-#define snprintf _wt_snprintf
-
-_Check_return_opt_ int __cdecl _wt_snprintf(
- _Out_writes_(_MaxCount) char * _DstBuf,
- _In_ size_t _MaxCount,
- _In_z_ _Printf_format_string_ const char * _Format, ...);
-#endif
-
/*
* Windows does have ssize_t
* Python headers declare also though so we need to guard it
@@ -61,18 +51,6 @@ _Check_return_opt_ int __cdecl _wt_snprintf(
typedef int ssize_t;
#endif
-/*
- * Provide a custom version of vsnprintf that returns the
- * needed buffer length instead of -1 on truncation
- */
-#define vsnprintf _wt_vsnprintf
-
-_Check_return_opt_ int __cdecl _wt_vsnprintf(
- _Out_writes_(_MaxCount) char * _DstBuf,
- _In_ size_t _MaxCount,
- _In_z_ _Printf_format_string_ const char * _Format,
- va_list _ArgList);
-
/* Provide a custom version of localtime_r */
struct tm *localtime_r(const time_t* timer, struct tm* result);
diff --git a/src/include/packing.i b/src/include/packing.i
index 17ca261bcfc..0eadb2f2027 100644
--- a/src/include/packing.i
+++ b/src/include/packing.i
@@ -104,8 +104,8 @@ __pack_name_next(WT_PACK_NAME *pn, WT_CONFIG_ITEM *name)
WT_CONFIG_ITEM ignore;
if (pn->genname) {
- (void)snprintf(pn->buf, sizeof(pn->buf),
- (pn->iskey ? "key%d" : "value%d"), pn->count);
+ WT_RET(__wt_snprintf(pn->buf, sizeof(pn->buf),
+ (pn->iskey ? "key%d" : "value%d"), pn->count));
WT_CLEAR(*name);
name->str = pn->buf;
name->len = strlen(pn->buf);
@@ -168,10 +168,15 @@ next: if (pack->cur == pack->end)
(int)(pack->end - pack->orig), pack->orig);
return (0);
case 'u':
- case 'U':
/* Special case for items with a size prefix. */
pv->type = (!pv->havesize && *pack->cur != '\0') ? 'U' : 'u';
return (0);
+ case 'U':
+ /*
+ * Don't change the type. 'U' is used internally, so this type
+ * was already changed to explicitly include the size.
+ */
+ return (0);
case 'b':
case 'h':
case 'i':
@@ -193,7 +198,7 @@ next: if (pack->cur == pack->end)
return (0);
default:
WT_RET_MSG(pack->session, EINVAL,
- "Invalid type '%c' found in format '%.*s'",
+ "Invalid type '%c' found in format '%.*s'",
pv->type, (int)(pack->end - pack->orig), pack->orig);
}
@@ -201,43 +206,43 @@ next: if (pack->cur == pack->end)
#define WT_PACK_GET(session, pv, ap) do { \
WT_ITEM *__item; \
- switch (pv.type) { \
+ switch ((pv).type) { \
case 'x': \
break; \
case 's': \
case 'S': \
- pv.u.s = va_arg(ap, const char *); \
+ (pv).u.s = va_arg(ap, const char *); \
break; \
case 'U': \
case 'u': \
__item = va_arg(ap, WT_ITEM *); \
- pv.u.item.data = __item->data; \
- pv.u.item.size = __item->size; \
+ (pv).u.item.data = __item->data; \
+ (pv).u.item.size = __item->size; \
break; \
case 'b': \
case 'h': \
case 'i': \
- pv.u.i = va_arg(ap, int); \
+ (pv).u.i = va_arg(ap, int); \
break; \
case 'B': \
case 'H': \
case 'I': \
case 't': \
- pv.u.u = va_arg(ap, unsigned int); \
+ (pv).u.u = va_arg(ap, unsigned int); \
break; \
case 'l': \
- pv.u.i = va_arg(ap, long); \
+ (pv).u.i = va_arg(ap, long); \
break; \
case 'L': \
- pv.u.u = va_arg(ap, unsigned long); \
+ (pv).u.u = va_arg(ap, unsigned long); \
break; \
case 'q': \
- pv.u.i = va_arg(ap, int64_t); \
+ (pv).u.i = va_arg(ap, int64_t); \
break; \
case 'Q': \
case 'r': \
case 'R': \
- pv.u.u = va_arg(ap, uint64_t); \
+ (pv).u.u = va_arg(ap, uint64_t); \
break; \
/* User format strings have already been validated. */ \
WT_ILLEGAL_VALUE(session); \
@@ -551,47 +556,47 @@ __unpack_read(WT_SESSION_IMPL *session,
#define WT_UNPACK_PUT(session, pv, ap) do { \
WT_ITEM *__item; \
- switch (pv.type) { \
+ switch ((pv).type) { \
case 'x': \
break; \
case 's': \
case 'S': \
- *va_arg(ap, const char **) = pv.u.s; \
+ *va_arg(ap, const char **) = (pv).u.s; \
break; \
case 'U': \
case 'u': \
__item = va_arg(ap, WT_ITEM *); \
- __item->data = pv.u.item.data; \
- __item->size = pv.u.item.size; \
+ __item->data = (pv).u.item.data; \
+ __item->size = (pv).u.item.size; \
break; \
case 'b': \
- *va_arg(ap, int8_t *) = (int8_t)pv.u.i; \
+ *va_arg(ap, int8_t *) = (int8_t)(pv).u.i; \
break; \
case 'h': \
- *va_arg(ap, int16_t *) = (short)pv.u.i; \
+ *va_arg(ap, int16_t *) = (short)(pv).u.i; \
break; \
case 'i': \
case 'l': \
- *va_arg(ap, int32_t *) = (int32_t)pv.u.i; \
+ *va_arg(ap, int32_t *) = (int32_t)(pv).u.i; \
break; \
case 'q': \
- *va_arg(ap, int64_t *) = pv.u.i; \
+ *va_arg(ap, int64_t *) = (pv).u.i; \
break; \
case 'B': \
case 't': \
- *va_arg(ap, uint8_t *) = (uint8_t)pv.u.u; \
+ *va_arg(ap, uint8_t *) = (uint8_t)(pv).u.u; \
break; \
case 'H': \
- *va_arg(ap, uint16_t *) = (uint16_t)pv.u.u; \
+ *va_arg(ap, uint16_t *) = (uint16_t)(pv).u.u; \
break; \
case 'I': \
case 'L': \
- *va_arg(ap, uint32_t *) = (uint32_t)pv.u.u; \
+ *va_arg(ap, uint32_t *) = (uint32_t)(pv).u.u; \
break; \
case 'Q': \
case 'r': \
case 'R': \
- *va_arg(ap, uint64_t *) = pv.u.u; \
+ *va_arg(ap, uint64_t *) = (pv).u.u; \
break; \
/* User format strings have already been validated. */ \
WT_ILLEGAL_VALUE(session); \
diff --git a/src/include/schema.h b/src/include/schema.h
index a17affb7660..50e141d9921 100644
--- a/src/include/schema.h
+++ b/src/include/schema.h
@@ -78,6 +78,14 @@ struct __wt_table {
*/
#define WT_COLGROUPS(t) WT_MAX((t)->ncolgroups, 1)
+/* Helpers for the locked state of the handle list and table locks. */
+#define WT_SESSION_LOCKED_HANDLE_LIST \
+ (WT_SESSION_LOCKED_HANDLE_LIST_READ | \
+ WT_SESSION_LOCKED_HANDLE_LIST_WRITE)
+#define WT_SESSION_LOCKED_TABLE \
+ (WT_SESSION_LOCKED_TABLE_READ | \
+ WT_SESSION_LOCKED_TABLE_WRITE)
+
/*
* WT_WITH_LOCK_WAIT --
* Wait for a lock, perform an operation, drop the lock.
@@ -85,7 +93,7 @@ struct __wt_table {
#define WT_WITH_LOCK_WAIT(session, lock, flag, op) do { \
if (F_ISSET(session, (flag))) { \
op; \
- } else { \
+ } else { \
__wt_spin_lock_track(session, lock); \
F_SET(session, (flag)); \
op; \
@@ -99,10 +107,11 @@ struct __wt_table {
* Acquire a lock if available, perform an operation, drop the lock.
*/
#define WT_WITH_LOCK_NOWAIT(session, ret, lock, flag, op) do { \
- ret = 0; \
+ (ret) = 0; \
if (F_ISSET(session, (flag))) { \
op; \
- } else if ((ret = __wt_spin_trylock(session, lock)) == 0) { \
+ } else if (((ret) = \
+ __wt_spin_trylock_track(session, lock)) == 0) { \
F_SET(session, (flag)); \
op; \
F_CLR(session, (flag)); \
@@ -122,16 +131,46 @@ struct __wt_table {
&S2C(session)->checkpoint_lock, WT_SESSION_LOCKED_CHECKPOINT, op)
/*
- * WT_WITH_HANDLE_LIST_LOCK --
- * Acquire the data handle list lock, perform an operation, drop the lock.
+ * WT_WITH_HANDLE_LIST_READ_LOCK --
+ * Acquire the data handle list lock in shared mode, perform an operation,
+ * drop the lock. The handle list lock is a read-write lock so the
+ * implementation is different to the other lock macros.
*
* Note: always waits because some operations need the handle list lock to
* discard handles, and we only expect it to be held across short
* operations.
*/
-#define WT_WITH_HANDLE_LIST_LOCK(session, op) \
- WT_WITH_LOCK_WAIT(session, \
- &S2C(session)->dhandle_lock, WT_SESSION_LOCKED_HANDLE_LIST, op)
+#define WT_WITH_HANDLE_LIST_READ_LOCK(session, op) do { \
+ if (F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST)) { \
+ op; \
+ } else { \
+ __wt_readlock(session, &S2C(session)->dhandle_lock); \
+ F_SET(session, WT_SESSION_LOCKED_HANDLE_LIST_READ); \
+ op; \
+ F_CLR(session, WT_SESSION_LOCKED_HANDLE_LIST_READ); \
+ __wt_readunlock(session, &S2C(session)->dhandle_lock); \
+ } \
+} while (0)
+
+/*
+ * WT_WITH_HANDLE_LIST_WRITE_LOCK --
+ * Acquire the data handle list lock in exclusive mode, perform an
+ * operation, drop the lock. The handle list lock is a read-write lock so
+ * the implementation is different to the other lock macros.
+ */
+#define WT_WITH_HANDLE_LIST_WRITE_LOCK(session, op) do { \
+ if (F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST_WRITE)) { \
+ op; \
+ } else { \
+ WT_ASSERT(session, \
+ !F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST_READ));\
+ __wt_writelock(session, &S2C(session)->dhandle_lock); \
+ F_SET(session, WT_SESSION_LOCKED_HANDLE_LIST_WRITE); \
+ op; \
+ F_CLR(session, WT_SESSION_LOCKED_HANDLE_LIST_WRITE); \
+ __wt_writeunlock(session, &S2C(session)->dhandle_lock); \
+ } \
+} while (0)
/*
* WT_WITH_METADATA_LOCK --
@@ -165,22 +204,58 @@ struct __wt_table {
} while (0)
/*
- * WT_WITH_TABLE_LOCK, WT_WITH_TABLE_LOCK_NOWAIT --
+ * WT_WITH_TABLE_READ_LOCK, WT_WITH_TABLE_WRITE_LOCK,
+ * WT_WITH_TABLE_WRITE_LOCK_NOWAIT --
* Acquire the table lock, perform an operation, drop the lock.
+ * The table lock is a read-write lock so the implementation is different
+ * to most other lock macros.
+ *
+ * Note: readlock always waits because some operations need the table lock
+ * to discard handles, and we only expect it to be held across short
+ * operations.
*/
-#define WT_WITH_TABLE_LOCK(session, op) do { \
- WT_ASSERT(session, \
- F_ISSET(session, WT_SESSION_LOCKED_TABLE) || \
- !F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST)); \
- WT_WITH_LOCK_WAIT(session, \
- &S2C(session)->table_lock, WT_SESSION_LOCKED_TABLE, op); \
+#define WT_WITH_TABLE_READ_LOCK(session, op) do { \
+ if (F_ISSET(session, WT_SESSION_LOCKED_TABLE)) { \
+ op; \
+ } else { \
+ WT_ASSERT(session, \
+ !F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST)); \
+ __wt_readlock(session, &S2C(session)->table_lock); \
+ F_SET(session, WT_SESSION_LOCKED_TABLE_READ); \
+ op; \
+ F_CLR(session, WT_SESSION_LOCKED_TABLE_READ); \
+ __wt_readunlock(session, &S2C(session)->table_lock); \
+ } \
+} while (0)
+
+#define WT_WITH_TABLE_WRITE_LOCK(session, op) do { \
+ if (F_ISSET(session, WT_SESSION_LOCKED_TABLE_WRITE)) { \
+ op; \
+ } else { \
+ WT_ASSERT(session, \
+ !F_ISSET(session, WT_SESSION_LOCKED_TABLE_READ | \
+ WT_SESSION_LOCKED_HANDLE_LIST)); \
+ __wt_writelock(session, &S2C(session)->table_lock); \
+ F_SET(session, WT_SESSION_LOCKED_TABLE_WRITE); \
+ op; \
+ F_CLR(session, WT_SESSION_LOCKED_TABLE_WRITE); \
+ __wt_writeunlock(session, &S2C(session)->table_lock); \
+ } \
} while (0)
-#define WT_WITH_TABLE_LOCK_NOWAIT(session, ret, op) do { \
+#define WT_WITH_TABLE_WRITE_LOCK_NOWAIT(session, ret, op) do { \
WT_ASSERT(session, \
- F_ISSET(session, WT_SESSION_LOCKED_TABLE) || \
- !F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST)); \
- WT_WITH_LOCK_NOWAIT(session, ret, \
- &S2C(session)->table_lock, WT_SESSION_LOCKED_TABLE, op); \
+ F_ISSET(session, WT_SESSION_LOCKED_TABLE_WRITE) || \
+ !F_ISSET(session, WT_SESSION_LOCKED_TABLE_READ | \
+ WT_SESSION_LOCKED_HANDLE_LIST)); \
+ if (F_ISSET(session, WT_SESSION_LOCKED_TABLE_WRITE)) { \
+ op; \
+ } else if (((ret) = __wt_try_writelock(session, \
+ &S2C(session)->table_lock)) == 0) { \
+ F_SET(session, WT_SESSION_LOCKED_TABLE_WRITE); \
+ op; \
+ F_CLR(session, WT_SESSION_LOCKED_TABLE_WRITE); \
+ __wt_writeunlock(session, &S2C(session)->table_lock); \
+ } \
} while (0)
/*
@@ -192,19 +267,31 @@ struct __wt_table {
WT_CONNECTION_IMPL *__conn = S2C(session); \
bool __checkpoint_locked = \
F_ISSET(session, WT_SESSION_LOCKED_CHECKPOINT); \
- bool __handle_locked = \
- F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST); \
- bool __table_locked = \
- F_ISSET(session, WT_SESSION_LOCKED_TABLE); \
+ bool __handle_read_locked = \
+ F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST_READ); \
+ bool __handle_write_locked = \
+ F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST_WRITE); \
+ bool __table_read_locked = \
+ F_ISSET(session, WT_SESSION_LOCKED_TABLE_READ); \
+ bool __table_write_locked = \
+ F_ISSET(session, WT_SESSION_LOCKED_TABLE_WRITE); \
bool __schema_locked = \
F_ISSET(session, WT_SESSION_LOCKED_SCHEMA); \
- if (__handle_locked) { \
- F_CLR(session, WT_SESSION_LOCKED_HANDLE_LIST); \
- __wt_spin_unlock(session, &__conn->dhandle_lock); \
+ if (__handle_read_locked) { \
+ F_CLR(session, WT_SESSION_LOCKED_HANDLE_LIST_READ); \
+ __wt_readunlock(session, &__conn->dhandle_lock); \
} \
- if (__table_locked) { \
- F_CLR(session, WT_SESSION_LOCKED_TABLE); \
- __wt_spin_unlock(session, &__conn->table_lock); \
+ if (__handle_write_locked) { \
+ F_CLR(session, WT_SESSION_LOCKED_HANDLE_LIST_WRITE); \
+ __wt_writeunlock(session, &__conn->dhandle_lock); \
+ } \
+ if (__table_read_locked) { \
+ F_CLR(session, WT_SESSION_LOCKED_TABLE_READ); \
+ __wt_readunlock(session, &__conn->table_lock); \
+ } \
+ if (__table_write_locked) { \
+ F_CLR(session, WT_SESSION_LOCKED_TABLE_WRITE); \
+ __wt_writeunlock(session, &__conn->table_lock); \
} \
if (__schema_locked) { \
F_CLR(session, WT_SESSION_LOCKED_SCHEMA); \
@@ -223,12 +310,20 @@ struct __wt_table {
__wt_spin_lock(session, &__conn->schema_lock); \
F_SET(session, WT_SESSION_LOCKED_SCHEMA); \
} \
- if (__table_locked) { \
- __wt_spin_lock(session, &__conn->table_lock); \
- F_SET(session, WT_SESSION_LOCKED_TABLE); \
+ if (__table_read_locked) { \
+ __wt_readlock(session, &__conn->table_lock); \
+ F_SET(session, WT_SESSION_LOCKED_TABLE_READ); \
+ } \
+ if (__table_write_locked) { \
+ __wt_writelock(session, &__conn->table_lock); \
+ F_SET(session, WT_SESSION_LOCKED_TABLE_WRITE); \
+ } \
+ if (__handle_read_locked) { \
+ __wt_readlock(session, &__conn->dhandle_lock); \
+ F_SET(session, WT_SESSION_LOCKED_HANDLE_LIST_READ); \
} \
- if (__handle_locked) { \
- __wt_spin_lock(session, &__conn->dhandle_lock); \
- F_SET(session, WT_SESSION_LOCKED_HANDLE_LIST); \
+ if (__handle_write_locked) { \
+ __wt_writelock(session, &__conn->dhandle_lock); \
+ F_SET(session, WT_SESSION_LOCKED_HANDLE_LIST_WRITE); \
} \
} while (0)
diff --git a/src/include/session.h b/src/include/session.h
index 7dd523aea26..674e92671b1 100644
--- a/src/include/session.h
+++ b/src/include/session.h
@@ -52,8 +52,6 @@ struct __wt_session_impl {
const char *lastop; /* Last operation */
uint32_t id; /* UID, offset in session array */
- WT_CONDVAR *cond; /* Condition variable */
-
WT_EVENT_HANDLER *event_handler;/* Application's event handlers */
WT_DATA_HANDLE *dhandle; /* Current data handle */
@@ -69,7 +67,6 @@ struct __wt_session_impl {
TAILQ_HEAD(__dhandles, __wt_data_handle_cache) dhandles;
time_t last_sweep; /* Last sweep for dead handles */
- WT_CURSOR *cursor; /* Current cursor */
/* Cursors closed with the session */
TAILQ_HEAD(__cursors, __wt_cursor) cursors;
@@ -90,7 +87,7 @@ struct __wt_session_impl {
void *meta_track_sub; /* Child transaction / save point */
size_t meta_track_alloc; /* Currently allocated */
int meta_track_nest; /* Nesting level of meta transaction */
-#define WT_META_TRACKING(session) (session->meta_track_next != NULL)
+#define WT_META_TRACKING(session) ((session)->meta_track_next != NULL)
/*
* Each session keeps a cache of table handles. The set of handles
@@ -153,20 +150,16 @@ struct __wt_session_impl {
uint32_t flags;
/*
- * The split stash memory and hazard information persist past session
- * close because they are accessed by threads of control other than the
- * thread owning the session.
- *
+ * All of the following fields live at the end of the structure so it's
+ * easier to clear everything but the fields that persist.
+ */
+#define WT_SESSION_CLEAR_SIZE (offsetof(WT_SESSION_IMPL, rnd))
+
+ /*
* The random number state persists past session close because we don't
- * want to repeatedly allocate repeated values for skiplist depth if the
+ * want to repeatedly use the same values for skiplist depth when the
* application isn't caching sessions.
- *
- * All of these fields live at the end of the structure so it's easier
- * to clear everything but the fields that persist.
*/
-#define WT_SESSION_CLEAR_SIZE(s) \
- (WT_PTRDIFF(&(s)->rnd, s))
-
WT_RAND_STATE rnd; /* Random number generation state */
/* Hashed handle reference list array */
@@ -175,6 +168,9 @@ struct __wt_session_impl {
TAILQ_HEAD(__tables_hash, __wt_table) *tablehash;
/*
+ * Split stash memory persists past session close because it's accessed
+ * by threads of control other than the thread owning the session.
+ *
* Splits can "free" memory that may still be in use, and we use a
* split generation number to track it, that is, the session stores a
* reference to the memory and allocates a split generation; when no
@@ -194,6 +190,9 @@ struct __wt_session_impl {
/*
* Hazard pointers.
*
+ * Hazard information persists past session close because it's accessed
+ * by threads of control other than the thread owning the session.
+ *
* Use the non-NULL state of the hazard field to know if the session has
* previously been initialized.
*/
diff --git a/src/include/stat.h b/src/include/stat.h
index 0daab83e166..6c274484bcb 100644
--- a/src/include/stat.h
+++ b/src/include/stat.h
@@ -72,7 +72,7 @@
* and the session ID is a small, monotonically increasing number.
*/
#define WT_STATS_SLOT_ID(session) \
- ((session)->id) % WT_COUNTER_SLOTS
+ (((session)->id) % WT_COUNTER_SLOTS)
/*
* Statistic structures are arrays of int64_t's. We have functions to read/write
@@ -310,10 +310,15 @@ struct __wt_connection_stats {
int64_t cache_eviction_slow;
int64_t cache_eviction_state;
int64_t cache_eviction_walks_abandoned;
+ int64_t cache_eviction_active_workers;
+ int64_t cache_eviction_worker_created;
int64_t cache_eviction_worker_evicting;
+ int64_t cache_eviction_worker_removed;
+ int64_t cache_eviction_stable_state_workers;
int64_t cache_eviction_force_fail;
int64_t cache_eviction_walks_active;
int64_t cache_eviction_walks_started;
+ int64_t cache_eviction_force_retune;
int64_t cache_eviction_hazard;
int64_t cache_hazard_checks;
int64_t cache_hazard_walks;
@@ -388,9 +393,7 @@ struct __wt_connection_stats {
int64_t lock_checkpoint_count;
int64_t lock_checkpoint_wait_application;
int64_t lock_checkpoint_wait_internal;
- int64_t lock_handle_list_count;
- int64_t lock_handle_list_wait_application;
- int64_t lock_handle_list_wait_internal;
+ int64_t lock_handle_list_wait_eviction;
int64_t lock_metadata_count;
int64_t lock_metadata_wait_application;
int64_t lock_metadata_wait_internal;
@@ -402,9 +405,11 @@ struct __wt_connection_stats {
int64_t lock_table_wait_internal;
int64_t log_slot_switch_busy;
int64_t log_slot_closes;
+ int64_t log_slot_active_closed;
int64_t log_slot_races;
int64_t log_slot_transitions;
int64_t log_slot_joins;
+ int64_t log_slot_no_free_slots;
int64_t log_slot_unbuffered;
int64_t log_bytes_payload;
int64_t log_bytes_written;
@@ -564,6 +569,7 @@ struct __wt_dsrc_stats {
int64_t cache_pages_requested;
int64_t cache_write;
int64_t cache_write_restore;
+ int64_t cache_bytes_dirty;
int64_t cache_eviction_clean;
int64_t cache_state_gen_avg_gap;
int64_t cache_state_avg_written_size;
diff --git a/src/include/thread_group.h b/src/include/thread_group.h
index 76758a090c4..77cff00dc8d 100644
--- a/src/include/thread_group.h
+++ b/src/include/thread_group.h
@@ -40,7 +40,7 @@ struct __wt_thread_group {
const char *name; /* Name */
- WT_RWLOCK *lock; /* Protects group changes */
+ WT_RWLOCK lock; /* Protects group changes */
/*
* Condition signalled when wanting to wake up threads that are
diff --git a/src/include/txn.h b/src/include/txn.h
index 12fc2a0a5b7..7e802c188ab 100644
--- a/src/include/txn.h
+++ b/src/include/txn.h
@@ -92,7 +92,7 @@ struct __wt_txn_global {
* Prevents the oldest ID moving forwards while threads are scanning
* the global transaction state.
*/
- WT_RWLOCK *scan_rwlock;
+ WT_RWLOCK scan_rwlock;
/*
* Track information about the running checkpoint. The transaction
@@ -114,7 +114,7 @@ struct __wt_txn_global {
volatile uint64_t metadata_pinned; /* Oldest ID for metadata */
/* Named snapshot state. */
- WT_RWLOCK *nsnap_rwlock;
+ WT_RWLOCK nsnap_rwlock;
volatile uint64_t nsnap_oldest_id;
TAILQ_HEAD(__wt_nsnap_qh, __wt_named_snapshot) nsnaph;
diff --git a/src/include/txn.i b/src/include/txn.i
index 0cc4a6f8439..314c948e4d1 100644
--- a/src/include/txn.i
+++ b/src/include/txn.i
@@ -125,7 +125,8 @@ __wt_txn_oldest_id(WT_SESSION_IMPL *session)
* minimum of it with the oldest ID, which is what we want.
*/
oldest_id = txn_global->oldest_id;
- include_checkpoint_txn = btree == NULL || btree->include_checkpoint_txn;
+ include_checkpoint_txn = btree == NULL ||
+ btree->checkpoint_gen != txn_global->checkpoint_gen;
WT_READ_BARRIER();
checkpoint_pinned = txn_global->checkpoint_pinned;
diff --git a/src/include/verify_build.h b/src/include/verify_build.h
index 8abc192892e..640f5e4cf5f 100644
--- a/src/include/verify_build.h
+++ b/src/include/verify_build.h
@@ -59,7 +59,6 @@ __wt_verify_build(void)
sizeof(s) > WT_CACHE_LINE_ALIGNMENT || \
sizeof(s) % WT_CACHE_LINE_ALIGNMENT == 0)
WT_PADDING_CHECK(WT_LOGSLOT);
- WT_PADDING_CHECK(WT_RWLOCK);
WT_PADDING_CHECK(WT_SPINLOCK);
WT_PADDING_CHECK(WT_TXN_STATE);
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index a6deed7e14e..ddecb2ac765 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -36,7 +36,7 @@ extern "C" {
#if defined(DOXYGEN) || defined(SWIG)
#define __F(func) func
#else
-#define __F(func) (*func)
+#define __F(func) (*(func))
#endif
#ifdef SWIG
@@ -114,16 +114,16 @@ struct __wt_item {
size_t size;
#ifndef DOXYGEN
-#define WT_ITEM_ALIGNED 0x00000001
-#define WT_ITEM_INUSE 0x00000002
- /* This appears in the middle of the struct to avoid padding. */
- /*! Object flags (internal use). */
- uint32_t flags;
-
/*! Managed memory chunk (internal use). */
void *mem;
+
/*! Managed memory size (internal use). */
size_t memsize;
+
+#define WT_ITEM_ALIGNED 0x00000001
+#define WT_ITEM_INUSE 0x00000002
+ /*! Object flags (internal use). */
+ uint32_t flags;
#endif
};
@@ -427,7 +427,7 @@ struct __wt_cursor {
*
* @param cursor the cursor handle
* @errors
- * In particular, if \c overwrite is not configured and a record with
+ * In particular, if \c overwrite=false is configured and a record with
* the specified key already exists, ::WT_DUPLICATE_KEY is returned.
* Also, if \c in_memory is configured for the database and the insert
* requires more than the configured cache size to complete,
@@ -452,7 +452,9 @@ struct __wt_cursor {
*
* On success, the cursor ends positioned at the modified record; to
* minimize cursor resources, the WT_CURSOR::reset method should be
- * called as soon as the cursor no longer needs that position.
+ * called as soon as the cursor no longer needs that position. (The
+ * WT_CURSOR::insert method never keeps a cursor position and may be
+ * more efficient for that reason.)
*
* The maximum length of a single column stored in a table is not fixed
* (as it partially depends on the underlying file configuration), but
@@ -460,7 +462,7 @@ struct __wt_cursor {
*
* @param cursor the cursor handle
* @errors
- * In particular, if \c overwrite is not configured and no record with
+ * In particular, if \c overwrite=false is configured and no record with
* the specified key exists, ::WT_NOTFOUND is returned.
* Also, if \c in_memory is configured for the database and the insert
* requires more than the configured cache size to complete,
@@ -477,8 +479,18 @@ struct __wt_cursor {
*
* @snippet ex_all.c Remove a record
*
- * If the cursor was not configured with "overwrite=true", the key must
- * be set and the key's record must exist; the record will be removed.
+ * If the cursor was configured with "overwrite=false" (not the
+ * default), the key must be set and the key's record must exist; the
+ * record will be removed.
+ *
+ * Any cursor position does not change: if the cursor was positioned
+ * before the WT_CURSOR::remove call, the cursor remains positioned
+ * at the removed record; to minimize cursor resources, the
+ * WT_CURSOR::reset method should be called as soon as the cursor no
+ * longer needs that position. If the cursor was not positioned before
+ * the WT_CURSOR::remove call, the cursor ends with no position, and a
+ * subsequent call to the WT_CURSOR::next (WT_CURSOR::prev) method will
+ * iterate from the beginning (end) of the table.
*
* @snippet ex_all.c Remove a record and fail if DNE
*
@@ -486,14 +498,10 @@ struct __wt_cursor {
* (that is, a store with an 'r' type key and 't' type value) is
* identical to setting the record's value to 0.
*
- * On success, the cursor ends positioned at the removed record; to
- * minimize cursor resources, the WT_CURSOR::reset method should be
- * called as soon as the cursor no longer needs that position.
- *
* @param cursor the cursor handle
* @errors
- * In particular, if \c overwrite is not configured and no record with
- * the specified key exists, ::WT_NOTFOUND is returned.
+ * In particular, if \c overwrite=false is configured and no record
+ * with the specified key exists, ::WT_NOTFOUND is returned.
*/
int __F(remove)(WT_CURSOR *cursor);
/*! @} */
@@ -576,8 +584,9 @@ struct __wt_cursor {
#define WT_CURSTD_OPEN 0x00200
#define WT_CURSTD_OVERWRITE 0x00400
#define WT_CURSTD_RAW 0x00800
-#define WT_CURSTD_VALUE_EXT 0x01000 /* Value points out of the tree. */
-#define WT_CURSTD_VALUE_INT 0x02000 /* Value points into the tree. */
+#define WT_CURSTD_RAW_SEARCH 0x01000
+#define WT_CURSTD_VALUE_EXT 0x02000 /* Value points out of the tree. */
+#define WT_CURSTD_VALUE_INT 0x04000 /* Value points into the tree. */
#define WT_CURSTD_VALUE_SET (WT_CURSTD_VALUE_EXT | WT_CURSTD_VALUE_INT)
uint32_t flags;
#endif
@@ -1233,8 +1242,8 @@ struct __wt_session {
* @config{split_pct, the Btree page split size as a percentage of the
* maximum Btree page size\, that is\, when a Btree page is split\, it
* will be split into smaller pages\, where each page is the specified
- * percentage of the maximum Btree page size., an integer between 25 and
- * 100; default \c 75.}
+ * percentage of the maximum Btree page size., an integer between 50 and
+ * 100; default \c 90.}
* @config{type, set the type of data source used to store a column
* group\, index or simple table. By default\, a \c "file:" URI is
* derived from the object name. The \c type configuration can be used
@@ -1471,6 +1480,10 @@ struct __wt_session {
* contains.
* @snippet ex_all.c Truncate a range
*
+ * Any specified cursors end with no position, and subsequent calls to
+ * the WT_CURSOR::next (WT_CURSOR::prev) method will iterate from the
+ * beginning (end) of the table.
+ *
* @param session the session handle
* @param name the URI of the file or table to truncate
* @param start optional cursor marking the first record discarded;
@@ -1855,7 +1868,7 @@ struct __wt_connection {
* threads WiredTiger will start to help evict pages from cache. The
* number of threads started will vary depending on the current eviction
* load. Each eviction worker thread uses a session from the configured
- * session_max., an integer between 1 and 20; default \c 1.}
+ * session_max., an integer between 1 and 20; default \c 8.}
* @config{&nbsp;&nbsp;&nbsp;&nbsp;threads_min, minimum number of
* threads WiredTiger will start to help evict pages from cache. The
* number of threads currently running will vary depending on the
@@ -1982,12 +1995,13 @@ struct __wt_connection {
* as a list\, such as <code>"verbose=[evictserver\,read]"</code>., a
* list\, with values chosen from the following options: \c "api"\, \c
* "block"\, \c "checkpoint"\, \c "compact"\, \c "evict"\, \c
- * "evictserver"\, \c "fileops"\, \c "handleops"\, \c "log"\, \c "lsm"\,
- * \c "lsm_manager"\, \c "metadata"\, \c "mutex"\, \c "overflow"\, \c
- * "read"\, \c "rebalance"\, \c "reconcile"\, \c "recovery"\, \c
- * "salvage"\, \c "shared_cache"\, \c "split"\, \c "temporary"\, \c
- * "thread_group"\, \c "transaction"\, \c "verify"\, \c "version"\, \c
- * "write"; default empty.}
+ * "evict_stuck"\, \c "evictserver"\, \c "fileops"\, \c "handleops"\, \c
+ * "log"\, \c "lsm"\, \c "lsm_manager"\, \c "metadata"\, \c "mutex"\, \c
+ * "overflow"\, \c "read"\, \c "rebalance"\, \c "reconcile"\, \c
+ * "recovery"\, \c "recovery_progress"\, \c "salvage"\, \c
+ * "shared_cache"\, \c "split"\, \c "temporary"\, \c "thread_group"\, \c
+ * "transaction"\, \c "verify"\, \c "version"\, \c "write"; default
+ * empty.}
* @configend
* @errors
*/
@@ -2331,7 +2345,7 @@ struct __wt_connection {
* WiredTiger will start to help evict pages from cache. The number of threads
* started will vary depending on the current eviction load. Each eviction
* worker thread uses a session from the configured session_max., an integer
- * between 1 and 20; default \c 1.}
+ * between 1 and 20; default \c 8.}
* @config{&nbsp;&nbsp;&nbsp;&nbsp;threads_min,
* minimum number of threads WiredTiger will start to help evict pages from
* cache. The number of threads currently running will vary depending on the
@@ -2361,7 +2375,7 @@ struct __wt_connection {
* @config{exclusive, fail if the database already exists\, generally used with
* the \c create option., a boolean flag; default \c false.}
* @config{extensions, list of shared library extensions to load (using dlopen).
- * Any values specified to an library extension are passed to
+ * Any values specified to a library extension are passed to
* WT_CONNECTION::load_extension as the \c config parameter (for example\,
* <code>extensions=(/path/ext.so={entry=my_entry})</code>)., a list of strings;
* default empty.}
@@ -2513,12 +2527,13 @@ struct __wt_connection {
* WiredTiger is configured with --enable-verbose. Options are given as a
* list\, such as <code>"verbose=[evictserver\,read]"</code>., a list\, with
* values chosen from the following options: \c "api"\, \c "block"\, \c
- * "checkpoint"\, \c "compact"\, \c "evict"\, \c "evictserver"\, \c "fileops"\,
- * \c "handleops"\, \c "log"\, \c "lsm"\, \c "lsm_manager"\, \c "metadata"\, \c
- * "mutex"\, \c "overflow"\, \c "read"\, \c "rebalance"\, \c "reconcile"\, \c
- * "recovery"\, \c "salvage"\, \c "shared_cache"\, \c "split"\, \c "temporary"\,
- * \c "thread_group"\, \c "transaction"\, \c "verify"\, \c "version"\, \c
- * "write"; default empty.}
+ * "checkpoint"\, \c "compact"\, \c "evict"\, \c "evict_stuck"\, \c
+ * "evictserver"\, \c "fileops"\, \c "handleops"\, \c "log"\, \c "lsm"\, \c
+ * "lsm_manager"\, \c "metadata"\, \c "mutex"\, \c "overflow"\, \c "read"\, \c
+ * "rebalance"\, \c "reconcile"\, \c "recovery"\, \c "recovery_progress"\, \c
+ * "salvage"\, \c "shared_cache"\, \c "split"\, \c "temporary"\, \c
+ * "thread_group"\, \c "transaction"\, \c "verify"\, \c "version"\, \c "write";
+ * default empty.}
* @config{write_through, Use \c FILE_FLAG_WRITE_THROUGH on Windows to write to
* files. Ignored on non-Windows systems. Options are given as a list\, such
* as <code>"write_through=[data]"</code>. Configuring \c write_through requires
@@ -3062,27 +3077,27 @@ const char *wiredtiger_version(int *majorp, int *minorp, int *patchp);
* transaction is in progress, it should be rolled back and the operation
* retried in a new transaction.
*/
-#define WT_ROLLBACK -31800
+#define WT_ROLLBACK (-31800)
/*!
* Attempt to insert an existing key.
* This error is generated when the application attempts to insert a record with
* the same key as an existing record without the 'overwrite' configuration to
* WT_SESSION::open_cursor.
*/
-#define WT_DUPLICATE_KEY -31801
+#define WT_DUPLICATE_KEY (-31801)
/*!
* Non-specific WiredTiger error.
* This error is returned when an error is not covered by a specific error
* return.
*/
-#define WT_ERROR -31802
+#define WT_ERROR (-31802)
/*!
* Item not found.
* This error indicates an operation did not find a value to return. This
* includes cursor search and other operations where no record matched the
* cursor's search key such as WT_CURSOR::update or WT_CURSOR::remove.
*/
-#define WT_NOTFOUND -31803
+#define WT_NOTFOUND (-31803)
/*!
* WiredTiger library panic.
* This error indicates an underlying problem that requires the application exit
@@ -3090,17 +3105,17 @@ const char *wiredtiger_version(int *majorp, int *minorp, int *patchp);
* returned from a WiredTiger interface, no further WiredTiger calls are
* required.
*/
-#define WT_PANIC -31804
+#define WT_PANIC (-31804)
/*! @cond internal */
/*! Restart the operation (internal). */
-#define WT_RESTART -31805
+#define WT_RESTART (-31805)
/*! @endcond */
/*!
* Recovery must be run to continue.
* This error is generated when wiredtiger_open is configured to return an error
* if recovery is required to use the database.
*/
-#define WT_RUN_RECOVERY -31806
+#define WT_RUN_RECOVERY (-31806)
/*!
* Operation would overflow cache.
* This error is only generated when wiredtiger_open is configured to run in-
@@ -3109,7 +3124,7 @@ const char *wiredtiger_version(int *majorp, int *minorp, int *patchp);
* progress, it should be rolled back and the operation retried in a new
* transaction.
*/
-#define WT_CACHE_FULL -31807
+#define WT_CACHE_FULL (-31807)
/*
* Error return section: END
* DO NOT EDIT: automatically built by dist/api_err.py.
@@ -4429,396 +4444,406 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_CONN_CACHE_EVICTION_STATE 1051
/*! cache: eviction walks abandoned */
#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ABANDONED 1052
+/*! cache: eviction worker thread active */
+#define WT_STAT_CONN_CACHE_EVICTION_ACTIVE_WORKERS 1053
+/*! cache: eviction worker thread created */
+#define WT_STAT_CONN_CACHE_EVICTION_WORKER_CREATED 1054
/*! cache: eviction worker thread evicting pages */
-#define WT_STAT_CONN_CACHE_EVICTION_WORKER_EVICTING 1053
+#define WT_STAT_CONN_CACHE_EVICTION_WORKER_EVICTING 1055
+/*! cache: eviction worker thread removed */
+#define WT_STAT_CONN_CACHE_EVICTION_WORKER_REMOVED 1056
+/*! cache: eviction worker thread stable number */
+#define WT_STAT_CONN_CACHE_EVICTION_STABLE_STATE_WORKERS 1057
/*! cache: failed eviction of pages that exceeded the in-memory maximum */
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE_FAIL 1054
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_FAIL 1058
/*! cache: files with active eviction walks */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ACTIVE 1055
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ACTIVE 1059
/*! cache: files with new eviction walks started */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STARTED 1056
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STARTED 1060
+/*! cache: force re-tuning of eviction workers once in a while */
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_RETUNE 1061
/*! cache: hazard pointer blocked page eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_HAZARD 1057
+#define WT_STAT_CONN_CACHE_EVICTION_HAZARD 1062
/*! cache: hazard pointer check calls */
-#define WT_STAT_CONN_CACHE_HAZARD_CHECKS 1058
+#define WT_STAT_CONN_CACHE_HAZARD_CHECKS 1063
/*! cache: hazard pointer check entries walked */
-#define WT_STAT_CONN_CACHE_HAZARD_WALKS 1059
+#define WT_STAT_CONN_CACHE_HAZARD_WALKS 1064
/*! cache: hazard pointer maximum array length */
-#define WT_STAT_CONN_CACHE_HAZARD_MAX 1060
+#define WT_STAT_CONN_CACHE_HAZARD_MAX 1065
/*! cache: in-memory page passed criteria to be split */
-#define WT_STAT_CONN_CACHE_INMEM_SPLITTABLE 1061
+#define WT_STAT_CONN_CACHE_INMEM_SPLITTABLE 1066
/*! cache: in-memory page splits */
-#define WT_STAT_CONN_CACHE_INMEM_SPLIT 1062
+#define WT_STAT_CONN_CACHE_INMEM_SPLIT 1067
/*! cache: internal pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_INTERNAL 1063
+#define WT_STAT_CONN_CACHE_EVICTION_INTERNAL 1068
/*! cache: internal pages split during eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_INTERNAL 1064
+#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_INTERNAL 1069
/*! cache: leaf pages split during eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_LEAF 1065
+#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_LEAF 1070
/*! cache: lookaside table insert calls */
-#define WT_STAT_CONN_CACHE_LOOKASIDE_INSERT 1066
+#define WT_STAT_CONN_CACHE_LOOKASIDE_INSERT 1071
/*! cache: lookaside table remove calls */
-#define WT_STAT_CONN_CACHE_LOOKASIDE_REMOVE 1067
+#define WT_STAT_CONN_CACHE_LOOKASIDE_REMOVE 1072
/*! cache: maximum bytes configured */
-#define WT_STAT_CONN_CACHE_BYTES_MAX 1068
+#define WT_STAT_CONN_CACHE_BYTES_MAX 1073
/*! cache: maximum page size at eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_MAXIMUM_PAGE_SIZE 1069
+#define WT_STAT_CONN_CACHE_EVICTION_MAXIMUM_PAGE_SIZE 1074
/*! cache: modified pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_DIRTY 1070
+#define WT_STAT_CONN_CACHE_EVICTION_DIRTY 1075
/*! cache: modified pages evicted by application threads */
-#define WT_STAT_CONN_CACHE_EVICTION_APP_DIRTY 1071
+#define WT_STAT_CONN_CACHE_EVICTION_APP_DIRTY 1076
/*! cache: overflow pages read into cache */
-#define WT_STAT_CONN_CACHE_READ_OVERFLOW 1072
+#define WT_STAT_CONN_CACHE_READ_OVERFLOW 1077
/*! cache: overflow values cached in memory */
-#define WT_STAT_CONN_CACHE_OVERFLOW_VALUE 1073
+#define WT_STAT_CONN_CACHE_OVERFLOW_VALUE 1078
/*! cache: page split during eviction deepened the tree */
-#define WT_STAT_CONN_CACHE_EVICTION_DEEPEN 1074
+#define WT_STAT_CONN_CACHE_EVICTION_DEEPEN 1079
/*! cache: page written requiring lookaside records */
-#define WT_STAT_CONN_CACHE_WRITE_LOOKASIDE 1075
+#define WT_STAT_CONN_CACHE_WRITE_LOOKASIDE 1080
/*! cache: pages currently held in the cache */
-#define WT_STAT_CONN_CACHE_PAGES_INUSE 1076
+#define WT_STAT_CONN_CACHE_PAGES_INUSE 1081
/*! cache: pages evicted because they exceeded the in-memory maximum */
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE 1077
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE 1082
/*! cache: pages evicted because they had chains of deleted items */
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE_DELETE 1078
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_DELETE 1083
/*! cache: pages evicted by application threads */
-#define WT_STAT_CONN_CACHE_EVICTION_APP 1079
+#define WT_STAT_CONN_CACHE_EVICTION_APP 1084
/*! cache: pages queued for eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED 1080
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED 1085
/*! cache: pages queued for urgent eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_URGENT 1081
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_URGENT 1086
/*! cache: pages queued for urgent eviction during walk */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_OLDEST 1082
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_OLDEST 1087
/*! cache: pages read into cache */
-#define WT_STAT_CONN_CACHE_READ 1083
+#define WT_STAT_CONN_CACHE_READ 1088
/*! cache: pages read into cache requiring lookaside entries */
-#define WT_STAT_CONN_CACHE_READ_LOOKASIDE 1084
+#define WT_STAT_CONN_CACHE_READ_LOOKASIDE 1089
/*! cache: pages requested from the cache */
-#define WT_STAT_CONN_CACHE_PAGES_REQUESTED 1085
+#define WT_STAT_CONN_CACHE_PAGES_REQUESTED 1090
/*! cache: pages seen by eviction walk */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_SEEN 1086
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_SEEN 1091
/*! cache: pages selected for eviction unable to be evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_FAIL 1087
+#define WT_STAT_CONN_CACHE_EVICTION_FAIL 1092
/*! cache: pages walked for eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_WALK 1088
+#define WT_STAT_CONN_CACHE_EVICTION_WALK 1093
/*! cache: pages written from cache */
-#define WT_STAT_CONN_CACHE_WRITE 1089
+#define WT_STAT_CONN_CACHE_WRITE 1094
/*! cache: pages written requiring in-memory restoration */
-#define WT_STAT_CONN_CACHE_WRITE_RESTORE 1090
+#define WT_STAT_CONN_CACHE_WRITE_RESTORE 1095
/*! cache: percentage overhead */
-#define WT_STAT_CONN_CACHE_OVERHEAD 1091
+#define WT_STAT_CONN_CACHE_OVERHEAD 1096
/*! cache: tracked bytes belonging to internal pages in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_INTERNAL 1092
+#define WT_STAT_CONN_CACHE_BYTES_INTERNAL 1097
/*! cache: tracked bytes belonging to leaf pages in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_LEAF 1093
+#define WT_STAT_CONN_CACHE_BYTES_LEAF 1098
/*! cache: tracked dirty bytes in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_DIRTY 1094
+#define WT_STAT_CONN_CACHE_BYTES_DIRTY 1099
/*! cache: tracked dirty pages in the cache */
-#define WT_STAT_CONN_CACHE_PAGES_DIRTY 1095
+#define WT_STAT_CONN_CACHE_PAGES_DIRTY 1100
/*! cache: unmodified pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_CLEAN 1096
+#define WT_STAT_CONN_CACHE_EVICTION_CLEAN 1101
/*! connection: auto adjusting condition resets */
-#define WT_STAT_CONN_COND_AUTO_WAIT_RESET 1097
+#define WT_STAT_CONN_COND_AUTO_WAIT_RESET 1102
/*! connection: auto adjusting condition wait calls */
-#define WT_STAT_CONN_COND_AUTO_WAIT 1098
+#define WT_STAT_CONN_COND_AUTO_WAIT 1103
/*! connection: files currently open */
-#define WT_STAT_CONN_FILE_OPEN 1099
+#define WT_STAT_CONN_FILE_OPEN 1104
/*! connection: memory allocations */
-#define WT_STAT_CONN_MEMORY_ALLOCATION 1100
+#define WT_STAT_CONN_MEMORY_ALLOCATION 1105
/*! connection: memory frees */
-#define WT_STAT_CONN_MEMORY_FREE 1101
+#define WT_STAT_CONN_MEMORY_FREE 1106
/*! connection: memory re-allocations */
-#define WT_STAT_CONN_MEMORY_GROW 1102
+#define WT_STAT_CONN_MEMORY_GROW 1107
/*! connection: pthread mutex condition wait calls */
-#define WT_STAT_CONN_COND_WAIT 1103
+#define WT_STAT_CONN_COND_WAIT 1108
/*! connection: pthread mutex shared lock read-lock calls */
-#define WT_STAT_CONN_RWLOCK_READ 1104
+#define WT_STAT_CONN_RWLOCK_READ 1109
/*! connection: pthread mutex shared lock write-lock calls */
-#define WT_STAT_CONN_RWLOCK_WRITE 1105
+#define WT_STAT_CONN_RWLOCK_WRITE 1110
/*! connection: total fsync I/Os */
-#define WT_STAT_CONN_FSYNC_IO 1106
+#define WT_STAT_CONN_FSYNC_IO 1111
/*! connection: total read I/Os */
-#define WT_STAT_CONN_READ_IO 1107
+#define WT_STAT_CONN_READ_IO 1112
/*! connection: total write I/Os */
-#define WT_STAT_CONN_WRITE_IO 1108
+#define WT_STAT_CONN_WRITE_IO 1113
/*! cursor: cursor create calls */
-#define WT_STAT_CONN_CURSOR_CREATE 1109
+#define WT_STAT_CONN_CURSOR_CREATE 1114
/*! cursor: cursor insert calls */
-#define WT_STAT_CONN_CURSOR_INSERT 1110
+#define WT_STAT_CONN_CURSOR_INSERT 1115
/*! cursor: cursor next calls */
-#define WT_STAT_CONN_CURSOR_NEXT 1111
+#define WT_STAT_CONN_CURSOR_NEXT 1116
/*! cursor: cursor prev calls */
-#define WT_STAT_CONN_CURSOR_PREV 1112
+#define WT_STAT_CONN_CURSOR_PREV 1117
/*! cursor: cursor remove calls */
-#define WT_STAT_CONN_CURSOR_REMOVE 1113
+#define WT_STAT_CONN_CURSOR_REMOVE 1118
/*! cursor: cursor reset calls */
-#define WT_STAT_CONN_CURSOR_RESET 1114
+#define WT_STAT_CONN_CURSOR_RESET 1119
/*! cursor: cursor restarted searches */
-#define WT_STAT_CONN_CURSOR_RESTART 1115
+#define WT_STAT_CONN_CURSOR_RESTART 1120
/*! cursor: cursor search calls */
-#define WT_STAT_CONN_CURSOR_SEARCH 1116
+#define WT_STAT_CONN_CURSOR_SEARCH 1121
/*! cursor: cursor search near calls */
-#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1117
+#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1122
/*! cursor: cursor update calls */
-#define WT_STAT_CONN_CURSOR_UPDATE 1118
+#define WT_STAT_CONN_CURSOR_UPDATE 1123
/*! cursor: truncate calls */
-#define WT_STAT_CONN_CURSOR_TRUNCATE 1119
+#define WT_STAT_CONN_CURSOR_TRUNCATE 1124
/*! data-handle: connection data handles currently active */
-#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1120
+#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1125
/*! data-handle: connection sweep candidate became referenced */
-#define WT_STAT_CONN_DH_SWEEP_REF 1121
+#define WT_STAT_CONN_DH_SWEEP_REF 1126
/*! data-handle: connection sweep dhandles closed */
-#define WT_STAT_CONN_DH_SWEEP_CLOSE 1122
+#define WT_STAT_CONN_DH_SWEEP_CLOSE 1127
/*! data-handle: connection sweep dhandles removed from hash list */
-#define WT_STAT_CONN_DH_SWEEP_REMOVE 1123
+#define WT_STAT_CONN_DH_SWEEP_REMOVE 1128
/*! data-handle: connection sweep time-of-death sets */
-#define WT_STAT_CONN_DH_SWEEP_TOD 1124
+#define WT_STAT_CONN_DH_SWEEP_TOD 1129
/*! data-handle: connection sweeps */
-#define WT_STAT_CONN_DH_SWEEPS 1125
+#define WT_STAT_CONN_DH_SWEEPS 1130
/*! data-handle: session dhandles swept */
-#define WT_STAT_CONN_DH_SESSION_HANDLES 1126
+#define WT_STAT_CONN_DH_SESSION_HANDLES 1131
/*! data-handle: session sweep attempts */
-#define WT_STAT_CONN_DH_SESSION_SWEEPS 1127
+#define WT_STAT_CONN_DH_SESSION_SWEEPS 1132
/*! lock: checkpoint lock acquisitions */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_COUNT 1128
+#define WT_STAT_CONN_LOCK_CHECKPOINT_COUNT 1133
/*! lock: checkpoint lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_APPLICATION 1129
+#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_APPLICATION 1134
/*! lock: checkpoint lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_INTERNAL 1130
-/*! lock: handle-list lock acquisitions */
-#define WT_STAT_CONN_LOCK_HANDLE_LIST_COUNT 1131
-/*! lock: handle-list lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_HANDLE_LIST_WAIT_APPLICATION 1132
-/*! lock: handle-list lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_HANDLE_LIST_WAIT_INTERNAL 1133
+#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_INTERNAL 1135
+/*! lock: handle-list lock eviction thread wait time (usecs) */
+#define WT_STAT_CONN_LOCK_HANDLE_LIST_WAIT_EVICTION 1136
/*! lock: metadata lock acquisitions */
-#define WT_STAT_CONN_LOCK_METADATA_COUNT 1134
+#define WT_STAT_CONN_LOCK_METADATA_COUNT 1137
/*! lock: metadata lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_METADATA_WAIT_APPLICATION 1135
+#define WT_STAT_CONN_LOCK_METADATA_WAIT_APPLICATION 1138
/*! lock: metadata lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_METADATA_WAIT_INTERNAL 1136
+#define WT_STAT_CONN_LOCK_METADATA_WAIT_INTERNAL 1139
/*! lock: schema lock acquisitions */
-#define WT_STAT_CONN_LOCK_SCHEMA_COUNT 1137
+#define WT_STAT_CONN_LOCK_SCHEMA_COUNT 1140
/*! lock: schema lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_APPLICATION 1138
+#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_APPLICATION 1141
/*! lock: schema lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_INTERNAL 1139
+#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_INTERNAL 1142
/*! lock: table lock acquisitions */
-#define WT_STAT_CONN_LOCK_TABLE_COUNT 1140
+#define WT_STAT_CONN_LOCK_TABLE_COUNT 1143
/*!
* lock: table lock application thread time waiting for the table lock
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_TABLE_WAIT_APPLICATION 1141
+#define WT_STAT_CONN_LOCK_TABLE_WAIT_APPLICATION 1144
/*!
* lock: table lock internal thread time waiting for the table lock
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_TABLE_WAIT_INTERNAL 1142
+#define WT_STAT_CONN_LOCK_TABLE_WAIT_INTERNAL 1145
/*! log: busy returns attempting to switch slots */
-#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1143
+#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1146
/*! log: consolidated slot closures */
-#define WT_STAT_CONN_LOG_SLOT_CLOSES 1144
+#define WT_STAT_CONN_LOG_SLOT_CLOSES 1147
+/*! log: consolidated slot join active slot closed */
+#define WT_STAT_CONN_LOG_SLOT_ACTIVE_CLOSED 1148
/*! log: consolidated slot join races */
-#define WT_STAT_CONN_LOG_SLOT_RACES 1145
+#define WT_STAT_CONN_LOG_SLOT_RACES 1149
/*! log: consolidated slot join transitions */
-#define WT_STAT_CONN_LOG_SLOT_TRANSITIONS 1146
+#define WT_STAT_CONN_LOG_SLOT_TRANSITIONS 1150
/*! log: consolidated slot joins */
-#define WT_STAT_CONN_LOG_SLOT_JOINS 1147
+#define WT_STAT_CONN_LOG_SLOT_JOINS 1151
+/*! log: consolidated slot transitions unable to find free slot */
+#define WT_STAT_CONN_LOG_SLOT_NO_FREE_SLOTS 1152
/*! log: consolidated slot unbuffered writes */
-#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1148
+#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1153
/*! log: log bytes of payload data */
-#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1149
+#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1154
/*! log: log bytes written */
-#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1150
+#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1155
/*! log: log files manually zero-filled */
-#define WT_STAT_CONN_LOG_ZERO_FILLS 1151
+#define WT_STAT_CONN_LOG_ZERO_FILLS 1156
/*! log: log flush operations */
-#define WT_STAT_CONN_LOG_FLUSH 1152
+#define WT_STAT_CONN_LOG_FLUSH 1157
/*! log: log force write operations */
-#define WT_STAT_CONN_LOG_FORCE_WRITE 1153
+#define WT_STAT_CONN_LOG_FORCE_WRITE 1158
/*! log: log force write operations skipped */
-#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1154
+#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1159
/*! log: log records compressed */
-#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1155
+#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1160
/*! log: log records not compressed */
-#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1156
+#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1161
/*! log: log records too small to compress */
-#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1157
+#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1162
/*! log: log release advances write LSN */
-#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1158
+#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1163
/*! log: log scan operations */
-#define WT_STAT_CONN_LOG_SCANS 1159
+#define WT_STAT_CONN_LOG_SCANS 1164
/*! log: log scan records requiring two reads */
-#define WT_STAT_CONN_LOG_SCAN_REREADS 1160
+#define WT_STAT_CONN_LOG_SCAN_REREADS 1165
/*! log: log server thread advances write LSN */
-#define WT_STAT_CONN_LOG_WRITE_LSN 1161
+#define WT_STAT_CONN_LOG_WRITE_LSN 1166
/*! log: log server thread write LSN walk skipped */
-#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1162
+#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1167
/*! log: log sync operations */
-#define WT_STAT_CONN_LOG_SYNC 1163
+#define WT_STAT_CONN_LOG_SYNC 1168
/*! log: log sync time duration (usecs) */
-#define WT_STAT_CONN_LOG_SYNC_DURATION 1164
+#define WT_STAT_CONN_LOG_SYNC_DURATION 1169
/*! log: log sync_dir operations */
-#define WT_STAT_CONN_LOG_SYNC_DIR 1165
+#define WT_STAT_CONN_LOG_SYNC_DIR 1170
/*! log: log sync_dir time duration (usecs) */
-#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1166
+#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1171
/*! log: log write operations */
-#define WT_STAT_CONN_LOG_WRITES 1167
+#define WT_STAT_CONN_LOG_WRITES 1172
/*! log: logging bytes consolidated */
-#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1168
+#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1173
/*! log: maximum log file size */
-#define WT_STAT_CONN_LOG_MAX_FILESIZE 1169
+#define WT_STAT_CONN_LOG_MAX_FILESIZE 1174
/*! log: number of pre-allocated log files to create */
-#define WT_STAT_CONN_LOG_PREALLOC_MAX 1170
+#define WT_STAT_CONN_LOG_PREALLOC_MAX 1175
/*! log: pre-allocated log files not ready and missed */
-#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1171
+#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1176
/*! log: pre-allocated log files prepared */
-#define WT_STAT_CONN_LOG_PREALLOC_FILES 1172
+#define WT_STAT_CONN_LOG_PREALLOC_FILES 1177
/*! log: pre-allocated log files used */
-#define WT_STAT_CONN_LOG_PREALLOC_USED 1173
+#define WT_STAT_CONN_LOG_PREALLOC_USED 1178
/*! log: records processed by log scan */
-#define WT_STAT_CONN_LOG_SCAN_RECORDS 1174
+#define WT_STAT_CONN_LOG_SCAN_RECORDS 1179
/*! log: total in-memory size of compressed records */
-#define WT_STAT_CONN_LOG_COMPRESS_MEM 1175
+#define WT_STAT_CONN_LOG_COMPRESS_MEM 1180
/*! log: total log buffer size */
-#define WT_STAT_CONN_LOG_BUFFER_SIZE 1176
+#define WT_STAT_CONN_LOG_BUFFER_SIZE 1181
/*! log: total size of compressed records */
-#define WT_STAT_CONN_LOG_COMPRESS_LEN 1177
+#define WT_STAT_CONN_LOG_COMPRESS_LEN 1182
/*! log: written slots coalesced */
-#define WT_STAT_CONN_LOG_SLOT_COALESCED 1178
+#define WT_STAT_CONN_LOG_SLOT_COALESCED 1183
/*! log: yields waiting for previous log file close */
-#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1179
+#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1184
/*! reconciliation: fast-path pages deleted */
-#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1180
+#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1185
/*! reconciliation: page reconciliation calls */
-#define WT_STAT_CONN_REC_PAGES 1181
+#define WT_STAT_CONN_REC_PAGES 1186
/*! reconciliation: page reconciliation calls for eviction */
-#define WT_STAT_CONN_REC_PAGES_EVICTION 1182
+#define WT_STAT_CONN_REC_PAGES_EVICTION 1187
/*! reconciliation: pages deleted */
-#define WT_STAT_CONN_REC_PAGE_DELETE 1183
+#define WT_STAT_CONN_REC_PAGE_DELETE 1188
/*! reconciliation: split bytes currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1184
+#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1189
/*! reconciliation: split objects currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1185
+#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1190
/*! session: open cursor count */
-#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1186
+#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1191
/*! session: open session count */
-#define WT_STAT_CONN_SESSION_OPEN 1187
+#define WT_STAT_CONN_SESSION_OPEN 1192
/*! session: table alter failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1188
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1193
/*! session: table alter successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1189
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1194
/*! session: table alter unchanged and skipped */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1190
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1195
/*! session: table compact failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1191
+#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1196
/*! session: table compact successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1192
+#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1197
/*! session: table create failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1193
+#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1198
/*! session: table create successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1194
+#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1199
/*! session: table drop failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1195
+#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1200
/*! session: table drop successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1196
+#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1201
/*! session: table rebalance failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_FAIL 1197
+#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_FAIL 1202
/*! session: table rebalance successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_SUCCESS 1198
+#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_SUCCESS 1203
/*! session: table rename failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1199
+#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1204
/*! session: table rename successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1200
+#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1205
/*! session: table salvage failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1201
+#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1206
/*! session: table salvage successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1202
+#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1207
/*! session: table truncate failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1203
+#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1208
/*! session: table truncate successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1204
+#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1209
/*! session: table verify failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1205
+#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1210
/*! session: table verify successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1206
+#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1211
/*! thread-state: active filesystem fsync calls */
-#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1207
+#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1212
/*! thread-state: active filesystem read calls */
-#define WT_STAT_CONN_THREAD_READ_ACTIVE 1208
+#define WT_STAT_CONN_THREAD_READ_ACTIVE 1213
/*! thread-state: active filesystem write calls */
-#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1209
+#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1214
/*! thread-yield: application thread time evicting (usecs) */
-#define WT_STAT_CONN_APPLICATION_EVICT_TIME 1210
+#define WT_STAT_CONN_APPLICATION_EVICT_TIME 1215
/*! thread-yield: application thread time waiting for cache (usecs) */
-#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1211
+#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1216
/*! thread-yield: page acquire busy blocked */
-#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1212
+#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1217
/*! thread-yield: page acquire eviction blocked */
-#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1213
+#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1218
/*! thread-yield: page acquire locked blocked */
-#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1214
+#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1219
/*! thread-yield: page acquire read blocked */
-#define WT_STAT_CONN_PAGE_READ_BLOCKED 1215
+#define WT_STAT_CONN_PAGE_READ_BLOCKED 1220
/*! thread-yield: page acquire time sleeping (usecs) */
-#define WT_STAT_CONN_PAGE_SLEEP 1216
+#define WT_STAT_CONN_PAGE_SLEEP 1221
/*! transaction: number of named snapshots created */
-#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1217
+#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1222
/*! transaction: number of named snapshots dropped */
-#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1218
+#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1223
/*! transaction: transaction begins */
-#define WT_STAT_CONN_TXN_BEGIN 1219
+#define WT_STAT_CONN_TXN_BEGIN 1224
/*! transaction: transaction checkpoint currently running */
-#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1220
+#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1225
/*! transaction: transaction checkpoint generation */
-#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1221
+#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1226
/*! transaction: transaction checkpoint max time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1222
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1227
/*! transaction: transaction checkpoint min time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1223
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1228
/*! transaction: transaction checkpoint most recent time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1224
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1229
/*! transaction: transaction checkpoint scrub dirty target */
-#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1225
+#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1230
/*! transaction: transaction checkpoint scrub time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1226
+#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1231
/*! transaction: transaction checkpoint total time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1227
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1232
/*! transaction: transaction checkpoints */
-#define WT_STAT_CONN_TXN_CHECKPOINT 1228
+#define WT_STAT_CONN_TXN_CHECKPOINT 1233
/*!
* transaction: transaction checkpoints skipped because database was
* clean
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_SKIPPED 1229
+#define WT_STAT_CONN_TXN_CHECKPOINT_SKIPPED 1234
/*! transaction: transaction failures due to cache overflow */
-#define WT_STAT_CONN_TXN_FAIL_CACHE 1230
+#define WT_STAT_CONN_TXN_FAIL_CACHE 1235
/*!
* transaction: transaction fsync calls for checkpoint after allocating
* the transaction ID
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1231
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1236
/*!
* transaction: transaction fsync duration for checkpoint after
* allocating the transaction ID (usecs)
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1232
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1237
/*! transaction: transaction range of IDs currently pinned */
-#define WT_STAT_CONN_TXN_PINNED_RANGE 1233
+#define WT_STAT_CONN_TXN_PINNED_RANGE 1238
/*! transaction: transaction range of IDs currently pinned by a checkpoint */
-#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1234
+#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1239
/*!
* transaction: transaction range of IDs currently pinned by named
* snapshots
*/
-#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1235
+#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1240
/*! transaction: transaction sync calls */
-#define WT_STAT_CONN_TXN_SYNC 1236
+#define WT_STAT_CONN_TXN_SYNC 1241
/*! transaction: transactions committed */
-#define WT_STAT_CONN_TXN_COMMIT 1237
+#define WT_STAT_CONN_TXN_COMMIT 1242
/*! transaction: transactions rolled back */
-#define WT_STAT_CONN_TXN_ROLLBACK 1238
+#define WT_STAT_CONN_TXN_ROLLBACK 1243
/*!
* @}
@@ -4978,181 +5003,183 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_DSRC_CACHE_WRITE 2059
/*! cache: pages written requiring in-memory restoration */
#define WT_STAT_DSRC_CACHE_WRITE_RESTORE 2060
+/*! cache: tracked dirty bytes in the cache */
+#define WT_STAT_DSRC_CACHE_BYTES_DIRTY 2061
/*! cache: unmodified pages evicted */
-#define WT_STAT_DSRC_CACHE_EVICTION_CLEAN 2061
+#define WT_STAT_DSRC_CACHE_EVICTION_CLEAN 2062
/*!
* cache_walk: Average difference between current eviction generation
* when the page was last considered, only reported if cache_walk or all
* statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_GEN_AVG_GAP 2062
+#define WT_STAT_DSRC_CACHE_STATE_GEN_AVG_GAP 2063
/*!
* cache_walk: Average on-disk page image size seen, only reported if
* cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_AVG_WRITTEN_SIZE 2063
+#define WT_STAT_DSRC_CACHE_STATE_AVG_WRITTEN_SIZE 2064
/*!
* cache_walk: Clean pages currently in cache, only reported if
* cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_PAGES_CLEAN 2064
+#define WT_STAT_DSRC_CACHE_STATE_PAGES_CLEAN 2065
/*!
* cache_walk: Current eviction generation, only reported if cache_walk
* or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_GEN_CURRENT 2065
+#define WT_STAT_DSRC_CACHE_STATE_GEN_CURRENT 2066
/*!
* cache_walk: Dirty pages currently in cache, only reported if
* cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_PAGES_DIRTY 2066
+#define WT_STAT_DSRC_CACHE_STATE_PAGES_DIRTY 2067
/*!
* cache_walk: Entries in the root page, only reported if cache_walk or
* all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_ROOT_ENTRIES 2067
+#define WT_STAT_DSRC_CACHE_STATE_ROOT_ENTRIES 2068
/*!
* cache_walk: Internal pages currently in cache, only reported if
* cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_PAGES_INTERNAL 2068
+#define WT_STAT_DSRC_CACHE_STATE_PAGES_INTERNAL 2069
/*!
* cache_walk: Leaf pages currently in cache, only reported if cache_walk
* or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_PAGES_LEAF 2069
+#define WT_STAT_DSRC_CACHE_STATE_PAGES_LEAF 2070
/*!
* cache_walk: Maximum difference between current eviction generation
* when the page was last considered, only reported if cache_walk or all
* statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_GEN_MAX_GAP 2070
+#define WT_STAT_DSRC_CACHE_STATE_GEN_MAX_GAP 2071
/*!
* cache_walk: Maximum page size seen, only reported if cache_walk or all
* statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_MAX_PAGESIZE 2071
+#define WT_STAT_DSRC_CACHE_STATE_MAX_PAGESIZE 2072
/*!
* cache_walk: Minimum on-disk page image size seen, only reported if
* cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_MIN_WRITTEN_SIZE 2072
+#define WT_STAT_DSRC_CACHE_STATE_MIN_WRITTEN_SIZE 2073
/*!
* cache_walk: On-disk page image sizes smaller than a single allocation
* unit, only reported if cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_SMALLER_ALLOC_SIZE 2073
+#define WT_STAT_DSRC_CACHE_STATE_SMALLER_ALLOC_SIZE 2074
/*!
* cache_walk: Pages created in memory and never written, only reported
* if cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_MEMORY 2074
+#define WT_STAT_DSRC_CACHE_STATE_MEMORY 2075
/*!
* cache_walk: Pages currently queued for eviction, only reported if
* cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_QUEUED 2075
+#define WT_STAT_DSRC_CACHE_STATE_QUEUED 2076
/*!
* cache_walk: Pages that could not be queued for eviction, only reported
* if cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_NOT_QUEUEABLE 2076
+#define WT_STAT_DSRC_CACHE_STATE_NOT_QUEUEABLE 2077
/*!
* cache_walk: Refs skipped during cache traversal, only reported if
* cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_REFS_SKIPPED 2077
+#define WT_STAT_DSRC_CACHE_STATE_REFS_SKIPPED 2078
/*!
* cache_walk: Size of the root page, only reported if cache_walk or all
* statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_ROOT_SIZE 2078
+#define WT_STAT_DSRC_CACHE_STATE_ROOT_SIZE 2079
/*!
* cache_walk: Total number of pages currently in cache, only reported if
* cache_walk or all statistics are enabled
*/
-#define WT_STAT_DSRC_CACHE_STATE_PAGES 2079
+#define WT_STAT_DSRC_CACHE_STATE_PAGES 2080
/*! compression: compressed pages read */
-#define WT_STAT_DSRC_COMPRESS_READ 2080
+#define WT_STAT_DSRC_COMPRESS_READ 2081
/*! compression: compressed pages written */
-#define WT_STAT_DSRC_COMPRESS_WRITE 2081
+#define WT_STAT_DSRC_COMPRESS_WRITE 2082
/*! compression: page written failed to compress */
-#define WT_STAT_DSRC_COMPRESS_WRITE_FAIL 2082
+#define WT_STAT_DSRC_COMPRESS_WRITE_FAIL 2083
/*! compression: page written was too small to compress */
-#define WT_STAT_DSRC_COMPRESS_WRITE_TOO_SMALL 2083
+#define WT_STAT_DSRC_COMPRESS_WRITE_TOO_SMALL 2084
/*! compression: raw compression call failed, additional data available */
-#define WT_STAT_DSRC_COMPRESS_RAW_FAIL_TEMPORARY 2084
+#define WT_STAT_DSRC_COMPRESS_RAW_FAIL_TEMPORARY 2085
/*! compression: raw compression call failed, no additional data available */
-#define WT_STAT_DSRC_COMPRESS_RAW_FAIL 2085
+#define WT_STAT_DSRC_COMPRESS_RAW_FAIL 2086
/*! compression: raw compression call succeeded */
-#define WT_STAT_DSRC_COMPRESS_RAW_OK 2086
+#define WT_STAT_DSRC_COMPRESS_RAW_OK 2087
/*! cursor: bulk-loaded cursor-insert calls */
-#define WT_STAT_DSRC_CURSOR_INSERT_BULK 2087
+#define WT_STAT_DSRC_CURSOR_INSERT_BULK 2088
/*! cursor: create calls */
-#define WT_STAT_DSRC_CURSOR_CREATE 2088
+#define WT_STAT_DSRC_CURSOR_CREATE 2089
/*! cursor: cursor-insert key and value bytes inserted */
-#define WT_STAT_DSRC_CURSOR_INSERT_BYTES 2089
+#define WT_STAT_DSRC_CURSOR_INSERT_BYTES 2090
/*! cursor: cursor-remove key bytes removed */
-#define WT_STAT_DSRC_CURSOR_REMOVE_BYTES 2090
+#define WT_STAT_DSRC_CURSOR_REMOVE_BYTES 2091
/*! cursor: cursor-update value bytes updated */
-#define WT_STAT_DSRC_CURSOR_UPDATE_BYTES 2091
+#define WT_STAT_DSRC_CURSOR_UPDATE_BYTES 2092
/*! cursor: insert calls */
-#define WT_STAT_DSRC_CURSOR_INSERT 2092
+#define WT_STAT_DSRC_CURSOR_INSERT 2093
/*! cursor: next calls */
-#define WT_STAT_DSRC_CURSOR_NEXT 2093
+#define WT_STAT_DSRC_CURSOR_NEXT 2094
/*! cursor: prev calls */
-#define WT_STAT_DSRC_CURSOR_PREV 2094
+#define WT_STAT_DSRC_CURSOR_PREV 2095
/*! cursor: remove calls */
-#define WT_STAT_DSRC_CURSOR_REMOVE 2095
+#define WT_STAT_DSRC_CURSOR_REMOVE 2096
/*! cursor: reset calls */
-#define WT_STAT_DSRC_CURSOR_RESET 2096
+#define WT_STAT_DSRC_CURSOR_RESET 2097
/*! cursor: restarted searches */
-#define WT_STAT_DSRC_CURSOR_RESTART 2097
+#define WT_STAT_DSRC_CURSOR_RESTART 2098
/*! cursor: search calls */
-#define WT_STAT_DSRC_CURSOR_SEARCH 2098
+#define WT_STAT_DSRC_CURSOR_SEARCH 2099
/*! cursor: search near calls */
-#define WT_STAT_DSRC_CURSOR_SEARCH_NEAR 2099
+#define WT_STAT_DSRC_CURSOR_SEARCH_NEAR 2100
/*! cursor: truncate calls */
-#define WT_STAT_DSRC_CURSOR_TRUNCATE 2100
+#define WT_STAT_DSRC_CURSOR_TRUNCATE 2101
/*! cursor: update calls */
-#define WT_STAT_DSRC_CURSOR_UPDATE 2101
+#define WT_STAT_DSRC_CURSOR_UPDATE 2102
/*! reconciliation: dictionary matches */
-#define WT_STAT_DSRC_REC_DICTIONARY 2102
+#define WT_STAT_DSRC_REC_DICTIONARY 2103
/*! reconciliation: fast-path pages deleted */
-#define WT_STAT_DSRC_REC_PAGE_DELETE_FAST 2103
+#define WT_STAT_DSRC_REC_PAGE_DELETE_FAST 2104
/*!
* reconciliation: internal page key bytes discarded using suffix
* compression
*/
-#define WT_STAT_DSRC_REC_SUFFIX_COMPRESSION 2104
+#define WT_STAT_DSRC_REC_SUFFIX_COMPRESSION 2105
/*! reconciliation: internal page multi-block writes */
-#define WT_STAT_DSRC_REC_MULTIBLOCK_INTERNAL 2105
+#define WT_STAT_DSRC_REC_MULTIBLOCK_INTERNAL 2106
/*! reconciliation: internal-page overflow keys */
-#define WT_STAT_DSRC_REC_OVERFLOW_KEY_INTERNAL 2106
+#define WT_STAT_DSRC_REC_OVERFLOW_KEY_INTERNAL 2107
/*! reconciliation: leaf page key bytes discarded using prefix compression */
-#define WT_STAT_DSRC_REC_PREFIX_COMPRESSION 2107
+#define WT_STAT_DSRC_REC_PREFIX_COMPRESSION 2108
/*! reconciliation: leaf page multi-block writes */
-#define WT_STAT_DSRC_REC_MULTIBLOCK_LEAF 2108
+#define WT_STAT_DSRC_REC_MULTIBLOCK_LEAF 2109
/*! reconciliation: leaf-page overflow keys */
-#define WT_STAT_DSRC_REC_OVERFLOW_KEY_LEAF 2109
+#define WT_STAT_DSRC_REC_OVERFLOW_KEY_LEAF 2110
/*! reconciliation: maximum blocks required for a page */
-#define WT_STAT_DSRC_REC_MULTIBLOCK_MAX 2110
+#define WT_STAT_DSRC_REC_MULTIBLOCK_MAX 2111
/*! reconciliation: overflow values written */
-#define WT_STAT_DSRC_REC_OVERFLOW_VALUE 2111
+#define WT_STAT_DSRC_REC_OVERFLOW_VALUE 2112
/*! reconciliation: page checksum matches */
-#define WT_STAT_DSRC_REC_PAGE_MATCH 2112
+#define WT_STAT_DSRC_REC_PAGE_MATCH 2113
/*! reconciliation: page reconciliation calls */
-#define WT_STAT_DSRC_REC_PAGES 2113
+#define WT_STAT_DSRC_REC_PAGES 2114
/*! reconciliation: page reconciliation calls for eviction */
-#define WT_STAT_DSRC_REC_PAGES_EVICTION 2114
+#define WT_STAT_DSRC_REC_PAGES_EVICTION 2115
/*! reconciliation: pages deleted */
-#define WT_STAT_DSRC_REC_PAGE_DELETE 2115
+#define WT_STAT_DSRC_REC_PAGE_DELETE 2116
/*! session: object compaction */
-#define WT_STAT_DSRC_SESSION_COMPACT 2116
+#define WT_STAT_DSRC_SESSION_COMPACT 2117
/*! session: open cursor count */
-#define WT_STAT_DSRC_SESSION_CURSOR_OPEN 2117
+#define WT_STAT_DSRC_SESSION_CURSOR_OPEN 2118
/*! transaction: update conflicts */
-#define WT_STAT_DSRC_TXN_UPDATE_CONFLICT 2118
+#define WT_STAT_DSRC_TXN_UPDATE_CONFLICT 2119
/*!
* @}
diff --git a/src/include/wt_internal.h b/src/include/wt_internal.h
index e18563dd2d2..da318ad8a86 100644
--- a/src/include/wt_internal.h
+++ b/src/include/wt_internal.h
@@ -106,6 +106,8 @@ struct __wt_col;
typedef struct __wt_col WT_COL;
struct __wt_col_rle;
typedef struct __wt_col_rle WT_COL_RLE;
+struct __wt_col_var_repeat;
+ typedef struct __wt_col_var_repeat WT_COL_VAR_REPEAT;
struct __wt_colgroup;
typedef struct __wt_colgroup WT_COLGROUP;
struct __wt_compact_state;
@@ -266,8 +268,6 @@ struct __wt_ref;
typedef struct __wt_ref WT_REF;
struct __wt_row;
typedef struct __wt_row WT_ROW;
-struct __wt_rwlock;
- typedef struct __wt_rwlock WT_RWLOCK;
struct __wt_salvage_cookie;
typedef struct __wt_salvage_cookie WT_SALVAGE_COOKIE;
struct __wt_save_upd;
@@ -302,6 +302,8 @@ union __wt_lsn;
typedef union __wt_lsn WT_LSN;
union __wt_rand_state;
typedef union __wt_rand_state WT_RAND_STATE;
+union __wt_rwlock;
+ typedef union __wt_rwlock WT_RWLOCK;
/*
* Forward type declarations for internal types: END
* DO NOT EDIT: automatically built by dist/s_typedef.