1 /***********************************************************************
2 
3 Copyright (c) 2010, 2021, Oracle and/or its affiliates.
4 Copyright (c) 2012, Facebook Inc.
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2.0,
8 as published by the Free Software Foundation.
9 
10 This program is also distributed with certain software (including
11 but not limited to OpenSSL) that is licensed under separate terms,
12 as designated in a particular file or component or in included license
13 documentation.  The authors of MySQL hereby grant you an additional
14 permission to link the program and your derivative works with the
15 separately licensed software that they have included with MySQL.
16 
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License, version 2.0, for more details.
21 
22 You should have received a copy of the GNU General Public License along with
23 this program; if not, write to the Free Software Foundation, Inc.,
24 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
25 
26 ***********************************************************************/
27 
28 /**************************************************//**
29 @file include/srv0mon.h
30 Server monitor counter related defines
31 
32 Created 12/15/2009	Jimmy Yang
33 *******************************************************/
34 
35 #ifndef srv0mon_h
36 #define srv0mon_h
37 
38 #include "univ.i"
39 
40 #ifndef __STDC_LIMIT_MACROS
41 /* Required for FreeBSD so that INT64_MAX is defined. */
42 #define __STDC_LIMIT_MACROS
43 #endif /* __STDC_LIMIT_MACROS */
44 #ifdef __DragonFly__
45 /* The hack above doen't work for dragonfly, stdint.h already imported */
46 #include <machine/int_limits.h>
47 #endif
48 
49 #include <stdint.h>
50 
51 #ifndef UNIV_HOTBACKUP
52 
53 
54 /** Possible status values for "mon_status" in "struct monitor_value" */
55 enum monitor_running_status {
56 	MONITOR_STARTED = 1,	/*!< Monitor has been turned on */
57 	MONITOR_STOPPED = 2	/*!< Monitor has been turned off */
58 };
59 
60 typedef enum monitor_running_status	monitor_running_t;
61 
62 /** Monitor counter value type */
63 typedef	int64_t				mon_type_t;
64 
65 /** Two monitor structures are defined in this file. One is
66 "monitor_value_t" which contains dynamic counter values for each
67 counter. The other is "monitor_info_t", which contains
68 static information (counter name, desc etc.) for each counter.
69 In addition, an enum datatype "monitor_id_t" is also defined,
70 it identifies each monitor with an internally used symbol, whose
71 integer value indexes into above two structure for its dynamic
72 and static information.
73 Developer who intend to add new counters would require to
74 fill in counter information as described in "monitor_info_t" and
75 create the internal counter ID in "monitor_id_t". */
76 
77 /** Structure containing the actual values of a monitor counter. */
78 struct monitor_value_t {
79 	ib_time_t	mon_start_time;	/*!< Start time of monitoring  */
80 	ib_time_t	mon_stop_time;	/*!< Stop time of monitoring */
81 	ib_time_t	mon_reset_time;	/*!< Time counter resetted */
82 	mon_type_t	mon_value;	/*!< Current counter Value */
83 	mon_type_t	mon_max_value;	/*!< Current Max value */
84 	mon_type_t	mon_min_value;	/*!< Current Min value */
85 	mon_type_t	mon_value_reset;/*!< value at last reset */
86 	mon_type_t	mon_max_value_start; /*!< Max value since start */
87 	mon_type_t	mon_min_value_start; /*!< Min value since start */
88 	mon_type_t	mon_start_value;/*!< Value at the start time */
89 	mon_type_t	mon_last_value;	/*!< Last set of values */
90 	monitor_running_t mon_status;	/* whether monitor still running */
91 };
92 
93 /** Follwoing defines are possible values for "monitor_type" field in
94 "struct monitor_info" */
95 enum monitor_type_t {
96 	MONITOR_NONE = 0,	/*!< No monitoring */
97 	MONITOR_MODULE = 1,	/*!< This is a monitor module type,
98 				not a counter */
99 	MONITOR_EXISTING = 2,	/*!< The monitor carries information from
100 				an existing system status variable */
101 	MONITOR_NO_AVERAGE = 4,	/*!< Set this status if we don't want to
102 				calculate the average value for the counter */
103 	MONITOR_DISPLAY_CURRENT = 8, /*!< Display current value of the
104 				counter, rather than incremental value
105 				over the period. Mostly for counters
106 				displaying current resource usage */
107 	MONITOR_GROUP_MODULE = 16, /*!< Monitor can be turned on/off
108 				only as a module, but not individually */
109 	MONITOR_DEFAULT_ON = 32,/*!< Monitor will be turned on by default at
110 				server start up */
111 	MONITOR_SET_OWNER = 64,	/*!< Owner of "monitor set", a set of
112 				monitor counters */
113 	MONITOR_SET_MEMBER = 128,/*!< Being part of a "monitor set" */
114 	MONITOR_HIDDEN = 256	/*!< Do not display this monitor in the
115 				metrics table */
116 };
117 
118 /** Counter minimum value is initialized to be max value of
119  mon_type_t (int64_t) */
120 #define	MIN_RESERVED		INT64_MAX
121 #define	MAX_RESERVED		(~MIN_RESERVED)
122 
123 /** This enumeration defines internal monitor identifier used internally
124 to identify each particular counter. Its value indexes into two arrays,
125 one is the "innodb_counter_value" array which records actual monitor
126 counter values, the other is "innodb_counter_info" array which describes
127 each counter's basic information (name, desc etc.). A couple of
128 naming rules here:
129 1) If the monitor defines a module, it starts with MONITOR_MODULE
130 2) If the monitor uses exisitng counters from "status variable", its ID
131 name shall start with MONITOR_OVLD
132 
133 Please refer to "innodb_counter_info" in srv/srv0mon.cc for detail
134 information for each monitor counter */
135 
136 enum monitor_id_t {
137 	/* This is to identify the default value set by the metrics
138 	control global variables */
139 	MONITOR_DEFAULT_START = 0,
140 
141 	/* Start of Metadata counter */
142 	MONITOR_MODULE_METADATA,
143 	MONITOR_TABLE_OPEN,
144 	MONITOR_TABLE_CLOSE,
145 	MONITOR_TABLE_REFERENCE,
146 
147 	/* Lock manager related counters */
148 	MONITOR_MODULE_LOCK,
149 	MONITOR_DEADLOCK,
150 	MONITOR_TIMEOUT,
151 	MONITOR_LOCKREC_WAIT,
152 	MONITOR_TABLELOCK_WAIT,
153 	MONITOR_NUM_RECLOCK_REQ,
154 	MONITOR_RECLOCK_CREATED,
155 	MONITOR_RECLOCK_REMOVED,
156 	MONITOR_NUM_RECLOCK,
157 	MONITOR_TABLELOCK_CREATED,
158 	MONITOR_TABLELOCK_REMOVED,
159 	MONITOR_NUM_TABLELOCK,
160 	MONITOR_OVLD_ROW_LOCK_CURRENT_WAIT,
161 	MONITOR_OVLD_LOCK_WAIT_TIME,
162 	MONITOR_OVLD_LOCK_MAX_WAIT_TIME,
163 	MONITOR_OVLD_ROW_LOCK_WAIT,
164 	MONITOR_OVLD_LOCK_AVG_WAIT_TIME,
165 
166 	/* Buffer and I/O realted counters. */
167 	MONITOR_MODULE_BUFFER,
168 	MONITOR_OVLD_BUFFER_POOL_SIZE,
169 	MONITOR_OVLD_BUF_POOL_READS,
170 	MONITOR_OVLD_BUF_POOL_READ_REQUESTS,
171 	MONITOR_OVLD_BUF_POOL_WRITE_REQUEST,
172 	MONITOR_OVLD_BUF_POOL_WAIT_FREE,
173 	MONITOR_OVLD_BUF_POOL_READ_AHEAD,
174 	MONITOR_OVLD_BUF_POOL_READ_AHEAD_EVICTED,
175 	MONITOR_OVLD_BUF_POOL_PAGE_TOTAL,
176 	MONITOR_OVLD_BUF_POOL_PAGE_MISC,
177 	MONITOR_OVLD_BUF_POOL_PAGES_DATA,
178 	MONITOR_OVLD_BUF_POOL_BYTES_DATA,
179 	MONITOR_OVLD_BUF_POOL_PAGES_DIRTY,
180 	MONITOR_OVLD_BUF_POOL_BYTES_DIRTY,
181 	MONITOR_OVLD_BUF_POOL_PAGES_FREE,
182 	MONITOR_OVLD_PAGE_CREATED,
183 	MONITOR_OVLD_PAGES_WRITTEN,
184 	MONITOR_OVLD_PAGES_READ,
185 	MONITOR_OVLD_PAGES0_READ,
186 	MONITOR_OVLD_BYTE_READ,
187 	MONITOR_OVLD_BYTE_WRITTEN,
188 	MONITOR_FLUSH_BATCH_SCANNED,
189 	MONITOR_FLUSH_BATCH_SCANNED_NUM_CALL,
190 	MONITOR_FLUSH_BATCH_SCANNED_PER_CALL,
191 	MONITOR_FLUSH_BATCH_TOTAL_PAGE,
192 	MONITOR_FLUSH_BATCH_COUNT,
193 	MONITOR_FLUSH_BATCH_PAGES,
194 	MONITOR_FLUSH_NEIGHBOR_TOTAL_PAGE,
195 	MONITOR_FLUSH_NEIGHBOR_COUNT,
196 	MONITOR_FLUSH_NEIGHBOR_PAGES,
197 	MONITOR_FLUSH_N_TO_FLUSH_REQUESTED,
198 
199 	MONITOR_FLUSH_N_TO_FLUSH_BY_AGE,
200 	MONITOR_FLUSH_ADAPTIVE_AVG_TIME_SLOT,
201 	MONITOR_LRU_BATCH_FLUSH_AVG_TIME_SLOT,
202 
203 	MONITOR_FLUSH_ADAPTIVE_AVG_TIME_THREAD,
204 	MONITOR_LRU_BATCH_FLUSH_AVG_TIME_THREAD,
205 	MONITOR_FLUSH_ADAPTIVE_AVG_TIME_EST,
206 	MONITOR_LRU_BATCH_FLUSH_AVG_TIME_EST,
207 	MONITOR_FLUSH_AVG_TIME,
208 
209 	MONITOR_FLUSH_ADAPTIVE_AVG_PASS,
210 	MONITOR_LRU_BATCH_FLUSH_AVG_PASS,
211 	MONITOR_FLUSH_AVG_PASS,
212 
213 	MONITOR_LRU_GET_FREE_LOOPS,
214 	MONITOR_LRU_GET_FREE_WAITS,
215 
216 	MONITOR_FLUSH_AVG_PAGE_RATE,
217 	MONITOR_FLUSH_LSN_AVG_RATE,
218 	MONITOR_FLUSH_PCT_FOR_DIRTY,
219 	MONITOR_FLUSH_PCT_FOR_LSN,
220 	MONITOR_FLUSH_SYNC_WAITS,
221 	MONITOR_FLUSH_ADAPTIVE_TOTAL_PAGE,
222 	MONITOR_FLUSH_ADAPTIVE_COUNT,
223 	MONITOR_FLUSH_ADAPTIVE_PAGES,
224 	MONITOR_FLUSH_SYNC_TOTAL_PAGE,
225 	MONITOR_FLUSH_SYNC_COUNT,
226 	MONITOR_FLUSH_SYNC_PAGES,
227 	MONITOR_FLUSH_BACKGROUND_TOTAL_PAGE,
228 	MONITOR_FLUSH_BACKGROUND_COUNT,
229 	MONITOR_FLUSH_BACKGROUND_PAGES,
230 	MONITOR_LRU_BATCH_SCANNED,
231 	MONITOR_LRU_BATCH_SCANNED_NUM_CALL,
232 	MONITOR_LRU_BATCH_SCANNED_PER_CALL,
233 	MONITOR_LRU_BATCH_FLUSH_TOTAL_PAGE,
234 	MONITOR_LRU_BATCH_FLUSH_COUNT,
235 	MONITOR_LRU_BATCH_FLUSH_PAGES,
236 	MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE,
237 	MONITOR_LRU_BATCH_EVICT_COUNT,
238 	MONITOR_LRU_BATCH_EVICT_PAGES,
239 	MONITOR_LRU_SINGLE_FLUSH_SCANNED,
240 	MONITOR_LRU_SINGLE_FLUSH_SCANNED_NUM_CALL,
241 	MONITOR_LRU_SINGLE_FLUSH_SCANNED_PER_CALL,
242 	MONITOR_LRU_SINGLE_FLUSH_FAILURE_COUNT,
243 	MONITOR_LRU_GET_FREE_SEARCH,
244 	MONITOR_LRU_SEARCH_SCANNED,
245 	MONITOR_LRU_SEARCH_SCANNED_NUM_CALL,
246 	MONITOR_LRU_SEARCH_SCANNED_PER_CALL,
247 	MONITOR_LRU_UNZIP_SEARCH_SCANNED,
248 	MONITOR_LRU_UNZIP_SEARCH_SCANNED_NUM_CALL,
249 	MONITOR_LRU_UNZIP_SEARCH_SCANNED_PER_CALL,
250 
251 	/* Buffer Page I/O specific counters. */
252 	MONITOR_MODULE_BUF_PAGE,
253 	MONITOR_INDEX_LEAF_PAGE_READ,
254 	MONITOR_INDEX_NON_LEAF_PAGE_READ,
255 	MONITOR_INDEX_IBUF_LEAF_PAGE_READ,
256 	MONITOR_INDEX_IBUF_NON_LEAF_PAGE_READ,
257 	MONITOR_UNDO_LOG_PAGE_READ,
258 	MONITOR_INODE_PAGE_READ,
259 	MONITOR_IBUF_FREELIST_PAGE_READ,
260 	MONITOR_IBUF_BITMAP_PAGE_READ,
261 	MONITOR_SYSTEM_PAGE_READ,
262 	MONITOR_TRX_SYSTEM_PAGE_READ,
263 	MONITOR_FSP_HDR_PAGE_READ,
264 	MONITOR_XDES_PAGE_READ,
265 	MONITOR_BLOB_PAGE_READ,
266 	MONITOR_ZBLOB_PAGE_READ,
267 	MONITOR_ZBLOB2_PAGE_READ,
268 	MONITOR_OTHER_PAGE_READ,
269 	MONITOR_INDEX_LEAF_PAGE_WRITTEN,
270 	MONITOR_INDEX_NON_LEAF_PAGE_WRITTEN,
271 	MONITOR_INDEX_IBUF_LEAF_PAGE_WRITTEN,
272 	MONITOR_INDEX_IBUF_NON_LEAF_PAGE_WRITTEN,
273 	MONITOR_UNDO_LOG_PAGE_WRITTEN,
274 	MONITOR_INODE_PAGE_WRITTEN,
275 	MONITOR_IBUF_FREELIST_PAGE_WRITTEN,
276 	MONITOR_IBUF_BITMAP_PAGE_WRITTEN,
277 	MONITOR_SYSTEM_PAGE_WRITTEN,
278 	MONITOR_TRX_SYSTEM_PAGE_WRITTEN,
279 	MONITOR_FSP_HDR_PAGE_WRITTEN,
280 	MONITOR_XDES_PAGE_WRITTEN,
281 	MONITOR_BLOB_PAGE_WRITTEN,
282 	MONITOR_ZBLOB_PAGE_WRITTEN,
283 	MONITOR_ZBLOB2_PAGE_WRITTEN,
284 	MONITOR_OTHER_PAGE_WRITTEN,
285 
286 	/* OS level counters (I/O) */
287 	MONITOR_MODULE_OS,
288 	MONITOR_OVLD_OS_FILE_READ,
289 	MONITOR_OVLD_OS_FILE_WRITE,
290 	MONITOR_OVLD_OS_FSYNC,
291 	MONITOR_OS_PENDING_READS,
292 	MONITOR_OS_PENDING_WRITES,
293 	MONITOR_OVLD_OS_LOG_WRITTEN,
294 	MONITOR_OVLD_OS_LOG_FSYNC,
295 	MONITOR_OVLD_OS_LOG_PENDING_FSYNC,
296 	MONITOR_OVLD_OS_LOG_PENDING_WRITES,
297 
298 	/* Transaction related counters */
299 	MONITOR_MODULE_TRX,
300 	MONITOR_TRX_RW_COMMIT,
301 	MONITOR_TRX_RO_COMMIT,
302 	MONITOR_TRX_NL_RO_COMMIT,
303 	MONITOR_TRX_COMMIT_UNDO,
304 	MONITOR_TRX_ROLLBACK,
305 	MONITOR_TRX_ROLLBACK_SAVEPOINT,
306 	MONITOR_TRX_ROLLBACK_ACTIVE,
307 	MONITOR_TRX_ACTIVE,
308 	MONITOR_RSEG_HISTORY_LEN,
309 	MONITOR_NUM_UNDO_SLOT_USED,
310 	MONITOR_NUM_UNDO_SLOT_CACHED,
311 	MONITOR_RSEG_CUR_SIZE,
312 
313 	/* Purge related counters */
314 	MONITOR_MODULE_PURGE,
315 	MONITOR_N_DEL_ROW_PURGE,
316 	MONITOR_N_UPD_EXIST_EXTERN,
317 	MONITOR_PURGE_INVOKED,
318 	MONITOR_PURGE_N_PAGE_HANDLED,
319 	MONITOR_DML_PURGE_DELAY,
320 	MONITOR_PURGE_STOP_COUNT,
321 	MONITOR_PURGE_RESUME_COUNT,
322 
323 	/* Recovery related counters */
324 	MONITOR_MODULE_RECOVERY,
325 	MONITOR_NUM_CHECKPOINT,
326 	MONITOR_OVLD_LSN_FLUSHDISK,
327 	MONITOR_OVLD_LSN_CHECKPOINT,
328 	MONITOR_OVLD_LSN_CURRENT,
329 	MONITOR_LSN_CHECKPOINT_AGE,
330 	MONITOR_OVLD_BUF_OLDEST_LSN,
331 	MONITOR_OVLD_MAX_AGE_ASYNC,
332 	MONITOR_OVLD_MAX_AGE_SYNC,
333 	MONITOR_PENDING_LOG_FLUSH,
334 	MONITOR_PENDING_CHECKPOINT_WRITE,
335 	MONITOR_LOG_IO,
336 	MONITOR_OVLD_LOG_WAITS,
337 	MONITOR_OVLD_LOG_WRITE_REQUEST,
338 	MONITOR_OVLD_LOG_WRITES,
339 	MONITOR_OVLD_LOG_PADDED,
340 
341 	/* Page Manager related counters */
342 	MONITOR_MODULE_PAGE,
343 	MONITOR_PAGE_COMPRESS,
344 	MONITOR_PAGE_DECOMPRESS,
345 	MONITOR_PAD_INCREMENTS,
346 	MONITOR_PAD_DECREMENTS,
347 
348 	/* New monitor variables for page encryption */
349 	MONITOR_OVLD_PAGES_ENCRYPTED,
350 	MONITOR_OVLD_PAGES_DECRYPTED,
351 
352 	/* Index related counters */
353 	MONITOR_MODULE_INDEX,
354 	MONITOR_INDEX_SPLIT,
355 	MONITOR_INDEX_MERGE_ATTEMPTS,
356 	MONITOR_INDEX_MERGE_SUCCESSFUL,
357 	MONITOR_INDEX_REORG_ATTEMPTS,
358 	MONITOR_INDEX_REORG_SUCCESSFUL,
359 	MONITOR_INDEX_DISCARD,
360 
361 	/* Adaptive Hash Index related counters */
362 	MONITOR_MODULE_ADAPTIVE_HASH,
363 	MONITOR_OVLD_ADAPTIVE_HASH_SEARCH,
364 	MONITOR_OVLD_ADAPTIVE_HASH_SEARCH_BTREE,
365 	MONITOR_ADAPTIVE_HASH_PAGE_ADDED,
366 	MONITOR_ADAPTIVE_HASH_PAGE_REMOVED,
367 	MONITOR_ADAPTIVE_HASH_ROW_ADDED,
368 	MONITOR_ADAPTIVE_HASH_ROW_REMOVED,
369 	MONITOR_ADAPTIVE_HASH_ROW_REMOVE_NOT_FOUND,
370 	MONITOR_ADAPTIVE_HASH_ROW_UPDATED,
371 
372 	/* Tablespace related counters */
373 	MONITOR_MODULE_FIL_SYSTEM,
374 	MONITOR_OVLD_N_FILE_OPENED,
375 
376 	/* InnoDB Change Buffer related counters */
377 	MONITOR_MODULE_IBUF_SYSTEM,
378 	MONITOR_OVLD_IBUF_MERGE_INSERT,
379 	MONITOR_OVLD_IBUF_MERGE_DELETE,
380 	MONITOR_OVLD_IBUF_MERGE_PURGE,
381 	MONITOR_OVLD_IBUF_MERGE_DISCARD_INSERT,
382 	MONITOR_OVLD_IBUF_MERGE_DISCARD_DELETE,
383 	MONITOR_OVLD_IBUF_MERGE_DISCARD_PURGE,
384 	MONITOR_OVLD_IBUF_MERGES,
385 	MONITOR_OVLD_IBUF_SIZE,
386 
387 	/* Counters for server operations */
388 	MONITOR_MODULE_SERVER,
389 	MONITOR_MASTER_THREAD_SLEEP,
390 	MONITOR_OVLD_SERVER_ACTIVITY,
391 	MONITOR_MASTER_ACTIVE_LOOPS,
392 	MONITOR_MASTER_IDLE_LOOPS,
393 	MONITOR_SRV_BACKGROUND_DROP_TABLE_MICROSECOND,
394 	MONITOR_SRV_IBUF_MERGE_MICROSECOND,
395 	MONITOR_SRV_LOG_FLUSH_MICROSECOND,
396 	MONITOR_SRV_MEM_VALIDATE_MICROSECOND,
397 	MONITOR_SRV_PURGE_MICROSECOND,
398 	MONITOR_SRV_DICT_LRU_MICROSECOND,
399 	MONITOR_SRV_DICT_LRU_EVICT_COUNT,
400 	MONITOR_SRV_CHECKPOINT_MICROSECOND,
401 	MONITOR_OVLD_SRV_DBLWR_WRITES,
402 	MONITOR_OVLD_SRV_DBLWR_PAGES_WRITTEN,
403 	MONITOR_OVLD_SRV_PAGE_SIZE,
404 	MONITOR_OVLD_RWLOCK_S_SPIN_WAITS,
405 	MONITOR_OVLD_RWLOCK_X_SPIN_WAITS,
406 	MONITOR_OVLD_RWLOCK_SX_SPIN_WAITS,
407 	MONITOR_OVLD_RWLOCK_S_SPIN_ROUNDS,
408 	MONITOR_OVLD_RWLOCK_X_SPIN_ROUNDS,
409 	MONITOR_OVLD_RWLOCK_SX_SPIN_ROUNDS,
410 	MONITOR_OVLD_RWLOCK_S_OS_WAITS,
411 	MONITOR_OVLD_RWLOCK_X_OS_WAITS,
412 	MONITOR_OVLD_RWLOCK_SX_OS_WAITS,
413 
414 	/* Data DML related counters */
415 	MONITOR_MODULE_DML_STATS,
416 	MONITOR_OLVD_ROW_READ,
417 	MONITOR_OLVD_ROW_INSERTED,
418 	MONITOR_OLVD_ROW_DELETED,
419 	MONITOR_OLVD_ROW_UPDTATED,
420 
421 	/* Data DDL related counters */
422 	MONITOR_MODULE_DDL_STATS,
423 	MONITOR_BACKGROUND_DROP_INDEX,
424 	MONITOR_BACKGROUND_DROP_TABLE,
425 	MONITOR_ONLINE_CREATE_INDEX,
426 	MONITOR_PENDING_ALTER_TABLE,
427 	MONITOR_ALTER_TABLE_SORT_FILES,
428 	MONITOR_ALTER_TABLE_LOG_FILES,
429 
430 	MONITOR_MODULE_ICP,
431 	MONITOR_ICP_ATTEMPTS,
432 	MONITOR_ICP_NO_MATCH,
433 	MONITOR_ICP_OUT_OF_RANGE,
434 	MONITOR_ICP_MATCH,
435 
436 	/* Mutex/RW-Lock related counters */
437 	MONITOR_MODULE_LATCHES,
438 	MONITOR_LATCHES,
439 
440 	/* This is used only for control system to turn
441 	on/off and reset all monitor counters */
442 	MONITOR_ALL_COUNTER,
443 
444 	/* This must be the last member */
445 	NUM_MONITOR
446 };
447 
448 /** This informs the monitor control system to turn
449 on/off and reset monitor counters through wild card match */
450 #define	MONITOR_WILDCARD_MATCH		(NUM_MONITOR + 1)
451 
452 /** Cannot find monitor counter with a specified name */
453 #define	MONITOR_NO_MATCH		(NUM_MONITOR + 2)
454 
455 /** struct monitor_info describes the basic/static information
456 about each monitor counter. */
457 struct monitor_info_t {
458 	const char*	monitor_name;	/*!< Monitor name */
459 	const char*	monitor_module;	/*!< Sub Module the monitor
460 					belongs to */
461 	const char*	monitor_desc;	/*!< Brief desc of monitor counter */
462 	monitor_type_t	monitor_type;	/*!< Type of Monitor Info */
463 	monitor_id_t	monitor_related_id;/*!< Monitor ID of counter that
464 					related to this monitor. This is
465 					set when the monitor belongs to
466 					a "monitor set" */
467 	monitor_id_t	monitor_id;	/*!< Monitor ID as defined in enum
468 					monitor_id_t */
469 };
470 
471 /** Following are the "set_option" values allowed for
472 srv_mon_process_existing_counter() and srv_mon_process_existing_counter()
473 functions. To turn on/off/reset the monitor counters. */
474 enum mon_option_t {
475 	MONITOR_TURN_ON = 1,		/*!< Turn on the counter */
476 	MONITOR_TURN_OFF,		/*!< Turn off the counter */
477 	MONITOR_RESET_VALUE,		/*!< Reset current values */
478 	MONITOR_RESET_ALL_VALUE,	/*!< Reset all values */
479 	MONITOR_GET_VALUE		/*!< Option for
480 					srv_mon_process_existing_counter()
481 					function */
482 };
483 
484 /** Number of bit in a ulint datatype */
485 #define	NUM_BITS_ULINT	(sizeof(ulint) * CHAR_BIT)
486 
487 /** This "monitor_set_tbl" is a bitmap records whether a particular monitor
488 counter has been turned on or off */
489 extern ulint		monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT - 1) /
490 					NUM_BITS_ULINT];
491 
492 /** Macros to turn on/off the control bit in monitor_set_tbl for a monitor
493 counter option. */
494 #define MONITOR_ON(monitor)				\
495 	(monitor_set_tbl[monitor / NUM_BITS_ULINT] |=	\
496 			((ulint)1 << (monitor % NUM_BITS_ULINT)))
497 
498 #define MONITOR_OFF(monitor)				\
499 	(monitor_set_tbl[monitor / NUM_BITS_ULINT] &=	\
500 			~((ulint)1 << (monitor % NUM_BITS_ULINT)))
501 
502 /** Check whether the requested monitor is turned on/off */
503 #define MONITOR_IS_ON(monitor)				\
504 	(monitor_set_tbl[monitor / NUM_BITS_ULINT] &	\
505 			((ulint)1 << (monitor % NUM_BITS_ULINT)))
506 
507 /** The actual monitor counter array that records each monintor counter
508 value */
509 extern monitor_value_t	 innodb_counter_value[NUM_MONITOR];
510 
511 /** Following are macro defines for basic montior counter manipulations.
512 Please note we do not provide any synchronization for these monitor
513 operations due to performance consideration. Most counters can
514 be placed under existing mutex protections in respective code
515 module. */
516 
517 /** Macros to access various fields of a monitor counters */
518 #define MONITOR_FIELD(monitor, field)			\
519 		(innodb_counter_value[monitor].field)
520 
521 #define MONITOR_VALUE(monitor)				\
522 		MONITOR_FIELD(monitor, mon_value)
523 
524 #define MONITOR_MAX_VALUE(monitor)			\
525 		MONITOR_FIELD(monitor, mon_max_value)
526 
527 #define MONITOR_MIN_VALUE(monitor)			\
528 		MONITOR_FIELD(monitor, mon_min_value)
529 
530 #define MONITOR_VALUE_RESET(monitor)			\
531 		MONITOR_FIELD(monitor, mon_value_reset)
532 
533 #define MONITOR_MAX_VALUE_START(monitor)		\
534 		MONITOR_FIELD(monitor, mon_max_value_start)
535 
536 #define MONITOR_MIN_VALUE_START(monitor)		\
537 		MONITOR_FIELD(monitor, mon_min_value_start)
538 
539 #define MONITOR_LAST_VALUE(monitor)			\
540 		MONITOR_FIELD(monitor, mon_last_value)
541 
542 #define MONITOR_START_VALUE(monitor)			\
543 		MONITOR_FIELD(monitor, mon_start_value)
544 
545 #define MONITOR_VALUE_SINCE_START(monitor)		\
546 		(MONITOR_VALUE(monitor) + MONITOR_VALUE_RESET(monitor))
547 
548 #define MONITOR_STATUS(monitor)				\
549 		MONITOR_FIELD(monitor, mon_status)
550 
551 #define MONITOR_SET_START(monitor)					\
552 	do {								\
553 		MONITOR_STATUS(monitor) = MONITOR_STARTED;		\
554 		MONITOR_FIELD((monitor), mon_start_time) = time(NULL);	\
555 	} while (0)
556 
557 #define MONITOR_SET_OFF(monitor)					\
558 	do {								\
559 		MONITOR_STATUS(monitor) = MONITOR_STOPPED;		\
560 		MONITOR_FIELD((monitor), mon_stop_time) = time(NULL);	\
561 	} while (0)
562 
563 #define	MONITOR_INIT_ZERO_VALUE		0
564 
565 /** Max and min values are initialized when we first turn on the monitor
566 counter, and set the MONITOR_STATUS. */
567 #define MONITOR_MAX_MIN_NOT_INIT(monitor)				\
568 		(MONITOR_STATUS(monitor) == MONITOR_INIT_ZERO_VALUE	\
569 		 && MONITOR_MIN_VALUE(monitor) == MONITOR_INIT_ZERO_VALUE \
570 		 && MONITOR_MAX_VALUE(monitor) == MONITOR_INIT_ZERO_VALUE)
571 
572 #define MONITOR_INIT(monitor)						\
573 	if (MONITOR_MAX_MIN_NOT_INIT(monitor)) {			\
574 		MONITOR_MIN_VALUE(monitor) = MIN_RESERVED;		\
575 		MONITOR_MIN_VALUE_START(monitor) = MIN_RESERVED;	\
576 		MONITOR_MAX_VALUE(monitor) = MAX_RESERVED;		\
577 		MONITOR_MAX_VALUE_START(monitor) = MAX_RESERVED;	\
578 	}
579 
580 /** Macros to increment/decrement the counters. The normal
581 monitor counter operation expects appropriate synchronization
582 already exists. No additional mutex is necessary when operating
583 on the counters */
584 #define	MONITOR_INC(monitor)						\
585 	if (MONITOR_IS_ON(monitor)) {					\
586 		MONITOR_VALUE(monitor)++;				\
587 		if (MONITOR_VALUE(monitor) > MONITOR_MAX_VALUE(monitor)) {  \
588 			MONITOR_MAX_VALUE(monitor) = MONITOR_VALUE(monitor);\
589 		}							\
590 	}
591 
592 /** Atomically increment a monitor counter.
593 Use MONITOR_INC if appropriate mutex protection exists.
594 @param monitor monitor to be incremented by 1 */
595 # define MONITOR_ATOMIC_INC(monitor)					\
596 	if (MONITOR_IS_ON(monitor)) {					\
597 		ib_uint64_t	value;					\
598 		value  = os_atomic_increment_uint64(			\
599 			(ib_uint64_t*) &MONITOR_VALUE(monitor),	 1);	\
600 		/* Note: This is not 100% accurate because of the	\
601 		inherent race, we ignore it due to performance. */	\
602 		if (value > (ib_uint64_t) MONITOR_MAX_VALUE(monitor)) {	\
603 			MONITOR_MAX_VALUE(monitor) = value;		\
604 		}							\
605 	}
606 
607 /** Atomically decrement a monitor counter.
608 Use MONITOR_DEC if appropriate mutex protection exists.
609 @param monitor monitor to be decremented by 1 */
610 # define MONITOR_ATOMIC_DEC(monitor)					\
611 	if (MONITOR_IS_ON(monitor)) {					\
612 		ib_uint64_t	value;					\
613 		value = os_atomic_decrement_uint64(			\
614 			(ib_uint64_t*) &MONITOR_VALUE(monitor), 1);	\
615 		/* Note: This is not 100% accurate because of the	\
616 		inherent race, we ignore it due to performance. */	\
617 		if (value < (ib_uint64_t) MONITOR_MIN_VALUE(monitor)) {	\
618 			MONITOR_MIN_VALUE(monitor) = value;		\
619 		}							\
620 	}
621 
622 #define	MONITOR_DEC(monitor)						\
623 	if (MONITOR_IS_ON(monitor)) {					\
624 		MONITOR_VALUE(monitor)--;				\
625 		if (MONITOR_VALUE(monitor) < MONITOR_MIN_VALUE(monitor)) {  \
626 			MONITOR_MIN_VALUE(monitor) = MONITOR_VALUE(monitor);\
627 		}							\
628 	}
629 
630 #ifdef UNIV_DEBUG_VALGRIND
631 # define MONITOR_CHECK_DEFINED(value) do {	\
632 	mon_type_t m = value;			\
633 	UNIV_MEM_ASSERT_RW(&m, sizeof m);	\
634 } while (0)
635 #else /* UNIV_DEBUG_VALGRIND */
636 # define MONITOR_CHECK_DEFINED(value) (void) 0
637 #endif /* UNIV_DEBUG_VALGRIND */
638 
639 #define	MONITOR_INC_VALUE(monitor, value)				\
640 	MONITOR_CHECK_DEFINED(value);					\
641 	if (MONITOR_IS_ON(monitor)) {					\
642 		MONITOR_VALUE(monitor) += (mon_type_t) (value);		\
643 		if (MONITOR_VALUE(monitor) > MONITOR_MAX_VALUE(monitor)) {  \
644 			MONITOR_MAX_VALUE(monitor) = MONITOR_VALUE(monitor);\
645 		}							\
646 	}
647 
648 #define	MONITOR_DEC_VALUE(monitor, value)				\
649 	MONITOR_CHECK_DEFINED(value);					\
650 	if (MONITOR_IS_ON(monitor)) {					\
651 		ut_ad(MONITOR_VALUE(monitor) >= (mon_type_t) (value);	\
652 		MONITOR_VALUE(monitor) -= (mon_type_t) (value);		\
653 		if (MONITOR_VALUE(monitor) < MONITOR_MIN_VALUE(monitor)) {  \
654 			MONITOR_MIN_VALUE(monitor) = MONITOR_VALUE(monitor);\
655 		}							\
656 	}
657 
658 /* Increment/decrement counter without check the monitor on/off bit, which
659 could already be checked as a module group */
660 #define	MONITOR_INC_NOCHECK(monitor)					\
661 	do {								\
662 		MONITOR_VALUE(monitor)++;				\
663 		if (MONITOR_VALUE(monitor) > MONITOR_MAX_VALUE(monitor)) {  \
664 			MONITOR_MAX_VALUE(monitor) = MONITOR_VALUE(monitor);\
665 		}							\
666 	} while (0)							\
667 
668 #define	MONITOR_DEC_NOCHECK(monitor)					\
669 	do {								\
670 		MONITOR_VALUE(monitor)--;				\
671 		if (MONITOR_VALUE(monitor) < MONITOR_MIN_VALUE(monitor)) {  \
672 			MONITOR_MIN_VALUE(monitor) = MONITOR_VALUE(monitor);\
673 		}							\
674 	} while (0)
675 
676 /** Directly set a monitor counter's value */
677 #define	MONITOR_SET(monitor, value)					\
678 	MONITOR_CHECK_DEFINED(value);					\
679 	if (MONITOR_IS_ON(monitor)) {					\
680 		MONITOR_VALUE(monitor) = (mon_type_t) (value);		\
681 		if (MONITOR_VALUE(monitor) > MONITOR_MAX_VALUE(monitor)) {  \
682 			MONITOR_MAX_VALUE(monitor) = MONITOR_VALUE(monitor);\
683 		}							\
684 		if (MONITOR_VALUE(monitor) < MONITOR_MIN_VALUE(monitor)) {  \
685 			MONITOR_MIN_VALUE(monitor) = MONITOR_VALUE(monitor);\
686 		}							\
687 	}
688 
689 /** Add time difference between now and input "value" (in seconds) to the
690 monitor counter
691 @param monitor monitor to update for the time difference
692 @param value the start time value */
693 #define	MONITOR_INC_TIME_IN_MICRO_SECS(monitor, value)			\
694 	MONITOR_CHECK_DEFINED(value);					\
695 	if (MONITOR_IS_ON(monitor)) {					\
696 		uint64_t	old_time = (value);			\
697 		value = ut_time_monotonic_us(); 			\
698 		MONITOR_VALUE(monitor) += (mon_type_t) (value - old_time);\
699 	}
700 
701 /** This macro updates 3 counters in one call. However, it only checks the
702 main/first monitor counter 'monitor', to see it is on or off to decide
703 whether to do the update.
704 @param monitor the main monitor counter to update. It accounts for
705 			the accumulative value for the counter.
706 @param monitor_n_calls counter that counts number of times this macro is
707 			called
708 @param monitor_per_call counter that records the current and max value of
709 			each incremental value
710 @param value incremental value to record this time */
711 #define MONITOR_INC_VALUE_CUMULATIVE(					\
712 		monitor, monitor_n_calls, monitor_per_call, value)	\
713 	MONITOR_CHECK_DEFINED(value);					\
714 	if (MONITOR_IS_ON(monitor)) {					\
715 		MONITOR_VALUE(monitor_n_calls)++;			\
716 		MONITOR_VALUE(monitor_per_call) = (mon_type_t) (value);	\
717 		if (MONITOR_VALUE(monitor_per_call)			\
718 		    > MONITOR_MAX_VALUE(monitor_per_call)) {		\
719 			MONITOR_MAX_VALUE(monitor_per_call) =		\
720 				 (mon_type_t) (value);			\
721 		}							\
722 		MONITOR_VALUE(monitor) += (mon_type_t) (value);		\
723 		if (MONITOR_VALUE(monitor) > MONITOR_MAX_VALUE(monitor)) {  \
724 			MONITOR_MAX_VALUE(monitor) = MONITOR_VALUE(monitor);\
725 		}							\
726 	}
727 
728 /** Directly set a monitor counter's value, and if the value
729 is monotonically increasing, only max value needs to be updated */
730 #define	MONITOR_SET_UPD_MAX_ONLY(monitor, value)			\
731 	MONITOR_CHECK_DEFINED(value);					\
732 	if (MONITOR_IS_ON(monitor)) {					\
733 		MONITOR_VALUE(monitor) = (mon_type_t) (value);		\
734 		if (MONITOR_VALUE(monitor) > MONITOR_MAX_VALUE(monitor)) {  \
735 			MONITOR_MAX_VALUE(monitor) = MONITOR_VALUE(monitor);\
736 		}							\
737 	}
738 
739 /** Some values such as log sequence number are montomically increasing
740 number, do not need to record max/min values */
741 #define MONITOR_SET_SIMPLE(monitor, value)				\
742 	MONITOR_CHECK_DEFINED(value);					\
743 	if (MONITOR_IS_ON(monitor)) {					\
744 		MONITOR_VALUE(monitor) = (mon_type_t) (value);		\
745 	}
746 
747 /** Reset the monitor value and max/min value to zero. The reset
748 operation would only be conducted when the counter is turned off */
749 #define MONITOR_RESET_ALL(monitor)					\
750 	do {								\
751 		MONITOR_VALUE(monitor) = MONITOR_INIT_ZERO_VALUE;	\
752 		MONITOR_MAX_VALUE(monitor) = MAX_RESERVED;		\
753 		MONITOR_MIN_VALUE(monitor) = MIN_RESERVED;		\
754 		MONITOR_VALUE_RESET(monitor) = MONITOR_INIT_ZERO_VALUE;	\
755 		MONITOR_MAX_VALUE_START(monitor) = MAX_RESERVED;	\
756 		MONITOR_MIN_VALUE_START(monitor) = MIN_RESERVED;	\
757 		MONITOR_LAST_VALUE(monitor) = MONITOR_INIT_ZERO_VALUE;	\
758 		MONITOR_FIELD(monitor, mon_start_time) =		\
759 					MONITOR_INIT_ZERO_VALUE;	\
760 		MONITOR_FIELD(monitor, mon_stop_time) =			\
761 					MONITOR_INIT_ZERO_VALUE;	\
762 		MONITOR_FIELD(monitor, mon_reset_time) =		\
763 					MONITOR_INIT_ZERO_VALUE;	\
764 	} while (0)
765 
766 /** Following four macros defines necessary operations to fetch and
767 consolidate information from existing system status variables. */
768 
769 /** Save the passed-in value to mon_start_value field of monitor
770 counters */
771 #define MONITOR_SAVE_START(monitor, value) do {				\
772 	MONITOR_CHECK_DEFINED(value);					\
773 	(MONITOR_START_VALUE(monitor) =					\
774 		(mon_type_t) (value) - MONITOR_VALUE_RESET(monitor));	\
775 	} while (0)
776 
777 /** Save the passed-in value to mon_last_value field of monitor
778 counters */
779 #define MONITOR_SAVE_LAST(monitor)					\
780 	do {								\
781 		MONITOR_LAST_VALUE(monitor) = MONITOR_VALUE(monitor);	\
782 		MONITOR_START_VALUE(monitor) += MONITOR_VALUE(monitor);	\
783 	} while (0)
784 
785 /** Set monitor value to the difference of value and mon_start_value
786 compensated by mon_last_value if accumulated value is required. */
787 #define MONITOR_SET_DIFF(monitor, value)				\
788 	MONITOR_SET_UPD_MAX_ONLY(monitor, ((value)			\
789 	- MONITOR_VALUE_RESET(monitor)					\
790 	- MONITOR_FIELD(monitor, mon_start_value)			\
791 	+ MONITOR_FIELD(monitor, mon_last_value)))
792 
793 /****************************************************************//**
794 Get monitor's monitor_info_t by its monitor id (index into the
795 innodb_counter_info array
796 @return Point to corresponding monitor_info_t, or NULL if no such
797 monitor */
798 monitor_info_t*
799 srv_mon_get_info(
800 /*=============*/
801 	monitor_id_t	monitor_id);	/*!< id index into the
802 					innodb_counter_info array */
803 /****************************************************************//**
804 Get monitor's name by its monitor id (index into the
805 innodb_counter_info array
806 @return corresponding monitor name, or NULL if no such
807 monitor */
808 const char*
809 srv_mon_get_name(
810 /*=============*/
811 	monitor_id_t	monitor_id);	/*!< id index into the
812 					innodb_counter_info array */
813 
814 /****************************************************************//**
815 Turn on/off/reset monitor counters in a module. If module_value
816 is NUM_MONITOR then turn on all monitor counters.
817 @return 0 if successful, or the first monitor that cannot be
818 turned on because it is already turned on. */
819 void
820 srv_mon_set_module_control(
821 /*=======================*/
822 	monitor_id_t	module_id,	/*!< in: Module ID as in
823 					monitor_counter_id. If it is
824 					set to NUM_MONITOR, this means
825 					we shall turn on all the counters */
826 	mon_option_t	set_option);	/*!< in: Turn on/off reset the
827 					counter */
828 /****************************************************************//**
829 This function consolidates some existing server counters used
830 by "system status variables". These existing system variables do not have
831 mechanism to start/stop and reset the counters, so we simulate these
832 controls by remembering the corresponding counter values when the
833 corresponding monitors are turned on/off/reset, and do appropriate
834 mathematics to deduct the actual value. */
835 void
836 srv_mon_process_existing_counter(
837 /*=============================*/
838 	monitor_id_t	monitor_id,	/*!< in: the monitor's ID as in
839 					monitor_counter_id */
840 	mon_option_t	set_option);	/*!< in: Turn on/off reset the
841 					counter */
842 /*************************************************************//**
843 This function is used to calculate the maximum counter value
844 since the start of monitor counter
845 @return max counter value since start. */
846 UNIV_INLINE
847 mon_type_t
848 srv_mon_calc_max_since_start(
849 /*=========================*/
850 	monitor_id_t	monitor);	/*!< in: monitor id */
851 /*************************************************************//**
852 This function is used to calculate the minimum counter value
853 since the start of monitor counter
854 @return min counter value since start. */
855 UNIV_INLINE
856 mon_type_t
857 srv_mon_calc_min_since_start(
858 /*=========================*/
859 	monitor_id_t	monitor);	/*!< in: monitor id*/
860 /*************************************************************//**
861 Reset a monitor, create a new base line with the current monitor
862 value. This baseline is recorded by MONITOR_VALUE_RESET(monitor) */
863 void
864 srv_mon_reset(
865 /*==========*/
866 	monitor_id_t	monitor);	/*!< in: monitor id*/
867 /*************************************************************//**
868 This function resets all values of a monitor counter */
869 UNIV_INLINE
870 void
871 srv_mon_reset_all(
872 /*==============*/
873 	monitor_id_t	monitor);	/*!< in: monitor id*/
874 /*************************************************************//**
875 Turn on monitor counters that are marked as default ON. */
876 void
877 srv_mon_default_on(void);
878 /*====================*/
879 
880 #ifndef UNIV_NONINL
881 #include "srv0mon.ic"
882 #endif
883 #else /* !UNIV_HOTBACKUP */
884 # define MONITOR_INC(x)		((void) 0)
885 # define MONITOR_DEC(x)		((void) 0)
886 #endif /* !UNIV_HOTBACKUP */
887 
888 #endif
889