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