diff options
author | Luke Chen <luke.chen@mongodb.com> | 2018-09-18 14:21:02 +1000 |
---|---|---|
committer | Luke Chen <luke.chen@mongodb.com> | 2018-09-18 14:21:02 +1000 |
commit | 4253bfb1bbda2429cb8d59a316a0bd10f6473504 (patch) | |
tree | 7011e15691ff64693fec9c22ef291712c1946f35 | |
parent | 590fdc69d78ecbca005381781a9e520bd023a43d (diff) | |
download | mongo-4253bfb1bbda2429cb8d59a316a0bd10f6473504.tar.gz |
Import wiredtiger: 7db12ec1b5b1843364ae28248b0680b816aab651 from branch mongodb-4.2
ref: 45fd19bcb1..7db12ec1b5
for: 4.1.4
WT-3736 Add statistics to measure contention on lookaside cursor
WT-4185 Don't remove all lookaside entries when reading a page
WT-4225 Automate a backup test that simulates volume snapshot via dd
WT-4308 Insert split during sync should not free blocks
WT-4321 Disable the random direct I/O test
WT-4325 Add a WiredTiger-local version of the qsort(3) call
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 *); |