1 /*-
2  * Copyright (c) 2014-2018 MongoDB, Inc.
3  * Copyright (c) 2008-2014 WiredTiger, Inc.
4  *	All rights reserved.
5  *
6  * See the file LICENSE for redistribution information.
7  */
8 
9 /*
10  * Statistics counters:
11  *
12  * We use an array of statistics structures; threads write different structures
13  * to avoid writing the same cache line and incurring cache coherency overheads,
14  * which can dramatically slow fast and otherwise read-mostly workloads.
15  *
16  * With an 8B statistics value and 64B cache-line alignment, 8 values share the
17  * same cache line. There are collisions when different threads choose the same
18  * statistics structure and update values that live on the cache line. There is
19  * likely some locality however: a thread updating the cursor search statistic
20  * is likely to update other cursor statistics with a chance of hitting already
21  * cached values.
22  *
23  * The actual statistic value must be signed, because one thread might increment
24  * the value in its structure, and then another thread might decrement the same
25  * value in another structure (where the value was initially zero), so the value
26  * in the second thread's slot will go negative.
27  *
28  * When reading a statistics value, the array values are summed and returned to
29  * the caller. The summation is performed without locking, so the value read
30  * may be inconsistent (and might be negative, if increments/decrements race
31  * with the reader).
32  *
33  * Choosing how many structures isn't easy: obviously, a smaller number creates
34  * more conflicts while a larger number uses more memory.
35  *
36  * Ideally, if the application running on the system is CPU-intensive, and using
37  * all CPUs on the system, we want to use the same number of slots as there are
38  * CPUs (because their L1 caches are the units of coherency). However, in
39  * practice we cannot easily determine how many CPUs are actually available to
40  * the application.
41  *
42  * Our next best option is to use the number of threads in the application as a
43  * heuristic for the number of CPUs (presumably, the application architect has
44  * figured out how many CPUs are available). However, inside WiredTiger we don't
45  * know when the application creates its threads.
46  *
47  * For now, we use a fixed number of slots. Ideally, we would approximate the
48  * largest number of cores we expect on any machine where WiredTiger might be
49  * run, however, we don't want to waste that much memory on smaller machines.
50  * As of 2015, machines with more than 24 CPUs are relatively rare.
51  *
52  * Default hash table size; use a prime number of buckets rather than assuming
53  * a good hash (Reference Sedgewick, Algorithms in C, "Hash Functions").
54  */
55 #define	WT_COUNTER_SLOTS	23
56 
57 /*
58  * WT_STATS_SLOT_ID is the thread's slot ID for the array of structures.
59  *
60  * Ideally, we want a slot per CPU, and we want each thread to index the slot
61  * corresponding to the CPU it runs on. Unfortunately, getting the ID of the
62  * current CPU is difficult: some operating systems provide a system call to
63  * acquire a CPU ID, but not all (regardless, making a system call to increment
64  * a statistics value is far too expensive).
65  *
66  * Our second-best option is to use the thread ID. Unfortunately, there is no
67  * portable way to obtain a unique thread ID that's a small-enough number to
68  * be used as an array index (portable thread IDs are usually a pointer or an
69  * opaque chunk, not a simple integer).
70  *
71  * Our solution is to use the session ID; there is normally a session per thread
72  * and the session ID is a small, monotonically increasing number.
73  */
74 #define	WT_STATS_SLOT_ID(session)					\
75 	(((session)->id) % WT_COUNTER_SLOTS)
76 
77 /*
78  * Statistic structures are arrays of int64_t's. We have functions to read/write
79  * those structures regardless of the specific statistic structure we're working
80  * with, by translating statistics structure field names to structure offsets.
81  *
82  * Translate a statistic's value name to an offset in the array.
83  */
84 #define	WT_STATS_FIELD_TO_OFFSET(stats, fld)				\
85 	(int)(&(stats)[0]->fld - (int64_t *)(stats)[0])
86 
87 /* AUTOMATIC FLAG VALUE GENERATION START */
88 #define	WT_STAT_CLEAR		0x01u
89 #define	WT_STAT_JSON		0x02u
90 #define	WT_STAT_ON_CLOSE	0x04u
91 #define	WT_STAT_TYPE_ALL	0x08u
92 #define	WT_STAT_TYPE_CACHE_WALK	0x10u
93 #define	WT_STAT_TYPE_FAST	0x20u
94 #define	WT_STAT_TYPE_SIZE	0x40u
95 #define	WT_STAT_TYPE_TREE_WALK	0x80u
96 /* AUTOMATIC FLAG VALUE GENERATION STOP */
97 
98 /*
99  * Sum the values from all structures in the array.
100  */
101 static inline int64_t
__wt_stats_aggregate(void * stats_arg,int slot)102 __wt_stats_aggregate(void *stats_arg, int slot)
103 {
104 	int64_t **stats, aggr_v;
105 	int i;
106 
107 	stats = stats_arg;
108 	for (aggr_v = 0, i = 0; i < WT_COUNTER_SLOTS; i++)
109 		aggr_v += stats[i][slot];
110 
111 	/*
112 	 * This can race. However, any implementation with a single value can
113 	 * race as well, different threads could set the same counter value
114 	 * simultaneously. While we are making races more likely, we are not
115 	 * fundamentally weakening the isolation semantics found in updating a
116 	 * single value.
117 	 *
118 	 * Additionally, the aggregation can go negative (imagine a thread
119 	 * incrementing a value after aggregation has passed its slot and a
120 	 * second thread decrementing a value before aggregation has reached
121 	 * its slot).
122 	 *
123 	 * For historic API compatibility, the external type is a uint64_t;
124 	 * limit our return to positive values, negative numbers would just
125 	 * look really, really large.
126 	 */
127 	if (aggr_v < 0)
128 		aggr_v = 0;
129 	return (aggr_v);
130 }
131 
132 /*
133  * Clear the values in all structures in the array.
134  */
135 static inline void
__wt_stats_clear(void * stats_arg,int slot)136 __wt_stats_clear(void *stats_arg, int slot)
137 {
138 	int64_t **stats;
139 	int i;
140 
141 	stats = stats_arg;
142 	for (i = 0; i < WT_COUNTER_SLOTS; i++)
143 		stats[i][slot] = 0;
144 }
145 
146 /*
147  * Read/write statistics if statistics gathering is enabled. Reading and
148  * writing the field requires different actions: reading sums the values
149  * across the array of structures, writing updates a single structure's value.
150  */
151 #define	WT_STAT_ENABLED(session) (S2C(session)->stat_flags != 0)
152 
153 #define	WT_STAT_READ(stats, fld)					\
154 	__wt_stats_aggregate(stats, WT_STATS_FIELD_TO_OFFSET(stats, fld))
155 #define	WT_STAT_WRITE(session, stats, fld, v) do {			\
156 	if (WT_STAT_ENABLED(session))					\
157 		(stats)->fld = (int64_t)(v);				\
158 } while (0)
159 
160 #define	WT_STAT_DECRV_BASE(session, stat, fld, value) do {		\
161 	if (WT_STAT_ENABLED(session))					\
162 		(stat)->fld -= (int64_t)(value);			\
163 } while (0)
164 #define	WT_STAT_DECRV_ATOMIC_BASE(session, stat, fld, value) do {	\
165 	if (WT_STAT_ENABLED(session))					\
166 		__wt_atomic_subi64(&(stat)->fld, (int64_t)(value));	\
167 } while (0)
168 #define	WT_STAT_INCRV_BASE(session, stat, fld, value) do {		\
169 	if (WT_STAT_ENABLED(session))					\
170 		(stat)->fld += (int64_t)(value);			\
171 } while (0)
172 #define	WT_STAT_INCRV_ATOMIC_BASE(session, stat, fld, value) do {	\
173 	if (WT_STAT_ENABLED(session))					\
174 		__wt_atomic_addi64(&(stat)->fld, (int64_t)(value));	\
175 } while (0)
176 
177 #define	WT_STAT_DECRV(session, stats, fld, value) do {			\
178 	WT_STAT_DECRV_BASE(						\
179 	    session, (stats)[(session)->stat_bucket], fld, value);	\
180 } while (0)
181 #define	WT_STAT_DECRV_ATOMIC(session, stats, fld, value) do {		\
182 	WT_STAT_DECRV_ATOMIC_BASE(					\
183 	    session, (stats)[(session)->stat_bucket], fld, value);	\
184 } while (0)
185 #define	WT_STAT_DECR(session, stats, fld)				\
186 	WT_STAT_DECRV(session, stats, fld, 1)
187 
188 #define	WT_STAT_INCRV(session, stats, fld, value) do {			\
189 	WT_STAT_INCRV_BASE(						\
190 	    session, (stats)[(session)->stat_bucket], fld, value);	\
191 } while (0)
192 #define	WT_STAT_INCRV_ATOMIC(session, stats, fld, value) do {		\
193 	WT_STAT_INCRV_ATOMIC_BASE(					\
194 	    session, (stats)[(session)->stat_bucket], fld, value);	\
195 } while (0)
196 #define	WT_STAT_INCR(session, stats, fld)				\
197 	WT_STAT_INCRV(session, stats, fld, 1)
198 #define	WT_STAT_SET(session, stats, fld, value) do {			\
199 	if (WT_STAT_ENABLED(session)) {					\
200 		__wt_stats_clear(stats,					\
201 		    WT_STATS_FIELD_TO_OFFSET(stats, fld));		\
202 		(stats)[0]->fld = (int64_t)(value);			\
203 	}								\
204 } while (0)
205 
206 /*
207  * Update connection handle statistics if statistics gathering is enabled.
208  */
209 #define	WT_STAT_CONN_DECRV(session, fld, value)				\
210 	WT_STAT_DECRV_BASE(session,					\
211 	    S2C(session)->stats[(session)->stat_bucket], fld, value)
212 #define	WT_STAT_CONN_DECR_ATOMIC(session, fld)				\
213 	WT_STAT_DECRV_ATOMIC_BASE(session,				\
214 	    S2C(session)->stats[(session)->stat_bucket], fld, 1)
215 #define	WT_STAT_CONN_DECR(session, fld)					\
216 	WT_STAT_CONN_DECRV(session, fld, 1)
217 
218 #define	WT_STAT_CONN_INCRV(session, fld, value)				\
219 	WT_STAT_INCRV_BASE(session,					\
220 	    S2C(session)->stats[(session)->stat_bucket], fld, value)
221 #define	WT_STAT_CONN_INCR_ATOMIC(session, fld)				\
222 	WT_STAT_INCRV_ATOMIC_BASE(session,				\
223 	    S2C(session)->stats[(session)->stat_bucket], fld, 1)
224 #define	WT_STAT_CONN_INCR(session, fld)					\
225 	WT_STAT_CONN_INCRV(session, fld, 1)
226 
227 #define	WT_STAT_CONN_SET(session, fld, value)				\
228 	WT_STAT_SET(session, S2C(session)->stats, fld, value)
229 
230 /*
231  * Update data-source handle statistics if statistics gathering is enabled
232  * and the data-source handle is set.
233  *
234  * XXX
235  * We shouldn't have to check if the data-source handle is NULL, but it's
236  * necessary until everything is converted to using data-source handles.
237  */
238 #define	WT_STAT_DATA_DECRV(session, fld, value) do {			\
239 	if ((session)->dhandle != NULL &&				\
240 	    (session)->dhandle->stat_array != NULL)			\
241 		WT_STAT_DECRV(						\
242 		    session, (session)->dhandle->stats, fld, value);	\
243 } while (0)
244 #define	WT_STAT_DATA_DECR(session, fld)					\
245 	WT_STAT_DATA_DECRV(session, fld, 1)
246 #define	WT_STAT_DATA_INCRV(session, fld, value) do {			\
247 	if ((session)->dhandle != NULL &&				\
248 	    (session)->dhandle->stat_array != NULL)			\
249 		WT_STAT_INCRV(						\
250 		    session, (session)->dhandle->stats, fld, value);	\
251 } while (0)
252 #define	WT_STAT_DATA_INCR(session, fld)					\
253 	WT_STAT_DATA_INCRV(session, fld, 1)
254 #define	WT_STAT_DATA_SET(session, fld, value) do {			\
255 	if ((session)->dhandle != NULL &&				\
256 	    (session)->dhandle->stat_array != NULL)			\
257 		WT_STAT_SET(						\
258 		    session, (session)->dhandle->stats, fld, value);	\
259 } while (0)
260 
261 /*
262  * Construct histogram increment functions to put the passed value into the
263  * right bucket. Bucket ranges, represented by various statistics, depend upon
264  * whether the passed value is in milliseconds or microseconds.  Also values
265  * less than a given minimum are ignored and not put in any bucket.  This floor
266  * value keeps us from having an excessively large smallest values.
267  */
268 #define	WT_STAT_MSECS_HIST_INCR_FUNC(name, stat, min_val)		\
269 static inline void							\
270 __wt_stat_msecs_hist_incr_##name(WT_SESSION_IMPL *session, uint64_t msecs) \
271 {									\
272 	if (msecs < (min_val))						\
273 		return;							\
274 	if (msecs < 50)							\
275 		WT_STAT_CONN_INCR(session, stat##_lt50);		\
276 	else if (msecs < 100)						\
277 		WT_STAT_CONN_INCR(session, stat##_lt100);		\
278 	else if (msecs < 250)						\
279 		WT_STAT_CONN_INCR(session, stat##_lt250);		\
280 	else if (msecs < 500)						\
281 		WT_STAT_CONN_INCR(session, stat##_lt500);		\
282 	else if (msecs < 1000)						\
283 		WT_STAT_CONN_INCR(session, stat##_lt1000);		\
284 	else								\
285 		WT_STAT_CONN_INCR(session, stat##_gt1000);		\
286 }
287 
288 #define	WT_STAT_USECS_HIST_INCR_FUNC(name, stat, min_val)		\
289 static inline void							\
290 __wt_stat_usecs_hist_incr_##name(WT_SESSION_IMPL *session, uint64_t usecs) \
291 {									\
292 	if (usecs < (min_val))						\
293 		return;							\
294 	if (usecs < 250)						\
295 		WT_STAT_CONN_INCR(session, stat##_lt250);		\
296 	else if (usecs < 500)						\
297 		WT_STAT_CONN_INCR(session, stat##_lt500);		\
298 	else if (usecs < 1000)						\
299 		WT_STAT_CONN_INCR(session, stat##_lt1000);		\
300 	else if (usecs < 10000)						\
301 		WT_STAT_CONN_INCR(session, stat##_lt10000);		\
302 	else								\
303 		WT_STAT_CONN_INCR(session, stat##_gt10000);		\
304 }
305 
306 /*
307  * DO NOT EDIT: automatically built by dist/stat.py.
308  */
309 /* Statistics section: BEGIN */
310 
311 /*
312  * Statistics entries for connections.
313  */
314 #define	WT_CONNECTION_STATS_BASE	1000
315 struct __wt_connection_stats {
316 	int64_t lsm_work_queue_app;
317 	int64_t lsm_work_queue_manager;
318 	int64_t lsm_rows_merged;
319 	int64_t lsm_checkpoint_throttle;
320 	int64_t lsm_merge_throttle;
321 	int64_t lsm_work_queue_switch;
322 	int64_t lsm_work_units_discarded;
323 	int64_t lsm_work_units_done;
324 	int64_t lsm_work_units_created;
325 	int64_t lsm_work_queue_max;
326 	int64_t async_cur_queue;
327 	int64_t async_max_queue;
328 	int64_t async_alloc_race;
329 	int64_t async_flush;
330 	int64_t async_alloc_view;
331 	int64_t async_full;
332 	int64_t async_nowork;
333 	int64_t async_op_alloc;
334 	int64_t async_op_compact;
335 	int64_t async_op_insert;
336 	int64_t async_op_remove;
337 	int64_t async_op_search;
338 	int64_t async_op_update;
339 	int64_t block_preload;
340 	int64_t block_read;
341 	int64_t block_write;
342 	int64_t block_byte_read;
343 	int64_t block_byte_write;
344 	int64_t block_byte_write_checkpoint;
345 	int64_t block_map_read;
346 	int64_t block_byte_map_read;
347 	int64_t cache_read_app_count;
348 	int64_t cache_read_app_time;
349 	int64_t cache_write_app_count;
350 	int64_t cache_write_app_time;
351 	int64_t cache_bytes_image;
352 	int64_t cache_bytes_lookaside;
353 	int64_t cache_bytes_inuse;
354 	int64_t cache_bytes_other;
355 	int64_t cache_bytes_read;
356 	int64_t cache_bytes_write;
357 	int64_t cache_lookaside_cursor_wait_application;
358 	int64_t cache_lookaside_cursor_wait_internal;
359 	int64_t cache_lookaside_score;
360 	int64_t cache_lookaside_entries;
361 	int64_t cache_lookaside_insert;
362 	int64_t cache_lookaside_ondisk_max;
363 	int64_t cache_lookaside_ondisk;
364 	int64_t cache_lookaside_remove;
365 	int64_t cache_eviction_checkpoint;
366 	int64_t cache_eviction_get_ref;
367 	int64_t cache_eviction_get_ref_empty;
368 	int64_t cache_eviction_get_ref_empty2;
369 	int64_t cache_eviction_aggressive_set;
370 	int64_t cache_eviction_empty_score;
371 	int64_t cache_eviction_walk_passes;
372 	int64_t cache_eviction_queue_empty;
373 	int64_t cache_eviction_queue_not_empty;
374 	int64_t cache_eviction_server_evicting;
375 	int64_t cache_eviction_server_slept;
376 	int64_t cache_eviction_slow;
377 	int64_t cache_eviction_state;
378 	int64_t cache_eviction_target_page_lt10;
379 	int64_t cache_eviction_target_page_lt32;
380 	int64_t cache_eviction_target_page_ge128;
381 	int64_t cache_eviction_target_page_lt64;
382 	int64_t cache_eviction_target_page_lt128;
383 	int64_t cache_eviction_walks_abandoned;
384 	int64_t cache_eviction_walks_stopped;
385 	int64_t cache_eviction_walks_gave_up_no_targets;
386 	int64_t cache_eviction_walks_gave_up_ratio;
387 	int64_t cache_eviction_walks_ended;
388 	int64_t cache_eviction_walk_from_root;
389 	int64_t cache_eviction_walk_saved_pos;
390 	int64_t cache_eviction_active_workers;
391 	int64_t cache_eviction_worker_created;
392 	int64_t cache_eviction_worker_evicting;
393 	int64_t cache_eviction_worker_removed;
394 	int64_t cache_eviction_stable_state_workers;
395 	int64_t cache_eviction_force_fail;
396 	int64_t cache_eviction_force_fail_time;
397 	int64_t cache_eviction_walks_active;
398 	int64_t cache_eviction_walks_started;
399 	int64_t cache_eviction_force_retune;
400 	int64_t cache_eviction_hazard;
401 	int64_t cache_hazard_checks;
402 	int64_t cache_hazard_walks;
403 	int64_t cache_hazard_max;
404 	int64_t cache_inmem_splittable;
405 	int64_t cache_inmem_split;
406 	int64_t cache_eviction_internal;
407 	int64_t cache_eviction_split_internal;
408 	int64_t cache_eviction_split_leaf;
409 	int64_t cache_bytes_max;
410 	int64_t cache_eviction_maximum_page_size;
411 	int64_t cache_eviction_dirty;
412 	int64_t cache_eviction_app_dirty;
413 	int64_t cache_timed_out_ops;
414 	int64_t cache_read_overflow;
415 	int64_t cache_eviction_deepen;
416 	int64_t cache_write_lookaside;
417 	int64_t cache_pages_inuse;
418 	int64_t cache_eviction_force;
419 	int64_t cache_eviction_force_time;
420 	int64_t cache_eviction_force_delete;
421 	int64_t cache_eviction_force_delete_time;
422 	int64_t cache_eviction_app;
423 	int64_t cache_eviction_pages_queued;
424 	int64_t cache_eviction_pages_queued_urgent;
425 	int64_t cache_eviction_pages_queued_oldest;
426 	int64_t cache_read;
427 	int64_t cache_read_deleted;
428 	int64_t cache_read_deleted_prepared;
429 	int64_t cache_read_lookaside;
430 	int64_t cache_read_lookaside_checkpoint;
431 	int64_t cache_read_lookaside_skipped;
432 	int64_t cache_read_lookaside_delay;
433 	int64_t cache_read_lookaside_delay_checkpoint;
434 	int64_t cache_pages_requested;
435 	int64_t cache_eviction_pages_seen;
436 	int64_t cache_eviction_fail;
437 	int64_t cache_eviction_walk;
438 	int64_t cache_write;
439 	int64_t cache_write_restore;
440 	int64_t cache_overhead;
441 	int64_t cache_bytes_internal;
442 	int64_t cache_bytes_leaf;
443 	int64_t cache_bytes_dirty;
444 	int64_t cache_pages_dirty;
445 	int64_t cache_eviction_clean;
446 	int64_t cond_auto_wait_reset;
447 	int64_t cond_auto_wait;
448 	int64_t time_travel;
449 	int64_t file_open;
450 	int64_t memory_allocation;
451 	int64_t memory_free;
452 	int64_t memory_grow;
453 	int64_t cond_wait;
454 	int64_t rwlock_read;
455 	int64_t rwlock_write;
456 	int64_t fsync_io;
457 	int64_t read_io;
458 	int64_t write_io;
459 	int64_t cursor_cached_count;
460 	int64_t cursor_cache;
461 	int64_t cursor_create;
462 	int64_t cursor_insert;
463 	int64_t cursor_modify;
464 	int64_t cursor_next;
465 	int64_t cursor_restart;
466 	int64_t cursor_prev;
467 	int64_t cursor_remove;
468 	int64_t cursor_reserve;
469 	int64_t cursor_reset;
470 	int64_t cursor_search;
471 	int64_t cursor_search_near;
472 	int64_t cursor_sweep_buckets;
473 	int64_t cursor_sweep_closed;
474 	int64_t cursor_sweep_examined;
475 	int64_t cursor_sweep;
476 	int64_t cursor_update;
477 	int64_t cursor_reopen;
478 	int64_t cursor_open_count;
479 	int64_t cursor_truncate;
480 	int64_t dh_conn_handle_count;
481 	int64_t dh_sweep_ref;
482 	int64_t dh_sweep_close;
483 	int64_t dh_sweep_remove;
484 	int64_t dh_sweep_tod;
485 	int64_t dh_sweeps;
486 	int64_t dh_session_handles;
487 	int64_t dh_session_sweeps;
488 	int64_t lock_checkpoint_count;
489 	int64_t lock_checkpoint_wait_application;
490 	int64_t lock_checkpoint_wait_internal;
491 	int64_t lock_commit_timestamp_wait_application;
492 	int64_t lock_commit_timestamp_wait_internal;
493 	int64_t lock_commit_timestamp_read_count;
494 	int64_t lock_commit_timestamp_write_count;
495 	int64_t lock_dhandle_wait_application;
496 	int64_t lock_dhandle_wait_internal;
497 	int64_t lock_dhandle_read_count;
498 	int64_t lock_dhandle_write_count;
499 	int64_t lock_metadata_count;
500 	int64_t lock_metadata_wait_application;
501 	int64_t lock_metadata_wait_internal;
502 	int64_t lock_read_timestamp_wait_application;
503 	int64_t lock_read_timestamp_wait_internal;
504 	int64_t lock_read_timestamp_read_count;
505 	int64_t lock_read_timestamp_write_count;
506 	int64_t lock_schema_count;
507 	int64_t lock_schema_wait_application;
508 	int64_t lock_schema_wait_internal;
509 	int64_t lock_table_wait_application;
510 	int64_t lock_table_wait_internal;
511 	int64_t lock_table_read_count;
512 	int64_t lock_table_write_count;
513 	int64_t lock_txn_global_wait_application;
514 	int64_t lock_txn_global_wait_internal;
515 	int64_t lock_txn_global_read_count;
516 	int64_t lock_txn_global_write_count;
517 	int64_t log_slot_switch_busy;
518 	int64_t log_force_archive_sleep;
519 	int64_t log_bytes_payload;
520 	int64_t log_bytes_written;
521 	int64_t log_zero_fills;
522 	int64_t log_flush;
523 	int64_t log_force_write;
524 	int64_t log_force_write_skip;
525 	int64_t log_compress_writes;
526 	int64_t log_compress_write_fails;
527 	int64_t log_compress_small;
528 	int64_t log_release_write_lsn;
529 	int64_t log_scans;
530 	int64_t log_scan_rereads;
531 	int64_t log_write_lsn;
532 	int64_t log_write_lsn_skip;
533 	int64_t log_sync;
534 	int64_t log_sync_duration;
535 	int64_t log_sync_dir;
536 	int64_t log_sync_dir_duration;
537 	int64_t log_writes;
538 	int64_t log_slot_consolidated;
539 	int64_t log_max_filesize;
540 	int64_t log_prealloc_max;
541 	int64_t log_prealloc_missed;
542 	int64_t log_prealloc_files;
543 	int64_t log_prealloc_used;
544 	int64_t log_scan_records;
545 	int64_t log_slot_close_race;
546 	int64_t log_slot_close_unbuf;
547 	int64_t log_slot_closes;
548 	int64_t log_slot_races;
549 	int64_t log_slot_yield_race;
550 	int64_t log_slot_immediate;
551 	int64_t log_slot_yield_close;
552 	int64_t log_slot_yield_sleep;
553 	int64_t log_slot_yield;
554 	int64_t log_slot_active_closed;
555 	int64_t log_slot_yield_duration;
556 	int64_t log_slot_no_free_slots;
557 	int64_t log_slot_unbuffered;
558 	int64_t log_compress_mem;
559 	int64_t log_buffer_size;
560 	int64_t log_compress_len;
561 	int64_t log_slot_coalesced;
562 	int64_t log_close_yields;
563 	int64_t perf_hist_fsread_latency_lt50;
564 	int64_t perf_hist_fsread_latency_lt100;
565 	int64_t perf_hist_fsread_latency_lt250;
566 	int64_t perf_hist_fsread_latency_lt500;
567 	int64_t perf_hist_fsread_latency_lt1000;
568 	int64_t perf_hist_fsread_latency_gt1000;
569 	int64_t perf_hist_fswrite_latency_lt50;
570 	int64_t perf_hist_fswrite_latency_lt100;
571 	int64_t perf_hist_fswrite_latency_lt250;
572 	int64_t perf_hist_fswrite_latency_lt500;
573 	int64_t perf_hist_fswrite_latency_lt1000;
574 	int64_t perf_hist_fswrite_latency_gt1000;
575 	int64_t perf_hist_opread_latency_lt250;
576 	int64_t perf_hist_opread_latency_lt500;
577 	int64_t perf_hist_opread_latency_lt1000;
578 	int64_t perf_hist_opread_latency_lt10000;
579 	int64_t perf_hist_opread_latency_gt10000;
580 	int64_t perf_hist_opwrite_latency_lt250;
581 	int64_t perf_hist_opwrite_latency_lt500;
582 	int64_t perf_hist_opwrite_latency_lt1000;
583 	int64_t perf_hist_opwrite_latency_lt10000;
584 	int64_t perf_hist_opwrite_latency_gt10000;
585 	int64_t rec_page_delete_fast;
586 	int64_t rec_pages;
587 	int64_t rec_pages_eviction;
588 	int64_t rec_page_delete;
589 	int64_t rec_split_stashed_bytes;
590 	int64_t rec_split_stashed_objects;
591 	int64_t session_open;
592 	int64_t session_query_ts;
593 	int64_t session_table_alter_fail;
594 	int64_t session_table_alter_success;
595 	int64_t session_table_alter_skip;
596 	int64_t session_table_compact_fail;
597 	int64_t session_table_compact_success;
598 	int64_t session_table_create_fail;
599 	int64_t session_table_create_success;
600 	int64_t session_table_drop_fail;
601 	int64_t session_table_drop_success;
602 	int64_t session_table_rebalance_fail;
603 	int64_t session_table_rebalance_success;
604 	int64_t session_table_rename_fail;
605 	int64_t session_table_rename_success;
606 	int64_t session_table_salvage_fail;
607 	int64_t session_table_salvage_success;
608 	int64_t session_table_truncate_fail;
609 	int64_t session_table_truncate_success;
610 	int64_t session_table_verify_fail;
611 	int64_t session_table_verify_success;
612 	int64_t thread_fsync_active;
613 	int64_t thread_read_active;
614 	int64_t thread_write_active;
615 	int64_t application_evict_time;
616 	int64_t application_cache_time;
617 	int64_t txn_release_blocked;
618 	int64_t conn_close_blocked_lsm;
619 	int64_t dhandle_lock_blocked;
620 	int64_t page_index_slot_ref_blocked;
621 	int64_t log_server_sync_blocked;
622 	int64_t prepared_transition_blocked_page;
623 	int64_t page_busy_blocked;
624 	int64_t page_forcible_evict_blocked;
625 	int64_t page_locked_blocked;
626 	int64_t page_read_blocked;
627 	int64_t page_sleep;
628 	int64_t page_del_rollback_blocked;
629 	int64_t child_modify_blocked_page;
630 	int64_t txn_commit_queue_walked;
631 	int64_t txn_commit_queue_empty;
632 	int64_t txn_commit_queue_head;
633 	int64_t txn_commit_queue_inserts;
634 	int64_t txn_commit_queue_len;
635 	int64_t txn_snapshots_created;
636 	int64_t txn_snapshots_dropped;
637 	int64_t txn_prepare;
638 	int64_t txn_prepare_commit;
639 	int64_t txn_prepare_active;
640 	int64_t txn_prepare_rollback;
641 	int64_t txn_query_ts;
642 	int64_t txn_read_queue_walked;
643 	int64_t txn_read_queue_empty;
644 	int64_t txn_read_queue_head;
645 	int64_t txn_read_queue_inserts;
646 	int64_t txn_read_queue_len;
647 	int64_t txn_rollback_to_stable;
648 	int64_t txn_rollback_upd_aborted;
649 	int64_t txn_rollback_las_removed;
650 	int64_t txn_set_ts;
651 	int64_t txn_set_ts_commit;
652 	int64_t txn_set_ts_commit_upd;
653 	int64_t txn_set_ts_oldest;
654 	int64_t txn_set_ts_oldest_upd;
655 	int64_t txn_set_ts_stable;
656 	int64_t txn_set_ts_stable_upd;
657 	int64_t txn_begin;
658 	int64_t txn_checkpoint_running;
659 	int64_t txn_checkpoint_generation;
660 	int64_t txn_checkpoint_time_max;
661 	int64_t txn_checkpoint_time_min;
662 	int64_t txn_checkpoint_time_recent;
663 	int64_t txn_checkpoint_scrub_target;
664 	int64_t txn_checkpoint_scrub_time;
665 	int64_t txn_checkpoint_time_total;
666 	int64_t txn_checkpoint;
667 	int64_t txn_checkpoint_skipped;
668 	int64_t txn_fail_cache;
669 	int64_t txn_checkpoint_fsync_post;
670 	int64_t txn_checkpoint_fsync_post_duration;
671 	int64_t txn_pinned_range;
672 	int64_t txn_pinned_checkpoint_range;
673 	int64_t txn_pinned_snapshot_range;
674 	int64_t txn_pinned_timestamp;
675 	int64_t txn_pinned_timestamp_checkpoint;
676 	int64_t txn_pinned_timestamp_oldest;
677 	int64_t txn_sync;
678 	int64_t txn_commit;
679 	int64_t txn_rollback;
680 	int64_t txn_update_conflict;
681 };
682 
683 /*
684  * Statistics entries for data sources.
685  */
686 #define	WT_DSRC_STATS_BASE	2000
687 struct __wt_dsrc_stats {
688 	int64_t bloom_false_positive;
689 	int64_t bloom_hit;
690 	int64_t bloom_miss;
691 	int64_t bloom_page_evict;
692 	int64_t bloom_page_read;
693 	int64_t bloom_count;
694 	int64_t lsm_chunk_count;
695 	int64_t lsm_generation_max;
696 	int64_t lsm_lookup_no_bloom;
697 	int64_t lsm_checkpoint_throttle;
698 	int64_t lsm_merge_throttle;
699 	int64_t bloom_size;
700 	int64_t block_extension;
701 	int64_t block_alloc;
702 	int64_t block_free;
703 	int64_t block_checkpoint_size;
704 	int64_t allocation_size;
705 	int64_t block_reuse_bytes;
706 	int64_t block_magic;
707 	int64_t block_major;
708 	int64_t block_size;
709 	int64_t block_minor;
710 	int64_t btree_checkpoint_generation;
711 	int64_t btree_column_fix;
712 	int64_t btree_column_internal;
713 	int64_t btree_column_rle;
714 	int64_t btree_column_deleted;
715 	int64_t btree_column_variable;
716 	int64_t btree_fixed_len;
717 	int64_t btree_maxintlkey;
718 	int64_t btree_maxintlpage;
719 	int64_t btree_maxleafkey;
720 	int64_t btree_maxleafpage;
721 	int64_t btree_maxleafvalue;
722 	int64_t btree_maximum_depth;
723 	int64_t btree_entries;
724 	int64_t btree_overflow;
725 	int64_t btree_compact_rewrite;
726 	int64_t btree_row_internal;
727 	int64_t btree_row_leaf;
728 	int64_t cache_bytes_inuse;
729 	int64_t cache_bytes_read;
730 	int64_t cache_bytes_write;
731 	int64_t cache_eviction_checkpoint;
732 	int64_t cache_eviction_fail;
733 	int64_t cache_eviction_walk_passes;
734 	int64_t cache_eviction_target_page_lt10;
735 	int64_t cache_eviction_target_page_lt32;
736 	int64_t cache_eviction_target_page_ge128;
737 	int64_t cache_eviction_target_page_lt64;
738 	int64_t cache_eviction_target_page_lt128;
739 	int64_t cache_eviction_walks_abandoned;
740 	int64_t cache_eviction_walks_stopped;
741 	int64_t cache_eviction_walks_gave_up_no_targets;
742 	int64_t cache_eviction_walks_gave_up_ratio;
743 	int64_t cache_eviction_walks_ended;
744 	int64_t cache_eviction_walk_from_root;
745 	int64_t cache_eviction_walk_saved_pos;
746 	int64_t cache_eviction_hazard;
747 	int64_t cache_inmem_splittable;
748 	int64_t cache_inmem_split;
749 	int64_t cache_eviction_internal;
750 	int64_t cache_eviction_split_internal;
751 	int64_t cache_eviction_split_leaf;
752 	int64_t cache_eviction_dirty;
753 	int64_t cache_read_overflow;
754 	int64_t cache_eviction_deepen;
755 	int64_t cache_write_lookaside;
756 	int64_t cache_read;
757 	int64_t cache_read_deleted;
758 	int64_t cache_read_deleted_prepared;
759 	int64_t cache_read_lookaside;
760 	int64_t cache_pages_requested;
761 	int64_t cache_eviction_pages_seen;
762 	int64_t cache_write;
763 	int64_t cache_write_restore;
764 	int64_t cache_bytes_dirty;
765 	int64_t cache_eviction_clean;
766 	int64_t cache_state_gen_avg_gap;
767 	int64_t cache_state_avg_written_size;
768 	int64_t cache_state_avg_visited_age;
769 	int64_t cache_state_avg_unvisited_age;
770 	int64_t cache_state_pages_clean;
771 	int64_t cache_state_gen_current;
772 	int64_t cache_state_pages_dirty;
773 	int64_t cache_state_root_entries;
774 	int64_t cache_state_pages_internal;
775 	int64_t cache_state_pages_leaf;
776 	int64_t cache_state_gen_max_gap;
777 	int64_t cache_state_max_pagesize;
778 	int64_t cache_state_min_written_size;
779 	int64_t cache_state_unvisited_count;
780 	int64_t cache_state_smaller_alloc_size;
781 	int64_t cache_state_memory;
782 	int64_t cache_state_queued;
783 	int64_t cache_state_not_queueable;
784 	int64_t cache_state_refs_skipped;
785 	int64_t cache_state_root_size;
786 	int64_t cache_state_pages;
787 	int64_t compress_read;
788 	int64_t compress_write;
789 	int64_t compress_write_fail;
790 	int64_t compress_write_too_small;
791 	int64_t compress_raw_fail_temporary;
792 	int64_t compress_raw_fail;
793 	int64_t compress_raw_ok;
794 	int64_t cursor_insert_bulk;
795 	int64_t cursor_cache;
796 	int64_t cursor_create;
797 	int64_t cursor_restart;
798 	int64_t cursor_insert_bytes;
799 	int64_t cursor_remove_bytes;
800 	int64_t cursor_update_bytes;
801 	int64_t cursor_reopen;
802 	int64_t cursor_insert;
803 	int64_t cursor_modify;
804 	int64_t cursor_next;
805 	int64_t cursor_open_count;
806 	int64_t cursor_prev;
807 	int64_t cursor_remove;
808 	int64_t cursor_reserve;
809 	int64_t cursor_reset;
810 	int64_t cursor_search;
811 	int64_t cursor_search_near;
812 	int64_t cursor_truncate;
813 	int64_t cursor_update;
814 	int64_t rec_dictionary;
815 	int64_t rec_page_delete_fast;
816 	int64_t rec_suffix_compression;
817 	int64_t rec_multiblock_internal;
818 	int64_t rec_overflow_key_internal;
819 	int64_t rec_prefix_compression;
820 	int64_t rec_multiblock_leaf;
821 	int64_t rec_overflow_key_leaf;
822 	int64_t rec_multiblock_max;
823 	int64_t rec_overflow_value;
824 	int64_t rec_page_match;
825 	int64_t rec_pages;
826 	int64_t rec_pages_eviction;
827 	int64_t rec_page_delete;
828 	int64_t session_compact;
829 	int64_t txn_update_conflict;
830 };
831 
832 /*
833  * Statistics entries for join cursors.
834  */
835 #define	WT_JOIN_STATS_BASE	3000
836 struct __wt_join_stats {
837 	int64_t main_access;
838 	int64_t bloom_false_positive;
839 	int64_t membership_check;
840 	int64_t bloom_insert;
841 	int64_t iterated;
842 };
843 
844 /* Statistics section: END */
845