summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger')
-rw-r--r--src/third_party/wiredtiger/dist/s_string.ok7
-rwxr-xr-xsrc/third_party/wiredtiger/dist/s_style6
-rw-r--r--src/third_party/wiredtiger/dist/stat_data.py2
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_read.c14
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_slvg.c15
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_split.c18
-rw-r--r--src/third_party/wiredtiger/src/cache/cache_las.c11
-rw-r--r--src/third_party/wiredtiger/src/config/config_collapse.c2
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_lru.c2
-rw-r--r--src/third_party/wiredtiger/src/include/misc.h9
-rw-r--r--src/third_party/wiredtiger/src/include/stat.h2
-rw-r--r--src/third_party/wiredtiger/src/include/wiredtiger.in642
-rw-r--r--src/third_party/wiredtiger/src/meta/meta_ckpt.c2
-rw-r--r--src/third_party/wiredtiger/src/support/huffman.c4
-rw-r--r--src/third_party/wiredtiger/src/support/stat.c8
-rw-r--r--src/third_party/wiredtiger/test/csuite/Makefile.am4
-rw-r--r--src/third_party/wiredtiger/test/csuite/random_directio/main.c1291
-rwxr-xr-xsrc/third_party/wiredtiger/test/csuite/random_directio/smoke.sh34
-rw-r--r--src/third_party/wiredtiger/test/utility/misc.c36
-rw-r--r--src/third_party/wiredtiger/test/utility/test_util.h3
21 files changed, 1771 insertions, 343 deletions
diff --git a/src/third_party/wiredtiger/dist/s_string.ok b/src/third_party/wiredtiger/dist/s_string.ok
index 81e1d9d3da9..ed5f27cdf11 100644
--- a/src/third_party/wiredtiger/dist/s_string.ok
+++ b/src/third_party/wiredtiger/dist/s_string.ok
@@ -24,6 +24,7 @@ Async
AsyncOp
Athanassoulis
Athlon
+Axxx
BBBBB
BBBBBB
BBBBBBBBBB
@@ -46,6 +47,7 @@ Brueckner
Bsearch
Btree
Buf
+Bxxx
Bzip
CAS
CCCCCCCCCCCCCCCCCC
@@ -500,6 +502,7 @@ bool
boolean
br
breakpoint
+bs
bswap
bt
btcur
@@ -658,6 +661,7 @@ dhandle
dhandles
difftime
dir
+directio
dirlist
disjunction
disjunctions
@@ -814,6 +818,7 @@ idlems
idx
ifdef
ifdef's
+iflag
iiSii
iiiS
iiii
@@ -1044,6 +1049,7 @@ other's
ovfl
ownp
pR
+pS
packv
pagesize
parens
@@ -1151,6 +1157,7 @@ rwlock
sH
sHQ
sT
+sanitizers
scalability
sched
scr
diff --git a/src/third_party/wiredtiger/dist/s_style b/src/third_party/wiredtiger/dist/s_style
index 3f4346173e6..9c1dd6fa506 100755
--- a/src/third_party/wiredtiger/dist/s_style
+++ b/src/third_party/wiredtiger/dist/s_style
@@ -101,6 +101,12 @@ else
cat $t
}
+ if ! expr "$f" : 'src/include/misc.h' > /dev/null &&
+ grep '[[:space:]]qsort(' $f > $t; then
+ echo "$f: qsort call, use WiredTiger __wt_qsort instead"
+ cat $t
+ fi
+
if ! expr "$f" : 'src/.*/os_setvbuf.c' > /dev/null &&
egrep -w 'setvbuf' $f > $t; then
echo "$f: setvbuf call, use WiredTiger library replacements"
diff --git a/src/third_party/wiredtiger/dist/stat_data.py b/src/third_party/wiredtiger/dist/stat_data.py
index 95d05e17e6d..c452efa9cc6 100644
--- a/src/third_party/wiredtiger/dist/stat_data.py
+++ b/src/third_party/wiredtiger/dist/stat_data.py
@@ -260,6 +260,8 @@ connection_stats = [
CacheStat('cache_hazard_walks', 'hazard pointer check entries walked'),
CacheStat('cache_inmem_split', 'in-memory page splits'),
CacheStat('cache_inmem_splittable', 'in-memory page passed criteria to be split'),
+ CacheStat('cache_lookaside_cursor_wait_application', 'cache overflow cursor application thread wait time (usecs)'),
+ CacheStat('cache_lookaside_cursor_wait_internal', 'cache overflow cursor internal thread wait time (usecs)'),
CacheStat('cache_lookaside_entries', 'cache overflow table entries', 'no_clear,no_scale'),
CacheStat('cache_lookaside_insert', 'cache overflow table insert calls'),
CacheStat('cache_lookaside_remove', 'cache overflow table remove calls'),
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index a5f5da1a0d5..52cea135a2b 100644
--- a/src/third_party/wiredtiger/import.data
+++ b/src/third_party/wiredtiger/import.data
@@ -1,5 +1,5 @@
{
- "commit": "45fd19bcb1007fd4e473d77ddd09d3157ff15c7e",
+ "commit": "7db12ec1b5b1843364ae28248b0680b816aab651",
"github": "wiredtiger/wiredtiger.git",
"vendor": "wiredtiger",
"branch": "mongodb-4.2"
diff --git a/src/third_party/wiredtiger/src/btree/bt_read.c b/src/third_party/wiredtiger/src/btree/bt_read.c
index ec356e72895..0d0cf17762c 100644
--- a/src/third_party/wiredtiger/src/btree/bt_read.c
+++ b/src/third_party/wiredtiger/src/btree/bt_read.c
@@ -541,13 +541,19 @@ skip_read:
}
/*
- * We no longer need lookaside entries once the page is instantiated.
- * There's no reason for the lookaside remove to fail, but ignore it
- * if for some reason it fails, we've got a valid page.
+ * Once the page is instantiated, we no longer need the history in
+ * lookaside. We leave the lookaside sweep thread to do most cleanup,
+ * but it can only remove keys that skew newest (if there are entries
+ * in the lookaside newer than the page, they need to be read back into
+ * cache or they will be lost).
+ *
+ * There is no reason for the lookaside remove should fail, but ignore
+ * it if for some reason it fails, we've got a valid page.
*
* Don't free WT_REF.page_las, there may be concurrent readers.
*/
- if (final_state == WT_REF_MEM && ref->page_las != NULL)
+ if (final_state == WT_REF_MEM &&
+ ref->page_las != NULL && !ref->page_las->skew_newest)
WT_IGNORE_RET(__wt_las_remove_block(
session, ref->page_las->las_pageid, false));
diff --git a/src/third_party/wiredtiger/src/btree/bt_slvg.c b/src/third_party/wiredtiger/src/btree/bt_slvg.c
index cc9c171ffda..475b026ddbf 100644
--- a/src/third_party/wiredtiger/src/btree/bt_slvg.c
+++ b/src/third_party/wiredtiger/src/btree/bt_slvg.c
@@ -259,7 +259,7 @@ __wt_bt_salvage(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, const char *cfg[])
* fixed-length format ranges to overlap during salvage, and I don't
* want to have to retrofit the code later.
*/
- qsort(ss->pages,
+ __wt_qsort(ss->pages,
(size_t)ss->pages_next, sizeof(WT_TRACK *), __slvg_trk_compare_key);
if (ss->page_type == WT_PAGE_ROW_LEAF)
WT_ERR(__slvg_row_range(session, ss));
@@ -1093,7 +1093,7 @@ __slvg_col_trk_update_start(uint32_t slot, WT_STUFF *ss)
}
i -= slot;
if (i > 1)
- qsort(ss->pages + slot, (size_t)i,
+ __wt_qsort(ss->pages + slot, (size_t)i,
sizeof(WT_TRACK *), __slvg_trk_compare_key);
}
@@ -1790,7 +1790,7 @@ __slvg_row_trk_update_start(
}
i -= slot;
if (i > 1)
- qsort(ss->pages + slot, (size_t)i,
+ __wt_qsort(ss->pages + slot, (size_t)i,
sizeof(WT_TRACK *), __slvg_trk_compare_key);
err: if (page != NULL)
@@ -2160,13 +2160,12 @@ __slvg_ovfl_reconcile(WT_SESSION_IMPL *session, WT_STUFF *ss)
* If an overflow page is referenced more than once, discard leaf pages
* with the lowest LSNs until overflow pages are only referenced once.
*
- * This requires sorting the page list by LSN, and the overflow array
-
- * by address cookie.
+ * This requires sorting the page list by LSN, and the overflow array by
+ * address cookie.
*/
- qsort(ss->pages,
+ __wt_qsort(ss->pages,
(size_t)ss->pages_next, sizeof(WT_TRACK *), __slvg_trk_compare_gen);
- qsort(ss->ovfl,
+ __wt_qsort(ss->ovfl,
(size_t)ss->ovfl_next, sizeof(WT_TRACK *), __slvg_trk_compare_addr);
/*
diff --git a/src/third_party/wiredtiger/src/btree/bt_split.c b/src/third_party/wiredtiger/src/btree/bt_split.c
index 96c898eac40..42d232fc7b4 100644
--- a/src/third_party/wiredtiger/src/btree/bt_split.c
+++ b/src/third_party/wiredtiger/src/btree/bt_split.c
@@ -625,6 +625,7 @@ static int
__split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new,
uint32_t new_entries, size_t parent_incr, bool exclusive, bool discard)
{
+ WT_BTREE *btree;
WT_DECL_ITEM(scr);
WT_DECL_RET;
WT_IKEY *ikey;
@@ -639,6 +640,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new,
uint32_t hint, i, j;
bool empty_parent;
+ btree = S2BT(session);
parent = ref->home;
alloc_index = pindex = NULL;
@@ -658,17 +660,23 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new,
parent_entries = pindex->entries;
/*
- * Remove any refs to deleted pages while we are splitting, we have
- * the internal page locked down, and are copying the refs into a new
- * array anyway. Switch them to the special split state, so that any
- * reading thread will restart.
+ * Remove any refs to deleted pages while we are splitting, we have the
+ * internal page locked down, and are copying the refs into a new array
+ * anyway. Switch them to the special split state, so that any reading
+ * thread will restart.
+ *
+ * We can't do this if there is a sync running in the tree in another
+ * session: removing the refs frees the blocks for the deleted pages,
+ * which can corrupt the free list calculated by the sync.
*/
WT_ERR(__wt_scr_alloc(session, 10 * sizeof(uint32_t), &scr));
for (deleted_entries = 0, i = 0; i < parent_entries; ++i) {
next_ref = pindex->index[i];
WT_ASSERT(session, next_ref->state != WT_REF_SPLIT);
if ((discard && next_ref == ref) ||
- (next_ref->state == WT_REF_DELETED &&
+ ((!WT_BTREE_SYNCING(btree) ||
+ WT_SESSION_BTREE_SYNC(session)) &&
+ next_ref->state == WT_REF_DELETED &&
__wt_delete_page_skip(session, next_ref, true) &&
__wt_atomic_casv32(
&next_ref->state, WT_REF_DELETED, WT_REF_SPLIT))) {
diff --git a/src/third_party/wiredtiger/src/cache/cache_las.c b/src/third_party/wiredtiger/src/cache/cache_las.c
index cf646c080f0..cf28027d8b7 100644
--- a/src/third_party/wiredtiger/src/cache/cache_las.c
+++ b/src/third_party/wiredtiger/src/cache/cache_las.c
@@ -310,7 +310,16 @@ __wt_las_cursor(
*
* XXX better as a condition variable.
*/
- __wt_sleep(0, 1000);
+ __wt_sleep(0, WT_THOUSAND);
+ if (F_ISSET(session, WT_SESSION_INTERNAL))
+ WT_STAT_CONN_INCRV(session,
+ cache_lookaside_cursor_wait_internal,
+ WT_THOUSAND);
+ else
+ WT_STAT_CONN_INCRV(session,
+ cache_lookaside_cursor_wait_application,
+ WT_THOUSAND);
+
}
}
diff --git a/src/third_party/wiredtiger/src/config/config_collapse.c b/src/third_party/wiredtiger/src/config/config_collapse.c
index 26636873902..60a319af15e 100644
--- a/src/third_party/wiredtiger/src/config/config_collapse.c
+++ b/src/third_party/wiredtiger/src/config/config_collapse.c
@@ -399,7 +399,7 @@ __wt_config_merge(WT_SESSION_IMPL *session,
* Sort the array by key and, in the case of identical keys, by
* generation.
*/
- qsort(merge.entries, merge.entries_next,
+ __wt_qsort(merge.entries, merge.entries_next,
sizeof(WT_CONFIG_MERGE_ENTRY), __config_merge_cmp);
/* Convert the array of entries into a string. */
diff --git a/src/third_party/wiredtiger/src/evict/evict_lru.c b/src/third_party/wiredtiger/src/evict/evict_lru.c
index 86564bd2947..ff3772533ae 100644
--- a/src/third_party/wiredtiger/src/evict/evict_lru.c
+++ b/src/third_party/wiredtiger/src/evict/evict_lru.c
@@ -1257,7 +1257,7 @@ __evict_lru_walk(WT_SESSION_IMPL *session)
queue->evict_current = NULL;
entries = queue->evict_entries;
- qsort(queue->evict_queue,
+ __wt_qsort(queue->evict_queue,
entries, sizeof(WT_EVICT_ENTRY), __evict_lru_cmp);
/* Trim empty entries from the end. */
diff --git a/src/third_party/wiredtiger/src/include/misc.h b/src/third_party/wiredtiger/src/include/misc.h
index 54d62cfe5f7..8c6af3ca14c 100644
--- a/src/third_party/wiredtiger/src/include/misc.h
+++ b/src/third_party/wiredtiger/src/include/misc.h
@@ -187,6 +187,15 @@
} while (0)
/*
+ * Some C compiler address sanitizers complain if qsort is passed a NULL base
+ * reference, even if there are no elements to compare (note zero elements is
+ * allowed by the IEEE Std 1003.1-2017 standard). Avoid the complaint.
+ */
+#define __wt_qsort(base, nmemb, size, compar) \
+ if ((nmemb) != 0) \
+ qsort(base, nmemb, size, compar)
+
+/*
* Binary search for an integer key.
*/
#define WT_BINARY_SEARCH(key, arrayp, n, found) do { \
diff --git a/src/third_party/wiredtiger/src/include/stat.h b/src/third_party/wiredtiger/src/include/stat.h
index 6646dd0a8bf..1ae4e56be03 100644
--- a/src/third_party/wiredtiger/src/include/stat.h
+++ b/src/third_party/wiredtiger/src/include/stat.h
@@ -354,6 +354,8 @@ struct __wt_connection_stats {
int64_t cache_bytes_other;
int64_t cache_bytes_read;
int64_t cache_bytes_write;
+ int64_t cache_lookaside_cursor_wait_application;
+ int64_t cache_lookaside_cursor_wait_internal;
int64_t cache_lookaside_score;
int64_t cache_lookaside_entries;
int64_t cache_lookaside_insert;
diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in
index e390016a38b..333c74b5e80 100644
--- a/src/third_party/wiredtiger/src/include/wiredtiger.in
+++ b/src/third_party/wiredtiger/src/include/wiredtiger.in
@@ -5064,707 +5064,711 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_CONN_CACHE_BYTES_READ 1039
/*! cache: bytes written from cache */
#define WT_STAT_CONN_CACHE_BYTES_WRITE 1040
+/*! cache: cache overflow cursor application thread wait time (usecs) */
+#define WT_STAT_CONN_CACHE_LOOKASIDE_CURSOR_WAIT_APPLICATION 1041
+/*! cache: cache overflow cursor internal thread wait time (usecs) */
+#define WT_STAT_CONN_CACHE_LOOKASIDE_CURSOR_WAIT_INTERNAL 1042
/*! cache: cache overflow score */
-#define WT_STAT_CONN_CACHE_LOOKASIDE_SCORE 1041
+#define WT_STAT_CONN_CACHE_LOOKASIDE_SCORE 1043
/*! cache: cache overflow table entries */
-#define WT_STAT_CONN_CACHE_LOOKASIDE_ENTRIES 1042
+#define WT_STAT_CONN_CACHE_LOOKASIDE_ENTRIES 1044
/*! cache: cache overflow table insert calls */
-#define WT_STAT_CONN_CACHE_LOOKASIDE_INSERT 1043
+#define WT_STAT_CONN_CACHE_LOOKASIDE_INSERT 1045
/*! cache: cache overflow table remove calls */
-#define WT_STAT_CONN_CACHE_LOOKASIDE_REMOVE 1044
+#define WT_STAT_CONN_CACHE_LOOKASIDE_REMOVE 1046
/*! cache: checkpoint blocked page eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_CHECKPOINT 1045
+#define WT_STAT_CONN_CACHE_EVICTION_CHECKPOINT 1047
/*! cache: eviction calls to get a page */
-#define WT_STAT_CONN_CACHE_EVICTION_GET_REF 1046
+#define WT_STAT_CONN_CACHE_EVICTION_GET_REF 1048
/*! cache: eviction calls to get a page found queue empty */
-#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY 1047
+#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY 1049
/*! cache: eviction calls to get a page found queue empty after locking */
-#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY2 1048
+#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY2 1050
/*! cache: eviction currently operating in aggressive mode */
-#define WT_STAT_CONN_CACHE_EVICTION_AGGRESSIVE_SET 1049
+#define WT_STAT_CONN_CACHE_EVICTION_AGGRESSIVE_SET 1051
/*! cache: eviction empty score */
-#define WT_STAT_CONN_CACHE_EVICTION_EMPTY_SCORE 1050
+#define WT_STAT_CONN_CACHE_EVICTION_EMPTY_SCORE 1052
/*! cache: eviction passes of a file */
-#define WT_STAT_CONN_CACHE_EVICTION_WALK_PASSES 1051
+#define WT_STAT_CONN_CACHE_EVICTION_WALK_PASSES 1053
/*! cache: eviction server candidate queue empty when topping up */
-#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_EMPTY 1052
+#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_EMPTY 1054
/*! cache: eviction server candidate queue not empty when topping up */
-#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_NOT_EMPTY 1053
+#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_NOT_EMPTY 1055
/*! cache: eviction server evicting pages */
-#define WT_STAT_CONN_CACHE_EVICTION_SERVER_EVICTING 1054
+#define WT_STAT_CONN_CACHE_EVICTION_SERVER_EVICTING 1056
/*!
* cache: eviction server slept, because we did not make progress with
* eviction
*/
-#define WT_STAT_CONN_CACHE_EVICTION_SERVER_SLEPT 1055
+#define WT_STAT_CONN_CACHE_EVICTION_SERVER_SLEPT 1057
/*! cache: eviction server unable to reach eviction goal */
-#define WT_STAT_CONN_CACHE_EVICTION_SLOW 1056
+#define WT_STAT_CONN_CACHE_EVICTION_SLOW 1058
/*! cache: eviction state */
-#define WT_STAT_CONN_CACHE_EVICTION_STATE 1057
+#define WT_STAT_CONN_CACHE_EVICTION_STATE 1059
/*! cache: eviction walk target pages histogram - 0-9 */
-#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT10 1058
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT10 1060
/*! cache: eviction walk target pages histogram - 10-31 */
-#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT32 1059
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT32 1061
/*! cache: eviction walk target pages histogram - 128 and higher */
-#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_GE128 1060
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_GE128 1062
/*! cache: eviction walk target pages histogram - 32-63 */
-#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT64 1061
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT64 1063
/*! cache: eviction walk target pages histogram - 64-128 */
-#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT128 1062
+#define WT_STAT_CONN_CACHE_EVICTION_TARGET_PAGE_LT128 1064
/*! cache: eviction walks abandoned */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ABANDONED 1063
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ABANDONED 1065
/*! cache: eviction walks gave up because they restarted their walk twice */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STOPPED 1064
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STOPPED 1066
/*!
* cache: eviction walks gave up because they saw too many pages and
* found no candidates
*/
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_GAVE_UP_NO_TARGETS 1065
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_GAVE_UP_NO_TARGETS 1067
/*!
* cache: eviction walks gave up because they saw too many pages and
* found too few candidates
*/
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_GAVE_UP_RATIO 1066
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_GAVE_UP_RATIO 1068
/*! cache: eviction walks reached end of tree */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ENDED 1067
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ENDED 1069
/*! cache: eviction walks started from root of tree */
-#define WT_STAT_CONN_CACHE_EVICTION_WALK_FROM_ROOT 1068
+#define WT_STAT_CONN_CACHE_EVICTION_WALK_FROM_ROOT 1070
/*! cache: eviction walks started from saved location in tree */
-#define WT_STAT_CONN_CACHE_EVICTION_WALK_SAVED_POS 1069
+#define WT_STAT_CONN_CACHE_EVICTION_WALK_SAVED_POS 1071
/*! cache: eviction worker thread active */
-#define WT_STAT_CONN_CACHE_EVICTION_ACTIVE_WORKERS 1070
+#define WT_STAT_CONN_CACHE_EVICTION_ACTIVE_WORKERS 1072
/*! cache: eviction worker thread created */
-#define WT_STAT_CONN_CACHE_EVICTION_WORKER_CREATED 1071
+#define WT_STAT_CONN_CACHE_EVICTION_WORKER_CREATED 1073
/*! cache: eviction worker thread evicting pages */
-#define WT_STAT_CONN_CACHE_EVICTION_WORKER_EVICTING 1072
+#define WT_STAT_CONN_CACHE_EVICTION_WORKER_EVICTING 1074
/*! cache: eviction worker thread removed */
-#define WT_STAT_CONN_CACHE_EVICTION_WORKER_REMOVED 1073
+#define WT_STAT_CONN_CACHE_EVICTION_WORKER_REMOVED 1075
/*! cache: eviction worker thread stable number */
-#define WT_STAT_CONN_CACHE_EVICTION_STABLE_STATE_WORKERS 1074
+#define WT_STAT_CONN_CACHE_EVICTION_STABLE_STATE_WORKERS 1076
/*!
* cache: failed eviction of pages that exceeded the in-memory maximum
* count
*/
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE_FAIL 1075
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_FAIL 1077
/*!
* cache: failed eviction of pages that exceeded the in-memory maximum
* time (usecs)
*/
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE_FAIL_TIME 1076
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_FAIL_TIME 1078
/*! cache: files with active eviction walks */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ACTIVE 1077
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ACTIVE 1079
/*! cache: files with new eviction walks started */
-#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STARTED 1078
+#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STARTED 1080
/*! cache: force re-tuning of eviction workers once in a while */
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE_RETUNE 1079
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_RETUNE 1081
/*! cache: hazard pointer blocked page eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_HAZARD 1080
+#define WT_STAT_CONN_CACHE_EVICTION_HAZARD 1082
/*! cache: hazard pointer check calls */
-#define WT_STAT_CONN_CACHE_HAZARD_CHECKS 1081
+#define WT_STAT_CONN_CACHE_HAZARD_CHECKS 1083
/*! cache: hazard pointer check entries walked */
-#define WT_STAT_CONN_CACHE_HAZARD_WALKS 1082
+#define WT_STAT_CONN_CACHE_HAZARD_WALKS 1084
/*! cache: hazard pointer maximum array length */
-#define WT_STAT_CONN_CACHE_HAZARD_MAX 1083
+#define WT_STAT_CONN_CACHE_HAZARD_MAX 1085
/*! cache: in-memory page passed criteria to be split */
-#define WT_STAT_CONN_CACHE_INMEM_SPLITTABLE 1084
+#define WT_STAT_CONN_CACHE_INMEM_SPLITTABLE 1086
/*! cache: in-memory page splits */
-#define WT_STAT_CONN_CACHE_INMEM_SPLIT 1085
+#define WT_STAT_CONN_CACHE_INMEM_SPLIT 1087
/*! cache: internal pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_INTERNAL 1086
+#define WT_STAT_CONN_CACHE_EVICTION_INTERNAL 1088
/*! cache: internal pages split during eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_INTERNAL 1087
+#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_INTERNAL 1089
/*! cache: leaf pages split during eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_LEAF 1088
+#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_LEAF 1090
/*! cache: maximum bytes configured */
-#define WT_STAT_CONN_CACHE_BYTES_MAX 1089
+#define WT_STAT_CONN_CACHE_BYTES_MAX 1091
/*! cache: maximum page size at eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_MAXIMUM_PAGE_SIZE 1090
+#define WT_STAT_CONN_CACHE_EVICTION_MAXIMUM_PAGE_SIZE 1092
/*! cache: modified pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_DIRTY 1091
+#define WT_STAT_CONN_CACHE_EVICTION_DIRTY 1093
/*! cache: modified pages evicted by application threads */
-#define WT_STAT_CONN_CACHE_EVICTION_APP_DIRTY 1092
+#define WT_STAT_CONN_CACHE_EVICTION_APP_DIRTY 1094
/*! cache: operations timed out waiting for space in cache */
-#define WT_STAT_CONN_CACHE_TIMED_OUT_OPS 1093
+#define WT_STAT_CONN_CACHE_TIMED_OUT_OPS 1095
/*! cache: overflow pages read into cache */
-#define WT_STAT_CONN_CACHE_READ_OVERFLOW 1094
+#define WT_STAT_CONN_CACHE_READ_OVERFLOW 1096
/*! cache: page split during eviction deepened the tree */
-#define WT_STAT_CONN_CACHE_EVICTION_DEEPEN 1095
+#define WT_STAT_CONN_CACHE_EVICTION_DEEPEN 1097
/*! cache: page written requiring cache overflow records */
-#define WT_STAT_CONN_CACHE_WRITE_LOOKASIDE 1096
+#define WT_STAT_CONN_CACHE_WRITE_LOOKASIDE 1098
/*! cache: pages currently held in the cache */
-#define WT_STAT_CONN_CACHE_PAGES_INUSE 1097
+#define WT_STAT_CONN_CACHE_PAGES_INUSE 1099
/*! cache: pages evicted because they exceeded the in-memory maximum count */
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE 1098
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE 1100
/*!
* cache: pages evicted because they exceeded the in-memory maximum time
* (usecs)
*/
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE_TIME 1099
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_TIME 1101
/*! cache: pages evicted because they had chains of deleted items count */
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE_DELETE 1100
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_DELETE 1102
/*!
* cache: pages evicted because they had chains of deleted items time
* (usecs)
*/
-#define WT_STAT_CONN_CACHE_EVICTION_FORCE_DELETE_TIME 1101
+#define WT_STAT_CONN_CACHE_EVICTION_FORCE_DELETE_TIME 1103
/*! cache: pages evicted by application threads */
-#define WT_STAT_CONN_CACHE_EVICTION_APP 1102
+#define WT_STAT_CONN_CACHE_EVICTION_APP 1104
/*! cache: pages queued for eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED 1103
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED 1105
/*! cache: pages queued for urgent eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_URGENT 1104
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_URGENT 1106
/*! cache: pages queued for urgent eviction during walk */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_OLDEST 1105
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_OLDEST 1107
/*! cache: pages read into cache */
-#define WT_STAT_CONN_CACHE_READ 1106
+#define WT_STAT_CONN_CACHE_READ 1108
/*! cache: pages read into cache after truncate */
-#define WT_STAT_CONN_CACHE_READ_DELETED 1107
+#define WT_STAT_CONN_CACHE_READ_DELETED 1109
/*! cache: pages read into cache after truncate in prepare state */
-#define WT_STAT_CONN_CACHE_READ_DELETED_PREPARED 1108
+#define WT_STAT_CONN_CACHE_READ_DELETED_PREPARED 1110
/*! cache: pages read into cache requiring cache overflow entries */
-#define WT_STAT_CONN_CACHE_READ_LOOKASIDE 1109
+#define WT_STAT_CONN_CACHE_READ_LOOKASIDE 1111
/*! cache: pages read into cache requiring cache overflow for checkpoint */
-#define WT_STAT_CONN_CACHE_READ_LOOKASIDE_CHECKPOINT 1110
+#define WT_STAT_CONN_CACHE_READ_LOOKASIDE_CHECKPOINT 1112
/*! cache: pages read into cache skipping older cache overflow entries */
-#define WT_STAT_CONN_CACHE_READ_LOOKASIDE_SKIPPED 1111
+#define WT_STAT_CONN_CACHE_READ_LOOKASIDE_SKIPPED 1113
/*!
* cache: pages read into cache with skipped cache overflow entries
* needed later
*/
-#define WT_STAT_CONN_CACHE_READ_LOOKASIDE_DELAY 1112
+#define WT_STAT_CONN_CACHE_READ_LOOKASIDE_DELAY 1114
/*!
* cache: pages read into cache with skipped cache overflow entries
* needed later by checkpoint
*/
-#define WT_STAT_CONN_CACHE_READ_LOOKASIDE_DELAY_CHECKPOINT 1113
+#define WT_STAT_CONN_CACHE_READ_LOOKASIDE_DELAY_CHECKPOINT 1115
/*! cache: pages requested from the cache */
-#define WT_STAT_CONN_CACHE_PAGES_REQUESTED 1114
+#define WT_STAT_CONN_CACHE_PAGES_REQUESTED 1116
/*! cache: pages seen by eviction walk */
-#define WT_STAT_CONN_CACHE_EVICTION_PAGES_SEEN 1115
+#define WT_STAT_CONN_CACHE_EVICTION_PAGES_SEEN 1117
/*! cache: pages selected for eviction unable to be evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_FAIL 1116
+#define WT_STAT_CONN_CACHE_EVICTION_FAIL 1118
/*! cache: pages walked for eviction */
-#define WT_STAT_CONN_CACHE_EVICTION_WALK 1117
+#define WT_STAT_CONN_CACHE_EVICTION_WALK 1119
/*! cache: pages written from cache */
-#define WT_STAT_CONN_CACHE_WRITE 1118
+#define WT_STAT_CONN_CACHE_WRITE 1120
/*! cache: pages written requiring in-memory restoration */
-#define WT_STAT_CONN_CACHE_WRITE_RESTORE 1119
+#define WT_STAT_CONN_CACHE_WRITE_RESTORE 1121
/*! cache: percentage overhead */
-#define WT_STAT_CONN_CACHE_OVERHEAD 1120
+#define WT_STAT_CONN_CACHE_OVERHEAD 1122
/*! cache: tracked bytes belonging to internal pages in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_INTERNAL 1121
+#define WT_STAT_CONN_CACHE_BYTES_INTERNAL 1123
/*! cache: tracked bytes belonging to leaf pages in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_LEAF 1122
+#define WT_STAT_CONN_CACHE_BYTES_LEAF 1124
/*! cache: tracked dirty bytes in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_DIRTY 1123
+#define WT_STAT_CONN_CACHE_BYTES_DIRTY 1125
/*! cache: tracked dirty pages in the cache */
-#define WT_STAT_CONN_CACHE_PAGES_DIRTY 1124
+#define WT_STAT_CONN_CACHE_PAGES_DIRTY 1126
/*! cache: unmodified pages evicted */
-#define WT_STAT_CONN_CACHE_EVICTION_CLEAN 1125
+#define WT_STAT_CONN_CACHE_EVICTION_CLEAN 1127
/*! connection: auto adjusting condition resets */
-#define WT_STAT_CONN_COND_AUTO_WAIT_RESET 1126
+#define WT_STAT_CONN_COND_AUTO_WAIT_RESET 1128
/*! connection: auto adjusting condition wait calls */
-#define WT_STAT_CONN_COND_AUTO_WAIT 1127
+#define WT_STAT_CONN_COND_AUTO_WAIT 1129
/*! connection: detected system time went backwards */
-#define WT_STAT_CONN_TIME_TRAVEL 1128
+#define WT_STAT_CONN_TIME_TRAVEL 1130
/*! connection: files currently open */
-#define WT_STAT_CONN_FILE_OPEN 1129
+#define WT_STAT_CONN_FILE_OPEN 1131
/*! connection: memory allocations */
-#define WT_STAT_CONN_MEMORY_ALLOCATION 1130
+#define WT_STAT_CONN_MEMORY_ALLOCATION 1132
/*! connection: memory frees */
-#define WT_STAT_CONN_MEMORY_FREE 1131
+#define WT_STAT_CONN_MEMORY_FREE 1133
/*! connection: memory re-allocations */
-#define WT_STAT_CONN_MEMORY_GROW 1132
+#define WT_STAT_CONN_MEMORY_GROW 1134
/*! connection: pthread mutex condition wait calls */
-#define WT_STAT_CONN_COND_WAIT 1133
+#define WT_STAT_CONN_COND_WAIT 1135
/*! connection: pthread mutex shared lock read-lock calls */
-#define WT_STAT_CONN_RWLOCK_READ 1134
+#define WT_STAT_CONN_RWLOCK_READ 1136
/*! connection: pthread mutex shared lock write-lock calls */
-#define WT_STAT_CONN_RWLOCK_WRITE 1135
+#define WT_STAT_CONN_RWLOCK_WRITE 1137
/*! connection: total fsync I/Os */
-#define WT_STAT_CONN_FSYNC_IO 1136
+#define WT_STAT_CONN_FSYNC_IO 1138
/*! connection: total read I/Os */
-#define WT_STAT_CONN_READ_IO 1137
+#define WT_STAT_CONN_READ_IO 1139
/*! connection: total write I/Os */
-#define WT_STAT_CONN_WRITE_IO 1138
+#define WT_STAT_CONN_WRITE_IO 1140
/*! cursor: cursor create calls */
-#define WT_STAT_CONN_CURSOR_CREATE 1139
+#define WT_STAT_CONN_CURSOR_CREATE 1141
/*! cursor: cursor insert calls */
-#define WT_STAT_CONN_CURSOR_INSERT 1140
+#define WT_STAT_CONN_CURSOR_INSERT 1142
/*! cursor: cursor modify calls */
-#define WT_STAT_CONN_CURSOR_MODIFY 1141
+#define WT_STAT_CONN_CURSOR_MODIFY 1143
/*! cursor: cursor next calls */
-#define WT_STAT_CONN_CURSOR_NEXT 1142
+#define WT_STAT_CONN_CURSOR_NEXT 1144
/*! cursor: cursor operation restarted */
-#define WT_STAT_CONN_CURSOR_RESTART 1143
+#define WT_STAT_CONN_CURSOR_RESTART 1145
/*! cursor: cursor prev calls */
-#define WT_STAT_CONN_CURSOR_PREV 1144
+#define WT_STAT_CONN_CURSOR_PREV 1146
/*! cursor: cursor remove calls */
-#define WT_STAT_CONN_CURSOR_REMOVE 1145
+#define WT_STAT_CONN_CURSOR_REMOVE 1147
/*! cursor: cursor reserve calls */
-#define WT_STAT_CONN_CURSOR_RESERVE 1146
+#define WT_STAT_CONN_CURSOR_RESERVE 1148
/*! cursor: cursor reset calls */
-#define WT_STAT_CONN_CURSOR_RESET 1147
+#define WT_STAT_CONN_CURSOR_RESET 1149
/*! cursor: cursor search calls */
-#define WT_STAT_CONN_CURSOR_SEARCH 1148
+#define WT_STAT_CONN_CURSOR_SEARCH 1150
/*! cursor: cursor search near calls */
-#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1149
+#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1151
/*! cursor: cursor sweep buckets */
-#define WT_STAT_CONN_CURSOR_SWEEP_BUCKETS 1150
+#define WT_STAT_CONN_CURSOR_SWEEP_BUCKETS 1152
/*! cursor: cursor sweep cursors closed */
-#define WT_STAT_CONN_CURSOR_SWEEP_CLOSED 1151
+#define WT_STAT_CONN_CURSOR_SWEEP_CLOSED 1153
/*! cursor: cursor sweep cursors examined */
-#define WT_STAT_CONN_CURSOR_SWEEP_EXAMINED 1152
+#define WT_STAT_CONN_CURSOR_SWEEP_EXAMINED 1154
/*! cursor: cursor sweeps */
-#define WT_STAT_CONN_CURSOR_SWEEP 1153
+#define WT_STAT_CONN_CURSOR_SWEEP 1155
/*! cursor: cursor update calls */
-#define WT_STAT_CONN_CURSOR_UPDATE 1154
+#define WT_STAT_CONN_CURSOR_UPDATE 1156
/*! cursor: cursors cached on close */
-#define WT_STAT_CONN_CURSOR_CACHE 1155
+#define WT_STAT_CONN_CURSOR_CACHE 1157
/*! cursor: cursors reused from cache */
-#define WT_STAT_CONN_CURSOR_REOPEN 1156
+#define WT_STAT_CONN_CURSOR_REOPEN 1158
/*! cursor: truncate calls */
-#define WT_STAT_CONN_CURSOR_TRUNCATE 1157
+#define WT_STAT_CONN_CURSOR_TRUNCATE 1159
/*! data-handle: connection data handles currently active */
-#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1158
+#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1160
/*! data-handle: connection sweep candidate became referenced */
-#define WT_STAT_CONN_DH_SWEEP_REF 1159
+#define WT_STAT_CONN_DH_SWEEP_REF 1161
/*! data-handle: connection sweep dhandles closed */
-#define WT_STAT_CONN_DH_SWEEP_CLOSE 1160
+#define WT_STAT_CONN_DH_SWEEP_CLOSE 1162
/*! data-handle: connection sweep dhandles removed from hash list */
-#define WT_STAT_CONN_DH_SWEEP_REMOVE 1161
+#define WT_STAT_CONN_DH_SWEEP_REMOVE 1163
/*! data-handle: connection sweep time-of-death sets */
-#define WT_STAT_CONN_DH_SWEEP_TOD 1162
+#define WT_STAT_CONN_DH_SWEEP_TOD 1164
/*! data-handle: connection sweeps */
-#define WT_STAT_CONN_DH_SWEEPS 1163
+#define WT_STAT_CONN_DH_SWEEPS 1165
/*! data-handle: session dhandles swept */
-#define WT_STAT_CONN_DH_SESSION_HANDLES 1164
+#define WT_STAT_CONN_DH_SESSION_HANDLES 1166
/*! data-handle: session sweep attempts */
-#define WT_STAT_CONN_DH_SESSION_SWEEPS 1165
+#define WT_STAT_CONN_DH_SESSION_SWEEPS 1167
/*! lock: checkpoint lock acquisitions */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_COUNT 1166
+#define WT_STAT_CONN_LOCK_CHECKPOINT_COUNT 1168
/*! lock: checkpoint lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_APPLICATION 1167
+#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_APPLICATION 1169
/*! lock: checkpoint lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_INTERNAL 1168
+#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_INTERNAL 1170
/*!
* lock: commit timestamp queue lock application thread time waiting
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_COMMIT_TIMESTAMP_WAIT_APPLICATION 1169
+#define WT_STAT_CONN_LOCK_COMMIT_TIMESTAMP_WAIT_APPLICATION 1171
/*! lock: commit timestamp queue lock internal thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_COMMIT_TIMESTAMP_WAIT_INTERNAL 1170
+#define WT_STAT_CONN_LOCK_COMMIT_TIMESTAMP_WAIT_INTERNAL 1172
/*! lock: commit timestamp queue read lock acquisitions */
-#define WT_STAT_CONN_LOCK_COMMIT_TIMESTAMP_READ_COUNT 1171
+#define WT_STAT_CONN_LOCK_COMMIT_TIMESTAMP_READ_COUNT 1173
/*! lock: commit timestamp queue write lock acquisitions */
-#define WT_STAT_CONN_LOCK_COMMIT_TIMESTAMP_WRITE_COUNT 1172
+#define WT_STAT_CONN_LOCK_COMMIT_TIMESTAMP_WRITE_COUNT 1174
/*! lock: dhandle lock application thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_APPLICATION 1173
+#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_APPLICATION 1175
/*! lock: dhandle lock internal thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_INTERNAL 1174
+#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_INTERNAL 1176
/*! lock: dhandle read lock acquisitions */
-#define WT_STAT_CONN_LOCK_DHANDLE_READ_COUNT 1175
+#define WT_STAT_CONN_LOCK_DHANDLE_READ_COUNT 1177
/*! lock: dhandle write lock acquisitions */
-#define WT_STAT_CONN_LOCK_DHANDLE_WRITE_COUNT 1176
+#define WT_STAT_CONN_LOCK_DHANDLE_WRITE_COUNT 1178
/*! lock: metadata lock acquisitions */
-#define WT_STAT_CONN_LOCK_METADATA_COUNT 1177
+#define WT_STAT_CONN_LOCK_METADATA_COUNT 1179
/*! lock: metadata lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_METADATA_WAIT_APPLICATION 1178
+#define WT_STAT_CONN_LOCK_METADATA_WAIT_APPLICATION 1180
/*! lock: metadata lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_METADATA_WAIT_INTERNAL 1179
+#define WT_STAT_CONN_LOCK_METADATA_WAIT_INTERNAL 1181
/*!
* lock: read timestamp queue lock application thread time waiting
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WAIT_APPLICATION 1180
+#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WAIT_APPLICATION 1182
/*! lock: read timestamp queue lock internal thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WAIT_INTERNAL 1181
+#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WAIT_INTERNAL 1183
/*! lock: read timestamp queue read lock acquisitions */
-#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_READ_COUNT 1182
+#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_READ_COUNT 1184
/*! lock: read timestamp queue write lock acquisitions */
-#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WRITE_COUNT 1183
+#define WT_STAT_CONN_LOCK_READ_TIMESTAMP_WRITE_COUNT 1185
/*! lock: schema lock acquisitions */
-#define WT_STAT_CONN_LOCK_SCHEMA_COUNT 1184
+#define WT_STAT_CONN_LOCK_SCHEMA_COUNT 1186
/*! lock: schema lock application thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_APPLICATION 1185
+#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_APPLICATION 1187
/*! lock: schema lock internal thread wait time (usecs) */
-#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_INTERNAL 1186
+#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_INTERNAL 1188
/*!
* lock: table lock application thread time waiting for the table lock
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_TABLE_WAIT_APPLICATION 1187
+#define WT_STAT_CONN_LOCK_TABLE_WAIT_APPLICATION 1189
/*!
* lock: table lock internal thread time waiting for the table lock
* (usecs)
*/
-#define WT_STAT_CONN_LOCK_TABLE_WAIT_INTERNAL 1188
+#define WT_STAT_CONN_LOCK_TABLE_WAIT_INTERNAL 1190
/*! lock: table read lock acquisitions */
-#define WT_STAT_CONN_LOCK_TABLE_READ_COUNT 1189
+#define WT_STAT_CONN_LOCK_TABLE_READ_COUNT 1191
/*! lock: table write lock acquisitions */
-#define WT_STAT_CONN_LOCK_TABLE_WRITE_COUNT 1190
+#define WT_STAT_CONN_LOCK_TABLE_WRITE_COUNT 1192
/*! lock: txn global lock application thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_APPLICATION 1191
+#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_APPLICATION 1193
/*! lock: txn global lock internal thread time waiting (usecs) */
-#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_INTERNAL 1192
+#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_INTERNAL 1194
/*! lock: txn global read lock acquisitions */
-#define WT_STAT_CONN_LOCK_TXN_GLOBAL_READ_COUNT 1193
+#define WT_STAT_CONN_LOCK_TXN_GLOBAL_READ_COUNT 1195
/*! lock: txn global write lock acquisitions */
-#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WRITE_COUNT 1194
+#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WRITE_COUNT 1196
/*! log: busy returns attempting to switch slots */
-#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1195
+#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1197
/*! log: force archive time sleeping (usecs) */
-#define WT_STAT_CONN_LOG_FORCE_ARCHIVE_SLEEP 1196
+#define WT_STAT_CONN_LOG_FORCE_ARCHIVE_SLEEP 1198
/*! log: log bytes of payload data */
-#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1197
+#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1199
/*! log: log bytes written */
-#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1198
+#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1200
/*! log: log files manually zero-filled */
-#define WT_STAT_CONN_LOG_ZERO_FILLS 1199
+#define WT_STAT_CONN_LOG_ZERO_FILLS 1201
/*! log: log flush operations */
-#define WT_STAT_CONN_LOG_FLUSH 1200
+#define WT_STAT_CONN_LOG_FLUSH 1202
/*! log: log force write operations */
-#define WT_STAT_CONN_LOG_FORCE_WRITE 1201
+#define WT_STAT_CONN_LOG_FORCE_WRITE 1203
/*! log: log force write operations skipped */
-#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1202
+#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1204
/*! log: log records compressed */
-#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1203
+#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1205
/*! log: log records not compressed */
-#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1204
+#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1206
/*! log: log records too small to compress */
-#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1205
+#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1207
/*! log: log release advances write LSN */
-#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1206
+#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1208
/*! log: log scan operations */
-#define WT_STAT_CONN_LOG_SCANS 1207
+#define WT_STAT_CONN_LOG_SCANS 1209
/*! log: log scan records requiring two reads */
-#define WT_STAT_CONN_LOG_SCAN_REREADS 1208
+#define WT_STAT_CONN_LOG_SCAN_REREADS 1210
/*! log: log server thread advances write LSN */
-#define WT_STAT_CONN_LOG_WRITE_LSN 1209
+#define WT_STAT_CONN_LOG_WRITE_LSN 1211
/*! log: log server thread write LSN walk skipped */
-#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1210
+#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1212
/*! log: log sync operations */
-#define WT_STAT_CONN_LOG_SYNC 1211
+#define WT_STAT_CONN_LOG_SYNC 1213
/*! log: log sync time duration (usecs) */
-#define WT_STAT_CONN_LOG_SYNC_DURATION 1212
+#define WT_STAT_CONN_LOG_SYNC_DURATION 1214
/*! log: log sync_dir operations */
-#define WT_STAT_CONN_LOG_SYNC_DIR 1213
+#define WT_STAT_CONN_LOG_SYNC_DIR 1215
/*! log: log sync_dir time duration (usecs) */
-#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1214
+#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1216
/*! log: log write operations */
-#define WT_STAT_CONN_LOG_WRITES 1215
+#define WT_STAT_CONN_LOG_WRITES 1217
/*! log: logging bytes consolidated */
-#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1216
+#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1218
/*! log: maximum log file size */
-#define WT_STAT_CONN_LOG_MAX_FILESIZE 1217
+#define WT_STAT_CONN_LOG_MAX_FILESIZE 1219
/*! log: number of pre-allocated log files to create */
-#define WT_STAT_CONN_LOG_PREALLOC_MAX 1218
+#define WT_STAT_CONN_LOG_PREALLOC_MAX 1220
/*! log: pre-allocated log files not ready and missed */
-#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1219
+#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1221
/*! log: pre-allocated log files prepared */
-#define WT_STAT_CONN_LOG_PREALLOC_FILES 1220
+#define WT_STAT_CONN_LOG_PREALLOC_FILES 1222
/*! log: pre-allocated log files used */
-#define WT_STAT_CONN_LOG_PREALLOC_USED 1221
+#define WT_STAT_CONN_LOG_PREALLOC_USED 1223
/*! log: records processed by log scan */
-#define WT_STAT_CONN_LOG_SCAN_RECORDS 1222
+#define WT_STAT_CONN_LOG_SCAN_RECORDS 1224
/*! log: slot close lost race */
-#define WT_STAT_CONN_LOG_SLOT_CLOSE_RACE 1223
+#define WT_STAT_CONN_LOG_SLOT_CLOSE_RACE 1225
/*! log: slot close unbuffered waits */
-#define WT_STAT_CONN_LOG_SLOT_CLOSE_UNBUF 1224
+#define WT_STAT_CONN_LOG_SLOT_CLOSE_UNBUF 1226
/*! log: slot closures */
-#define WT_STAT_CONN_LOG_SLOT_CLOSES 1225
+#define WT_STAT_CONN_LOG_SLOT_CLOSES 1227
/*! log: slot join atomic update races */
-#define WT_STAT_CONN_LOG_SLOT_RACES 1226
+#define WT_STAT_CONN_LOG_SLOT_RACES 1228
/*! log: slot join calls atomic updates raced */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_RACE 1227
+#define WT_STAT_CONN_LOG_SLOT_YIELD_RACE 1229
/*! log: slot join calls did not yield */
-#define WT_STAT_CONN_LOG_SLOT_IMMEDIATE 1228
+#define WT_STAT_CONN_LOG_SLOT_IMMEDIATE 1230
/*! log: slot join calls found active slot closed */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_CLOSE 1229
+#define WT_STAT_CONN_LOG_SLOT_YIELD_CLOSE 1231
/*! log: slot join calls slept */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_SLEEP 1230
+#define WT_STAT_CONN_LOG_SLOT_YIELD_SLEEP 1232
/*! log: slot join calls yielded */
-#define WT_STAT_CONN_LOG_SLOT_YIELD 1231
+#define WT_STAT_CONN_LOG_SLOT_YIELD 1233
/*! log: slot join found active slot closed */
-#define WT_STAT_CONN_LOG_SLOT_ACTIVE_CLOSED 1232
+#define WT_STAT_CONN_LOG_SLOT_ACTIVE_CLOSED 1234
/*! log: slot joins yield time (usecs) */
-#define WT_STAT_CONN_LOG_SLOT_YIELD_DURATION 1233
+#define WT_STAT_CONN_LOG_SLOT_YIELD_DURATION 1235
/*! log: slot transitions unable to find free slot */
-#define WT_STAT_CONN_LOG_SLOT_NO_FREE_SLOTS 1234
+#define WT_STAT_CONN_LOG_SLOT_NO_FREE_SLOTS 1236
/*! log: slot unbuffered writes */
-#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1235
+#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1237
/*! log: total in-memory size of compressed records */
-#define WT_STAT_CONN_LOG_COMPRESS_MEM 1236
+#define WT_STAT_CONN_LOG_COMPRESS_MEM 1238
/*! log: total log buffer size */
-#define WT_STAT_CONN_LOG_BUFFER_SIZE 1237
+#define WT_STAT_CONN_LOG_BUFFER_SIZE 1239
/*! log: total size of compressed records */
-#define WT_STAT_CONN_LOG_COMPRESS_LEN 1238
+#define WT_STAT_CONN_LOG_COMPRESS_LEN 1240
/*! log: written slots coalesced */
-#define WT_STAT_CONN_LOG_SLOT_COALESCED 1239
+#define WT_STAT_CONN_LOG_SLOT_COALESCED 1241
/*! log: yields waiting for previous log file close */
-#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1240
+#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1242
/*! perf: file system read latency histogram (bucket 1) - 10-49ms */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT50 1241
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT50 1243
/*! perf: file system read latency histogram (bucket 2) - 50-99ms */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT100 1242
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT100 1244
/*! perf: file system read latency histogram (bucket 3) - 100-249ms */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT250 1243
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT250 1245
/*! perf: file system read latency histogram (bucket 4) - 250-499ms */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT500 1244
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT500 1246
/*! perf: file system read latency histogram (bucket 5) - 500-999ms */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT1000 1245
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT1000 1247
/*! perf: file system read latency histogram (bucket 6) - 1000ms+ */
-#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_GT1000 1246
+#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_GT1000 1248
/*! perf: file system write latency histogram (bucket 1) - 10-49ms */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT50 1247
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT50 1249
/*! perf: file system write latency histogram (bucket 2) - 50-99ms */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT100 1248
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT100 1250
/*! perf: file system write latency histogram (bucket 3) - 100-249ms */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT250 1249
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT250 1251
/*! perf: file system write latency histogram (bucket 4) - 250-499ms */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT500 1250
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT500 1252
/*! perf: file system write latency histogram (bucket 5) - 500-999ms */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT1000 1251
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT1000 1253
/*! perf: file system write latency histogram (bucket 6) - 1000ms+ */
-#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_GT1000 1252
+#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_GT1000 1254
/*! perf: operation read latency histogram (bucket 1) - 100-249us */
-#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT250 1253
+#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT250 1255
/*! perf: operation read latency histogram (bucket 2) - 250-499us */
-#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT500 1254
+#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT500 1256
/*! perf: operation read latency histogram (bucket 3) - 500-999us */
-#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT1000 1255
+#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT1000 1257
/*! perf: operation read latency histogram (bucket 4) - 1000-9999us */
-#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT10000 1256
+#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT10000 1258
/*! perf: operation read latency histogram (bucket 5) - 10000us+ */
-#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_GT10000 1257
+#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_GT10000 1259
/*! perf: operation write latency histogram (bucket 1) - 100-249us */
-#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT250 1258
+#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT250 1260
/*! perf: operation write latency histogram (bucket 2) - 250-499us */
-#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT500 1259
+#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT500 1261
/*! perf: operation write latency histogram (bucket 3) - 500-999us */
-#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT1000 1260
+#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT1000 1262
/*! perf: operation write latency histogram (bucket 4) - 1000-9999us */
-#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT10000 1261
+#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT10000 1263
/*! perf: operation write latency histogram (bucket 5) - 10000us+ */
-#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_GT10000 1262
+#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_GT10000 1264
/*! reconciliation: fast-path pages deleted */
-#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1263
+#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1265
/*! reconciliation: page reconciliation calls */
-#define WT_STAT_CONN_REC_PAGES 1264
+#define WT_STAT_CONN_REC_PAGES 1266
/*! reconciliation: page reconciliation calls for eviction */
-#define WT_STAT_CONN_REC_PAGES_EVICTION 1265
+#define WT_STAT_CONN_REC_PAGES_EVICTION 1267
/*! reconciliation: pages deleted */
-#define WT_STAT_CONN_REC_PAGE_DELETE 1266
+#define WT_STAT_CONN_REC_PAGE_DELETE 1268
/*! reconciliation: split bytes currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1267
+#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1269
/*! reconciliation: split objects currently awaiting free */
-#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1268
+#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1270
/*! session: open cursor count */
-#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1269
+#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1271
/*! session: open session count */
-#define WT_STAT_CONN_SESSION_OPEN 1270
+#define WT_STAT_CONN_SESSION_OPEN 1272
/*! session: session query timestamp calls */
-#define WT_STAT_CONN_SESSION_QUERY_TS 1271
+#define WT_STAT_CONN_SESSION_QUERY_TS 1273
/*! session: table alter failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1272
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1274
/*! session: table alter successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1273
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1275
/*! session: table alter unchanged and skipped */
-#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1274
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1276
/*! session: table compact failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1275
+#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1277
/*! session: table compact successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1276
+#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1278
/*! session: table create failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1277
+#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1279
/*! session: table create successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1278
+#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1280
/*! session: table drop failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1279
+#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1281
/*! session: table drop successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1280
+#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1282
/*! session: table rebalance failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_FAIL 1281
+#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_FAIL 1283
/*! session: table rebalance successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_SUCCESS 1282
+#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_SUCCESS 1284
/*! session: table rename failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1283
+#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1285
/*! session: table rename successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1284
+#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1286
/*! session: table salvage failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1285
+#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1287
/*! session: table salvage successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1286
+#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1288
/*! session: table truncate failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1287
+#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1289
/*! session: table truncate successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1288
+#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1290
/*! session: table verify failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1289
+#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1291
/*! session: table verify successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1290
+#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1292
/*! thread-state: active filesystem fsync calls */
-#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1291
+#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1293
/*! thread-state: active filesystem read calls */
-#define WT_STAT_CONN_THREAD_READ_ACTIVE 1292
+#define WT_STAT_CONN_THREAD_READ_ACTIVE 1294
/*! thread-state: active filesystem write calls */
-#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1293
+#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1295
/*! thread-yield: application thread time evicting (usecs) */
-#define WT_STAT_CONN_APPLICATION_EVICT_TIME 1294
+#define WT_STAT_CONN_APPLICATION_EVICT_TIME 1296
/*! thread-yield: application thread time waiting for cache (usecs) */
-#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1295
+#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1297
/*!
* thread-yield: connection close blocked waiting for transaction state
* stabilization
*/
-#define WT_STAT_CONN_TXN_RELEASE_BLOCKED 1296
+#define WT_STAT_CONN_TXN_RELEASE_BLOCKED 1298
/*! thread-yield: connection close yielded for lsm manager shutdown */
-#define WT_STAT_CONN_CONN_CLOSE_BLOCKED_LSM 1297
+#define WT_STAT_CONN_CONN_CLOSE_BLOCKED_LSM 1299
/*! thread-yield: data handle lock yielded */
-#define WT_STAT_CONN_DHANDLE_LOCK_BLOCKED 1298
+#define WT_STAT_CONN_DHANDLE_LOCK_BLOCKED 1300
/*!
* thread-yield: get reference for page index and slot time sleeping
* (usecs)
*/
-#define WT_STAT_CONN_PAGE_INDEX_SLOT_REF_BLOCKED 1299
+#define WT_STAT_CONN_PAGE_INDEX_SLOT_REF_BLOCKED 1301
/*! thread-yield: log server sync yielded for log write */
-#define WT_STAT_CONN_LOG_SERVER_SYNC_BLOCKED 1300
+#define WT_STAT_CONN_LOG_SERVER_SYNC_BLOCKED 1302
/*! thread-yield: page access yielded due to prepare state change */
-#define WT_STAT_CONN_PREPARED_TRANSITION_BLOCKED_PAGE 1301
+#define WT_STAT_CONN_PREPARED_TRANSITION_BLOCKED_PAGE 1303
/*! thread-yield: page acquire busy blocked */
-#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1302
+#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1304
/*! thread-yield: page acquire eviction blocked */
-#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1303
+#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1305
/*! thread-yield: page acquire locked blocked */
-#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1304
+#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1306
/*! thread-yield: page acquire read blocked */
-#define WT_STAT_CONN_PAGE_READ_BLOCKED 1305
+#define WT_STAT_CONN_PAGE_READ_BLOCKED 1307
/*! thread-yield: page acquire time sleeping (usecs) */
-#define WT_STAT_CONN_PAGE_SLEEP 1306
+#define WT_STAT_CONN_PAGE_SLEEP 1308
/*!
* thread-yield: page delete rollback time sleeping for state change
* (usecs)
*/
-#define WT_STAT_CONN_PAGE_DEL_ROLLBACK_BLOCKED 1307
+#define WT_STAT_CONN_PAGE_DEL_ROLLBACK_BLOCKED 1309
/*! thread-yield: page reconciliation yielded due to child modification */
-#define WT_STAT_CONN_CHILD_MODIFY_BLOCKED_PAGE 1308
+#define WT_STAT_CONN_CHILD_MODIFY_BLOCKED_PAGE 1310
/*! transaction: commit timestamp queue entries walked */
-#define WT_STAT_CONN_TXN_COMMIT_QUEUE_WALKED 1309
+#define WT_STAT_CONN_TXN_COMMIT_QUEUE_WALKED 1311
/*! transaction: commit timestamp queue insert to empty */
-#define WT_STAT_CONN_TXN_COMMIT_QUEUE_EMPTY 1310
+#define WT_STAT_CONN_TXN_COMMIT_QUEUE_EMPTY 1312
/*! transaction: commit timestamp queue inserts to head */
-#define WT_STAT_CONN_TXN_COMMIT_QUEUE_HEAD 1311
+#define WT_STAT_CONN_TXN_COMMIT_QUEUE_HEAD 1313
/*! transaction: commit timestamp queue inserts total */
-#define WT_STAT_CONN_TXN_COMMIT_QUEUE_INSERTS 1312
+#define WT_STAT_CONN_TXN_COMMIT_QUEUE_INSERTS 1314
/*! transaction: commit timestamp queue length */
-#define WT_STAT_CONN_TXN_COMMIT_QUEUE_LEN 1313
+#define WT_STAT_CONN_TXN_COMMIT_QUEUE_LEN 1315
/*! transaction: number of named snapshots created */
-#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1314
+#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1316
/*! transaction: number of named snapshots dropped */
-#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1315
+#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1317
/*! transaction: prepared transactions */
-#define WT_STAT_CONN_TXN_PREPARE 1316
+#define WT_STAT_CONN_TXN_PREPARE 1318
/*! transaction: prepared transactions committed */
-#define WT_STAT_CONN_TXN_PREPARE_COMMIT 1317
+#define WT_STAT_CONN_TXN_PREPARE_COMMIT 1319
/*! transaction: prepared transactions currently active */
-#define WT_STAT_CONN_TXN_PREPARE_ACTIVE 1318
+#define WT_STAT_CONN_TXN_PREPARE_ACTIVE 1320
/*! transaction: prepared transactions rolled back */
-#define WT_STAT_CONN_TXN_PREPARE_ROLLBACK 1319
+#define WT_STAT_CONN_TXN_PREPARE_ROLLBACK 1321
/*! transaction: query timestamp calls */
-#define WT_STAT_CONN_TXN_QUERY_TS 1320
+#define WT_STAT_CONN_TXN_QUERY_TS 1322
/*! transaction: read timestamp queue entries walked */
-#define WT_STAT_CONN_TXN_READ_QUEUE_WALKED 1321
+#define WT_STAT_CONN_TXN_READ_QUEUE_WALKED 1323
/*! transaction: read timestamp queue insert to empty */
-#define WT_STAT_CONN_TXN_READ_QUEUE_EMPTY 1322
+#define WT_STAT_CONN_TXN_READ_QUEUE_EMPTY 1324
/*! transaction: read timestamp queue inserts to head */
-#define WT_STAT_CONN_TXN_READ_QUEUE_HEAD 1323
+#define WT_STAT_CONN_TXN_READ_QUEUE_HEAD 1325
/*! transaction: read timestamp queue inserts total */
-#define WT_STAT_CONN_TXN_READ_QUEUE_INSERTS 1324
+#define WT_STAT_CONN_TXN_READ_QUEUE_INSERTS 1326
/*! transaction: read timestamp queue length */
-#define WT_STAT_CONN_TXN_READ_QUEUE_LEN 1325
+#define WT_STAT_CONN_TXN_READ_QUEUE_LEN 1327
/*! transaction: rollback to stable calls */
-#define WT_STAT_CONN_TXN_ROLLBACK_TO_STABLE 1326
+#define WT_STAT_CONN_TXN_ROLLBACK_TO_STABLE 1328
/*! transaction: rollback to stable updates aborted */
-#define WT_STAT_CONN_TXN_ROLLBACK_UPD_ABORTED 1327
+#define WT_STAT_CONN_TXN_ROLLBACK_UPD_ABORTED 1329
/*! transaction: rollback to stable updates removed from cache overflow */
-#define WT_STAT_CONN_TXN_ROLLBACK_LAS_REMOVED 1328
+#define WT_STAT_CONN_TXN_ROLLBACK_LAS_REMOVED 1330
/*! transaction: set timestamp calls */
-#define WT_STAT_CONN_TXN_SET_TS 1329
+#define WT_STAT_CONN_TXN_SET_TS 1331
/*! transaction: set timestamp commit calls */
-#define WT_STAT_CONN_TXN_SET_TS_COMMIT 1330
+#define WT_STAT_CONN_TXN_SET_TS_COMMIT 1332
/*! transaction: set timestamp commit updates */
-#define WT_STAT_CONN_TXN_SET_TS_COMMIT_UPD 1331
+#define WT_STAT_CONN_TXN_SET_TS_COMMIT_UPD 1333
/*! transaction: set timestamp oldest calls */
-#define WT_STAT_CONN_TXN_SET_TS_OLDEST 1332
+#define WT_STAT_CONN_TXN_SET_TS_OLDEST 1334
/*! transaction: set timestamp oldest updates */
-#define WT_STAT_CONN_TXN_SET_TS_OLDEST_UPD 1333
+#define WT_STAT_CONN_TXN_SET_TS_OLDEST_UPD 1335
/*! transaction: set timestamp stable calls */
-#define WT_STAT_CONN_TXN_SET_TS_STABLE 1334
+#define WT_STAT_CONN_TXN_SET_TS_STABLE 1336
/*! transaction: set timestamp stable updates */
-#define WT_STAT_CONN_TXN_SET_TS_STABLE_UPD 1335
+#define WT_STAT_CONN_TXN_SET_TS_STABLE_UPD 1337
/*! transaction: transaction begins */
-#define WT_STAT_CONN_TXN_BEGIN 1336
+#define WT_STAT_CONN_TXN_BEGIN 1338
/*! transaction: transaction checkpoint currently running */
-#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1337
+#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1339
/*! transaction: transaction checkpoint generation */
-#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1338
+#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1340
/*! transaction: transaction checkpoint max time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1339
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1341
/*! transaction: transaction checkpoint min time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1340
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1342
/*! transaction: transaction checkpoint most recent time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1341
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1343
/*! transaction: transaction checkpoint scrub dirty target */
-#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1342
+#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1344
/*! transaction: transaction checkpoint scrub time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1343
+#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1345
/*! transaction: transaction checkpoint total time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1344
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1346
/*! transaction: transaction checkpoints */
-#define WT_STAT_CONN_TXN_CHECKPOINT 1345
+#define WT_STAT_CONN_TXN_CHECKPOINT 1347
/*!
* transaction: transaction checkpoints skipped because database was
* clean
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_SKIPPED 1346
+#define WT_STAT_CONN_TXN_CHECKPOINT_SKIPPED 1348
/*! transaction: transaction failures due to cache overflow */
-#define WT_STAT_CONN_TXN_FAIL_CACHE 1347
+#define WT_STAT_CONN_TXN_FAIL_CACHE 1349
/*!
* transaction: transaction fsync calls for checkpoint after allocating
* the transaction ID
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1348
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1350
/*!
* transaction: transaction fsync duration for checkpoint after
* allocating the transaction ID (usecs)
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1349
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1351
/*! transaction: transaction range of IDs currently pinned */
-#define WT_STAT_CONN_TXN_PINNED_RANGE 1350
+#define WT_STAT_CONN_TXN_PINNED_RANGE 1352
/*! transaction: transaction range of IDs currently pinned by a checkpoint */
-#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1351
+#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1353
/*!
* transaction: transaction range of IDs currently pinned by named
* snapshots
*/
-#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1352
+#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1354
/*! transaction: transaction range of timestamps currently pinned */
-#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP 1353
+#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP 1355
/*! transaction: transaction range of timestamps pinned by a checkpoint */
-#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_CHECKPOINT 1354
+#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_CHECKPOINT 1356
/*!
* transaction: transaction range of timestamps pinned by the oldest
* timestamp
*/
-#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_OLDEST 1355
+#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_OLDEST 1357
/*! transaction: transaction sync calls */
-#define WT_STAT_CONN_TXN_SYNC 1356
+#define WT_STAT_CONN_TXN_SYNC 1358
/*! transaction: transactions committed */
-#define WT_STAT_CONN_TXN_COMMIT 1357
+#define WT_STAT_CONN_TXN_COMMIT 1359
/*! transaction: transactions rolled back */
-#define WT_STAT_CONN_TXN_ROLLBACK 1358
+#define WT_STAT_CONN_TXN_ROLLBACK 1360
/*! transaction: update conflicts */
-#define WT_STAT_CONN_TXN_UPDATE_CONFLICT 1359
+#define WT_STAT_CONN_TXN_UPDATE_CONFLICT 1361
/*!
* @}
diff --git a/src/third_party/wiredtiger/src/meta/meta_ckpt.c b/src/third_party/wiredtiger/src/meta/meta_ckpt.c
index f32a1cbeb19..13e84efc199 100644
--- a/src/third_party/wiredtiger/src/meta/meta_ckpt.c
+++ b/src/third_party/wiredtiger/src/meta/meta_ckpt.c
@@ -291,7 +291,7 @@ __wt_meta_ckptlist_get(
WT_ERR(__wt_realloc_def(session, &allocated, slot + 2, &ckptbase));
/* Sort in creation-order. */
- qsort(ckptbase, slot, sizeof(WT_CKPT), __ckpt_compare_order);
+ __wt_qsort(ckptbase, slot, sizeof(WT_CKPT), __ckpt_compare_order);
/* Return the array to our caller. */
*ckptbasep = ckptbase;
diff --git a/src/third_party/wiredtiger/src/support/huffman.c b/src/third_party/wiredtiger/src/support/huffman.c
index 55910ab835d..03d442403d5 100644
--- a/src/third_party/wiredtiger/src/support/huffman.c
+++ b/src/third_party/wiredtiger/src/support/huffman.c
@@ -352,7 +352,7 @@ __wt_huffman_open(WT_SESSION_IMPL *session,
* duplicates.
*/
sym = symbol_frequency_array;
- qsort(sym, symcnt, sizeof(INDEXED_SYMBOL), indexed_symbol_compare);
+ __wt_qsort(sym, symcnt, sizeof(INDEXED_SYMBOL), indexed_symbol_compare);
for (i = 0; i < symcnt; ++i) {
if (i > 0 && sym[i].symbol == sym[i - 1].symbol)
WT_ERR_MSG(session, EINVAL,
@@ -397,7 +397,7 @@ __wt_huffman_open(WT_SESSION_IMPL *session,
* The array must be sorted by frequency to be able to use a linear time
* construction algorithm.
*/
- qsort((void *)indexed_freqs,
+ __wt_qsort((void *)indexed_freqs,
symcnt, sizeof(INDEXED_SYMBOL), indexed_freq_compare);
/* We need two node queues to build the tree. */
diff --git a/src/third_party/wiredtiger/src/support/stat.c b/src/third_party/wiredtiger/src/support/stat.c
index 7993c7b6dab..61300dfeab9 100644
--- a/src/third_party/wiredtiger/src/support/stat.c
+++ b/src/third_party/wiredtiger/src/support/stat.c
@@ -788,6 +788,8 @@ static const char * const __stats_connection_desc[] = {
"cache: bytes not belonging to page images in the cache",
"cache: bytes read into cache",
"cache: bytes written from cache",
+ "cache: cache overflow cursor application thread wait time (usecs)",
+ "cache: cache overflow cursor internal thread wait time (usecs)",
"cache: cache overflow score",
"cache: cache overflow table entries",
"cache: cache overflow table insert calls",
@@ -1190,6 +1192,8 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
/* not clearing cache_bytes_other */
stats->cache_bytes_read = 0;
stats->cache_bytes_write = 0;
+ stats->cache_lookaside_cursor_wait_application = 0;
+ stats->cache_lookaside_cursor_wait_internal = 0;
/* not clearing cache_lookaside_score */
/* not clearing cache_lookaside_entries */
stats->cache_lookaside_insert = 0;
@@ -1575,6 +1579,10 @@ __wt_stat_connection_aggregate(
to->cache_bytes_other += WT_STAT_READ(from, cache_bytes_other);
to->cache_bytes_read += WT_STAT_READ(from, cache_bytes_read);
to->cache_bytes_write += WT_STAT_READ(from, cache_bytes_write);
+ to->cache_lookaside_cursor_wait_application +=
+ WT_STAT_READ(from, cache_lookaside_cursor_wait_application);
+ to->cache_lookaside_cursor_wait_internal +=
+ WT_STAT_READ(from, cache_lookaside_cursor_wait_internal);
to->cache_lookaside_score +=
WT_STAT_READ(from, cache_lookaside_score);
to->cache_lookaside_entries +=
diff --git a/src/third_party/wiredtiger/test/csuite/Makefile.am b/src/third_party/wiredtiger/test/csuite/Makefile.am
index ce57c9b3de9..e625f2e4bfe 100644
--- a/src/third_party/wiredtiger/test/csuite/Makefile.am
+++ b/src/third_party/wiredtiger/test/csuite/Makefile.am
@@ -11,6 +11,10 @@ test_random_abort_SOURCES = random_abort/main.c
noinst_PROGRAMS += test_random_abort
all_TESTS += random_abort/smoke.sh
+test_random_directio_SOURCES = random_directio/main.c
+noinst_PROGRAMS += test_random_directio
+all_TESTS += random_directio/smoke.sh
+
test_rwlock_SOURCES = rwlock/main.c
noinst_PROGRAMS += test_rwlock
all_TESTS += test_rwlock
diff --git a/src/third_party/wiredtiger/test/csuite/random_directio/main.c b/src/third_party/wiredtiger/test/csuite/random_directio/main.c
new file mode 100644
index 00000000000..83c0ae46ef3
--- /dev/null
+++ b/src/third_party/wiredtiger/test/csuite/random_directio/main.c
@@ -0,0 +1,1291 @@
+/*-
+ * Public Domain 2014-2018 MongoDB, Inc.
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * This test simulates system crashes. It uses direct IO, and currently
+ * runs only on Linux.
+ *
+ * Our strategy is to run a subordinate 'writer' process that creates/modifies
+ * data, including schema modifications. Every N seconds, asynchronously, we
+ * send a stop signal to the writer and then copy (with direct IO) the entire
+ * contents of its database home to a new saved location where we can run and
+ * verify the recovered home. Then we send a continue signal. We repeat this:
+ *
+ * sleep N, STOP, copy, run recovery, CONTINUE
+ *
+ * which allows the writer to make continuing progress, while the main
+ * process is verifying what's on disk.
+ *
+ * By using stop signal to suspend the process and copying with direct IO,
+ * we are roughly simulating a system crash, by seeing what's actually on
+ * disk (not in file system buffer cache) at the moment that the copy is
+ * made. It's not quite as harsh as a system crash, as suspending does not
+ * halt writes that are in-flight. Still, it's a reasonable proxy for testing.
+ *
+ * In the main table, the keys look like:
+ *
+ * xxxx:T:LARGE_STRING
+ *
+ * where xxxx represents an increasing decimal id (0 padded to 12 digits).
+ * These ids are only unique per thread, so this key is the xxxx-th key
+ * written by a thread. T represents the thread id reduced to a single
+ * hex digit. LARGE_STRING is a portion of a large string that includes
+ * the thread id and a lot of spaces, over and over (see the large_buf
+ * function). When forming the key, the large string is truncated so
+ * that the key is effectively padded to the right length.
+ *
+ * The key space for the main table is designed to be interleaved tightly
+ * among all the threads. The matching values in the main table are the
+ * same, except with the xxxx string reversed. So the keys and values
+ * are the same size.
+ *
+ * There is also a reverse table where the keys/values are swapped.
+ */
+
+#include "test_util.h"
+
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+static char home[1024]; /* Program working dir */
+
+/*
+ * These two names for the URI and file system must be maintained in tandem.
+ */
+static const char * const uri_main = "table:main";
+static const char * const fs_main = "main.wt";
+
+static const char * const uri_rev = "table:rev";
+
+/*
+ * The number of threads cannot be more than 16, we are using a hex digit
+ * to encode this in the key.
+ */
+#define MAX_TH 16
+#define MIN_TH 5
+
+#define MAX_TIME 40
+#define MIN_TIME 10
+
+#define LARGE_WRITE_SIZE (128*1024)
+#define MIN_DATA_SIZE 30
+#define DEFAULT_DATA_SIZE 50
+
+#define DEFAULT_CYCLES 5
+#define DEFAULT_INTERVAL 3
+
+#define KEY_SEP "_" /* Must be one char string */
+
+#define ENV_CONFIG \
+ "create,log=(file_max=10M,enabled)," \
+ "transaction_sync=(enabled,method=%s)"
+#define ENV_CONFIG_REC "log=(recover=on)"
+
+/* 64 spaces */
+#define SPACES \
+ " "
+
+/*
+ * Set the "schema operation frequency" higher to be less stressful for schema
+ * operations. With the current value, 100, there are sequences of schema
+ * operations that are begun when the id is in the range 0 to 9, 100 to 109,
+ * 200 to 209, etc. That is, 10 sequences per 100. A higher number (say 1000)
+ * means there are 10 sequences started per 1000. A sequence of schema
+ * operations lasts for 4 ids. So, for example, if thread 3 is inserting id
+ * 100 into the main table, an additional schema operation is done (creating a
+ * table), and operations on this table continue (while other schema operations
+ * continue).
+ *
+ * Starting at the insert of id 99 (which has no schema operations), here's
+ * what will happen (for thread #3).
+ *
+ * insert k/v 99 into table:main (with no additional schema operations)
+ *
+ * insert k/v 100 into table:main
+ * create table:A100-3 (3 for thread #3)
+ *
+ * insert k/v 101 into table:main
+ * insert into table:A100-3 (continuing the sequence)
+ * create table:A101-3 (starts a new sequence)
+ *
+ * insert k/v 102 into table:main
+ * rename table:A100-3 -> table:B100-3 (third step in sequence)
+ * insert into table:A101-3 (second step in sequence)
+ * create table:A102-3 (starting new sequence)
+ *
+ * insert k/v 103 into table:main
+ * update key in table:B100-3 (fourth step)
+ * rename table:A101-3 -> table:B101-3 (third step)
+ * insert into table:A102-3
+ * create table:A103-3
+ *
+ * insert k/v 104 into table:main
+ * drop table:B100-3 (fifth and last step)
+ * update key in table:B101-3 (fourth step)
+ * rename table:A102-3 -> table:B102-3
+ * insert into table:A103-3
+ * create table:A104-3
+ * ...
+ *
+ * This continues, with the last table created when k/v 109 is inserted into
+ * table:main and the last sequence finishing at k/v 113. Each clump above
+ * separated by a blank line represents a transaction. Meanwhile, other
+ * threads are doing the same thing. That stretch, from id 100 to id 113
+ * that has schema operations happens again at id 200, assuming frequency
+ * set to 100. So it is a good test of schema operations 'in flight'.
+ */
+#define SCHEMA_OP_FREQUENCY 100
+
+#define TEST_STREQ(expect, got, message) \
+ do { \
+ if (!WT_STREQ(expect, got)) { \
+ printf("FAIL: %s: expect %s, got %s", message, \
+ expect, got); \
+ testutil_assert(WT_STREQ(expect, got)); \
+ } \
+ } while (0)
+
+/*
+ * Values for flags used in various places.
+ */
+#define SCHEMA_CREATE 0x0001
+#define SCHEMA_CREATE_CHECK 0x0002
+#define SCHEMA_DATA_CHECK 0x0004
+#define SCHEMA_DROP 0x0008
+#define SCHEMA_DROP_CHECK 0x0010
+#define SCHEMA_RENAME 0x0020
+#define SCHEMA_VERBOSE 0x0040
+#define SCHEMA_ALL \
+ (SCHEMA_CREATE | SCHEMA_CREATE_CHECK | \
+ SCHEMA_DATA_CHECK | SCHEMA_DROP | \
+ SCHEMA_DROP_CHECK | SCHEMA_RENAME)
+
+extern int __wt_optind;
+extern char *__wt_optarg;
+
+static void handler(int);
+
+typedef struct {
+ WT_CONNECTION *conn;
+ char *data;
+ uint32_t datasize;
+ uint32_t id;
+
+ uint32_t flags; /* Uses SCHEMA_* values above */
+} WT_THREAD_DATA;
+
+/*
+ * usage --
+ * Print usage and exit.
+ */
+static void usage(void)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [options]\n", progname);
+ fprintf(stderr, "options:\n");
+ fprintf(stderr, " %-20s%s\n", "-d data_size",
+ "approximate size of keys and values [1000]");
+ fprintf(stderr, " %-20s%s\n", "-h home",
+ "WiredTiger home directory [WT_TEST.directio]");
+ fprintf(stderr, " %-20s%s\n", "-i interval",
+ "interval timeout between copy/recover cycles [3]");
+ fprintf(stderr, " %-20s%s\n", "-m method",
+ "sync method: fsync, dsync, none [none]");
+ fprintf(stderr, " %-20s%s\n", "-n num_cycles",
+ "number of copy/recover cycles [5]");
+ fprintf(stderr, " %-20s%s\n", "-p", "populate only [false]");
+ fprintf(stderr, " %-20s%s\n", "-S arg1,arg2,...",
+ "comma separated schema operations, from the following:");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "none",
+ "no schema operations [default]");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "all",
+ "all of the below operations, except verbose");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "create",
+ "create tables");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "create_check",
+ "newly created tables are checked (requires create)");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "data_check",
+ "check contents of files for various ops (requires create)");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "rename",
+ "rename tables (requires create)");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "drop",
+ "drop tables (requires create)");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "drop_check",
+ "after recovery, dropped tables are checked (requires drop)");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "",
+ "that they no longer exist (requires drop)");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "verbose",
+ "verbose print during schema operation checks,");
+ fprintf(stderr, " %-5s%-15s%s\n", "", "",
+ "done after recovery, so does not effect test timing");
+ fprintf(stderr, " %-20s%s\n", "-T num_threads",
+ "number of threads in writer [random]");
+ fprintf(stderr, " %-20s%s\n", "-t timeout",
+ "initial timeout before first copy [random]");
+ fprintf(stderr, " %-20s%s\n", "-v", "verify only [false]");
+ exit(EXIT_FAILURE);
+}
+
+/*
+ * has_schema_operation --
+ * Return true if a schema operation should be performed for this id.
+ * See the comment above describing schema operation frequency.
+ */
+static bool
+has_schema_operation(uint64_t id, uint32_t offset)
+{
+ return (id >= offset &&
+ (id - offset) % SCHEMA_OP_FREQUENCY < 10);
+}
+
+/*
+ * large_buf --
+ * Fill or check a large buffer.
+ */
+static void
+large_buf(char *large, size_t lsize, uint32_t id, bool fill)
+{
+ size_t len;
+ uint64_t i;
+ char lgbuf[1024 + 20];
+
+ /*
+ * Set up a large value putting our id in it every 1024 bytes or so.
+ */
+ testutil_check(__wt_snprintf(
+ lgbuf, sizeof(lgbuf), "th-%" PRIu32
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", id,
+ SPACES, SPACES, SPACES, SPACES,
+ SPACES, SPACES, SPACES, SPACES,
+ SPACES, SPACES, SPACES, SPACES,
+ SPACES, SPACES, SPACES, SPACES));
+
+ len = strlen(lgbuf);
+ for (i = 0; i < lsize - len; i += len)
+ if (fill)
+ testutil_check(__wt_snprintf(
+ &large[i], lsize - i, "%s", lgbuf));
+ else
+ testutil_check(strncmp(&large[i], lgbuf, len));
+}
+
+/*
+ * reverse --
+ * Reverse a string in place.
+ */
+static void
+reverse(char *s)
+{
+ size_t i, j, len;
+ char tmp;
+
+ len = strlen(s);
+ for (i = 0, j = len - 1; i < len / 2; i++, j--) {
+ tmp = s[i];
+ s[i] = s[j];
+ s[j] = tmp;
+ }
+}
+
+/*
+ * gen_kv --
+ * Generate a key/value.
+ */
+static void
+gen_kv(char *buf, size_t buf_size, uint64_t id, uint32_t threadid,
+ const char *large, bool forward)
+{
+ size_t keyid_size, large_size;
+ char keyid[64];
+
+ testutil_check(__wt_snprintf(keyid, sizeof(keyid),
+ "%10.10" PRIu64, id));
+ keyid_size = strlen(keyid);
+ if (!forward)
+ reverse(keyid);
+ testutil_assert(keyid_size + 4 <= buf_size);
+ large_size = buf_size - 4 - keyid_size;
+ testutil_check(__wt_snprintf(buf, buf_size,
+ "%s" KEY_SEP "%1.1x" KEY_SEP "%.*s",
+ keyid, threadid, (int)large_size, large));
+}
+
+/*
+ * gen_table_name --
+ * Generate a table name used for the schema test.
+ */
+static void
+gen_table_name(char *buf, size_t buf_size, uint64_t id, uint32_t threadid)
+{
+ testutil_check(__wt_snprintf(buf, buf_size,
+ "table:A%" PRIu64 "-%" PRIu32, id, threadid));
+}
+
+/*
+ * gen_table2_name --
+ * Generate a second table name used for the schema test.
+ */
+static void
+gen_table2_name(char *buf, size_t buf_size, uint64_t id, uint32_t threadid,
+ uint32_t flags)
+{
+ if (!LF_ISSET(SCHEMA_RENAME))
+ /* table is not renamed, so use original table name */
+ gen_table_name(buf, buf_size, id, threadid);
+ else
+ testutil_check(__wt_snprintf(buf, buf_size,
+ "table:B%" PRIu64 "-%" PRIu32, id, threadid));
+}
+
+static int
+schema_operation(WT_SESSION *session, uint32_t threadid, uint64_t id,
+ uint32_t op, uint32_t flags)
+{
+ WT_CURSOR *cursor;
+ int ret;
+ const char *retry_opname;
+ char uri1[50], uri2[50];
+
+ if (!has_schema_operation(id, op))
+ return (0);
+
+ id -= op;
+ ret = 0;
+ retry_opname = NULL;
+
+ switch (op) {
+ case 0:
+ /* Create a table. */
+ gen_table_name(uri1, sizeof(uri1), id, threadid);
+ /*
+ fprintf(stderr, "CREATE: %s\n", uri1);
+ */
+ testutil_check(session->create(session, uri1,
+ "key_format=S,value_format=S"));
+ break;
+ case 1:
+ /* Insert a value into the table. */
+ gen_table_name(uri1, sizeof(uri1), id, threadid);
+ /*
+ fprintf(stderr, "INSERT: %s\n", uri1);
+ */
+ testutil_check(session->open_cursor(
+ session, uri1, NULL, NULL, &cursor));
+ cursor->set_key(cursor, uri1);
+ cursor->set_value(cursor, uri1);
+ testutil_check(cursor->insert(cursor));
+ cursor->close(cursor);
+ break;
+ case 2:
+ /* Rename the table. */
+ if (LF_ISSET(SCHEMA_RENAME)) {
+ gen_table_name(uri1, sizeof(uri1), id, threadid);
+ gen_table2_name(uri2, sizeof(uri2), id, threadid,
+ flags);
+ retry_opname = "rename";
+ /*
+ fprintf(stderr, "RENAME: %s->%s\n", uri1, uri2);
+ */
+ ret = session->rename(session, uri1, uri2, NULL);
+ }
+ break;
+ case 3:
+ /* Update the single value in the table. */
+ gen_table_name(uri1, sizeof(uri1), id, threadid);
+ gen_table2_name(uri2, sizeof(uri2), id, threadid, flags);
+ testutil_check(session->open_cursor(session,
+ uri2, NULL, NULL, &cursor));
+ cursor->set_key(cursor, uri1);
+ cursor->set_value(cursor, uri2);
+ /*
+ fprintf(stderr, "UPDATE: %s\n", uri2);
+ */
+ testutil_check(cursor->update(cursor));
+ cursor->close(cursor);
+ break;
+ case 4:
+ /* Drop the table. */
+ if (LF_ISSET(SCHEMA_DROP)) {
+ gen_table2_name(uri1, sizeof(uri1), id, threadid,
+ flags);
+ retry_opname = "drop";
+ /*
+ fprintf(stderr, "DROP: %s\n", uri1);
+ */
+ ret = session->drop(session, uri1, NULL);
+ }
+ }
+ /*
+ * XXX
+ * We notice occasional EBUSY errors from
+ * rename or drop, even though neither URI should be
+ * used by any other thread. Report it, and retry.
+ */
+ if (retry_opname != NULL && ret == EBUSY)
+ printf("%s(\"%s\", ....) failed, retrying transaction\n",
+ retry_opname, uri1);
+ else if (ret != 0) {
+ printf("FAIL: %s(\"%s\", ....) returns %d: %s\n",
+ retry_opname, uri1, ret, wiredtiger_strerror(ret));
+ testutil_check(ret);
+ }
+
+ return (ret);
+}
+
+/*
+ * thread_run --
+ * Run a writer thread.
+ */
+static WT_THREAD_RET thread_run(void *)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
+static WT_THREAD_RET
+thread_run(void *arg)
+{
+ WT_CURSOR *cursor, *rev;
+ WT_RAND_STATE rnd;
+ WT_SESSION *session;
+ WT_THREAD_DATA *td;
+ size_t lsize;
+ uint64_t i;
+ uint32_t kvsize, op;
+ int ret;
+ char *buf1, *buf2;
+ char large[LARGE_WRITE_SIZE];
+
+ __wt_random_init(&rnd);
+ lsize = sizeof(large);
+ memset(large, 0, lsize);
+
+ td = (WT_THREAD_DATA *)arg;
+ large_buf(large, lsize, td->id, true);
+
+ testutil_check(td->conn->open_session(td->conn, NULL, NULL, &session));
+ testutil_check(session->open_cursor(session, uri_main, NULL, NULL,
+ &cursor));
+ testutil_check(session->open_cursor(session, uri_rev, NULL, NULL,
+ &rev));
+
+ /*
+ * Split the allocated buffer into two parts, one for
+ * the key, one for the value.
+ */
+ kvsize = td->datasize / 2;
+ buf1 = td->data;
+ buf2 = &td->data[kvsize];
+
+ /*
+ * Continuing writing until we're killed.
+ */
+ printf("Thread %" PRIu32 "\n", td->id);
+ for (i = 0; ; ++i) {
+again:
+ /*
+ if (i > 0 && i % 10000 == 0)
+ printf("Thread %d completed %d entries\n",
+ (int)td->id, (int)i);
+ */
+
+ gen_kv(buf1, kvsize, i, td->id, large, true);
+ gen_kv(buf2, kvsize, i, td->id, large, false);
+
+ testutil_check(session->begin_transaction(session, NULL));
+ cursor->set_key(cursor, buf1);
+ /*
+ * Every 1000th record write a very large value that exceeds the
+ * log buffer size. This forces us to use the unbuffered path.
+ */
+ if (i % 1000 == 0) {
+ cursor->set_value(cursor, large);
+ } else {
+ cursor->set_value(cursor, buf2);
+ }
+ testutil_check(cursor->insert(cursor));
+
+ /*
+ * The reverse table has no very large records.
+ */
+ rev->set_key(rev, buf2);
+ rev->set_value(rev, buf1);
+ testutil_check(rev->insert(rev));
+
+ /*
+ * If we are doing a schema test, generate operations
+ * for additional tables. Each table has a 'lifetime'
+ * of 4 values of the id.
+ */
+ if (F_ISSET(td, SCHEMA_ALL)) {
+ /* Create is implied by any schema operation. */
+ testutil_assert(F_ISSET(td, SCHEMA_CREATE));
+
+ /*
+ * Any or all of the schema operations may be
+ * performed as part of this transaction.
+ * See the comment for schema operation frequency.
+ */
+ ret = 0;
+ for (op = 0; op <= 4 && ret == 0; op++)
+ ret = schema_operation(session, td->id, i, op,
+ td->flags);
+ if (ret == EBUSY) {
+ testutil_check(session->rollback_transaction(
+ session, NULL));
+ sleep(1);
+ goto again;
+ }
+ }
+ testutil_check(session->commit_transaction(session, NULL));
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * fill_db --
+ * The child process creates the database and table, and then creates
+ * worker threads to add data until it is killed by the parent.
+ */
+static void fill_db(uint32_t, uint32_t, const char *, uint32_t)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
+static void
+ fill_db(uint32_t nth, uint32_t datasize, const char *method, uint32_t flags)
+{
+ WT_CONNECTION *conn;
+ WT_SESSION *session;
+ WT_THREAD_DATA *td;
+ wt_thread_t *thr;
+ uint32_t i;
+ char envconf[512];
+
+ thr = dcalloc(nth, sizeof(*thr));
+ td = dcalloc(nth, sizeof(WT_THREAD_DATA));
+ if (chdir(home) != 0)
+ testutil_die(errno, "Child chdir: %s", home);
+ testutil_check(__wt_snprintf(envconf, sizeof(envconf),
+ ENV_CONFIG, method));
+
+ testutil_check(wiredtiger_open(".", NULL, envconf, &conn));
+ testutil_check(conn->open_session(conn, NULL, NULL, &session));
+ testutil_check(session->create(
+ session, uri_main, "key_format=S,value_format=S"));
+ testutil_check(session->create(
+ session, uri_rev, "key_format=S,value_format=S"));
+ /*
+ * Checkpoint to help ensure that at least the main tables
+ * can be opened after recovery.
+ */
+ testutil_check(session->checkpoint(session, NULL));
+ testutil_check(session->close(session, NULL));
+
+ datasize += 1; /* Add an extra byte for string termination */
+ printf("Create %" PRIu32 " writer threads\n", nth);
+ for (i = 0; i < nth; ++i) {
+ td[i].conn = conn;
+ td[i].data = dcalloc(datasize, 1);
+ td[i].datasize = datasize;
+ td[i].id = i;
+ td[i].flags = flags;
+ testutil_check(__wt_thread_create(
+ NULL, &thr[i], thread_run, &td[i]));
+ }
+ printf("Spawned %" PRIu32 " writer threads\n", nth);
+ fflush(stdout);
+ /*
+ * The threads never exit, so the child will just wait here until
+ * it is killed.
+ */
+ for (i = 0; i < nth; ++i) {
+ testutil_check(__wt_thread_join(NULL, &thr[i]));
+ free(td[i].data);
+ }
+ /*
+ * NOTREACHED
+ */
+ free(thr);
+ free(td);
+ exit(EXIT_SUCCESS);
+}
+
+/*
+ * check_kv --
+ * Check that a key exists with a value, or does not exist.
+ */
+static void
+check_kv(WT_CURSOR *cursor, const char *key, const char *value, bool exists)
+{
+ int ret;
+ char *got;
+
+ cursor->set_key(cursor, key);
+ ret = cursor->search(cursor);
+ if ((ret = cursor->search(cursor)) == WT_NOTFOUND) {
+ if (exists) {
+ printf("FAIL: expected rev file to have: %s\n", key);
+ testutil_assert(!exists);
+ }
+ } else {
+ testutil_check(ret);
+ if (!exists) {
+ printf("FAIL: unexpected key in rev file: %s\n", key);
+ testutil_assert(exists);
+ }
+ cursor->get_value(cursor, &got);
+ TEST_STREQ(value, got, "value");
+ }
+}
+
+/*
+ * check_dropped --
+ * Check that the uri has been dropped.
+ */
+static void
+check_dropped(WT_SESSION *session, const char *uri)
+{
+ WT_CURSOR *cursor;
+ int ret;
+
+ ret = session->open_cursor(session, uri, NULL, NULL, &cursor);
+ testutil_assert(ret == WT_NOTFOUND);
+}
+
+/*
+ * check_empty --
+ * Check that the uri exists and is empty.
+ */
+static void
+check_empty(WT_SESSION *session, const char *uri)
+{
+ WT_CURSOR *cursor;
+ int ret;
+
+ testutil_check(session->open_cursor(session, uri, NULL, NULL, &cursor));
+ ret = cursor->next(cursor);
+ testutil_assert(ret == WT_NOTFOUND);
+ testutil_check(cursor->close(cursor));
+}
+
+/*
+ * check_empty --
+ * Check that the uri exists and has one entry.
+ */
+static void
+check_one_entry(WT_SESSION *session, const char *uri, const char *key,
+ const char *value)
+{
+ WT_CURSOR *cursor;
+ int ret;
+ char *gotkey, *gotvalue;
+
+ testutil_check(session->open_cursor(session, uri, NULL, NULL, &cursor));
+ testutil_check(cursor->next(cursor));
+ cursor->get_key(cursor, &gotkey);
+ cursor->get_value(cursor, &gotvalue);
+ testutil_assert(WT_STREQ(key, gotkey));
+ testutil_assert(WT_STREQ(value, gotvalue));
+ ret = cursor->next(cursor);
+ testutil_assert(ret == WT_NOTFOUND);
+ testutil_check(cursor->close(cursor));
+}
+
+/*
+ * check_schema
+ * Check that the database has the expected schema according to the
+ * last id seen for this thread.
+ */
+static void
+check_schema(WT_SESSION *session, uint64_t lastid, uint32_t threadid,
+ uint32_t flags)
+{
+ char uri[50], uri2[50];
+
+ if (!LF_ISSET(SCHEMA_ALL))
+ return;
+
+ if (LF_ISSET(SCHEMA_VERBOSE))
+ fprintf(stderr, "check_schema(%d, thread=%d)\n",
+ (int)lastid, (int)threadid);
+ if (has_schema_operation(lastid, 0)) {
+ /* Create table operation. */
+ gen_table_name(uri, sizeof(uri), lastid, threadid);
+ if (LF_ISSET(SCHEMA_VERBOSE))
+ fprintf(stderr, " create %s\n", uri);
+ if (LF_ISSET(SCHEMA_CREATE_CHECK))
+ check_empty(session, uri);
+ }
+ if (has_schema_operation(lastid, 1)) {
+ /* Insert value operation. */
+ gen_table_name(uri, sizeof(uri), lastid - 1, threadid);
+ if (LF_ISSET(SCHEMA_VERBOSE))
+ fprintf(stderr, " insert %s\n", uri);
+ if (LF_ISSET(SCHEMA_DATA_CHECK))
+ check_one_entry(session, uri, uri, uri);
+ }
+ if (LF_ISSET(SCHEMA_RENAME) && has_schema_operation(lastid, 2)) {
+ /* Table rename operation. */
+ gen_table_name(uri, sizeof(uri), lastid - 2, threadid);
+ gen_table2_name(uri2, sizeof(uri2), lastid - 2, threadid,
+ flags);
+ if (LF_ISSET(SCHEMA_VERBOSE))
+ fprintf(stderr, " rename %s,%s\n", uri, uri2);
+ if (LF_ISSET(SCHEMA_DROP_CHECK))
+ check_dropped(session, uri);
+ if (LF_ISSET(SCHEMA_CREATE_CHECK))
+ check_one_entry(session, uri2, uri, uri);
+ }
+ if (has_schema_operation(lastid, 3)) {
+ /* Value update operation. */
+ gen_table_name(uri, sizeof(uri), lastid - 2, threadid);
+ gen_table2_name(uri2, sizeof(uri2), lastid - 2, threadid,
+ flags);
+ if (LF_ISSET(SCHEMA_VERBOSE))
+ fprintf(stderr, " update %s\n", uri2);
+ if (LF_ISSET(SCHEMA_DATA_CHECK))
+ check_one_entry(session, uri2, uri, uri2);
+ }
+ if (LF_ISSET(SCHEMA_DROP_CHECK) && has_schema_operation(lastid, 4)) {
+ /* Drop table operation. */
+ gen_table2_name(uri2, sizeof(uri2), lastid - 2, threadid,
+ flags);
+ if (LF_ISSET(SCHEMA_VERBOSE))
+ fprintf(stderr, " drop %s\n", uri2);
+ check_dropped(session, uri2);
+ }
+}
+
+/*
+ * check_db --
+ * Make a copy of the database and verify its contents.
+ */
+static bool
+check_db(uint32_t nth, uint32_t datasize, bool directio, uint32_t flags)
+{
+ struct sigaction sa;
+ WT_CONNECTION *conn;
+ WT_CURSOR *cursor, *meta, *rev;
+ WT_SESSION *session;
+ uint64_t gotid, id;
+ uint64_t *lastid;
+ uint32_t gotth, kvsize, th, threadmap;
+ int ret, status;
+ char buf[4096];
+ char *gotkey, *gotvalue, *keybuf, *p;
+ char **large_arr;
+
+ keybuf = dcalloc(datasize, 1);
+ lastid = dcalloc(nth, sizeof(uint64_t));
+
+ large_arr = dcalloc(nth, sizeof(char *));
+ for (th = 0; th < nth; th++) {
+ large_arr[th] = dcalloc(LARGE_WRITE_SIZE, 1);
+ large_buf(large_arr[th], LARGE_WRITE_SIZE, th, true);
+ }
+
+ /*
+ * We make a copy of the directory (possibly using direct IO)
+ * for recovery and checking, and an identical copy that
+ * keeps the state of all files before recovery starts.
+ */
+ testutil_check(__wt_snprintf(buf, sizeof(buf),
+ "H='%s'; C=$H.CHECK; S=$H.SAVE; rm -rf $C $S;"
+ " mkdir $C; for f in `ls $H/`; do "
+ " dd if=$H/$f of=$C/$f bs=4096 %s >/dev/null 2>&1 || exit 1; done;"
+ " cp -pr $C $S",
+ home, directio ? "iflag=direct" : ""));
+ printf(
+ "Copy database home directory using direct I/O to run recovery,\n"
+ "along with a saved 'pre-recovery' copy.\n");
+ printf("Shell command: %s\n", buf);
+
+ /* Temporarily turn off the child handler while running 'system' */
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_DFL;
+ testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
+ if ((status = system(buf)) < 0)
+ testutil_die(status, "system: %s", buf);
+ sa.sa_handler = handler;
+ testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
+
+ testutil_check(__wt_snprintf(buf, sizeof(buf), "%s.CHECK", home));
+
+ printf("Open database, run recovery and verify content\n");
+ testutil_check(wiredtiger_open(buf, NULL, ENV_CONFIG_REC, &conn));
+ testutil_check(conn->open_session(conn, NULL, NULL, &session));
+ testutil_check(session->open_cursor(session, uri_main, NULL, NULL,
+ &cursor));
+ testutil_check(session->open_cursor(session, uri_rev, NULL, NULL,
+ &rev));
+ kvsize = datasize / 2;
+
+ /*
+ * We're most interested in the final records on disk.
+ * Rather than walk all records, we do a quick scan
+ * to find the last complete set of written ids.
+ * Each thread writes each id, along with the thread id,
+ * so they are interleaved. Once we have the neighborhood
+ * where some keys may be missing, we'll back up to do a scan
+ * from that point.
+ */
+#define CHECK_INCR 1000
+ for (id = 0; ; id += CHECK_INCR) {
+ gen_kv(keybuf, kvsize, id, 0, large_arr[0], true);
+ cursor->set_key(cursor, keybuf);
+ if ((ret = cursor->search(cursor)) == WT_NOTFOUND)
+ break;
+ testutil_check(ret);
+ for (th = 1; th < nth; th++) {
+ gen_kv(keybuf, kvsize, id, th, large_arr[th], true);
+ cursor->set_key(cursor, keybuf);
+ if ((ret = cursor->search(cursor)) == WT_NOTFOUND)
+ break;
+ testutil_check(ret);
+ }
+ if (ret == WT_NOTFOUND)
+ break;
+ }
+ if (id < CHECK_INCR * 2)
+ id = 0;
+ else
+ id -= CHECK_INCR * 2;
+
+ printf("starting full scan at %" PRIu64 "\n", id);
+ gen_kv(keybuf, kvsize, id, 0, large_arr[0], true);
+ cursor->set_key(cursor, keybuf);
+ testutil_check(cursor->search(cursor));
+ th = 0;
+
+ /* Keep bitmap of "active" threads. */
+ threadmap = (0x1U << nth) - 1;
+ for (ret = 0; ret != WT_NOTFOUND && threadmap != 0;
+ ret = cursor->next(cursor)) {
+ testutil_check(ret);
+ cursor->get_key(cursor, &gotkey);
+ gotid = (uint64_t)strtol(gotkey, &p, 10);
+ testutil_assert(*p == KEY_SEP[0]);
+ p++;
+ testutil_assert(isxdigit(*p));
+ if (isdigit(*p))
+ gotth = (uint32_t)(*p - '0');
+ else if (*p >= 'a' && *p <= 'f')
+ gotth = (uint32_t)(*p - 'a' + 10);
+ else
+ gotth = (uint32_t)(*p - 'A' + 10);
+ p++;
+ testutil_assert(*p == KEY_SEP[0]);
+ p++;
+
+ /*
+ * See if the expected thread has finished at this point.
+ * If so, remove it from the thread map.
+ */
+ while (gotth != th) {
+ if ((threadmap & (0x1U << th)) != 0) {
+ threadmap &= ~(0x1U << th);
+ lastid[th] = id - 1;
+ /*
+ * Any newly removed value in the main table
+ * should not be present as a key in the
+ * reverse table, since they were
+ * transactionally inserted at the same time.
+ */
+ gen_kv(keybuf, kvsize, id, th, large_arr[th],
+ false);
+ check_kv(rev, keybuf, NULL, false);
+ check_schema(session, id - 1, th, flags);
+ }
+ th = (th + 1) % nth;
+ if (th == 0)
+ id++;
+ }
+ testutil_assert(gotid == id);
+ /*
+ * Check that the key and value fully match.
+ */
+ gen_kv(keybuf, kvsize, id, th, large_arr[th], true);
+ gen_kv(&keybuf[kvsize], kvsize, id, th, large_arr[th], false);
+ cursor->get_value(cursor, &gotvalue);
+ TEST_STREQ(keybuf, gotkey, "main table key");
+
+ /*
+ * Every 1000th record is large.
+ */
+ if (id % 1000 == 0)
+ TEST_STREQ(large_arr[th], gotvalue,
+ "main table large value");
+ else
+ TEST_STREQ(&keybuf[kvsize], gotvalue,
+ "main table value");
+
+ /*
+ * Check the reverse file, with key/value reversed.
+ */
+ check_kv(rev, &keybuf[kvsize], keybuf, true);
+
+ check_schema(session, id, th, flags);
+
+ /* Bump thread number and id to the next expected key. */
+ th = (th + 1) % nth;
+ if (th == 0)
+ id++;
+ }
+ printf("scanned to %" PRIu64 "\n", id);
+
+ if (LF_ISSET(SCHEMA_ALL)) {
+ /*
+ * Check metadata to see if there are any tables
+ * present that shouldn't be there.
+ */
+ testutil_check(session->open_cursor(session, "metadata:", NULL,
+ NULL, &meta));
+ while ((ret = meta->next(meta)) != WT_NOTFOUND) {
+ testutil_check(ret);
+ meta->get_key(meta, &gotkey);
+ /*
+ * Names involved in schema testing are of the form:
+ * table:Axxx-t
+ * table:Bxxx-t
+ * xxx corresponds to the id inserted into the main
+ * table when the table was created, and t corresponds
+ * to the thread id that did this.
+ */
+ if (WT_PREFIX_SKIP(gotkey, "table:") &&
+ (*gotkey == 'A' || *gotkey == 'B')) {
+ gotid = (uint64_t)strtol(gotkey + 1, &p, 10);
+ testutil_assert(*p == '-');
+ th = (uint32_t)strtol(p + 1, &p, 10);
+ testutil_assert(*p == '\0');
+ /*
+ * If table operations are truly
+ * transactional, then there shouldn't
+ * be any extra files that unaccounted for.
+ */
+ if (LF_ISSET(SCHEMA_DROP_CHECK))
+ testutil_assert(gotid == lastid[th]);
+ }
+ }
+ testutil_check(meta->close(meta));
+
+ }
+
+ testutil_check(cursor->close(cursor));
+ testutil_check(rev->close(rev));
+ testutil_check(session->close(session, NULL));
+ testutil_check(conn->close(conn, NULL));
+
+ for (th = 0; th < nth; th++)
+ free(large_arr[th]);
+ free(large_arr);
+ free(keybuf);
+ free(lastid);
+ return (true);
+}
+
+/*
+ * handler --
+ * Child signal handler
+ */
+static void
+handler(int sig)
+{
+ pid_t pid;
+ int status, termsig;
+
+ WT_UNUSED(sig);
+ pid = waitpid(-1, &status, WNOHANG|WUNTRACED);
+ if (pid == 0)
+ return; /* Nothing to wait for. */
+ if (WIFSTOPPED(status))
+ return;
+ if (WIFSIGNALED(status)) {
+ termsig = WTERMSIG(status);
+ if (termsig == SIGCONT || termsig == SIGSTOP)
+ return;
+ printf("Child got signal %d (status = %d, 0x%x)\n",
+ termsig, status, (unsigned int)status);
+#ifdef WCOREDUMP
+ if (WCOREDUMP(status))
+ printf("Child process id=%d created core file\n", pid);
+#endif
+ }
+
+ /*
+ * The core file will indicate why the child exited. Choose EINVAL here.
+ */
+ testutil_die(EINVAL,
+ "Child process %" PRIu64 " abnormally exited, status=%d (0x%x)",
+ (uint64_t)pid, status, status);
+}
+
+/*
+ * has_direct_io --
+ * Check for direct I/O support.
+ */
+static bool
+has_direct_io(void)
+{
+#ifdef O_DIRECT
+ return (true);
+#else
+ return (false);
+#endif
+}
+
+/*
+ * main --
+ * Top level test.
+ */
+int
+main(int argc, char *argv[])
+{
+ struct sigaction sa;
+ struct stat sb;
+ WT_RAND_STATE rnd;
+ pid_t pid;
+ size_t size;
+ uint32_t datasize, flags, i, interval, ncycles, nth, timeout;
+ int ch, status;
+ const char *method, *working_dir;
+ char *arg, *p;
+ char args[1024], buf[1024];
+ bool populate_only, rand_th, rand_time, verify_only;
+
+ (void)testutil_set_progname(argv);
+
+ datasize = DEFAULT_DATA_SIZE;
+ nth = MIN_TH;
+ ncycles = DEFAULT_CYCLES;
+ rand_th = rand_time = true;
+ timeout = MIN_TIME;
+ interval = DEFAULT_INTERVAL;
+ flags = 0;
+ populate_only = verify_only = false;
+ working_dir = "WT_TEST.random-directio";
+ method = "none";
+ pid = 0;
+ WT_CLEAR(args);
+
+ if (!has_direct_io()) {
+ fprintf(stderr, "**** test_random_directio: this system does "
+ "not support direct I/O.\n**** Skipping test.\n");
+ return (EXIT_SUCCESS);
+ }
+ for (i = 0, p = args; i < (uint32_t)argc; i++) {
+ testutil_check(__wt_snprintf_len_set(p,
+ sizeof(args) - (size_t)(p - args), &size, " %s",
+ argv[i]));
+ p += size;
+ }
+ while ((ch = __wt_getopt(progname, argc, argv,
+ "d:h:i:m:n:pS:T:t:v")) != EOF)
+ switch (ch) {
+ case 'd':
+ datasize = (uint32_t)atoi(__wt_optarg);
+ if (datasize > LARGE_WRITE_SIZE ||
+ datasize < MIN_DATA_SIZE) {
+ fprintf(stderr,
+ "-d value is larger than maximum %"
+ PRId32 "\n",
+ LARGE_WRITE_SIZE);
+ return (EXIT_FAILURE);
+ }
+ break;
+ case 'h':
+ working_dir = __wt_optarg;
+ break;
+ case 'i':
+ interval = (uint32_t)atoi(__wt_optarg);
+ break;
+ case 'm':
+ method = __wt_optarg;
+ if (!WT_STREQ(method, "fsync") &&
+ !WT_STREQ(method, "dsync") &&
+ !WT_STREQ(method, "none")) {
+ fprintf(stderr,
+ "-m option requires fsync|dsync|none\n");
+ return (EXIT_FAILURE);
+ }
+ break;
+ case 'n':
+ ncycles = (uint32_t)atoi(__wt_optarg);
+ break;
+ case 'p':
+ populate_only = true;
+ break;
+ case 'S':
+ p = __wt_optarg;
+ while ((arg = strtok_r(p, ",", &p)) != NULL) {
+ if (WT_STREQ(arg, "all"))
+ LF_SET(SCHEMA_ALL);
+ else if (WT_STREQ(arg, "create"))
+ LF_SET(SCHEMA_CREATE);
+ else if (WT_STREQ(arg, "create_check"))
+ LF_SET(SCHEMA_CREATE_CHECK);
+ else if (WT_STREQ(arg, "data_check"))
+ LF_SET(SCHEMA_DATA_CHECK);
+ else if (WT_STREQ(arg, "drop"))
+ LF_SET(SCHEMA_DROP);
+ else if (WT_STREQ(arg, "drop_check"))
+ LF_SET(SCHEMA_DROP_CHECK);
+ else if (WT_STREQ(arg, "none"))
+ flags = 0;
+ else if (WT_STREQ(arg, "rename"))
+ LF_SET(SCHEMA_RENAME);
+ else if (WT_STREQ(arg, "verbose"))
+ LF_SET(SCHEMA_VERBOSE);
+ else {
+ fprintf(stderr,
+ "Unknown -S arg '%s'\n", arg);
+ usage();
+ }
+ }
+ break;
+ case 'T':
+ rand_th = false;
+ nth = (uint32_t)atoi(__wt_optarg);
+ break;
+ case 't':
+ rand_time = false;
+ timeout = (uint32_t)atoi(__wt_optarg);
+ break;
+ case 'v':
+ verify_only = true;
+ break;
+ default:
+ usage();
+ }
+ argc -= __wt_optind;
+ if (argc != 0)
+ usage();
+
+ testutil_work_dir_from_path(home, sizeof(home), working_dir);
+ /*
+ * If the user wants to verify they need to tell us how many threads
+ * there were so we know what records we can expect.
+ */
+ if (verify_only && rand_th) {
+ fprintf(stderr,
+ "Verify option requires specifying number of threads\n");
+ return (EXIT_FAILURE);
+ }
+ if ((LF_ISSET(SCHEMA_RENAME|SCHEMA_DROP|SCHEMA_CREATE_CHECK|
+ SCHEMA_DATA_CHECK) &&
+ !LF_ISSET(SCHEMA_CREATE)) ||
+ (LF_ISSET(SCHEMA_DROP_CHECK) &&
+ !LF_ISSET(SCHEMA_DROP))) {
+ fprintf(stderr, "Schema operations incompatible\n");
+ usage();
+ }
+ printf("CONFIG:%s\n", args);
+ if (!verify_only) {
+ testutil_check(__wt_snprintf(buf, sizeof(buf),
+ "rm -rf %s", home));
+ if ((status = system(buf)) < 0)
+ testutil_die(status, "system: %s", buf);
+ testutil_make_work_dir(home);
+
+ __wt_random_init_seed(NULL, &rnd);
+ if (rand_time) {
+ timeout = __wt_random(&rnd) % MAX_TIME;
+ if (timeout < MIN_TIME)
+ timeout = MIN_TIME;
+ }
+ if (rand_th) {
+ nth = __wt_random(&rnd) % MAX_TH;
+ if (nth < MIN_TH)
+ nth = MIN_TH;
+ }
+ printf("Parent: Create %" PRIu32
+ " threads; sleep %" PRIu32 " seconds\n", nth, timeout);
+
+ if (!populate_only) {
+ /*
+ * Fork a child to insert as many items. We will
+ * then randomly suspend the child, run recovery and
+ * make sure all items we wrote exist after recovery
+ * runs.
+ */
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = handler;
+ testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
+ if ((pid = fork()) < 0)
+ testutil_die(errno, "fork");
+ }
+ if (pid == 0) { /* child, or populate_only */
+ fill_db(nth, datasize, method, flags);
+ return (EXIT_SUCCESS);
+ }
+
+ /* parent */
+ /*
+ * Sleep for the configured amount of time before killing
+ * the child. Start the timeout from the time we notice that
+ * the table has been created. That allows the test to run
+ * correctly on really slow machines.
+ */
+ testutil_check(__wt_snprintf(
+ buf, sizeof(buf), "%s/%s", home, fs_main));
+ while (stat(buf, &sb) != 0 || sb.st_size < 4096)
+ testutil_sleep_wait(1, pid);
+ testutil_sleep_wait(timeout, pid);
+
+ /*
+ * Begin our cycles of suspend, copy, recover.
+ */
+ for (i = 0; i < ncycles; i++) {
+ printf("Beginning cycle %" PRIu32 "/%" PRIu32 "\n",
+ i + 1, ncycles);
+ if (i != 0)
+ testutil_sleep_wait(interval, pid);
+ printf("Suspend child\n");
+ if (kill(pid, SIGSTOP) != 0)
+ testutil_die(errno, "kill");
+ printf("Check DB\n");
+ fflush(stdout);
+ if (!check_db(nth, datasize, true, flags))
+ return (EXIT_FAILURE);
+ if (kill(pid, SIGCONT) != 0)
+ testutil_die(errno, "kill");
+ printf("\n");
+ }
+
+ printf("Kill child\n");
+ sa.sa_handler = SIG_DFL;
+ testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
+ if (kill(pid, SIGKILL) != 0)
+ testutil_die(errno, "kill");
+ if (waitpid(pid, &status, 0) == -1)
+ testutil_die(errno, "waitpid");
+ }
+ if (verify_only && !check_db(nth, datasize, false, flags)) {
+ printf("FAIL\n");
+ return (EXIT_FAILURE);
+ }
+ printf("SUCCESS\n");
+ return (EXIT_SUCCESS);
+}
diff --git a/src/third_party/wiredtiger/test/csuite/random_directio/smoke.sh b/src/third_party/wiredtiger/test/csuite/random_directio/smoke.sh
new file mode 100755
index 00000000000..0ba243bd0f8
--- /dev/null
+++ b/src/third_party/wiredtiger/test/csuite/random_directio/smoke.sh
@@ -0,0 +1,34 @@
+#! /bin/sh
+
+set -e
+
+# Smoke-test random_directio as part of running "make check".
+
+RUN_TEST_CMD="$TEST_WRAPPER ./test_random_directio"
+
+# Disabled for now until we fix issues encountered via the test
+exit 0
+
+# Replace for more complete testing
+#TEST_THREADS="1 5 10"
+TEST_THREADS="5"
+
+# Replace for more complete testing
+#TEST_METHODS="none dsync fsync"
+TEST_METHODS="none"
+
+for threads in $TEST_THREADS; do
+ for method in $TEST_METHODS; do
+ RUN_TEST="$RUN_TEST_CMD -t 5 -m $method"
+ $RUN_TEST -T $threads || exit 1
+ $RUN_TEST -T $threads -S create,drop,verbose || exit 1
+
+ # Here are successively tougher schema tests that do not yet
+ # reliably pass. 'verbose' can be added to any.
+ #$RUN_TEST -T $threads -S create,create_check || exit 1
+ #$RUN_TEST -T $threads -S create,drop,drop_check || exit 1
+ #$RUN_TEST -T $threads -S create,rename || exit 1
+ #$RUN_TEST -T $threads -S create,rename,drop_check || exit 1
+ #$RUN_TEST -T $threads -S all,verbose || exit 1
+ done
+done
diff --git a/src/third_party/wiredtiger/test/utility/misc.c b/src/third_party/wiredtiger/test/utility/misc.c
index d038254c7ea..2cc7ad8a94b 100644
--- a/src/third_party/wiredtiger/test/utility/misc.c
+++ b/src/third_party/wiredtiger/test/utility/misc.c
@@ -27,6 +27,10 @@
*/
#include "test_util.h"
+#ifndef _WIN32
+#include <sys/wait.h>
+#endif
+
void (*custom_die)(void) = NULL;
const char *progname = "program name not set";
@@ -211,6 +215,38 @@ testutil_is_flag_set(const char *flag)
return (enable_long_tests);
}
+#ifndef _WIN32
+/*
+ * testutil_sleep_wait --
+ * Wait for a process up to a number of seconds.
+ */
+void
+testutil_sleep_wait(uint32_t seconds, pid_t pid)
+{
+ pid_t got;
+ int status;
+
+ while (seconds > 0) {
+ if ((got = waitpid(pid, &status, WNOHANG|WUNTRACED)) == pid) {
+ if (WIFEXITED(status))
+ testutil_die(EINVAL,
+ "Child process %" PRIu64 " exited early"
+ " with status %d", (uint64_t)pid,
+ WEXITSTATUS(status));
+ if (WIFSIGNALED(status))
+ testutil_die(EINVAL,
+ "Child process %" PRIu64 " terminated "
+ " with signal %d", (uint64_t)pid,
+ WTERMSIG(status));
+ } else if (got == -1)
+ testutil_die(errno, "waitpid");
+
+ --seconds;
+ sleep(1);
+ }
+}
+#endif
+
/*
* dcalloc --
* Call calloc, dying on failure.
diff --git a/src/third_party/wiredtiger/test/utility/test_util.h b/src/third_party/wiredtiger/test/utility/test_util.h
index 7387615c84b..0f5398c4189 100644
--- a/src/third_party/wiredtiger/test/utility/test_util.h
+++ b/src/third_party/wiredtiger/test/utility/test_util.h
@@ -248,6 +248,9 @@ bool testutil_is_flag_set(const char *);
void testutil_make_work_dir(const char *);
int testutil_parse_opts(int, char * const *, TEST_OPTS *);
void testutil_progress(TEST_OPTS *, const char *);
+#ifndef _WIN32
+void testutil_sleep_wait(uint32_t, pid_t);
+#endif
void testutil_work_dir_from_path(char *, size_t, const char *);
WT_THREAD_RET thread_append(void *);