1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3 #ident "$Id$"
4 /*======
5 This file is part of PerconaFT.
6 
7 
8 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9 
10     PerconaFT is free software: you can redistribute it and/or modify
11     it under the terms of the GNU General Public License, version 2,
12     as published by the Free Software Foundation.
13 
14     PerconaFT is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18 
19     You should have received a copy of the GNU General Public License
20     along with PerconaFT.  If not, see <http://www.gnu.org/licenses/>.
21 
22 ----------------------------------------
23 
24     PerconaFT is free software: you can redistribute it and/or modify
25     it under the terms of the GNU Affero General Public License, version 3,
26     as published by the Free Software Foundation.
27 
28     PerconaFT is distributed in the hope that it will be useful,
29     but WITHOUT ANY WARRANTY; without even the implied warranty of
30     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31     GNU Affero General Public License for more details.
32 
33     You should have received a copy of the GNU Affero General Public License
34     along with PerconaFT.  If not, see <http://www.gnu.org/licenses/>.
35 
36 ----------------------------------------
37 
38    Licensed under the Apache License, Version 2.0 (the "License");
39    you may not use this file except in compliance with the License.
40    You may obtain a copy of the License at
41 
42        http://www.apache.org/licenses/LICENSE-2.0
43 
44    Unless required by applicable law or agreed to in writing, software
45    distributed under the License is distributed on an "AS IS" BASIS,
46    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47    See the License for the specific language governing permissions and
48    limitations under the License.
49 ======= */
50 
51 #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
52 
53 #pragma once
54 
55 #include <db.h>
56 
57 #include "portability/toku_config.h"
58 #include "portability/toku_list.h"
59 #include "portability/toku_race_tools.h"
60 
61 #include "util/status.h"
62 
63 //
64 // Leaf Entry statistics
65 //
66 class LE_STATUS_S {
67 public:
68     enum {
69         LE_MAX_COMMITTED_XR = 0,
70         LE_MAX_PROVISIONAL_XR,
71         LE_EXPANDED,
72         LE_MAX_MEMSIZE,
73         LE_APPLY_GC_BYTES_IN,
74         LE_APPLY_GC_BYTES_OUT,
75         LE_NORMAL_GC_BYTES_IN,
76         LE_NORMAL_GC_BYTES_OUT,
77         LE_STATUS_NUM_ROWS
78     };
79 
80     void init();
81     void destroy();
82 
83     TOKU_ENGINE_STATUS_ROW_S status[LE_STATUS_NUM_ROWS];
84 
85 private:
86     bool m_initialized;
87 };
88 typedef LE_STATUS_S* LE_STATUS;
89 extern LE_STATUS_S le_status;
90 
91 // executed too often to be worth making threadsafe
92 #define LE_STATUS_VAL(x) le_status.status[LE_STATUS_S::x].value.num
93 #define LE_STATUS_INC(x, d)                                                         \
94     do {                                                                            \
95         if (le_status.status[LE_STATUS_S::x].type == PARCOUNT) {                                 \
96             increment_partitioned_counter(le_status.status[LE_STATUS_S::x].value.parcount, d);   \
97         } else {                                                                    \
98             toku_sync_fetch_and_add(&le_status.status[LE_STATUS_S::x].value.num, d);             \
99         }                                                                           \
100     } while (0)
101 
102 
103 
104 //
105 // Checkpoint statistics
106 //
107 class CHECKPOINT_STATUS_S {
108 public:
109     enum {
110         CP_PERIOD,
111         CP_FOOTPRINT,
112         CP_TIME_LAST_CHECKPOINT_BEGIN,
113         CP_TIME_LAST_CHECKPOINT_BEGIN_COMPLETE,
114         CP_TIME_LAST_CHECKPOINT_END,
115         CP_TIME_CHECKPOINT_DURATION,
116         CP_TIME_CHECKPOINT_DURATION_LAST,
117         CP_LAST_LSN,
118         CP_CHECKPOINT_COUNT,
119         CP_CHECKPOINT_COUNT_FAIL,
120         CP_WAITERS_NOW,          // how many threads are currently waiting for the checkpoint_safe lock to perform a checkpoint
121         CP_WAITERS_MAX,          // max threads ever simultaneously waiting for the checkpoint_safe lock to perform a checkpoint
122         CP_CLIENT_WAIT_ON_MO,    // how many times a client thread waited to take the multi_operation lock, not for checkpoint
123         CP_CLIENT_WAIT_ON_CS,    // how many times a client thread waited for the checkpoint_safe lock, not for checkpoint
124         CP_BEGIN_TIME,
125         CP_LONG_BEGIN_TIME,
126         CP_LONG_BEGIN_COUNT,
127         CP_END_TIME,
128         CP_LONG_END_TIME,
129         CP_LONG_END_COUNT,
130         CP_STATUS_NUM_ROWS       // number of rows in this status array.  must be last.
131     };
132 
133     void init();
134     void destroy();
135 
136     TOKU_ENGINE_STATUS_ROW_S status[CP_STATUS_NUM_ROWS];
137 
138 private:
139     bool m_initialized;
140 };
141 typedef CHECKPOINT_STATUS_S* CHECKPOINT_STATUS;
142 extern CHECKPOINT_STATUS_S cp_status;
143 
144 #define CP_STATUS_VAL(x) cp_status.status[CHECKPOINT_STATUS_S::x].value.num
145 
146 
147 
148 //
149 // Cachetable statistics
150 //
151 class CACHETABLE_STATUS_S {
152 public:
153     enum {
154         CT_MISS = 0,
155         CT_MISSTIME,               // how many usec spent waiting for disk read because of cache miss
156         CT_PREFETCHES,             // how many times has a block been prefetched into the cachetable?
157         CT_SIZE_CURRENT,           // the sum of the sizes of the nodes represented in the cachetable
158         CT_SIZE_LIMIT,             // the limit to the sum of the node sizes
159         CT_SIZE_WRITING,           // the sum of the sizes of the nodes being written
160         CT_SIZE_NONLEAF,           // number of bytes in cachetable belonging to nonleaf nodes
161         CT_SIZE_LEAF,              // number of bytes in cachetable belonging to leaf nodes
162         CT_SIZE_ROLLBACK,          // number of bytes in cachetable belonging to rollback nodes
163         CT_SIZE_CACHEPRESSURE,     // number of bytes causing cache pressure (sum of buffers and workdone counters)
164         CT_SIZE_CLONED,            // number of bytes of cloned data in the system
165         CT_EVICTIONS,
166         CT_CLEANER_EXECUTIONS,     // number of times the cleaner thread's loop has executed
167         CT_CLEANER_PERIOD,
168         CT_CLEANER_ITERATIONS,     // number of times the cleaner thread runs the cleaner per period
169         CT_WAIT_PRESSURE_COUNT,
170         CT_WAIT_PRESSURE_TIME,
171         CT_LONG_WAIT_PRESSURE_COUNT,
172         CT_LONG_WAIT_PRESSURE_TIME,
173 
174         CT_POOL_CLIENT_NUM_THREADS,
175         CT_POOL_CLIENT_NUM_THREADS_ACTIVE,
176         CT_POOL_CLIENT_QUEUE_SIZE,
177         CT_POOL_CLIENT_MAX_QUEUE_SIZE,
178         CT_POOL_CLIENT_TOTAL_ITEMS_PROCESSED,
179         CT_POOL_CLIENT_TOTAL_EXECUTION_TIME,
180         CT_POOL_CACHETABLE_NUM_THREADS,
181         CT_POOL_CACHETABLE_NUM_THREADS_ACTIVE,
182         CT_POOL_CACHETABLE_QUEUE_SIZE,
183         CT_POOL_CACHETABLE_MAX_QUEUE_SIZE,
184         CT_POOL_CACHETABLE_TOTAL_ITEMS_PROCESSED,
185         CT_POOL_CACHETABLE_TOTAL_EXECUTION_TIME,
186         CT_POOL_CHECKPOINT_NUM_THREADS,
187         CT_POOL_CHECKPOINT_NUM_THREADS_ACTIVE,
188         CT_POOL_CHECKPOINT_QUEUE_SIZE,
189         CT_POOL_CHECKPOINT_MAX_QUEUE_SIZE,
190         CT_POOL_CHECKPOINT_TOTAL_ITEMS_PROCESSED,
191         CT_POOL_CHECKPOINT_TOTAL_EXECUTION_TIME,
192 
193         CT_STATUS_NUM_ROWS
194     };
195 
196     void init();
197     void destroy();
198 
199     TOKU_ENGINE_STATUS_ROW_S status[CT_STATUS_NUM_ROWS];
200 
201 private:
202     bool m_initialized;
203 };
204 typedef CACHETABLE_STATUS_S* CACHETABLE_STATUS;
205 extern CACHETABLE_STATUS_S ct_status;
206 
207 #define CT_STATUS_VAL(x) ct_status.status[CACHETABLE_STATUS_S::x].value.num
208 
209 
210 
211 //
212 // Lock Tree Manager statistics
213 //
214 class LTM_STATUS_S {
215 public:
216     enum {
217         LTM_SIZE_CURRENT = 0,
218         LTM_SIZE_LIMIT,
219         LTM_ESCALATION_COUNT,
220         LTM_ESCALATION_TIME,
221         LTM_ESCALATION_LATEST_RESULT,
222         LTM_NUM_LOCKTREES,
223         LTM_LOCK_REQUESTS_PENDING,
224         LTM_STO_NUM_ELIGIBLE,
225         LTM_STO_END_EARLY_COUNT,
226         LTM_STO_END_EARLY_TIME,
227         LTM_WAIT_COUNT,
228         LTM_WAIT_TIME,
229         LTM_LONG_WAIT_COUNT,
230         LTM_LONG_WAIT_TIME,
231         LTM_TIMEOUT_COUNT,
232         LTM_WAIT_ESCALATION_COUNT,
233         LTM_WAIT_ESCALATION_TIME,
234         LTM_LONG_WAIT_ESCALATION_COUNT,
235         LTM_LONG_WAIT_ESCALATION_TIME,
236         LTM_STATUS_NUM_ROWS // must be last
237     };
238 
239     void init(void);
240     void destroy(void);
241 
242     TOKU_ENGINE_STATUS_ROW_S status[LTM_STATUS_NUM_ROWS];
243 
244 private:
245     bool m_initialized;
246 };
247 typedef  LTM_STATUS_S* LTM_STATUS;
248 extern LTM_STATUS_S ltm_status;
249 
250 #define LTM_STATUS_VAL(x) ltm_status.status[LTM_STATUS_S::x].value.num
251 
252 
253 //
254 // Fractal Tree statistics
255 //
256 class FT_STATUS_S {
257 public:
258     enum {
259         FT_UPDATES = 0,
260         FT_UPDATES_BROADCAST,
261         FT_DESCRIPTOR_SET,
262         FT_MSN_DISCARDS,                           // how many messages were ignored by leaf because of msn
263         FT_TOTAL_RETRIES,                          // total number of search retries due to TRY_AGAIN
264         FT_SEARCH_TRIES_GT_HEIGHT,                 // number of searches that required more tries than the height of the tree
265         FT_SEARCH_TRIES_GT_HEIGHTPLUS3,            // number of searches that required more tries than the height of the tree plus three
266         FT_DISK_FLUSH_LEAF,                        // number of leaf nodes flushed to disk,    not for checkpoint
267         FT_DISK_FLUSH_LEAF_BYTES,                  // number of leaf nodes flushed to disk,    not for checkpoint
268         FT_DISK_FLUSH_LEAF_UNCOMPRESSED_BYTES,     // number of leaf nodes flushed to disk,    not for checkpoint
269         FT_DISK_FLUSH_LEAF_TOKUTIME,               // number of leaf nodes flushed to disk,    not for checkpoint
270         FT_DISK_FLUSH_NONLEAF,                     // number of nonleaf nodes flushed to disk, not for checkpoint
271         FT_DISK_FLUSH_NONLEAF_BYTES,               // number of nonleaf nodes flushed to disk, not for checkpoint
272         FT_DISK_FLUSH_NONLEAF_UNCOMPRESSED_BYTES,  // number of nonleaf nodes flushed to disk, not for checkpoint
273         FT_DISK_FLUSH_NONLEAF_TOKUTIME,            // number of nonleaf nodes flushed to disk, not for checkpoint
274         FT_DISK_FLUSH_LEAF_FOR_CHECKPOINT,         // number of leaf nodes flushed to disk for checkpoint
275         FT_DISK_FLUSH_LEAF_BYTES_FOR_CHECKPOINT,   // number of leaf nodes flushed to disk for checkpoint
276         FT_DISK_FLUSH_LEAF_UNCOMPRESSED_BYTES_FOR_CHECKPOINT,// number of leaf nodes flushed to disk for checkpoint
277         FT_DISK_FLUSH_LEAF_TOKUTIME_FOR_CHECKPOINT,// number of leaf nodes flushed to disk for checkpoint
278         FT_DISK_FLUSH_NONLEAF_FOR_CHECKPOINT,      // number of nonleaf nodes flushed to disk for checkpoint
279         FT_DISK_FLUSH_NONLEAF_BYTES_FOR_CHECKPOINT,// number of nonleaf nodes flushed to disk for checkpoint
280         FT_DISK_FLUSH_NONLEAF_UNCOMPRESSED_BYTES_FOR_CHECKPOINT,// number of nonleaf nodes flushed to disk for checkpoint
281         FT_DISK_FLUSH_NONLEAF_TOKUTIME_FOR_CHECKPOINT,// number of nonleaf nodes flushed to disk for checkpoint
282         FT_DISK_FLUSH_LEAF_COMPRESSION_RATIO,      // effective compression ratio for leaf bytes flushed to disk
283         FT_DISK_FLUSH_NONLEAF_COMPRESSION_RATIO,   // effective compression ratio for nonleaf bytes flushed to disk
284         FT_DISK_FLUSH_OVERALL_COMPRESSION_RATIO,   // effective compression ratio for all bytes flushed to disk
285         FT_PARTIAL_EVICTIONS_NONLEAF,              // number of nonleaf node partial evictions
286         FT_PARTIAL_EVICTIONS_NONLEAF_BYTES,        // number of nonleaf node partial evictions
287         FT_PARTIAL_EVICTIONS_LEAF,                 // number of leaf node partial evictions
288         FT_PARTIAL_EVICTIONS_LEAF_BYTES,           // number of leaf node partial evictions
289         FT_FULL_EVICTIONS_LEAF,                    // number of full cachetable evictions on leaf nodes
290         FT_FULL_EVICTIONS_LEAF_BYTES,              // number of full cachetable evictions on leaf nodes (bytes)
291         FT_FULL_EVICTIONS_NONLEAF,                 // number of full cachetable evictions on nonleaf nodes
292         FT_FULL_EVICTIONS_NONLEAF_BYTES,           // number of full cachetable evictions on nonleaf nodes (bytes)
293         FT_CREATE_LEAF,                            // number of leaf nodes created
294         FT_CREATE_NONLEAF,                         // number of nonleaf nodes created
295         FT_DESTROY_LEAF,                           // number of leaf nodes destroyed
296         FT_DESTROY_NONLEAF,                        // number of nonleaf nodes destroyed
297         FT_MSG_BYTES_IN,                           // how many bytes of messages injected at root (for all trees)
298         FT_MSG_BYTES_OUT,                          // how many bytes of messages flushed from h1 nodes to leaves
299         FT_MSG_BYTES_CURR,                         // how many bytes of messages currently in trees (estimate)
300         FT_MSG_NUM,                                // how many messages injected at root
301         FT_MSG_NUM_BROADCAST,                      // how many broadcast messages injected at root
302         FT_NUM_BASEMENTS_DECOMPRESSED_NORMAL,      // how many basement nodes were decompressed because they were the target of a query
303         FT_NUM_BASEMENTS_DECOMPRESSED_AGGRESSIVE,  // ... because they were between lc and rc
304         FT_NUM_BASEMENTS_DECOMPRESSED_PREFETCH,
305         FT_NUM_BASEMENTS_DECOMPRESSED_WRITE,
306         FT_NUM_MSG_BUFFER_DECOMPRESSED_NORMAL,     // how many msg buffers were decompressed because they were the target of a query
307         FT_NUM_MSG_BUFFER_DECOMPRESSED_AGGRESSIVE, // ... because they were between lc and rc
308         FT_NUM_MSG_BUFFER_DECOMPRESSED_PREFETCH,
309         FT_NUM_MSG_BUFFER_DECOMPRESSED_WRITE,
310         FT_NUM_PIVOTS_FETCHED_QUERY,               // how many pivots were fetched for a query
311         FT_BYTES_PIVOTS_FETCHED_QUERY,             // how many pivots were fetched for a query
312         FT_TOKUTIME_PIVOTS_FETCHED_QUERY,          // how many pivots were fetched for a query
313         FT_NUM_PIVOTS_FETCHED_PREFETCH,            // ... for a prefetch
314         FT_BYTES_PIVOTS_FETCHED_PREFETCH,          // ... for a prefetch
315         FT_TOKUTIME_PIVOTS_FETCHED_PREFETCH,       // ... for a prefetch
316         FT_NUM_PIVOTS_FETCHED_WRITE,               // ... for a write
317         FT_BYTES_PIVOTS_FETCHED_WRITE,             // ... for a write
318         FT_TOKUTIME_PIVOTS_FETCHED_WRITE,          // ... for a write
319         FT_NUM_BASEMENTS_FETCHED_NORMAL,           // how many basement nodes were fetched because they were the target of a query
320         FT_BYTES_BASEMENTS_FETCHED_NORMAL,         // how many basement nodes were fetched because they were the target of a query
321         FT_TOKUTIME_BASEMENTS_FETCHED_NORMAL,      // how many basement nodes were fetched because they were the target of a query
322         FT_NUM_BASEMENTS_FETCHED_AGGRESSIVE,       // ... because they were between lc and rc
323         FT_BYTES_BASEMENTS_FETCHED_AGGRESSIVE,     // ... because they were between lc and rc
324         FT_TOKUTIME_BASEMENTS_FETCHED_AGGRESSIVE,  // ... because they were between lc and rc
325         FT_NUM_BASEMENTS_FETCHED_PREFETCH,
326         FT_BYTES_BASEMENTS_FETCHED_PREFETCH,
327         FT_TOKUTIME_BASEMENTS_FETCHED_PREFETCH,
328         FT_NUM_BASEMENTS_FETCHED_WRITE,
329         FT_BYTES_BASEMENTS_FETCHED_WRITE,
330         FT_TOKUTIME_BASEMENTS_FETCHED_WRITE,
331         FT_NUM_MSG_BUFFER_FETCHED_NORMAL,          // how many msg buffers were fetched because they were the target of a query
332         FT_BYTES_MSG_BUFFER_FETCHED_NORMAL,        // how many msg buffers were fetched because they were the target of a query
333         FT_TOKUTIME_MSG_BUFFER_FETCHED_NORMAL,     // how many msg buffers were fetched because they were the target of a query
334         FT_NUM_MSG_BUFFER_FETCHED_AGGRESSIVE,      // ... because they were between lc and rc
335         FT_BYTES_MSG_BUFFER_FETCHED_AGGRESSIVE,    // ... because they were between lc and rc
336         FT_TOKUTIME_MSG_BUFFER_FETCHED_AGGRESSIVE, // ... because they were between lc and rc
337         FT_NUM_MSG_BUFFER_FETCHED_PREFETCH,
338         FT_BYTES_MSG_BUFFER_FETCHED_PREFETCH,
339         FT_TOKUTIME_MSG_BUFFER_FETCHED_PREFETCH,
340         FT_NUM_MSG_BUFFER_FETCHED_WRITE,
341         FT_BYTES_MSG_BUFFER_FETCHED_WRITE,
342         FT_TOKUTIME_MSG_BUFFER_FETCHED_WRITE,
343         FT_LEAF_COMPRESS_TOKUTIME, // seconds spent compressing leaf leaf nodes to memory
344         FT_LEAF_SERIALIZE_TOKUTIME, // seconds spent serializing leaf node to memory
345         FT_LEAF_DECOMPRESS_TOKUTIME, // seconds spent decompressing leaf nodes to memory
346         FT_LEAF_DESERIALIZE_TOKUTIME, // seconds spent deserializing leaf nodes to memory
347         FT_NONLEAF_COMPRESS_TOKUTIME, // seconds spent compressing nonleaf nodes to memory
348         FT_NONLEAF_SERIALIZE_TOKUTIME, // seconds spent serializing nonleaf nodes to memory
349         FT_NONLEAF_DECOMPRESS_TOKUTIME, // seconds spent decompressing nonleaf nodes to memory
350         FT_NONLEAF_DESERIALIZE_TOKUTIME, // seconds spent deserializing nonleaf nodes to memory
351         FT_PRO_NUM_ROOT_SPLIT,
352         FT_PRO_NUM_ROOT_H0_INJECT,
353         FT_PRO_NUM_ROOT_H1_INJECT,
354         FT_PRO_NUM_INJECT_DEPTH_0,
355         FT_PRO_NUM_INJECT_DEPTH_1,
356         FT_PRO_NUM_INJECT_DEPTH_2,
357         FT_PRO_NUM_INJECT_DEPTH_3,
358         FT_PRO_NUM_INJECT_DEPTH_GT3,
359         FT_PRO_NUM_STOP_NONEMPTY_BUF,
360         FT_PRO_NUM_STOP_H1,
361         FT_PRO_NUM_STOP_LOCK_CHILD,
362         FT_PRO_NUM_STOP_CHILD_INMEM,
363         FT_PRO_NUM_DIDNT_WANT_PROMOTE,
364         FT_BASEMENT_DESERIALIZE_FIXED_KEYSIZE, // how many basement nodes were deserialized with a fixed keysize
365         FT_BASEMENT_DESERIALIZE_VARIABLE_KEYSIZE, // how many basement nodes were deserialized with a variable keysize
366         FT_PRO_RIGHTMOST_LEAF_SHORTCUT_SUCCESS,
367         FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_POS,
368         FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_REACTIVE,
369         FT_CURSOR_SKIP_DELETED_LEAF_ENTRY, // how many deleted leaf entries were skipped by a cursor
370         FT_STATUS_NUM_ROWS
371     };
372 
373     void init(void);
374     void destroy(void);
375 
376     TOKU_ENGINE_STATUS_ROW_S status[FT_STATUS_NUM_ROWS];
377 
378 private:
379     bool m_initialized;
380 };
381 typedef FT_STATUS_S* FT_STATUS;
382 extern FT_STATUS_S ft_status;
383 
384 #define FT_STATUS_VAL(x)                                                            \
385     (ft_status.status[FT_STATUS_S::x].type == PARCOUNT ?                                         \
386         read_partitioned_counter(ft_status.status[FT_STATUS_S::x].value.parcount) :              \
387         ft_status.status[FT_STATUS_S::x].value.num)
388 
389 #define FT_STATUS_INC(x, d)                                                         \
390     do {                                                                            \
391         if (ft_status.status[FT_STATUS_S::x].type == PARCOUNT) {                                 \
392             increment_partitioned_counter(ft_status.status[FT_STATUS_S::x].value.parcount, d);   \
393         } else {                                                                    \
394             toku_sync_fetch_and_add(&ft_status.status[FT_STATUS_S::x].value.num, d);             \
395         }                                                                           \
396     } while (0)
397 
398 
399 
400 //
401 // Flusher statistics
402 //
403 class FT_FLUSHER_STATUS_S {
404 public:
405     enum {
406         FT_FLUSHER_CLEANER_TOTAL_NODES = 0,     // total number of nodes whose buffers are potentially flushed by cleaner thread
407         FT_FLUSHER_CLEANER_H1_NODES,            // number of nodes of height one whose message buffers are flushed by cleaner thread
408         FT_FLUSHER_CLEANER_HGT1_NODES,          // number of nodes of height > 1 whose message buffers are flushed by cleaner thread
409         FT_FLUSHER_CLEANER_EMPTY_NODES,         // number of nodes that are selected by cleaner, but whose buffers are empty
410         FT_FLUSHER_CLEANER_NODES_DIRTIED,       // number of nodes that are made dirty by the cleaner thread
411         FT_FLUSHER_CLEANER_MAX_BUFFER_SIZE,     // max number of bytes in message buffer flushed by cleaner thread
412         FT_FLUSHER_CLEANER_MIN_BUFFER_SIZE,
413         FT_FLUSHER_CLEANER_TOTAL_BUFFER_SIZE,
414         FT_FLUSHER_CLEANER_MAX_BUFFER_WORKDONE, // max workdone value of any message buffer flushed by cleaner thread
415         FT_FLUSHER_CLEANER_MIN_BUFFER_WORKDONE,
416         FT_FLUSHER_CLEANER_TOTAL_BUFFER_WORKDONE,
417         FT_FLUSHER_CLEANER_NUM_LEAF_MERGES_STARTED,     // number of times cleaner thread tries to merge a leaf
418         FT_FLUSHER_CLEANER_NUM_LEAF_MERGES_RUNNING,     // number of cleaner thread leaf merges in progress
419         FT_FLUSHER_CLEANER_NUM_LEAF_MERGES_COMPLETED,   // number of times cleaner thread successfully merges a leaf
420         FT_FLUSHER_CLEANER_NUM_DIRTIED_FOR_LEAF_MERGE,  // nodes dirtied by the "flush from root" process to merge a leaf node
421         FT_FLUSHER_FLUSH_TOTAL,                 // total number of flushes done by flusher threads or cleaner threads
422         FT_FLUSHER_FLUSH_IN_MEMORY,             // number of in memory flushes
423         FT_FLUSHER_FLUSH_NEEDED_IO,             // number of flushes that had to read a child (or part) off disk
424         FT_FLUSHER_FLUSH_CASCADES,              // number of flushes that triggered another flush in the child
425         FT_FLUSHER_FLUSH_CASCADES_1,            // number of flushes that triggered 1 cascading flush
426         FT_FLUSHER_FLUSH_CASCADES_2,            // number of flushes that triggered 2 cascading flushes
427         FT_FLUSHER_FLUSH_CASCADES_3,            // number of flushes that triggered 3 cascading flushes
428         FT_FLUSHER_FLUSH_CASCADES_4,            // number of flushes that triggered 4 cascading flushes
429         FT_FLUSHER_FLUSH_CASCADES_5,            // number of flushes that triggered 5 cascading flushes
430         FT_FLUSHER_FLUSH_CASCADES_GT_5,         // number of flushes that triggered more than 5 cascading flushes
431         FT_FLUSHER_SPLIT_LEAF,                  // number of leaf nodes split
432         FT_FLUSHER_SPLIT_NONLEAF,               // number of nonleaf nodes split
433         FT_FLUSHER_MERGE_LEAF,                  // number of times leaf nodes are merged
434         FT_FLUSHER_MERGE_NONLEAF,               // number of times nonleaf nodes are merged
435         FT_FLUSHER_BALANCE_LEAF,                // number of times a leaf node is balanced
436         FT_FLUSHER_STATUS_NUM_ROWS
437     };
438 
439     void init(void);
440     void destroy(void);
441 
442     TOKU_ENGINE_STATUS_ROW_S status[FT_FLUSHER_STATUS_NUM_ROWS];
443 
444 private:
445     bool m_initialized;
446 };
447 typedef FT_FLUSHER_STATUS_S* FT_FLUSHER_STATUS;
448 extern FT_FLUSHER_STATUS_S fl_status;
449 
450 #define FL_STATUS_VAL(x) fl_status.status[FT_FLUSHER_STATUS_S::x].value.num
451 
452 
453 
454 //
455 // Hot Flusher
456 //
457 class FT_HOT_STATUS_S {
458 public:
459     enum {
460         FT_HOT_NUM_STARTED = 0,      // number of HOT operations that have begun
461         FT_HOT_NUM_COMPLETED,        // number of HOT operations that have successfully completed
462         FT_HOT_NUM_ABORTED,          // number of HOT operations that have been aborted
463         FT_HOT_MAX_ROOT_FLUSH_COUNT, // max number of flushes from root ever required to optimize a tree
464         FT_HOT_STATUS_NUM_ROWS
465     };
466 
467     void init(void);
468     void destroy(void);
469 
470     TOKU_ENGINE_STATUS_ROW_S status[FT_HOT_STATUS_NUM_ROWS];
471 
472 private:
473     bool m_initialized;
474 };
475 typedef FT_HOT_STATUS_S* FT_HOT_STATUS;
476 extern FT_HOT_STATUS_S hot_status;
477 
478 #define HOT_STATUS_VAL(x) hot_status.status[FT_HOT_STATUS_S::x].value.num
479 
480 
481 
482 //
483 // Transaction statistics
484 //
485 class TXN_STATUS_S {
486 public:
487     enum {
488         TXN_BEGIN,             // total number of transactions begun (does not include recovered txns)
489         TXN_READ_BEGIN,        // total number of read only transactions begun (does not include recovered txns)
490         TXN_COMMIT,            // successful commits
491         TXN_ABORT,
492         TXN_STATUS_NUM_ROWS
493     };
494 
495     void init(void);
496     void destroy(void);
497 
498     TOKU_ENGINE_STATUS_ROW_S status[TXN_STATUS_NUM_ROWS];
499 
500 private:
501     bool m_initialized;
502 };
503 typedef TXN_STATUS_S* TXN_STATUS;
504 extern TXN_STATUS_S txn_status;
505 
506 #define TXN_STATUS_INC(x, d) increment_partitioned_counter(txn_status.status[TXN_STATUS_S::x].value.parcount, d)
507 
508 
509 
510 //
511 // Logger statistics
512 //
513 class LOGGER_STATUS_S {
514 public:
515     enum {
516         LOGGER_NEXT_LSN = 0,
517         LOGGER_NUM_WRITES,
518         LOGGER_BYTES_WRITTEN,
519         LOGGER_UNCOMPRESSED_BYTES_WRITTEN,
520         LOGGER_TOKUTIME_WRITES,
521         LOGGER_WAIT_BUF_LONG,
522         LOGGER_STATUS_NUM_ROWS
523     };
524 
525     void init(void);
526     void destroy(void);
527 
528     TOKU_ENGINE_STATUS_ROW_S status[LOGGER_STATUS_NUM_ROWS];
529 
530 private:
531     bool m_initialized;
532 };
533 typedef LOGGER_STATUS_S* LOGGER_STATUS;
534 extern LOGGER_STATUS_S log_status;
535 
536 #define LOG_STATUS_VAL(x) log_status.status[LOGGER_STATUS_S::x].value.num
537 
538 void toku_status_init(void);
539 void toku_status_destroy(void);
540