CUBRID Engine  latest
perf_monitor.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * perf_monitor.c - Monitor execution statistics at Client
21  * Monitor execution statistics
22  * Monitor execution statistics at Server
23  * diag server module
24  */
25 
26 #include <stdio.h>
27 #include <time.h>
28 #include <assert.h>
29 #if !defined (WINDOWS)
30 #include <sys/time.h>
31 #include <sys/resource.h>
32 #endif /* WINDOWS */
33 
34 #include "perf_monitor.h"
35 
36 #include "error_manager.h"
37 #include "object_representation.h"
38 #if !defined(SERVER_MODE)
39 #include "memory_alloc.h"
40 #include "server_interface.h"
41 #endif /* !SERVER_MODE */
42 #include "thread_worker_pool.hpp"
43 #if defined (SERVER_MODE)
44 #include "thread_daemon.hpp"
45 #endif // SERVER_MODE
46 #if defined (SERVER_MODE) || defined (SA_MODE)
47 #include "thread_manager.hpp" // for thread_get_thread_entry_info
48 #endif // SERVER_MODE or SA_MODE
49 
50 #include <cstring>
51 
52 #if defined(SERVER_MODE)
53 #include <string.h>
54 #include <errno.h>
55 #include <sys/types.h>
56 
57 #if !defined(WINDOWS)
58 #include <sys/shm.h>
59 #include <sys/ipc.h>
60 #endif /* WINDOWS */
61 
62 #include <sys/stat.h>
63 #include "connection_defs.h"
64 #include "environment_variable.h"
65 #include "connection_error.h"
66 #include "databases_file.h"
67 #endif /* SERVER_MODE */
68 
69 #if defined (SERVER_MODE) || defined (SA_MODE)
70 #include <string.h>
71 
72 #include "log_impl.h"
73 #include "session.h"
74 #include "error_manager.h"
75 #include "log_manager.h"
76 #include "server_support.h"
77 #include "system_parameter.h"
78 #include "xserver_interface.h"
79 #include "heap_file.h"
80 #include "vacuum.h"
81 #include "xasl_cache.h"
82 #include "load_worker_manager.hpp"
83 
84 #if defined (SERVER_MODE)
85 #include "connection_error.h"
86 #endif /* SERVER_MODE */
87 
88 #if !defined(SERVER_MODE)
89 #define pthread_mutex_init(a, b)
90 #define pthread_mutex_destroy(a)
91 #define pthread_mutex_lock(a) 0
92 #define pthread_mutex_unlock(a)
93 static int rv;
94 #endif /* SERVER_MODE */
95 #endif /* defined (SERVER_MODE) || defined (SA_MODE) */
96 
97 #if !defined (SERVER_MODE)
98 #include "network_interface_cl.h"
99 #endif /* !defined (SERVER_MODE) */
100 
101 /* Custom values. */
102 #define PSTAT_VALUE_CUSTOM 0x00000001
103 
104 #define PSTAT_METADATA_INIT_SINGLE_ACC(id, name) { id, name, PSTAT_ACCUMULATE_SINGLE_VALUE, 0, 0, NULL, NULL, NULL }
105 #define PSTAT_METADATA_INIT_SINGLE_PEEK(id, name) \
106  { id, name, PSTAT_PEEK_SINGLE_VALUE, 0, 0, NULL, NULL, NULL }
107 #define PSTAT_METADATA_INIT_COUNTER_TIMER(id, name) { id, name, PSTAT_COUNTER_TIMER_VALUE, 0, 0, NULL, NULL, NULL }
108 #define PSTAT_METADATA_INIT_COMPUTED_RATIO(id, name) \
109  { id, name, PSTAT_COMPUTED_RATIO_VALUE, 0, 0, NULL, NULL, NULL }
110 #define PSTAT_METADATA_INIT_COMPLEX(id, name, f_dump_in_file, f_dump_in_buffer, f_load) \
111  { id, name, PSTAT_COMPLEX_VALUE, 0, 0, f_dump_in_file, f_dump_in_buffer, f_load }
112 
113 #define PERFMON_VALUES_MEMSIZE (pstat_Global.n_stat_values * sizeof (UINT64))
114 
115 static int f_load_Num_data_page_fix_ext (void);
116 static int f_load_Num_data_page_promote_ext (void);
117 static int f_load_Num_data_page_promote_time_ext (void);
118 static int f_load_Num_data_page_unfix_ext (void);
122 static int f_load_Num_mvcc_snapshot_ext (void);
123 static int f_load_Time_obj_lock_acquire_time (void);
124 static int f_load_Num_dwb_flushed_block_volumes (void);
125 static int f_load_Time_get_snapshot_acquire_time (void);
126 static int f_load_Count_get_snapshot_retry (void);
127 static int f_load_Time_tran_complete_time (void);
129 static int f_load_Count_get_oldest_mvcc_retry (void);
130 static int f_load_thread_stats (void);
131 static int f_load_thread_daemon_stats (void);
132 
133 static void f_dump_in_file_Num_data_page_fix_ext (FILE *, const UINT64 * stat_vals);
134 static void f_dump_in_file_Num_data_page_promote_ext (FILE *, const UINT64 * stat_vals);
135 static void f_dump_in_file_Num_data_page_promote_time_ext (FILE *, const UINT64 * stat_vals);
136 static void f_dump_in_file_Num_data_page_unfix_ext (FILE *, const UINT64 * stat_vals);
137 static void f_dump_in_file_Time_data_page_lock_acquire_time (FILE *, const UINT64 * stat_vals);
138 static void f_dump_in_file_Time_data_page_hold_acquire_time (FILE *, const UINT64 * stat_vals);
139 static void f_dump_in_file_Time_data_page_fix_acquire_time (FILE *, const UINT64 * stat_vals);
140 static void f_dump_in_file_Num_mvcc_snapshot_ext (FILE *, const UINT64 * stat_vals);
141 static void f_dump_in_file_Time_obj_lock_acquire_time (FILE *, const UINT64 * stat_vals);
142 static void f_dump_in_file_thread_stats (FILE * f, const UINT64 * stat_vals);
143 static void f_dump_in_file_thread_daemon_stats (FILE * f, const UINT64 * stat_vals);
144 static void f_dump_in_file_Num_dwb_flushed_block_volumes (FILE *, const UINT64 * stat_vals);
145 
146 static void f_dump_in_buffer_Num_data_page_fix_ext (char **, const UINT64 * stat_vals, int *remaining_size);
147 static void f_dump_in_buffer_Num_data_page_promote_ext (char **, const UINT64 * stat_vals, int *remaining_size);
148 static void f_dump_in_buffer_Num_data_page_promote_time_ext (char **, const UINT64 * stat_vals, int *remaining_size);
149 static void f_dump_in_buffer_Num_data_page_unfix_ext (char **, const UINT64 * stat_vals, int *remaining_size);
150 static void f_dump_in_buffer_Time_data_page_lock_acquire_time (char **, const UINT64 * stat_vals, int *remaining_size);
151 static void f_dump_in_buffer_Time_data_page_hold_acquire_time (char **, const UINT64 * stat_vals, int *remaining_size);
152 static void f_dump_in_buffer_Time_data_page_fix_acquire_time (char **, const UINT64 * stat_vals, int *remaining_size);
153 static void f_dump_in_buffer_Num_mvcc_snapshot_ext (char **, const UINT64 * stat_vals, int *remaining_size);
154 static void f_dump_in_buffer_Time_obj_lock_acquire_time (char **, const UINT64 * stat_vals, int *remaining_size);
155 static void f_dump_in_buffer_thread_stats (char **s, const UINT64 * stat_vals, int *remaining_size);
156 static void f_dump_in_buffer_thread_daemon_stats (char **s, const UINT64 * stat_vals, int *remaining_size);
157 static void f_dump_in_buffer_Num_dwb_flushed_block_volumes (char **s, const UINT64 * stat_vals, int *remaining_size);
158 
159 static void perfmon_stat_dump_in_file_fix_page_array_stat (FILE *, const UINT64 * stats_ptr);
160 static void perfmon_stat_dump_in_file_promote_page_array_stat (FILE *, const UINT64 * stats_ptr);
161 static void perfmon_stat_dump_in_file_unfix_page_array_stat (FILE *, const UINT64 * stats_ptr);
162 static void perfmon_stat_dump_in_file_page_lock_time_array_stat (FILE *, const UINT64 * stats_ptr);
163 static void perfmon_stat_dump_in_file_page_hold_time_array_stat (FILE *, const UINT64 * stats_ptr);
164 static void perfmon_stat_dump_in_file_page_fix_time_array_stat (FILE *, const UINT64 * stats_ptr);
165 static void perfmon_stat_dump_in_file_snapshot_array_stat (FILE *, const UINT64 * stats_ptr);
166 static void perfmon_stat_dump_in_file_thread_stats (FILE * stream, const UINT64 * stats_ptr);
167 static void perfmon_stat_dump_in_file_thread_daemon_stats (FILE * stream, const UINT64 * stats_ptr);
168 
169 static void perfmon_stat_dump_in_buffer_fix_page_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size);
170 static void perfmon_stat_dump_in_buffer_promote_page_array_stat (const UINT64 * stats_ptr, char **s,
171  int *remaining_size);
172 static void perfmon_stat_dump_in_buffer_unfix_page_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size);
173 static void perfmon_stat_dump_in_buffer_page_lock_time_array_stat (const UINT64 * stats_ptr, char **s,
174  int *remaining_size);
175 static void perfmon_stat_dump_in_buffer_page_hold_time_array_stat (const UINT64 * stats_ptr, char **s,
176  int *remaining_size);
177 static void perfmon_stat_dump_in_buffer_page_fix_time_array_stat (const UINT64 * stats_ptr, char **s,
178  int *remaining_size);
179 static void perfmon_stat_dump_in_buffer_snapshot_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size);
180 static void perfmon_stat_dump_in_buffer_thread_stats (const UINT64 * stats_ptr, char **s, int *remaining_size);
181 static void perfmon_stat_dump_in_buffer_thread_daemon_stats (const UINT64 * stats_ptr, char **s, int *remaining_size);
182 
183 static void perfmon_print_timer_to_file (FILE * stream, int stat_index, UINT64 * stats_ptr);
184 static void perfmon_print_timer_to_buffer (char **s, int stat_index, UINT64 * stats_ptr, int *remained_size);
185 
187 STATIC_INLINE size_t perfmon_thread_daemon_stats_count (void) __attribute__ ((ALWAYS_INLINE));
188 #if defined (SERVER_MODE)
189 static void perfmon_peek_thread_daemon_stats (UINT64 * stats);
190 #endif // SERVER_MODE
191 
193 
195  /* Execution statistics for the file io */
204 
205  /* Page buffer basic module */
206  /* Execution statistics for the page buffer manager */
207  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_NUM_FETCHES, "Num_data_page_fetches"),
208  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_NUM_DIRTIES, "Num_data_page_dirties"),
209  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_NUM_IOREADS, "Num_data_page_ioreads"),
210  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_NUM_IOWRITES, "Num_data_page_iowrites"),
211  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_NUM_FLUSHED, "Num_data_page_flushed"),
212  /* peeked stats */
213  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_PRIVATE_QUOTA, "Num_data_page_private_quota"),
214  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_PRIVATE_COUNT, "Num_data_page_private_count"),
215  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_FIXED_CNT, "Num_data_page_fixed"),
216  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_DIRTY_CNT, "Num_data_page_dirty"),
217  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_LRU1_CNT, "Num_data_page_lru1"),
218  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_LRU2_CNT, "Num_data_page_lru2"),
219  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_LRU3_CNT, "Num_data_page_lru3"),
220  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_VICT_CAND, "Num_data_page_victim_candidate"),
221 
222  /* Execution statistics for the log manager */
223  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_LOG_NUM_FETCHES, "Num_log_page_fetches"),
224  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_LOG_NUM_IOREADS, "Num_log_page_ioreads"),
225  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_LOG_NUM_IOWRITES, "Num_log_page_iowrites"),
226  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_LOG_NUM_APPENDRECS, "Num_log_append_records"),
231  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_LOG_NUM_REPLACEMENTS_IOWRITES, "Num_log_page_iowrites_for_replacement"),
232  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_LOG_NUM_REPLACEMENTS, "Num_log_page_replacements"),
233 
234  /* Execution statistics for the lock manager */
240  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_LK_NUM_RE_REQUESTED_ON_OBJECTS, "Num_object_locks_re-requested"),
241  /* TODO: Count and timer */
243  /* TODO: Count and timer */
245  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_LK_NUM_WAITED_TIME_ON_OBJECTS, "Num_object_locks_time_waited_usec"),
246 
247  /* Execution statistics for transactions */
254  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_TRAN_NUM_PPCACHE_HITS, "Num_tran_postpone_cache_hits"),
255  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_TRAN_NUM_PPCACHE_MISS, "Num_tran_postpone_cache_miss"),
256  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_TRAN_NUM_TOPOP_PPCACHE_HITS, "Num_tran_topop_postpone_cache_hits"),
257  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_TRAN_NUM_TOPOP_PPCACHE_MISS, "Num_tran_topop_postpone_cache_miss"),
258 
259  /* Execution statistics for the btree manager */
266  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_BT_NUM_MULTI_RANGE_OPT, "Num_btree_multirange_optimization"),
270 
275 
276  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_BT_ONLINE_NUM_INSERTS, "Num_btree_online_inserts"),
278  "Num_btree_online_inserts_same_page_hold"),
279  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_BT_ONLINE_NUM_RETRY, "Num_btree_online_inserts_retry"),
280  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_BT_ONLINE_NUM_RETRY_NICE, "Num_btree_online_inserts_retry_nice"),
281 
282  /* Execution statistics for the query manager */
295  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_QM_NUM_HOLDABLE_CURSORS, "Num_query_holdable_cursors"),
296 
297  /* Execution statistics for external sort */
300 
301  /* Execution statistics for network communication */
302  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_NET_NUM_REQUESTS, "Num_network_requests"),
303 
304  /* flush control stat */
305  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_FC_NUM_PAGES, "Num_adaptive_flush_pages"),
306  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_FC_NUM_LOG_PAGES, "Num_adaptive_flush_log_pages"),
307  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_FC_TOKENS, "Num_adaptive_flush_max_pages"),
308 
309  /* prior lsa info */
310  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PRIOR_LSA_LIST_SIZE, "Num_prior_lsa_list_size"),
311  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PRIOR_LSA_LIST_MAXED, "Num_prior_lsa_list_maxed"),
312  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PRIOR_LSA_LIST_REMOVED, "Num_prior_lsa_list_removed"),
313 
314  /* HA replication delay */
315  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_HA_REPL_DELAY, "Time_ha_replication_delay"),
316 
317  /* Execution statistics for Plan cache */
318  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PC_NUM_ADD, "Num_plan_cache_add"),
319  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PC_NUM_LOOKUP, "Num_plan_cache_lookup"),
320  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PC_NUM_HIT, "Num_plan_cache_hit"),
321  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PC_NUM_MISS, "Num_plan_cache_miss"),
322  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PC_NUM_FULL, "Num_plan_cache_full"),
323  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PC_NUM_DELETE, "Num_plan_cache_delete"),
324  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PC_NUM_INVALID_XASL_ID, "Num_plan_cache_invalid_xasl_id"),
326 
327  /* Vacuum process log section. */
328  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_VAC_NUM_VACUUMED_LOG_PAGES, "Num_vacuum_log_pages_vacuumed"),
329  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_VAC_NUM_TO_VACUUM_LOG_PAGES, "Num_vacuum_log_pages_to_vacuum"),
330  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_VAC_NUM_PREFETCH_REQUESTS_LOG_PAGES, "Num_vacuum_prefetch_requests_log_pages"),
331  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_VAC_NUM_PREFETCH_HITS_LOG_PAGES, "Num_vacuum_prefetch_hits_log_pages"),
332 
333  /* Track heap modify counters. */
334  /* Make a complex entry for heap stats */
335  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_HOME_INSERTS, "Num_heap_home_inserts"),
336  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_BIG_INSERTS, "Num_heap_big_inserts"),
337  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_ASSIGN_INSERTS, "Num_heap_assign_inserts"),
338  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_HOME_DELETES, "Num_heap_home_deletes"),
339  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_HOME_MVCC_DELETES, "Num_heap_home_mvcc_deletes"),
340  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_HOME_TO_REL_DELETES, "Num_heap_home_to_rel_deletes"),
341  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_HOME_TO_BIG_DELETES, "Num_heap_home_to_big_deletes"),
342  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REL_DELETES, "Num_heap_rel_deletes"),
343  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REL_MVCC_DELETES, "Num_heap_rel_mvcc_deletes"),
344  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REL_TO_HOME_DELETES, "Num_heap_rel_to_home_deletes"),
345  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REL_TO_BIG_DELETES, "Num_heap_rel_to_big_deletes"),
346  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REL_TO_REL_DELETES, "Num_heap_rel_to_rel_deletes"),
347  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_BIG_DELETES, "Num_heap_big_deletes"),
348  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_BIG_MVCC_DELETES, "Num_heap_big_mvcc_deletes"),
349  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_HOME_UPDATES, "Num_heap_home_updates"),
350  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_HOME_TO_REL_UPDATES, "Num_heap_home_to_rel_updates"),
351  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_HOME_TO_BIG_UPDATES, "Num_heap_home_to_big_updates"),
352  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REL_UPDATES, "Num_heap_rel_updates"),
353  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REL_TO_HOME_UPDATES, "Num_heap_rel_to_home_updates"),
354  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REL_TO_REL_UPDATES, "Num_heap_rel_to_rel_updates"),
355  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REL_TO_BIG_UPDATES, "Num_heap_rel_to_big_updates"),
356  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_BIG_UPDATES, "Num_heap_big_updates"),
357  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_HOME_VACUUMS, "Num_heap_home_vacuums"),
358  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_BIG_VACUUMS, "Num_heap_big_vacuums"),
359  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REL_VACUUMS, "Num_heap_rel_vacuums"),
360  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_INSID_VACUUMS, "Num_heap_insid_vacuums"),
361  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HEAP_REMOVE_VACUUMS, "Num_heap_remove_vacuums"),
362 
363  /* Track heap modify timers. */
376 
377  /* Execution statistics for the heap manager */
378  /* best space info */
380  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_HF_NUM_STATS_ENTRIES, "Num_heap_stats_bestspace_entries"),
381  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_HF_NUM_STATS_MAXED, "Num_heap_stats_bestspace_maxed"),
387 
388  /* B-tree detailed statistics. */
392 
395 
398 
401 
404 
407 
410 
413 
416 
419 
422 
425 
428 
429  /* Vacuum master/worker timers. */
434 
435  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_LOG_SNAPSHOT_TIME_COUNTERS, "Time_get_snapshot_acquire_time"),
440 
441  /* computed statistics */
442  PSTAT_METADATA_INIT_COMPUTED_RATIO (PSTAT_PB_HIT_RATIO, "Data_page_buffer_hit_ratio"),
443  PSTAT_METADATA_INIT_COMPUTED_RATIO (PSTAT_LOG_HIT_RATIO, "Log_page_buffer_hit_ratio"),
444  PSTAT_METADATA_INIT_COMPUTED_RATIO (PSTAT_VACUUM_DATA_HIT_RATIO, "Vacuum_data_page_buffer_hit_ratio"),
445  PSTAT_METADATA_INIT_COMPUTED_RATIO (PSTAT_PB_VACUUM_EFFICIENCY, "Vacuum_page_efficiency_ratio"),
447 
448  PSTAT_METADATA_INIT_COMPUTED_RATIO (PSTAT_PB_PAGE_LOCK_ACQUIRE_TIME_10USEC, "Data_page_fix_lock_acquire_time_msec"),
449  PSTAT_METADATA_INIT_COMPUTED_RATIO (PSTAT_PB_PAGE_HOLD_ACQUIRE_TIME_10USEC, "Data_page_fix_hold_acquire_time_msec"),
452  PSTAT_METADATA_INIT_COMPUTED_RATIO (PSTAT_PB_PAGE_PROMOTE_SUCCESS, "Data_page_total_promote_success"),
453  PSTAT_METADATA_INIT_COMPUTED_RATIO (PSTAT_PB_PAGE_PROMOTE_FAILED, "Data_page_total_promote_fail"),
455 
456  /* Page buffer extended */
457  /* detailed unfix module */
458  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_VOID_TO_PRIVATE_TOP, "Num_unfix_void_to_private_top"),
459  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_VOID_TO_PRIVATE_MID, "Num_unfix_void_to_private_mid"),
460  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_VOID_TO_SHARED_MID, "Num_unfix_void_to_shared_mid"),
461  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_ONE_PRV_TO_SHR_MID, "Num_unfix_lru1_private_to_shared_mid"),
462  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_TWO_PRV_TO_SHR_MID, "Num_unfix_lru2_private_to_shared_mid"),
463  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_THREE_PRV_TO_SHR_MID, "Num_unfix_lru3_private_to_shared_mid"),
464  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_TWO_PRV_KEEP, "Num_unfix_lru2_private_keep"),
465  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_TWO_SHR_KEEP, "Num_unfix_lru2_shared_keep"),
466  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_TWO_PRV_TO_TOP, "Num_unfix_lru2_private_to_top"),
467  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_TWO_SHR_TO_TOP, "Num_unfix_lru2_shared_to_top"),
468  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_THREE_PRV_TO_TOP, "Num_unfix_lru3_private_to_top"),
470  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_ONE_PRV_KEEP, "Num_unfix_lru1_private_keep"),
471  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_ONE_SHR_KEEP, "Num_unfix_lru1_shared_keep"),
472  /* vacuum */
473  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_VOID_TO_PRIVATE_TOP_VAC, "Num_unfix_void_to_private_mid_vacuum"),
474  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_ONE_KEEP_VAC, "Num_unfix_lru1_any_keep_vacuum"),
475  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_TWO_KEEP_VAC, "Num_unfix_lru2_any_keep_vacuum"),
476  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_LRU_THREE_KEEP_VAC, "Num_unfix_lru3_any_keep_vacuum"),
477  /* aout */
478  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_VOID_AOUT_FOUND, "Num_unfix_void_aout_found"),
479  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_VOID_AOUT_NOT_FOUND, "Num_unfix_void_aout_not_found"),
480  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_VOID_AOUT_FOUND_VAC, "Num_unfix_void_aout_found_vacuum"),
481  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_UNFIX_VOID_AOUT_NOT_FOUND_VAC, "Num_unfix_void_aout_not_found_vacuum"),
482  /* hash anchor */
483  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_NUM_HASH_ANCHOR_WAITS, "Num_data_page_hash_anchor_waits"),
484  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_TIME_HASH_ANCHOR_WAIT, "Time_data_page_hash_anchor_wait"),
485  /* flushing */
492  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_FLUSH_SEND_DIRTY_TO_POST_FLUSH, "Num_data_page_dirty_to_post_flush"),
493  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_NUM_SKIPPED_FLUSH, "Num_data_page_skipped_flush"),
494  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_NUM_SKIPPED_NEED_WAL, "Num_data_page_skipped_flush_need_wal"),
495  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_NUM_SKIPPED_ALREADY_FLUSHED, "Num_data_page_skipped_flush_already_flushed"),
496  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_NUM_SKIPPED_FIXED_OR_HOT, "Num_data_page_skipped_flush_fixed_or_hot"),
500  /* allocate and victim assignments */
505  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_ALLOC_BCB_PRIORITIZE_VACUUM, "Num_alloc_bcb_prioritize_vacuum"),
506  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_USE_INVALID_BCB, "Num_victim_use_invalid_bcb"),
507  /* direct assignments */
509  "alloc_bcb_get_victim_search_own_private_list"),
511  "alloc_bcb_get_victim_search_others_private_list"),
512  PSTAT_METADATA_INIT_COUNTER_TIMER (PSTAT_PB_VICTIM_SEARCH_SHARED_LISTS, "alloc_bcb_get_victim_search_shared_list"),
513  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_ASSIGN_DIRECT_VACUUM_VOID, "Num_victim_assign_direct_vacuum_void"),
514  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_ASSIGN_DIRECT_VACUUM_LRU, "Num_victim_assign_direct_vacuum_lru"),
515  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_ASSIGN_DIRECT_FLUSH, "Num_victim_assign_direct_flush"),
516  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_ASSIGN_DIRECT_PANIC, "Num_victim_assign_direct_panic"),
517  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_ASSIGN_DIRECT_ADJUST, "Num_victim_assign_direct_adjust_lru"),
519  "Num_victim_assign_direct_adjust_lru_to_vacuum"),
521  "Num_victim_assign_direct_search_for_flush"),
522  /* successful searches */
523  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_SHARED_LRU_SUCCESS, "Num_victim_shared_lru_success"),
524  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_OWN_VICTIM_PRIVATE_LRU_SUCCESS, "Num_victim_own_private_lru_success"),
525  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_OTHER_PRIVATE_LRU_SUCCESS, "Num_victim_other_private_lru_success"),
526  /* failed searches */
527  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_SHARED_LRU_FAIL, "Num_victim_shared_lru_fail"),
528  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_OWN_PRIVATE_LRU_FAIL, "Num_victim_own_private_lru_fail"),
529  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_OTHER_PRIVATE_LRU_FAIL, "Num_victim_other_private_lru_fail"),
531  /* search lru's */
534  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_GET_FROM_LRU_FAIL, "Num_victim_get_from_lru_fail"),
535  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_VICTIM_GET_FROM_LRU_BAD_HINT, "Num_victim_get_from_lru_bad_hint"),
536  /* lock-free circular queues with lru lists having victims */
537  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_LFCQ_LRU_PRV_GET_CALLS, "Num_lfcq_prv_get_total_calls"),
540  PSTAT_METADATA_INIT_SINGLE_ACC (PSTAT_PB_LFCQ_LRU_SHR_GET_CALLS, "Num_lfcq_shr_get_total_calls"),
542 
551 
552  /* Log LZ4 compression statistics */
555 
556  /* peeked stats */
557  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_WAIT_THREADS_HIGH_PRIO, "Num_alloc_bcb_wait_threads_high_priority"),
558  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_WAIT_THREADS_LOW_PRIO, "Num_alloc_bcb_wait_threads_low_priority"),
559  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_FLUSHED_BCBS_WAIT_FOR_ASSIGN, "Num_flushed_bcbs_wait_for_direct_victim"),
560  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_LFCQ_BIG_PRV_NUM, "Num_lfcq_big_private_lists"),
561  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_LFCQ_PRV_NUM, "Num_lfcq_private_lists"),
562  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_LFCQ_SHR_NUM, "Num_lfcq_shared_lists"),
563  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_AVOID_DEALLOC_CNT, "Num_data_page_avoid_dealloc"),
564  PSTAT_METADATA_INIT_SINGLE_PEEK (PSTAT_PB_AVOID_VICTIM_CNT, "Num_data_page_avoid_victim"),
565 
566  /* Array type statistics */
569  PSTAT_METADATA_INIT_COMPLEX (PSTAT_PBX_PROMOTE_COUNTERS, "Num_data_page_promote_ext",
572  PSTAT_METADATA_INIT_COMPLEX (PSTAT_PBX_PROMOTE_TIME_COUNTERS, "Num_data_page_promote_time_ext",
576  PSTAT_METADATA_INIT_COMPLEX (PSTAT_PBX_UNFIX_COUNTERS, "Num_data_page_unfix_ext",
579  PSTAT_METADATA_INIT_COMPLEX (PSTAT_PBX_LOCK_TIME_COUNTERS, "Time_data_page_lock_acquire_time",
583  PSTAT_METADATA_INIT_COMPLEX (PSTAT_PBX_HOLD_TIME_COUNTERS, "Time_data_page_hold_acquire_time",
587  PSTAT_METADATA_INIT_COMPLEX (PSTAT_PBX_FIX_TIME_COUNTERS, "Time_data_page_fix_acquire_time",
594  PSTAT_METADATA_INIT_COMPLEX (PSTAT_OBJ_LOCK_TIME_COUNTERS, "Time_obj_lock_acquire_time",
599  PSTAT_METADATA_INIT_COMPLEX (PSTAT_THREAD_DAEMON_STATS, "Thread_pgbuf_daemon_stats_counters_timers",
602  PSTAT_METADATA_INIT_COMPLEX (PSTAT_DWB_FLUSHED_BLOCK_NUM_VOLUMES, "Num_dwb_flushed_block_volumes",
606  PSTAT_METADATA_INIT_COMPLEX (PSTAT_LOAD_THREAD_STATS, "Thread_loaddb_stats_counters_timers",
608 };
609 
610 STATIC_INLINE void perfmon_add_stat_at_offset (THREAD_ENTRY * thread_p, PERF_STAT_ID psid, const int offset,
611  UINT64 amount) __attribute__ ((ALWAYS_INLINE));
612 
613 static void perfmon_server_calc_stats (UINT64 * stats);
614 
615 STATIC_INLINE const char *perfmon_stat_module_name (const int module) __attribute__ ((ALWAYS_INLINE));
616 #if defined (SERVER_MODE) || defined (SA_MODE)
617 STATIC_INLINE int perfmon_get_module_type (THREAD_ENTRY * thread_p) __attribute__ ((ALWAYS_INLINE));
618 #endif
619 STATIC_INLINE const char *perfmon_stat_page_type_name (const int page_type) __attribute__ ((ALWAYS_INLINE));
620 STATIC_INLINE const char *perfmon_stat_page_mode_name (const int page_mode) __attribute__ ((ALWAYS_INLINE));
621 STATIC_INLINE const char *perfmon_stat_holder_latch_name (const int holder_latch) __attribute__ ((ALWAYS_INLINE));
622 STATIC_INLINE const char *perfmon_stat_cond_type_name (const int cond_type) __attribute__ ((ALWAYS_INLINE));
623 STATIC_INLINE const char *perfmon_stat_promote_cond_name (const int cond_type) __attribute__ ((ALWAYS_INLINE));
624 STATIC_INLINE const char *perfmon_stat_snapshot_name (const int snapshot) __attribute__ ((ALWAYS_INLINE));
625 STATIC_INLINE const char *perfmon_stat_snapshot_record_type (const int rec_type) __attribute__ ((ALWAYS_INLINE));
626 STATIC_INLINE const char *perfmon_stat_lock_mode_name (const int lock_mode) __attribute__ ((ALWAYS_INLINE));
627 static const char *perfmon_stat_thread_stat_name (size_t index);
628 
629 STATIC_INLINE void perfmon_get_peek_stats (UINT64 * stats) __attribute__ ((ALWAYS_INLINE));
630 
631 #if defined(CS_MODE) || defined(SA_MODE)
632 bool perfmon_Iscollecting_stats = false;
633 
634 /* Client execution statistics */
635 static PERFMON_CLIENT_STAT_INFO perfmon_Stat_info;
636 
637 /*
638  * perfmon_start_stats - Start collecting client execution statistics
639  * return: NO_ERROR or ERROR
640  */
641 int
642 perfmon_start_stats (bool for_all_trans)
643 {
644  int err = NO_ERROR;
645 
646  if (perfmon_Iscollecting_stats == true)
647  {
648  goto exit;
649  }
650 
651  perfmon_Stat_info.old_global_stats = NULL;
652  perfmon_Stat_info.current_global_stats = NULL;
653  perfmon_Stat_info.base_server_stats = NULL;
654  perfmon_Stat_info.current_server_stats = NULL;
655 
657  if (err != NO_ERROR)
658  {
659  ASSERT_ERROR ();
660  goto exit;
661  }
662 
663  perfmon_Iscollecting_stats = true;
664 
665  perfmon_get_current_times (&perfmon_Stat_info.cpu_start_usr_time, &perfmon_Stat_info.cpu_start_sys_time,
666  &perfmon_Stat_info.elapsed_start_time);
667 
668  if (for_all_trans)
669  {
670  perfmon_Stat_info.old_global_stats = perfmon_allocate_values ();
671  if (perfmon_Stat_info.old_global_stats == NULL)
672  {
673  ASSERT_ERROR ();
675  goto exit;
676  }
677  perfmon_Stat_info.current_global_stats = perfmon_allocate_values ();
678 
679  if (perfmon_Stat_info.current_global_stats == NULL)
680  {
681  ASSERT_ERROR ();
683  goto exit;
684  }
685 
686  if (perfmon_get_global_stats () == NO_ERROR)
687  {
688  perfmon_copy_values (perfmon_Stat_info.old_global_stats, perfmon_Stat_info.current_global_stats);
689  }
690  }
691  else
692  {
693  perfmon_Stat_info.base_server_stats = perfmon_allocate_values ();
694  if (perfmon_Stat_info.base_server_stats == NULL)
695  {
696  ASSERT_ERROR ();
698  goto exit;
699  }
700  perfmon_Stat_info.current_server_stats = perfmon_allocate_values ();
701  if (perfmon_Stat_info.current_server_stats == NULL)
702  {
703  ASSERT_ERROR ();
705  goto exit;
706  }
707 
708  if (perfmon_get_stats () == NO_ERROR)
709  {
710  perfmon_copy_values (perfmon_Stat_info.base_server_stats, perfmon_Stat_info.current_server_stats);
711  }
712  }
713 exit:
714  return err;
715 }
716 
717 /*
718  * perfmon_stop_stats - Stop collecting client execution statistics
719  * return: NO_ERROR or ER_FAILED
720  */
721 int
722 perfmon_stop_stats (void)
723 {
724  int err = NO_ERROR;
725 
726  if (perfmon_Iscollecting_stats != false)
727  {
728  err = perfmon_server_stop_stats ();
729  perfmon_Iscollecting_stats = false;
730  }
731 
732  if (perfmon_Stat_info.old_global_stats != NULL)
733  {
734  free_and_init (perfmon_Stat_info.old_global_stats);
735  }
736  if (perfmon_Stat_info.current_global_stats != NULL)
737  {
738  free_and_init (perfmon_Stat_info.current_global_stats);
739  }
740  if (perfmon_Stat_info.base_server_stats != NULL)
741  {
742  free_and_init (perfmon_Stat_info.base_server_stats);
743  }
744 
745  if (perfmon_Stat_info.current_server_stats != NULL)
746  {
747  free_and_init (perfmon_Stat_info.current_server_stats);
748  }
749 
750  return err;
751 }
752 
753 /*
754  * perfmon_reset_stats - Reset client statistics
755  * return: none
756  */
757 void
758 perfmon_reset_stats (void)
759 {
760  if (perfmon_Iscollecting_stats != false)
761  {
762  perfmon_get_current_times (&perfmon_Stat_info.cpu_start_usr_time, &perfmon_Stat_info.cpu_start_sys_time,
763  &perfmon_Stat_info.elapsed_start_time);
764 
765  if (perfmon_get_stats () == NO_ERROR)
766  {
767  perfmon_copy_values (perfmon_Stat_info.base_server_stats, perfmon_Stat_info.current_server_stats);
768  }
769  }
770 }
771 
772 /*
773  * perfmon_get_stats - Get the recorded client statistics
774  * return: client statistics
775  */
776 int
777 perfmon_get_stats (void)
778 {
779  int err = NO_ERROR;
780 
781  if (perfmon_Iscollecting_stats != true)
782  {
783  return ER_FAILED;
784  }
785 
786  err = perfmon_server_copy_stats (perfmon_Stat_info.current_server_stats);
787  return err;
788 }
789 
790 /*
791  * perfmon_get_global_stats - Get the recorded client statistics
792  * return: client statistics
793  */
794 int
795 perfmon_get_global_stats (void)
796 {
797  UINT64 *tmp_stats;
798  int err = NO_ERROR;
799 
800  if (perfmon_Iscollecting_stats != true)
801  {
802  return ER_FAILED;
803  }
804 
805  tmp_stats = perfmon_Stat_info.current_global_stats;
806  perfmon_Stat_info.current_global_stats = perfmon_Stat_info.old_global_stats;
807  perfmon_Stat_info.old_global_stats = tmp_stats;
808 
809  /* Refresh statistics from server */
810  err = perfmon_server_copy_global_stats (perfmon_Stat_info.current_global_stats);
811  if (err != NO_ERROR)
812  {
813  ASSERT_ERROR ();
814  }
815 
816  return err;
817 }
818 
819 /*
820  * perfmon_print_stats - Print the current client statistics
821  * return: error or no error
822  * stream(in): if NULL is given, stdout is used
823  */
824 int
825 perfmon_print_stats (FILE * stream)
826 {
827  time_t cpu_total_usr_time;
828  time_t cpu_total_sys_time;
829  time_t elapsed_total_time;
830  UINT64 *diff_result = NULL;
831  int err = NO_ERROR;
832 
833  if (perfmon_Iscollecting_stats != true)
834  {
835  return err;
836  }
837 
838  diff_result = perfmon_allocate_values ();
839 
840  if (diff_result == NULL)
841  {
842  ASSERT_ERROR ();
844  goto exit;
845  }
846 
847  if (stream == NULL)
848  {
849  stream = stdout;
850  }
851 
852  if (perfmon_get_stats () != NO_ERROR)
853  {
854  ASSERT_ERROR ();
855  goto exit;
856  }
857 
858  perfmon_get_current_times (&cpu_total_usr_time, &cpu_total_sys_time, &elapsed_total_time);
859 
860  fprintf (stream, "\n *** CLIENT EXECUTION STATISTICS ***\n");
861 
862  fprintf (stream, "System CPU (sec) = %10d\n",
863  (int) (cpu_total_sys_time - perfmon_Stat_info.cpu_start_sys_time));
864  fprintf (stream, "User CPU (sec) = %10d\n",
865  (int) (cpu_total_usr_time - perfmon_Stat_info.cpu_start_usr_time));
866  fprintf (stream, "Elapsed (sec) = %10d\n",
867  (int) (elapsed_total_time - perfmon_Stat_info.elapsed_start_time));
868 
869  if (perfmon_calc_diff_stats (diff_result, perfmon_Stat_info.current_server_stats,
870  perfmon_Stat_info.base_server_stats) != NO_ERROR)
871  {
872  assert (false);
873  goto exit;
874  }
875  perfmon_server_dump_stats (diff_result, stream, NULL);
876 
877 exit:
878  if (diff_result != NULL)
879  {
880  free_and_init (diff_result);
881  }
882  return err;
883 }
884 
885 /*
886  * perfmon_print_global_stats - Print the global statistics
887  * return: error or no error
888  * stream(in): if NULL is given, stdout is used
889  */
890 int
891 perfmon_print_global_stats (FILE * stream, bool cumulative, const char *substr)
892 {
893  UINT64 *diff_result = NULL;
894  int err = NO_ERROR;
895 
896  if (stream == NULL)
897  {
898  stream = stdout;
899  }
900 
901  diff_result = perfmon_allocate_values ();
902 
903  if (diff_result == NULL)
904  {
905  ASSERT_ERROR ();
907  goto exit;
908  }
909  err = perfmon_get_global_stats ();
910  if (err != NO_ERROR)
911  {
912  ASSERT_ERROR ();
913  goto exit;
914  }
915 
916  if (cumulative)
917  {
918  perfmon_server_dump_stats (perfmon_Stat_info.current_global_stats, stream, substr);
919  }
920  else
921  {
922  if (perfmon_calc_diff_stats (diff_result, perfmon_Stat_info.current_global_stats,
923  perfmon_Stat_info.old_global_stats) != NO_ERROR)
924  {
925  assert (false);
926  goto exit;
927  }
928  perfmon_server_dump_stats (diff_result, stream, substr);
929  }
930 
931 exit:
932  if (diff_result != NULL)
933  {
934  free_and_init (diff_result);
935  }
936  return err;
937 }
938 
939 #endif /* CS_MODE || SA_MODE */
940 
941 #if defined(SERVER_MODE) || defined(SA_MODE)
942 
943 /*
944  * perfmon_server_is_stats_on - Is collecting server execution statistics
945  * for the current transaction index
946  * return: bool
947  */
948 bool
949 perfmon_server_is_stats_on (THREAD_ENTRY * thread_p)
950 {
951  int tran_index;
952 
953  tran_index = LOG_FIND_THREAD_TRAN_INDEX (thread_p);
954  assert (tran_index >= 0);
955 
956  if (tran_index >= pstat_Global.n_trans)
957  {
958  return false;
959  }
960 
961  return pstat_Global.is_watching[tran_index];
962 }
963 
964 /*
965  * perfmon_server_get_stats - Get the recorded server statistics for the current
966  * transaction index
967  */
968 STATIC_INLINE UINT64 *
969 perfmon_server_get_stats (THREAD_ENTRY * thread_p)
970 {
971  int tran_index;
972 
973  tran_index = LOG_FIND_THREAD_TRAN_INDEX (thread_p);
974  assert (tran_index >= 0);
975 
976  if (tran_index >= pstat_Global.n_trans)
977  {
978  return NULL;
979  }
980 
981  perfmon_get_peek_stats (pstat_Global.tran_stats[tran_index]);
982  return pstat_Global.tran_stats[tran_index];
983 }
984 
985 /*
986  * xperfmon_server_copy_stats - Copy recorded server statistics for the current
987  * transaction index
988  * return: none
989  * to_stats(out): buffer to copy
990  */
991 void
992 xperfmon_server_copy_stats (THREAD_ENTRY * thread_p, UINT64 * to_stats)
993 {
994  UINT64 *from_stats;
995 
996  from_stats = perfmon_server_get_stats (thread_p);
997 
998  if (from_stats != NULL)
999  {
1000  perfmon_server_calc_stats (from_stats);
1001  perfmon_copy_values (to_stats, from_stats);
1002  }
1003 }
1004 
1005 /*
1006  * xperfmon_server_copy_global_stats - Copy recorded system wide statistics
1007  * return: none
1008  * to_stats(out): buffer to copy
1009  */
1010 void
1011 xperfmon_server_copy_global_stats (UINT64 * to_stats)
1012 {
1013  if (to_stats)
1014  {
1015  perfmon_get_peek_stats (pstat_Global.global_stats);
1016  perfmon_copy_values (to_stats, pstat_Global.global_stats);
1017  perfmon_server_calc_stats (to_stats);
1018  }
1019 }
1020 
1021 UINT64
1022 perfmon_get_from_statistic (THREAD_ENTRY * thread_p, const int statistic_id)
1023 {
1024  UINT64 *stats;
1025 
1026  stats = perfmon_server_get_stats (thread_p);
1027  if (stats != NULL)
1028  {
1029  int offset = pstat_Metadata[statistic_id].start_offset;
1030  return stats[offset];
1031  }
1032 
1033  return 0;
1034 }
1035 
1036 /*
1037  * perfmon_lk_waited_time_on_objects - Increase lock time wait counter of
1038  * the current transaction index
1039  * return: none
1040  */
1041 void
1042 perfmon_lk_waited_time_on_objects (THREAD_ENTRY * thread_p, int lock_mode, UINT64 amount)
1043 {
1044  assert (pstat_Global.initialized);
1045 
1047  assert (lock_mode >= NA_LOCK && lock_mode <= SCH_M_LOCK);
1048  perfmon_add_stat_at_offset (thread_p, PSTAT_OBJ_LOCK_TIME_COUNTERS, lock_mode, amount);
1049 }
1050 
1051 UINT64
1052 perfmon_get_stats_and_clear (THREAD_ENTRY * thread_p, const char *stat_name)
1053 {
1054  UINT64 *stats;
1055  int i;
1056  UINT64 *stats_ptr;
1057  UINT64 copied = 0;
1058 
1059  stats = perfmon_server_get_stats (thread_p);
1060  if (stats != NULL)
1061  {
1062  stats_ptr = (UINT64 *) stats;
1063  for (i = 0; i < PSTAT_COUNT; i++)
1064  {
1065  if (strcmp (pstat_Metadata[i].stat_name, stat_name) == 0)
1066  {
1067  int offset = pstat_Metadata[i].start_offset;
1068 
1069  switch (pstat_Metadata[i].valtype)
1070  {
1074  copied = stats_ptr[offset];
1075  stats_ptr[offset] = 0;
1076  break;
1078  copied = stats_ptr[PSTAT_COUNTER_TIMER_TOTAL_TIME_VALUE (offset)];
1079  stats_ptr[PSTAT_COUNTER_TIMER_COUNT_VALUE (offset)] = 0;
1080  stats_ptr[PSTAT_COUNTER_TIMER_TOTAL_TIME_VALUE (offset)] = 0;
1081  stats_ptr[PSTAT_COUNTER_TIMER_MAX_TIME_VALUE (offset)] = 0;
1082  stats_ptr[PSTAT_COUNTER_TIMER_AVG_TIME_VALUE (offset)] = 0;
1083  break;
1084  case PSTAT_COMPLEX_VALUE:
1085  default:
1086  assert (false);
1087  break;
1088  }
1089  return copied;
1090  }
1091  }
1092  }
1093 
1094  return 0;
1095 }
1096 
1097 /*
1098  * perfmon_pbx_fix -
1099  * return: none
1100  */
1101 void
1102 perfmon_pbx_fix (THREAD_ENTRY * thread_p, int page_type, int page_found_mode, int latch_mode, int cond_type)
1103 {
1104  int module;
1105  int offset;
1106 
1107  assert (pstat_Global.initialized);
1108 
1109  module = perfmon_get_module_type (thread_p);
1110 
1111  assert (module >= PERF_MODULE_SYSTEM && module < PERF_MODULE_CNT);
1112  assert (page_type >= PERF_PAGE_UNKNOWN && page_type < PERF_PAGE_CNT);
1113  assert (page_found_mode >= PERF_PAGE_MODE_OLD_LOCK_WAIT && page_found_mode < PERF_PAGE_MODE_CNT);
1114  assert (latch_mode >= PERF_HOLDER_LATCH_READ && latch_mode < PERF_HOLDER_LATCH_CNT);
1115  assert (cond_type >= PERF_CONDITIONAL_FIX && cond_type < PERF_CONDITIONAL_FIX_CNT);
1116 
1117  offset = PERF_PAGE_FIX_STAT_OFFSET (module, page_type, page_found_mode, latch_mode, cond_type);
1118  assert (offset < PERF_PAGE_FIX_COUNTERS);
1119 
1120  perfmon_add_stat_at_offset (thread_p, PSTAT_PBX_FIX_COUNTERS, offset, 1);
1121 }
1122 
1123 /*
1124  * perfmon_pbx_promote -
1125  * return: none
1126  */
1127 void
1128 perfmon_pbx_promote (THREAD_ENTRY * thread_p, int page_type, int promote_cond, int holder_latch, int success,
1129  UINT64 amount)
1130 {
1131  int module;
1132  int offset;
1133 
1134  assert (pstat_Global.initialized);
1135 
1136  module = perfmon_get_module_type (thread_p);
1137 
1138  assert (module >= PERF_MODULE_SYSTEM && module < PERF_MODULE_CNT);
1139  assert (page_type >= PERF_PAGE_UNKNOWN && page_type < PERF_PAGE_CNT);
1140  assert (promote_cond >= PERF_PROMOTE_ONLY_READER && promote_cond < PERF_PROMOTE_CONDITION_CNT);
1141  assert (holder_latch >= PERF_HOLDER_LATCH_READ && holder_latch < PERF_HOLDER_LATCH_CNT);
1142  assert (success == 0 || success == 1);
1143 
1144  offset = PERF_PAGE_PROMOTE_STAT_OFFSET (module, page_type, promote_cond, holder_latch, success);
1146 
1148  perfmon_add_stat_at_offset (thread_p, PSTAT_PBX_PROMOTE_TIME_COUNTERS, offset, amount);
1149 }
1150 
1151 /*
1152  * perfmon_pbx_unfix -
1153  * return: none
1154  *
1155  * todo: inline
1156  */
1157 void
1158 perfmon_pbx_unfix (THREAD_ENTRY * thread_p, int page_type, int buf_dirty, int dirtied_by_holder, int holder_latch)
1159 {
1160  int module;
1161  int offset;
1162 
1163  assert (pstat_Global.initialized);
1164 
1165  module = perfmon_get_module_type (thread_p);
1166 
1167  assert (module >= PERF_MODULE_SYSTEM && module < PERF_MODULE_CNT);
1168  assert (page_type >= PERF_PAGE_UNKNOWN && page_type < PERF_PAGE_CNT);
1169  assert (buf_dirty == 0 || buf_dirty == 1);
1170  assert (dirtied_by_holder == 0 || dirtied_by_holder == 1);
1171  assert (holder_latch >= PERF_HOLDER_LATCH_READ && holder_latch < PERF_HOLDER_LATCH_CNT);
1172 
1173  offset = PERF_PAGE_UNFIX_STAT_OFFSET (module, page_type, buf_dirty, dirtied_by_holder, holder_latch);
1174  assert (offset < PERF_PAGE_UNFIX_COUNTERS);
1175 
1177 }
1178 
1179 /*
1180  * perfmon_pbx_lock_acquire_time -
1181  * return: none
1182  */
1183 void
1184 perfmon_pbx_lock_acquire_time (THREAD_ENTRY * thread_p, int page_type, int page_found_mode, int latch_mode,
1185  int cond_type, UINT64 amount)
1186 {
1187  int module;
1188  int offset;
1189 
1190  assert (pstat_Global.initialized);
1191 
1192  module = perfmon_get_module_type (thread_p);
1193 
1194  assert (module >= PERF_MODULE_SYSTEM && module < PERF_MODULE_CNT);
1195  assert (page_type >= PERF_PAGE_UNKNOWN && page_type < PERF_PAGE_CNT);
1196  assert (page_found_mode >= PERF_PAGE_MODE_OLD_LOCK_WAIT && page_found_mode < PERF_PAGE_MODE_CNT);
1197  assert (latch_mode >= PERF_HOLDER_LATCH_READ && latch_mode < PERF_HOLDER_LATCH_CNT);
1198  assert (cond_type >= PERF_CONDITIONAL_FIX && cond_type < PERF_CONDITIONAL_FIX_CNT);
1199  assert (amount > 0);
1200 
1201  offset = PERF_PAGE_LOCK_TIME_OFFSET (module, page_type, page_found_mode, latch_mode, cond_type);
1203 
1204  perfmon_add_stat_at_offset (thread_p, PSTAT_PBX_LOCK_TIME_COUNTERS, offset, amount);
1205 }
1206 
1207 /*
1208  * perfmon_pbx_hold_acquire_time -
1209  * return: none
1210  */
1211 void
1212 perfmon_pbx_hold_acquire_time (THREAD_ENTRY * thread_p, int page_type, int page_found_mode, int latch_mode,
1213  UINT64 amount)
1214 {
1215  int module;
1216  int offset;
1217 
1218  assert (pstat_Global.initialized);
1219 
1220  module = perfmon_get_module_type (thread_p);
1221 
1222  assert (module >= PERF_MODULE_SYSTEM && module < PERF_MODULE_CNT);
1223  assert (page_type >= PERF_PAGE_UNKNOWN && page_type < PERF_PAGE_CNT);
1224  assert (page_found_mode >= PERF_PAGE_MODE_OLD_LOCK_WAIT && page_found_mode < PERF_PAGE_MODE_CNT);
1225  assert (latch_mode >= PERF_HOLDER_LATCH_READ && latch_mode < PERF_HOLDER_LATCH_CNT);
1226  assert (amount > 0);
1227 
1228  offset = PERF_PAGE_HOLD_TIME_OFFSET (module, page_type, page_found_mode, latch_mode);
1230 
1231  perfmon_add_stat_at_offset (thread_p, PSTAT_PBX_HOLD_TIME_COUNTERS, offset, amount);
1232 }
1233 
1234 /*
1235  * perfmon_pbx_fix_acquire_time -
1236  * return: none
1237  */
1238 void
1239 perfmon_pbx_fix_acquire_time (THREAD_ENTRY * thread_p, int page_type, int page_found_mode, int latch_mode,
1240  int cond_type, UINT64 amount)
1241 {
1242  int module;
1243  int offset;
1244 
1245  assert (pstat_Global.initialized);
1246 
1247  module = perfmon_get_module_type (thread_p);
1248 
1249  assert (module >= PERF_MODULE_SYSTEM && module < PERF_MODULE_CNT);
1250  assert (page_type >= PERF_PAGE_UNKNOWN && page_type < PERF_PAGE_CNT);
1251  assert (page_found_mode >= PERF_PAGE_MODE_OLD_LOCK_WAIT && page_found_mode < PERF_PAGE_MODE_CNT);
1252  assert (latch_mode >= PERF_HOLDER_LATCH_READ && latch_mode < PERF_HOLDER_LATCH_CNT);
1253  assert (cond_type >= PERF_CONDITIONAL_FIX && cond_type < PERF_CONDITIONAL_FIX_CNT);
1254  assert (amount > 0);
1255 
1256  offset = PERF_PAGE_FIX_TIME_OFFSET (module, page_type, page_found_mode, latch_mode, cond_type);
1258 
1259  perfmon_add_stat_at_offset (thread_p, PSTAT_PBX_FIX_TIME_COUNTERS, offset, amount);
1260 }
1261 
1262 /*
1263  * perfmon_mvcc_snapshot -
1264  * return: none
1265  */
1266 void
1267 perfmon_mvcc_snapshot (THREAD_ENTRY * thread_p, int snapshot, int rec_type, int visibility)
1268 {
1269  int offset;
1270 
1271  assert (pstat_Global.initialized);
1272 
1273  assert (snapshot >= PERF_SNAPSHOT_SATISFIES_DELETE && snapshot < PERF_SNAPSHOT_CNT);
1275  assert (visibility >= PERF_SNAPSHOT_INVISIBLE && visibility < PERF_SNAPSHOT_VISIBILITY_CNT);
1276  offset = PERF_MVCC_SNAPSHOT_OFFSET (snapshot, rec_type, visibility);
1278 
1280 }
1281 
1282 /*
1283  * perfmon_db_flushed_block_volumes -
1284  * return: none
1285  */
1286 void
1287 perfmon_db_flushed_block_volumes (THREAD_ENTRY * thread_p, int num_volumes)
1288 {
1289  int offset;
1290 
1291  assert (num_volumes >= 0);
1292  if (num_volumes < PERF_DWB_FLUSHED_BLOCK_VOLUMES_CNT)
1293  {
1294  offset = num_volumes;
1295  }
1296  else
1297  {
1299  }
1301 }
1302 #endif /* SERVER_MODE || SA_MODE */
1303 
1304 int
1305 perfmon_calc_diff_stats (UINT64 * stats_diff, UINT64 * new_stats, UINT64 * old_stats)
1306 {
1307  int i, j;
1308  int offset;
1309 
1310  if (!stats_diff || !new_stats || !old_stats)
1311  {
1312  assert (false);
1313  return ER_FAILED;
1314  }
1315 
1316  offset = pstat_Metadata[PSTAT_PB_AVOID_VICTIM_CNT].start_offset;
1317  if (new_stats[offset] >= old_stats[offset])
1318  {
1319  stats_diff[offset] = new_stats[offset] - old_stats[offset];
1320  }
1321  else
1322  {
1323  stats_diff[offset] = 0;
1324  }
1325 
1326  for (i = 0; i < PSTAT_COUNT; i++)
1327  {
1328  switch (pstat_Metadata[i].valtype)
1329  {
1332  case PSTAT_COMPLEX_VALUE:
1334  for (j = pstat_Metadata[i].start_offset; j < pstat_Metadata[i].start_offset + pstat_Metadata[i].n_vals; j++)
1335  {
1336  if (new_stats[j] >= old_stats[j])
1337  {
1338  stats_diff[j] = new_stats[j] - old_stats[j];
1339  }
1340  else
1341  {
1342  stats_diff[j] = 0;
1343  }
1344  }
1345  break;
1346 
1348  if (i != PSTAT_PB_AVOID_VICTIM_CNT)
1349  {
1350  stats_diff[pstat_Metadata[i].start_offset] = new_stats[pstat_Metadata[i].start_offset];
1351  }
1352  break;
1353  default:
1354  assert (false);
1355  break;
1356  }
1357  }
1358 
1359  perfmon_server_calc_stats (stats_diff);
1360  return NO_ERROR;
1361 }
1362 
1363 /*
1364  * perfmon_server_dump_stats_to_buffer -
1365  * return: none
1366  * stats(in) server statistics to print
1367  * buffer(in):
1368  * buf_size(in):
1369  * substr(in):
1370  */
1371 void
1372 perfmon_server_dump_stats_to_buffer (const UINT64 * stats, char *buffer, int buf_size, const char *substr)
1373 {
1374  int i;
1375  int ret;
1376  UINT64 *stats_ptr;
1377  int remained_size;
1378  const char *s;
1379  char *p;
1380 
1381  if (buffer == NULL || buf_size <= 0)
1382  {
1383  return;
1384  }
1385 
1386  p = buffer;
1387  remained_size = buf_size - 1;
1388  ret = snprintf (p, remained_size, "\n *** SERVER EXECUTION STATISTICS *** \n");
1389  remained_size -= ret;
1390  p += ret;
1391 
1392  if (remained_size <= 0)
1393  {
1394  return;
1395  }
1396 
1397  stats_ptr = (UINT64 *) stats;
1398  for (i = 0; i < PSTAT_COUNT; i++)
1399  {
1400  if (pstat_Metadata[i].valtype == PSTAT_COMPLEX_VALUE)
1401  {
1402  break;
1403  }
1404 
1405  if (substr != NULL)
1406  {
1407  s = strstr (pstat_Metadata[i].stat_name, substr);
1408  }
1409  else
1410  {
1411  s = pstat_Metadata[i].stat_name;
1412  }
1413 
1414  if (s)
1415  {
1416  int offset = pstat_Metadata[i].start_offset;
1417 
1418  if (pstat_Metadata[i].valtype != PSTAT_COMPUTED_RATIO_VALUE)
1419  {
1420  if (pstat_Metadata[i].valtype != PSTAT_COUNTER_TIMER_VALUE)
1421  {
1422  ret = snprintf (p, remained_size, "%-29s = %10llu\n", pstat_Metadata[i].stat_name,
1423  (unsigned long long) stats_ptr[offset]);
1424  }
1425  else
1426  {
1427  perfmon_print_timer_to_buffer (&p, i, stats_ptr, &remained_size);
1428  ret = 0;
1429  }
1430  }
1431  else
1432  {
1433  ret = snprintf (p, remained_size, "%-29s = %10.2f\n", pstat_Metadata[i].stat_name,
1434  (float) stats_ptr[offset] / 100);
1435  }
1436  remained_size -= ret;
1437  p += ret;
1438  if (remained_size <= 0)
1439  {
1440  assert (remained_size == 0); /* should not overrun the buffer */
1441  return;
1442  }
1443  }
1444  }
1445 
1446  for (; i < PSTAT_COUNT && remained_size > 0; i++)
1447  {
1448  if (substr != NULL)
1449  {
1450  s = strstr (pstat_Metadata[i].stat_name, substr);
1451  }
1452  else
1453  {
1454  s = pstat_Metadata[i].stat_name;
1455  }
1456  if (s == NULL)
1457  {
1458  continue;
1459  }
1460 
1461  ret = snprintf (p, remained_size, "%s:\n", pstat_Metadata[i].stat_name);
1462  remained_size -= ret;
1463  p += ret;
1464  if (remained_size <= 0)
1465  {
1466  assert (remained_size == 0); /* should not overrun the buffer */
1467  return;
1468  }
1469  pstat_Metadata[i].f_dump_in_buffer (&p, &(stats[pstat_Metadata[i].start_offset]), &remained_size);
1470  }
1471 
1472  buffer[buf_size - 1] = '\0';
1473 }
1474 
1475 /*
1476  * perfmon_server_dump_stats - Print the given server statistics
1477  * return: none
1478  * stats(in) server statistics to print
1479  * stream(in): if NULL is given, stdout is used
1480  */
1481 void
1482 perfmon_server_dump_stats (const UINT64 * stats, FILE * stream, const char *substr)
1483 {
1484  int i;
1485  UINT64 *stats_ptr;
1486  const char *s;
1487 
1488  if (stream == NULL)
1489  {
1490  stream = stdout;
1491  }
1492 
1493  fprintf (stream, "\n *** SERVER EXECUTION STATISTICS *** \n");
1494 
1495  stats_ptr = (UINT64 *) stats;
1496  for (i = 0; i < PSTAT_COUNT; i++)
1497  {
1498  if (pstat_Metadata[i].valtype == PSTAT_COMPLEX_VALUE)
1499  {
1500  break;
1501  }
1502 
1503  if (substr != NULL)
1504  {
1505  s = strstr (pstat_Metadata[i].stat_name, substr);
1506  }
1507  else
1508  {
1509  s = pstat_Metadata[i].stat_name;
1510  }
1511 
1512  if (s)
1513  {
1514  int offset = pstat_Metadata[i].start_offset;
1515 
1516  if (pstat_Metadata[i].valtype != PSTAT_COMPUTED_RATIO_VALUE)
1517  {
1518  if (pstat_Metadata[i].valtype != PSTAT_COUNTER_TIMER_VALUE)
1519  {
1520  fprintf (stream, "%-29s = %10llu\n", pstat_Metadata[i].stat_name,
1521  (unsigned long long) stats_ptr[offset]);
1522  }
1523  else
1524  {
1525  perfmon_print_timer_to_file (stream, i, stats_ptr);
1526  }
1527  }
1528  else
1529  {
1530  fprintf (stream, "%-29s = %10.2f\n", pstat_Metadata[i].stat_name, (float) stats_ptr[offset] / 100);
1531  }
1532  }
1533  }
1534 
1535  for (; i < PSTAT_COUNT; i++)
1536  {
1537  if (substr != NULL)
1538  {
1539  s = strstr (pstat_Metadata[i].stat_name, substr);
1540  }
1541  else
1542  {
1543  s = pstat_Metadata[i].stat_name;
1544  }
1545  if (s == NULL)
1546  {
1547  continue;
1548  }
1549 
1550  fprintf (stream, "%s:\n", pstat_Metadata[i].stat_name);
1551  pstat_Metadata[i].f_dump_in_file (stream, &(stats[pstat_Metadata[i].start_offset]));
1552  }
1553 }
1554 
1555 /*
1556  * perfmon_get_current_times - Get current CPU and elapsed times
1557  * return:
1558  * cpu_user_time(out):
1559  * cpu_sys_time(out):
1560  * elapsed_time(out):
1561  *
1562  * Note:
1563  */
1564 void
1565 perfmon_get_current_times (time_t * cpu_user_time, time_t * cpu_sys_time, time_t * elapsed_time)
1566 {
1567 #if defined (WINDOWS)
1568  *cpu_user_time = 0;
1569  *cpu_sys_time = 0;
1570  *elapsed_time = 0;
1571 
1572  *elapsed_time = time (NULL);
1573 #else /* WINDOWS */
1574  struct rusage rusage;
1575 
1576  *cpu_user_time = 0;
1577  *cpu_sys_time = 0;
1578  *elapsed_time = 0;
1579 
1580  *elapsed_time = time (NULL);
1581 
1582  if (getrusage (RUSAGE_SELF, &rusage) == 0)
1583  {
1584  *cpu_user_time = rusage.ru_utime.tv_sec;
1585  *cpu_sys_time = rusage.ru_stime.tv_sec;
1586  }
1587 #endif /* WINDOWS */
1588 }
1589 
1590 /*
1591  * perfmon_server_calc_stats - Do post processing of server statistics
1592  * return: none
1593  * stats(in/out): server statistics block to be processed
1594  */
1595 static void
1597 {
1598  int page_type;
1599  int module;
1600  int offset;
1601  int buf_dirty;
1602  int holder_dirty;
1603  int holder_latch;
1604  int page_found_mode;
1605  int cond_type;
1606  int promote_cond;
1607  int success;
1608  UINT64 counter = 0;
1609  UINT64 total_unfix_vacuum = 0;
1610  UINT64 total_unfix_vacuum_dirty = 0;
1611  UINT64 total_unfix = 0;
1612  UINT64 total_fix_vacuum = 0;
1613  UINT64 total_fix_vacuum_hit = 0;
1614  UINT64 fix_time_usec = 0;
1615  UINT64 lock_time_usec = 0;
1616  UINT64 hold_time_usec = 0;
1617  UINT64 total_promote_time = 0;
1618  int i;
1619 
1620  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
1621  {
1622  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
1623  {
1624  for (buf_dirty = 0; buf_dirty <= 1; buf_dirty++)
1625  {
1626  for (holder_dirty = 0; holder_dirty <= 1; holder_dirty++)
1627  {
1628  for (holder_latch = PERF_HOLDER_LATCH_READ; holder_latch < PERF_HOLDER_LATCH_CNT; holder_latch++)
1629  {
1630  offset = PERF_PAGE_UNFIX_STAT_OFFSET (module, page_type, buf_dirty, holder_dirty, holder_latch);
1631 
1632  assert (offset < PERF_PAGE_UNFIX_COUNTERS);
1633  counter = stats[pstat_Metadata[PSTAT_PBX_UNFIX_COUNTERS].start_offset + offset];
1634 
1635  total_unfix += counter;
1636  if (module == PERF_MODULE_VACUUM)
1637  {
1638  total_unfix_vacuum += counter;
1639  if (holder_dirty == 1)
1640  {
1641  total_unfix_vacuum_dirty += counter;
1642  }
1643  }
1644  }
1645  }
1646  }
1647  }
1648  }
1649 
1650  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
1651  {
1652  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
1653  {
1654  for (page_found_mode = PERF_PAGE_MODE_OLD_LOCK_WAIT; page_found_mode < PERF_PAGE_MODE_CNT; page_found_mode++)
1655  {
1656  for (holder_latch = PERF_HOLDER_LATCH_READ; holder_latch < PERF_HOLDER_LATCH_CNT; holder_latch++)
1657  {
1658  offset = PERF_PAGE_HOLD_TIME_OFFSET (module, page_type, page_found_mode, holder_latch);
1660  counter = stats[pstat_Metadata[PSTAT_PBX_HOLD_TIME_COUNTERS].start_offset + offset];
1661 
1662  if (page_type != PAGE_LOG && counter > 0)
1663  {
1664  hold_time_usec += counter;
1665  }
1666 
1667  for (cond_type = PERF_CONDITIONAL_FIX; cond_type < PERF_CONDITIONAL_FIX_CNT; cond_type++)
1668  {
1669  offset = PERF_PAGE_FIX_TIME_OFFSET (module, page_type, page_found_mode, holder_latch, cond_type);
1671  counter = stats[pstat_Metadata[PSTAT_PBX_FIX_TIME_COUNTERS].start_offset + offset];
1672  /* do not include fix time of log pages */
1673  if (page_type != PAGE_LOG && counter > 0)
1674  {
1675  fix_time_usec += counter;
1676  }
1677 
1678  offset = PERF_PAGE_LOCK_TIME_OFFSET (module, page_type, page_found_mode, holder_latch, cond_type);
1680  counter = stats[pstat_Metadata[PSTAT_PBX_LOCK_TIME_COUNTERS].start_offset + offset];
1681 
1682  if (page_type != PAGE_LOG && counter > 0)
1683  {
1684  lock_time_usec += counter;
1685  }
1686 
1687  if (module == PERF_MODULE_VACUUM && page_found_mode != PERF_PAGE_MODE_NEW_LOCK_WAIT
1688  && page_found_mode != PERF_PAGE_MODE_NEW_NO_WAIT)
1689  {
1690  offset =
1691  PERF_PAGE_FIX_STAT_OFFSET (module, page_type, page_found_mode, holder_latch, cond_type);
1692 
1693  assert (offset < PERF_PAGE_FIX_COUNTERS);
1694  counter = stats[pstat_Metadata[PSTAT_PBX_FIX_COUNTERS].start_offset + offset];
1695 
1696  if (module == PERF_MODULE_VACUUM)
1697  {
1698  total_fix_vacuum += counter;
1699  if (page_found_mode == PERF_PAGE_MODE_OLD_IN_BUFFER)
1700  {
1701  total_fix_vacuum_hit += counter;
1702  }
1703  }
1704  }
1705  }
1706  }
1707  }
1708  }
1709  }
1710 
1711  stats[pstat_Metadata[PSTAT_PB_VACUUM_EFFICIENCY].start_offset] =
1712  SAFE_DIV (total_unfix_vacuum_dirty * 100 * 100, total_unfix_vacuum);
1713 
1714  stats[pstat_Metadata[PSTAT_PB_VACUUM_FETCH_RATIO].start_offset] =
1715  SAFE_DIV (total_unfix_vacuum * 100 * 100, total_unfix);
1716 
1717  stats[pstat_Metadata[PSTAT_VACUUM_DATA_HIT_RATIO].start_offset] =
1718  SAFE_DIV (total_fix_vacuum_hit * 100 * 100, total_fix_vacuum);
1719 
1720  stats[pstat_Metadata[PSTAT_PB_HIT_RATIO].start_offset] =
1721  SAFE_DIV ((stats[pstat_Metadata[PSTAT_PB_NUM_FETCHES].start_offset] -
1722  stats[pstat_Metadata[PSTAT_PB_NUM_IOREADS].start_offset]) * 100 * 100,
1723  stats[pstat_Metadata[PSTAT_PB_NUM_FETCHES].start_offset]);
1724 
1725  stats[pstat_Metadata[PSTAT_LOG_HIT_RATIO].start_offset] =
1726  SAFE_DIV ((stats[pstat_Metadata[PSTAT_LOG_NUM_FETCHES].start_offset]
1727  - stats[pstat_Metadata[PSTAT_LOG_NUM_IOREADS].start_offset]) * 100 * 100,
1728  stats[pstat_Metadata[PSTAT_LOG_NUM_FETCHES].start_offset]);
1729 
1730  stats[pstat_Metadata[PSTAT_PB_PAGE_LOCK_ACQUIRE_TIME_10USEC].start_offset] = 100 * lock_time_usec / 1000;
1731  stats[pstat_Metadata[PSTAT_PB_PAGE_HOLD_ACQUIRE_TIME_10USEC].start_offset] = 100 * hold_time_usec / 1000;
1732  stats[pstat_Metadata[PSTAT_PB_PAGE_FIX_ACQUIRE_TIME_10USEC].start_offset] = 100 * fix_time_usec / 1000;
1733 
1734  stats[pstat_Metadata[PSTAT_PB_PAGE_ALLOCATE_TIME_RATIO].start_offset] =
1735  SAFE_DIV ((stats[pstat_Metadata[PSTAT_PB_PAGE_FIX_ACQUIRE_TIME_10USEC].start_offset] -
1736  stats[pstat_Metadata[PSTAT_PB_PAGE_HOLD_ACQUIRE_TIME_10USEC].start_offset] -
1737  stats[pstat_Metadata[PSTAT_PB_PAGE_LOCK_ACQUIRE_TIME_10USEC].start_offset]) * 100 * 100,
1738  stats[pstat_Metadata[PSTAT_PB_PAGE_FIX_ACQUIRE_TIME_10USEC].start_offset]);
1739 
1740  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
1741  {
1742  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
1743  {
1744  for (promote_cond = PERF_PROMOTE_ONLY_READER; promote_cond < PERF_PROMOTE_CONDITION_CNT; promote_cond++)
1745  {
1746  for (holder_latch = PERF_HOLDER_LATCH_READ; holder_latch < PERF_HOLDER_LATCH_CNT; holder_latch++)
1747  {
1748  for (success = 0; success < 2; success++)
1749  {
1750  offset = PERF_PAGE_PROMOTE_STAT_OFFSET (module, page_type, promote_cond, holder_latch, success);
1752 
1753  counter = stats[pstat_Metadata[PSTAT_PBX_PROMOTE_TIME_COUNTERS].start_offset + offset];
1754  if (counter)
1755  {
1756  total_promote_time += counter;
1757  }
1758 
1759  counter = stats[pstat_Metadata[PSTAT_PBX_PROMOTE_COUNTERS].start_offset + offset];
1760  if (counter)
1761  {
1762  if (success)
1763  {
1764  stats[pstat_Metadata[PSTAT_PB_PAGE_PROMOTE_SUCCESS].start_offset] += counter;
1765  }
1766  else
1767  {
1768  stats[pstat_Metadata[PSTAT_PB_PAGE_PROMOTE_FAILED].start_offset] += counter;
1769  }
1770  }
1771  }
1772  }
1773  }
1774  }
1775  }
1776 
1777  stats[pstat_Metadata[PSTAT_PB_PAGE_PROMOTE_TOTAL_TIME_10USEC].start_offset] = 100 * total_promote_time / 1000;
1778  stats[pstat_Metadata[PSTAT_PB_PAGE_PROMOTE_SUCCESS].start_offset] *= 100;
1779  stats[pstat_Metadata[PSTAT_PB_PAGE_PROMOTE_FAILED].start_offset] *= 100;
1780 
1781 #if defined (SERVER_MODE)
1782  pgbuf_peek_stats (&(stats[pstat_Metadata[PSTAT_PB_FIXED_CNT].start_offset]),
1783  &(stats[pstat_Metadata[PSTAT_PB_DIRTY_CNT].start_offset]),
1784  &(stats[pstat_Metadata[PSTAT_PB_LRU1_CNT].start_offset]),
1785  &(stats[pstat_Metadata[PSTAT_PB_LRU2_CNT].start_offset]),
1786  &(stats[pstat_Metadata[PSTAT_PB_LRU3_CNT].start_offset]),
1787  &(stats[pstat_Metadata[PSTAT_PB_VICT_CAND].start_offset]),
1788  &(stats[pstat_Metadata[PSTAT_PB_AVOID_DEALLOC_CNT].start_offset]),
1789  &(stats[pstat_Metadata[PSTAT_PB_AVOID_VICTIM_CNT].start_offset]),
1790  &(stats[pstat_Metadata[PSTAT_PB_PRIVATE_QUOTA].start_offset]),
1791  &(stats[pstat_Metadata[PSTAT_PB_PRIVATE_COUNT].start_offset]),
1792  &(stats[pstat_Metadata[PSTAT_PB_WAIT_THREADS_HIGH_PRIO].start_offset]),
1793  &(stats[pstat_Metadata[PSTAT_PB_WAIT_THREADS_LOW_PRIO].start_offset]),
1794  &(stats[pstat_Metadata[PSTAT_PB_FLUSHED_BCBS_WAIT_FOR_ASSIGN].start_offset]),
1795  &(stats[pstat_Metadata[PSTAT_PB_LFCQ_BIG_PRV_NUM].start_offset]),
1796  &(stats[pstat_Metadata[PSTAT_PB_LFCQ_PRV_NUM].start_offset]),
1797  &(stats[pstat_Metadata[PSTAT_PB_LFCQ_SHR_NUM].start_offset]));
1798 
1799  css_get_thread_stats (&stats[pstat_Metadata[PSTAT_THREAD_STATS].start_offset]);
1800  perfmon_peek_thread_daemon_stats (stats);
1801  // *INDENT-OFF*
1802  cubload::worker_manager_get_stats (&stats[pstat_Metadata[PSTAT_LOAD_THREAD_STATS].start_offset]);
1803  // *INDENT-ON*
1804 #endif // SERVER_MODE
1805 
1806  for (i = 0; i < PSTAT_COUNT; i++)
1807  {
1808  if (pstat_Metadata[i].valtype == PSTAT_COUNTER_TIMER_VALUE)
1809  {
1810  int offset = pstat_Metadata[i].start_offset;
1811  stats[PSTAT_COUNTER_TIMER_AVG_TIME_VALUE (offset)]
1813  stats[PSTAT_COUNTER_TIMER_COUNT_VALUE (offset)]);
1814  }
1815  }
1816 }
1817 
1818 /*
1819  * perfmon_stat_module_name () -
1820  */
1821 STATIC_INLINE const char *
1822 perfmon_stat_module_name (const int module)
1823 {
1824  switch (module)
1825  {
1826  case PERF_MODULE_SYSTEM:
1827  return "SYSTEM";
1828  case PERF_MODULE_USER:
1829  return "WORKER";
1830  case PERF_MODULE_VACUUM:
1831  return "VACUUM";
1832  default:
1833  break;
1834  }
1835  return "ERROR";
1836 }
1837 
1838 #if defined (SERVER_MODE) || defined (SA_MODE)
1839 /*
1840  * perfmon_get_module_type () -
1841  */
1842 STATIC_INLINE int
1843 perfmon_get_module_type (THREAD_ENTRY * thread_p)
1844 {
1845 #if defined (SERVER_MODE)
1846  if (thread_p == NULL)
1847  {
1848  thread_p = thread_get_thread_entry_info ();
1849  }
1850 
1851  switch (thread_p->type)
1852  {
1853  case TT_WORKER:
1854  return PERF_MODULE_USER;
1855  case TT_VACUUM_WORKER:
1856  case TT_VACUUM_MASTER:
1857  return PERF_MODULE_VACUUM;
1858  default:
1859  return PERF_MODULE_SYSTEM;
1860  }
1861 #else
1862  return PERF_MODULE_USER;
1863 #endif
1864 }
1865 #endif /* defined (SERVER_MODE) || defined (SA_MODE) */
1866 
1867 /*
1868  * perf_stat_page_type_name () -
1869  */
1870 STATIC_INLINE const char *
1871 perfmon_stat_page_type_name (const int page_type)
1872 {
1873  switch (page_type)
1874  {
1875  case PERF_PAGE_UNKNOWN:
1876  return "PAGE_UNKNOWN";
1877  case PERF_PAGE_FTAB:
1878  return "PAGE_FTAB";
1879  case PERF_PAGE_HEAP:
1880  return "PAGE_HEAP";
1881  case PERF_PAGE_VOLHEADER:
1882  return "PAGE_VOLHEADER";
1883  case PERF_PAGE_VOLBITMAP:
1884  return "PAGE_VOLBITMAP";
1885  case PERF_PAGE_QRESULT:
1886  return "PAGE_QRESULT";
1887  case PERF_PAGE_EHASH:
1888  return "PAGE_EHASH";
1889  case PERF_PAGE_OVERFLOW:
1890  return "PAGE_OVERFLOW";
1891  case PERF_PAGE_AREA:
1892  return "PAGE_AREA";
1893  case PERF_PAGE_CATALOG:
1894  return "PAGE_CATALOG";
1896  return "PAGE_BTREE";
1897  case PERF_PAGE_LOG:
1898  return "PAGE_LOG";
1900  return "PAGE_DROPPED";
1901  case PERF_PAGE_VACUUM_DATA:
1902  return "PAGE_VACUUM_DATA";
1903  case PERF_PAGE_BTREE_ROOT:
1904  return "PAGE_BTREE_R";
1905  case PERF_PAGE_BTREE_OVF:
1906  return "PAGE_BTREE_O";
1907  case PERF_PAGE_BTREE_LEAF:
1908  return "PAGE_BTREE_L";
1910  return "PAGE_BTREE_N";
1911  default:
1912  break;
1913  }
1914  return "ERROR";
1915 }
1916 
1917 /*
1918  * perfmon_stat_page_mode_name () -
1919  */
1920 STATIC_INLINE const char *
1921 perfmon_stat_page_mode_name (const int page_mode)
1922 {
1923  switch (page_mode)
1924  {
1926  return "OLD_WAIT";
1928  return "OLD_NO_WAIT";
1930  return "NEW_WAIT";
1932  return "NEW_NO_WAIT";
1934  return "OLD_PAGE_IN_PB";
1935  default:
1936  break;
1937  }
1938  return "ERROR";
1939 }
1940 
1941 /*
1942  * perfmon_stat_holder_latch_name () -
1943  */
1944 STATIC_INLINE const char *
1945 perfmon_stat_holder_latch_name (const int holder_latch)
1946 {
1947  switch (holder_latch)
1948  {
1950  return "READ";
1952  return "WRITE";
1954  return "MIXED";
1955  default:
1956  break;
1957  }
1958  return "ERROR";
1959 }
1960 
1961 /*
1962  * perfmon_stat_cond_type_name () -
1963  */
1964 STATIC_INLINE const char *
1965 perfmon_stat_cond_type_name (const int cond_type)
1966 {
1967  switch (cond_type)
1968  {
1969  case PERF_CONDITIONAL_FIX:
1970  return "COND";
1972  return "UNCOND";
1974  return "UNCOND_WAIT";
1975  default:
1976  break;
1977  }
1978  return "ERROR";
1979 }
1980 
1981 /*
1982  * perfmon_stat_snapshot_name () -
1983  */
1984 STATIC_INLINE const char *
1985 perfmon_stat_snapshot_name (const int snapshot)
1986 {
1987  switch (snapshot)
1988  {
1990  return "DELETE";
1992  return "DIRTY";
1994  return "SNAPSHOT";
1996  return "VACUUM";
1997  default:
1998  break;
1999  }
2000  return "ERROR";
2001 }
2002 
2003 /*
2004  * perfmon_stat_snapshot_record_type () -
2005  */
2006 STATIC_INLINE const char *
2008 {
2009  switch (rec_type)
2010  {
2012  return "INS_VACUUMED";
2014  return "INS_CURR";
2016  return "INS_OTHER";
2018  return "INS_COMMITTED";
2020  return "INS_COMMITTED_L";
2022  return "INS_DELETED";
2024  return "DELETED_CURR";
2026  return "DELETED_OTHER";
2028  return "DELETED_COMMITED";
2030  return "DELETED_COMMITED_L";
2031  default:
2032  break;
2033  }
2034  return "ERROR";
2035 }
2036 
2037 STATIC_INLINE const char *
2038 perfmon_stat_lock_mode_name (const int lock_mode)
2039 {
2040  switch (lock_mode)
2041  {
2042  case NA_LOCK:
2043  return "NA_LOCK";
2045  return "INCON_2PL";
2046  case NULL_LOCK:
2047  return "NULL_LOCK";
2048  case SCH_S_LOCK:
2049  return "SCH_S_LOCK";
2050  case IS_LOCK:
2051  return "IS_LOCK";
2052  case S_LOCK:
2053  return "S_LOCK";
2054  case IX_LOCK:
2055  return "IX_LOCK";
2056  case SIX_LOCK:
2057  return "SIX_LOCK";
2058  case U_LOCK:
2059  return "U_LOCK";
2060  case X_LOCK:
2061  return "X_LOCK";
2062  case SCH_M_LOCK:
2063  return "SCH_M_LOCK";
2064  default:
2065  break;
2066  }
2067  return "ERROR";
2068 }
2069 
2070 /*
2071  * perfmon_stat_cond_type_name () -
2072  */
2073 STATIC_INLINE const char *
2074 perfmon_stat_promote_cond_name (const int cond_type)
2075 {
2076  switch (cond_type)
2077  {
2079  return "ONLY_READER";
2081  return "SHARED_READER";
2082  default:
2083  break;
2084  }
2085  return "ERROR";
2086 }
2087 
2088 /*
2089  * perfmon_stat_dump_in_buffer_fix_page_array_stat () -
2090  *
2091  * stats_ptr(in): start of array values
2092  * s(in/out): output string (NULL if not used)
2093  * remaining_size(in/out): remaining size in string s (NULL if not used)
2094  *
2095  */
2096 static void
2097 perfmon_stat_dump_in_buffer_fix_page_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size)
2098 {
2099  int module;
2100  int page_type;
2101  int page_mode;
2102  int latch_mode;
2103  int cond_type;
2104  int offset;
2105  UINT64 counter = 0;
2106  int ret;
2107 
2108  assert (remaining_size != NULL);
2109  assert (s != NULL);
2110  if (*s != NULL)
2111  {
2112  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2113  {
2114  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
2115  {
2116  for (page_mode = PERF_PAGE_MODE_OLD_LOCK_WAIT; page_mode < PERF_PAGE_MODE_CNT; page_mode++)
2117  {
2118  for (latch_mode = PERF_HOLDER_LATCH_READ; latch_mode < PERF_HOLDER_LATCH_CNT; latch_mode++)
2119  {
2120  for (cond_type = PERF_CONDITIONAL_FIX; cond_type < PERF_CONDITIONAL_FIX_CNT; cond_type++)
2121  {
2122  offset = PERF_PAGE_FIX_STAT_OFFSET (module, page_type, page_mode, latch_mode, cond_type);
2123 
2124  assert (offset < PERF_PAGE_FIX_COUNTERS);
2125 
2126  counter = stats_ptr[offset];
2127  if (counter == 0)
2128  {
2129  continue;
2130  }
2131 
2132  ret = snprintf (*s, *remaining_size, "%-6s,%-14s,%-18s,%-5s,%-11s = %10llu\n",
2134  perfmon_stat_page_mode_name (page_mode),
2135  perfmon_stat_holder_latch_name (latch_mode),
2136  perfmon_stat_cond_type_name (cond_type), (long long unsigned int) counter);
2137  *remaining_size -= ret;
2138  *s += ret;
2139  if (*remaining_size <= 0)
2140  {
2141  return;
2142  }
2143  }
2144  }
2145  }
2146  }
2147  }
2148  }
2149 }
2150 
2151 /*
2152  * perfmon_stat_dump_in_file_fix_page_array_stat () -
2153  *
2154  * stream(in): output file
2155  * stats_ptr(in): start of array values
2156  *
2157  */
2158 static void
2159 perfmon_stat_dump_in_file_fix_page_array_stat (FILE * stream, const UINT64 * stats_ptr)
2160 {
2161  int module;
2162  int page_type;
2163  int page_mode;
2164  int latch_mode;
2165  int cond_type;
2166  int offset;
2167  UINT64 counter = 0;
2168 
2169  assert (stream != NULL);
2170  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2171  {
2172  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
2173  {
2174  for (page_mode = PERF_PAGE_MODE_OLD_LOCK_WAIT; page_mode < PERF_PAGE_MODE_CNT; page_mode++)
2175  {
2176  for (latch_mode = PERF_HOLDER_LATCH_READ; latch_mode < PERF_HOLDER_LATCH_CNT; latch_mode++)
2177  {
2178  for (cond_type = PERF_CONDITIONAL_FIX; cond_type < PERF_CONDITIONAL_FIX_CNT; cond_type++)
2179  {
2180  offset = PERF_PAGE_FIX_STAT_OFFSET (module, page_type, page_mode, latch_mode, cond_type);
2181 
2182  assert (offset < PERF_PAGE_FIX_COUNTERS);
2183  counter = stats_ptr[offset];
2184  if (counter == 0)
2185  {
2186  continue;
2187  }
2188 
2189  fprintf (stream, "%-6s,%-14s,%-18s,%-5s,%-11s = %10llu\n", perfmon_stat_module_name (module),
2192  (long long unsigned int) counter);
2193  }
2194  }
2195  }
2196  }
2197  }
2198 }
2199 
2200 /*
2201  * perfmon_stat_dump_in_buffer_promote_page_array_stat () -
2202  *
2203  * stats_ptr(in): start of array values
2204  * s(in/out): output string (NULL if not used)
2205  * remaining_size(in/out): remaining size in string s (NULL if not used)
2206  *
2207  */
2208 static void
2209 perfmon_stat_dump_in_buffer_promote_page_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size)
2210 {
2211  int module;
2212  int page_type;
2213  int promote_cond;
2214  int holder_latch;
2215  int success;
2216  int offset;
2217  UINT64 counter = 0;
2218  int ret;
2219 
2220  assert (remaining_size != NULL);
2221  assert (s != NULL);
2222  if (*s != NULL)
2223  {
2224  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2225  {
2226  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
2227  {
2228  for (promote_cond = PERF_PROMOTE_ONLY_READER; promote_cond < PERF_PROMOTE_CONDITION_CNT; promote_cond++)
2229  {
2230  for (holder_latch = PERF_HOLDER_LATCH_READ; holder_latch < PERF_HOLDER_LATCH_CNT; holder_latch++)
2231  {
2232  for (success = 0; success < 2; success++)
2233  {
2234  offset =
2235  PERF_PAGE_PROMOTE_STAT_OFFSET (module, page_type, promote_cond, holder_latch, success);
2236 
2238 
2239  counter = stats_ptr[offset];
2240  if (counter == 0)
2241  {
2242  continue;
2243  }
2244 
2245  ret = snprintf (*s, *remaining_size, "%-6s,%-14s,%-13s,%-5s,%-7s = %10llu\n",
2247  perfmon_stat_promote_cond_name (promote_cond),
2248  perfmon_stat_holder_latch_name (holder_latch),
2249  (success ? "SUCCESS" : "FAILED"), (long long unsigned int) counter);
2250  *remaining_size -= ret;
2251  *s += ret;
2252  if (*remaining_size <= 0)
2253  {
2254  return;
2255  }
2256  }
2257  }
2258  }
2259  }
2260  }
2261  }
2262 }
2263 
2264 /*
2265  * perfmon_stat_dump_in_file_promote_page_array_stat () -
2266  *
2267  * stream(in): output file
2268  * stats_ptr(in): start of array values
2269  *
2270  */
2271 static void
2272 perfmon_stat_dump_in_file_promote_page_array_stat (FILE * stream, const UINT64 * stats_ptr)
2273 {
2274  int module;
2275  int page_type;
2276  int promote_cond;
2277  int holder_latch;
2278  int success;
2279  int offset;
2280  UINT64 counter = 0;
2281 
2282  assert (stream != NULL);
2283  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2284  {
2285  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
2286  {
2287  for (promote_cond = PERF_PROMOTE_ONLY_READER; promote_cond < PERF_PROMOTE_CONDITION_CNT; promote_cond++)
2288  {
2289  for (holder_latch = PERF_HOLDER_LATCH_READ; holder_latch < PERF_HOLDER_LATCH_CNT; holder_latch++)
2290  {
2291  for (success = 0; success < 2; success++)
2292  {
2293  offset = PERF_PAGE_PROMOTE_STAT_OFFSET (module, page_type, promote_cond, holder_latch, success);
2294 
2296  counter = stats_ptr[offset];
2297  if (counter == 0)
2298  {
2299  continue;
2300  }
2301 
2302  fprintf (stream, "%-6s,%-14s,%-13s,%-5s,%-7s = %10llu\n", perfmon_stat_module_name (module),
2303  perfmon_stat_page_type_name (page_type), perfmon_stat_promote_cond_name (promote_cond),
2304  perfmon_stat_holder_latch_name (holder_latch), (success ? "SUCCESS" : "FAILED"),
2305  (long long unsigned int) counter);
2306  }
2307  }
2308  }
2309  }
2310  }
2311 }
2312 
2313 
2314 /*
2315  * perfmon_stat_dump_in_buffer_unfix_page_array_stat () -
2316  *
2317  * stats_ptr(in): start of array values
2318  * s(in/out): output string (NULL if not used)
2319  * remaining_size(in/out): remaining size in string s (NULL if not used)
2320  *
2321  */
2322 static void
2323 perfmon_stat_dump_in_buffer_unfix_page_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size)
2324 {
2325  int module;
2326  int page_type;
2327  int buf_dirty;
2328  int holder_dirty;
2329  int holder_latch;
2330  int offset;
2331  UINT64 counter = 0;
2332  int ret;
2333 
2334  assert (remaining_size != NULL);
2335  assert (s != NULL);
2336  if (*s != NULL)
2337  {
2338  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2339  {
2340  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
2341  {
2342  for (buf_dirty = 0; buf_dirty <= 1; buf_dirty++)
2343  {
2344  for (holder_dirty = 0; holder_dirty <= 1; holder_dirty++)
2345  {
2346  for (holder_latch = PERF_HOLDER_LATCH_READ; holder_latch < PERF_HOLDER_LATCH_CNT; holder_latch++)
2347  {
2348  offset =
2349  PERF_PAGE_UNFIX_STAT_OFFSET (module, page_type, buf_dirty, holder_dirty, holder_latch);
2350 
2351  assert (offset < PERF_PAGE_UNFIX_COUNTERS);
2352  counter = stats_ptr[offset];
2353  if (counter == 0)
2354  {
2355  continue;
2356  }
2357 
2358  ret = snprintf (*s, *remaining_size, "%-6s,%-14s,%-13s,%-16s,%-5s = %10llu\n",
2360  buf_dirty ? "BUF_DIRTY" : "BUF_NON_DIRTY",
2361  holder_dirty ? "HOLDER_DIRTY" : "HOLDER_NON_DIRTY",
2362  perfmon_stat_holder_latch_name (holder_latch),
2363  (long long unsigned int) counter);
2364  *remaining_size -= ret;
2365  *s += ret;
2366  if (*remaining_size <= 0)
2367  {
2368  return;
2369  }
2370  }
2371  }
2372  }
2373  }
2374  }
2375  }
2376 }
2377 
2378 /*
2379  * perfmon_stat_dump_in_file_unfix_page_array_stat () -
2380  *
2381  * stream(in): output file
2382  * stats_ptr(in): start of array values
2383  *
2384  */
2385 static void
2386 perfmon_stat_dump_in_file_unfix_page_array_stat (FILE * stream, const UINT64 * stats_ptr)
2387 {
2388  int module;
2389  int page_type;
2390  int buf_dirty;
2391  int holder_dirty;
2392  int holder_latch;
2393  int offset;
2394  UINT64 counter = 0;
2395 
2396  assert (stream != NULL);
2397  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2398  {
2399  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
2400  {
2401  for (buf_dirty = 0; buf_dirty <= 1; buf_dirty++)
2402  {
2403  for (holder_dirty = 0; holder_dirty <= 1; holder_dirty++)
2404  {
2405  for (holder_latch = PERF_HOLDER_LATCH_READ; holder_latch < PERF_HOLDER_LATCH_CNT; holder_latch++)
2406  {
2407  offset = PERF_PAGE_UNFIX_STAT_OFFSET (module, page_type, buf_dirty, holder_dirty, holder_latch);
2408 
2409  assert (offset < PERF_PAGE_UNFIX_COUNTERS);
2410  counter = stats_ptr[offset];
2411  if (counter == 0)
2412  {
2413  continue;
2414  }
2415 
2416  fprintf (stream, "%-6s,%-14s,%-13s,%-16s,%-5s = %10llu\n", perfmon_stat_module_name (module),
2417  perfmon_stat_page_type_name (page_type), buf_dirty ? "BUF_DIRTY" : "BUF_NON_DIRTY",
2418  holder_dirty ? "HOLDER_DIRTY" : "HOLDER_NON_DIRTY",
2419  perfmon_stat_holder_latch_name (holder_latch), (long long unsigned int) counter);
2420  }
2421  }
2422  }
2423  }
2424  }
2425 }
2426 
2427 /*
2428  * perfmon_stat_dump_in_buffer_page_lock_time_array_stat () -
2429  *
2430  * stats_ptr(in): start of array values
2431  * s(in/out): output string (NULL if not used)
2432  * remaining_size(in/out): remaining size in string s (NULL if not used)
2433  *
2434  */
2435 static void
2436 perfmon_stat_dump_in_buffer_page_lock_time_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size)
2437 {
2438  int module;
2439  int page_type;
2440  int page_mode;
2441  int latch_mode;
2442  int cond_type;
2443  int offset;
2444  UINT64 counter = 0;
2445  int ret;
2446 
2447  assert (remaining_size != NULL);
2448  assert (s != NULL);
2449  if (*s != NULL)
2450  {
2451  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2452  {
2453  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
2454  {
2455  for (page_mode = PERF_PAGE_MODE_OLD_LOCK_WAIT; page_mode < PERF_PAGE_MODE_CNT; page_mode++)
2456  {
2457  for (latch_mode = PERF_HOLDER_LATCH_READ; latch_mode < PERF_HOLDER_LATCH_CNT; latch_mode++)
2458  {
2459  for (cond_type = PERF_CONDITIONAL_FIX; cond_type < PERF_CONDITIONAL_FIX_CNT; cond_type++)
2460  {
2461  offset = PERF_PAGE_FIX_STAT_OFFSET (module, page_type, page_mode, latch_mode, cond_type);
2462 
2463  assert (offset < PERF_PAGE_FIX_COUNTERS);
2464  counter = stats_ptr[offset];
2465  if (counter == 0)
2466  {
2467  continue;
2468  }
2469 
2470  ret = snprintf (*s, *remaining_size, "%-6s,%-14s,%-18s,%-5s,%-11s = %16llu\n",
2472  perfmon_stat_page_mode_name (page_mode),
2473  perfmon_stat_holder_latch_name (latch_mode),
2474  perfmon_stat_cond_type_name (cond_type), (long long unsigned int) counter);
2475  *remaining_size -= ret;
2476  *s += ret;
2477  if (*remaining_size <= 0)
2478  {
2479  return;
2480  }
2481  }
2482  }
2483  }
2484  }
2485  }
2486  }
2487 }
2488 
2489 /*
2490  * perfmon_stat_dump_in_file_page_lock_time_array_stat () -
2491  *
2492  * stream(in): output file
2493  * stats_ptr(in): start of array values
2494  *
2495  */
2496 static void
2497 perfmon_stat_dump_in_file_page_lock_time_array_stat (FILE * stream, const UINT64 * stats_ptr)
2498 {
2499  int module;
2500  int page_type;
2501  int page_mode;
2502  int latch_mode;
2503  int cond_type;
2504  int offset;
2505  UINT64 counter = 0;
2506 
2507  assert (stream != NULL);
2508  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2509  {
2510  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
2511  {
2512  for (page_mode = PERF_PAGE_MODE_OLD_LOCK_WAIT; page_mode < PERF_PAGE_MODE_CNT; page_mode++)
2513  {
2514  for (latch_mode = PERF_HOLDER_LATCH_READ; latch_mode < PERF_HOLDER_LATCH_CNT; latch_mode++)
2515  {
2516  for (cond_type = PERF_CONDITIONAL_FIX; cond_type < PERF_CONDITIONAL_FIX_CNT; cond_type++)
2517  {
2518  offset = PERF_PAGE_FIX_STAT_OFFSET (module, page_type, page_mode, latch_mode, cond_type);
2519 
2520  assert (offset < PERF_PAGE_FIX_COUNTERS);
2521  counter = stats_ptr[offset];
2522  if (counter == 0)
2523  {
2524  continue;
2525  }
2526 
2527  fprintf (stream, "%-6s,%-14s,%-18s,%-5s,%-11s = %16llu\n", perfmon_stat_module_name (module),
2530  (long long unsigned int) counter);
2531  }
2532  }
2533  }
2534  }
2535  }
2536 }
2537 
2538 /*
2539  * perfmon_stat_dump_in_buffer_page_hold_time_array_stat () -
2540  *
2541  * stats_ptr(in): start of array values
2542  * s(in/out): output string (NULL if not used)
2543  * remaining_size(in/out): remaining size in string s (NULL if not used)
2544  *
2545  */
2546 static void
2547 perfmon_stat_dump_in_buffer_page_hold_time_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size)
2548 {
2549  int module;
2550  int page_type;
2551  int page_mode;
2552  int latch_mode;
2553  int offset;
2554  UINT64 counter = 0;
2555  int ret;
2556 
2557  assert (remaining_size != NULL);
2558  assert (s != NULL);
2559  if (*s != NULL)
2560  {
2561  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2562  {
2563  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
2564  {
2565  for (page_mode = PERF_PAGE_MODE_OLD_LOCK_WAIT; page_mode < PERF_PAGE_MODE_CNT; page_mode++)
2566  {
2567  for (latch_mode = PERF_HOLDER_LATCH_READ; latch_mode < PERF_HOLDER_LATCH_CNT; latch_mode++)
2568  {
2569  offset = PERF_PAGE_HOLD_TIME_OFFSET (module, page_type, page_mode, latch_mode);
2570 
2572  counter = stats_ptr[offset];
2573  if (counter == 0)
2574  {
2575  continue;
2576  }
2577 
2578  ret = snprintf (*s, *remaining_size, "%-6s,%-14s,%-18s,%-5s = %16llu\n",
2580  perfmon_stat_page_mode_name (page_mode),
2581  perfmon_stat_holder_latch_name (latch_mode), (long long unsigned int) counter);
2582  *remaining_size -= ret;
2583  *s += ret;
2584  if (*remaining_size <= 0)
2585  {
2586  return;
2587  }
2588  }
2589  }
2590  }
2591  }
2592  }
2593 }
2594 
2595 /*
2596  * perfmon_stat_dump_in_file_page_hold_time_array_stat () -
2597  *
2598  * stream(in): output file
2599  * stats_ptr(in): start of array values
2600  *
2601  */
2602 static void
2603 perfmon_stat_dump_in_file_page_hold_time_array_stat (FILE * stream, const UINT64 * stats_ptr)
2604 {
2605  int module;
2606  int page_type;
2607  int page_mode;
2608  int latch_mode;
2609  int offset;
2610  UINT64 counter = 0;
2611 
2612  assert (stream != NULL);
2613  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2614  {
2615  for (page_type = PERF_PAGE_UNKNOWN; page_type < PERF_PAGE_CNT; page_type++)
2616  {
2617  for (page_mode = PERF_PAGE_MODE_OLD_LOCK_WAIT; page_mode < PERF_PAGE_MODE_CNT; page_mode++)
2618  {
2619  for (latch_mode = PERF_HOLDER_LATCH_READ; latch_mode < PERF_HOLDER_LATCH_CNT; latch_mode++)
2620  {
2621  offset = PERF_PAGE_HOLD_TIME_OFFSET (module, page_type, page_mode, latch_mode);
2622 
2624 
2625 
2626  counter = stats_ptr[offset];
2627  if (counter == 0)
2628  {
2629  continue;
2630  }
2631 
2632  fprintf (stream, "%-6s,%-14s,%-18s,%-5s = %16llu\n", perfmon_stat_module_name (module),
2634  perfmon_stat_holder_latch_name (latch_mode), (long long unsigned int) counter);
2635  }
2636  }
2637  }
2638  }
2639 }
2640 
2641 /*
2642  * perfmon_stat_dump_in_buffer_page_fix_time_array_stat () -
2643  *
2644  * stats_ptr(in): start of array values
2645  * s(in/out): output string (NULL if not used)
2646  * remaining_size(in/out): remaining size in string s (NULL if not used)
2647  *
2648  */
2649 static void
2650 perfmon_stat_dump_in_buffer_page_fix_time_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size)
2651 {
2652  /* the counters partitioning match with page fix statistics */
2653  perfmon_stat_dump_in_buffer_page_lock_time_array_stat (stats_ptr, s, remaining_size);
2654 }
2655 
2656 /*
2657  * perfmon_stat_dump_in_file_page_fix_time_array_stat () -
2658  *
2659  * stream(in): output file
2660  * stats_ptr(in): start of array values
2661  *
2662  */
2663 static void
2664 perfmon_stat_dump_in_file_page_fix_time_array_stat (FILE * stream, const UINT64 * stats_ptr)
2665 {
2666  /* the counters partitioning match with page fix statistics */
2668 }
2669 
2670 /*
2671  * perfmon_stat_dump_in_buffer_mvcc_snapshot_array_stat () -
2672  *
2673  * stats_ptr(in): start of array values
2674  * s(in/out): output string (NULL if not used)
2675  * remaining_size(in/out): remaining size in string s (NULL if not used)
2676  *
2677  */
2678 static void
2679 perfmon_stat_dump_in_buffer_mvcc_snapshot_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size)
2680 {
2681  unsigned int snapshot;
2682  unsigned int rec_type;
2683  unsigned int visibility;
2684  int offset;
2685  UINT64 counter = 0;
2686  int ret;
2687 
2688  assert (remaining_size != NULL);
2689  assert (s != NULL);
2690  if (*s != NULL)
2691  {
2692  for (snapshot = (unsigned int) PERF_SNAPSHOT_SATISFIES_DELETE; snapshot < (unsigned int) PERF_SNAPSHOT_CNT;
2693  snapshot++)
2694  {
2695  for (rec_type = (unsigned int) PERF_SNAPSHOT_RECORD_INSERTED_VACUUMED;
2696  rec_type < (unsigned int) PERF_SNAPSHOT_RECORD_TYPE_CNT; rec_type++)
2697  {
2698  for (visibility = (unsigned int) PERF_SNAPSHOT_INVISIBLE;
2699  visibility < (unsigned int) PERF_SNAPSHOT_VISIBILITY_CNT; visibility++)
2700  {
2701  offset = PERF_MVCC_SNAPSHOT_OFFSET (snapshot, rec_type, visibility);
2702 
2704  counter = stats_ptr[offset];
2705  if (counter == 0)
2706  {
2707  continue;
2708  }
2709 
2710  ret =
2711  snprintf (*s, *remaining_size, "%-8s,%-18s,%-9s = %16llu\n", perfmon_stat_snapshot_name (snapshot),
2713  (visibility == PERF_SNAPSHOT_INVISIBLE) ? "INVISIBLE" : "VISIBLE",
2714  (long long unsigned int) counter);
2715  *remaining_size -= ret;
2716  *s += ret;
2717  if (*remaining_size <= 0)
2718  {
2719  return;
2720  }
2721  }
2722  }
2723  }
2724  }
2725 }
2726 
2727 /*
2728  * perf_stat_dump_in_file_mvcc_snapshot_array_stat () -
2729  *
2730  * stream(in): output file
2731  * stats_ptr(in): start of array values
2732  *
2733  */
2734 static void
2735 perfmon_stat_dump_in_file_mvcc_snapshot_array_stat (FILE * stream, const UINT64 * stats_ptr)
2736 {
2737  unsigned int snapshot;
2738  unsigned int rec_type;
2739  unsigned int visibility;
2740  int offset;
2741  UINT64 counter = 0;
2742 
2743  assert (stream != NULL);
2744  for (snapshot = (unsigned int) PERF_SNAPSHOT_SATISFIES_DELETE; snapshot < (unsigned int) PERF_SNAPSHOT_CNT;
2745  snapshot++)
2746  {
2747  for (rec_type = (unsigned int) PERF_SNAPSHOT_RECORD_INSERTED_VACUUMED;
2748  rec_type < (unsigned int) PERF_SNAPSHOT_RECORD_TYPE_CNT; rec_type++)
2749  {
2750  for (visibility = (unsigned int) PERF_SNAPSHOT_INVISIBLE;
2751  visibility < (unsigned int) PERF_SNAPSHOT_VISIBILITY_CNT; visibility++)
2752  {
2753  offset = PERF_MVCC_SNAPSHOT_OFFSET (snapshot, rec_type, visibility);
2754 
2756 
2757  counter = stats_ptr[offset];
2758  if (counter == 0)
2759  {
2760  continue;
2761  }
2762 
2763  fprintf (stream, "%-8s,%-18s,%-9s = %16llu\n", perfmon_stat_snapshot_name (snapshot),
2765  (visibility == PERF_SNAPSHOT_INVISIBLE) ? "INVISIBLE" : "VISIBLE",
2766  (long long unsigned int) counter);
2767  }
2768  }
2769  }
2770 }
2771 
2772 /*
2773  * perfmon_stat_dump_in_buffer_obj_lock_array_stat () -
2774  *
2775  * stats_ptr(in): start of array values
2776  * s(in/out): output string (NULL if not used)
2777  * remaining_size(in/out): remaining size in string s (NULL if not used)
2778  *
2779  */
2780 static void
2781 perfmon_stat_dump_in_buffer_obj_lock_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size)
2782 {
2783  unsigned int lock_mode;
2784  UINT64 counter = 0;
2785  int ret;
2786 
2787  assert (remaining_size != NULL);
2788  assert (s != NULL);
2789  if (*s != NULL)
2790  {
2791  for (lock_mode = (unsigned int) NA_LOCK; lock_mode <= (unsigned int) SCH_M_LOCK; lock_mode++)
2792  {
2793  counter = stats_ptr[lock_mode];
2794  if (counter == 0)
2795  {
2796  continue;
2797  }
2798 
2799  ret = snprintf (*s, *remaining_size, "%-10s = %16llu\n", perfmon_stat_lock_mode_name (lock_mode),
2800  (long long unsigned int) counter);
2801  *remaining_size -= ret;
2802  *s += ret;
2803  if (*remaining_size <= 0)
2804  {
2805  return;
2806  }
2807  }
2808  }
2809 }
2810 
2811 /*
2812  * perfmon_stat_dump_in_file_obj_lock_array_stat () -
2813  *
2814  * stream(in): output file
2815  * stats_ptr(in): start of array values
2816  *
2817  */
2818 static void
2819 perfmon_stat_dump_in_file_obj_lock_array_stat (FILE * stream, const UINT64 * stats_ptr)
2820 {
2821  int lock_mode;
2822  UINT64 counter = 0;
2823 
2824  assert (stream != NULL);
2825 
2826  for (lock_mode = NA_LOCK; lock_mode <= SCH_M_LOCK; lock_mode++)
2827  {
2828  counter = stats_ptr[lock_mode];
2829  if (counter == 0)
2830  {
2831  continue;
2832  }
2833 
2834  fprintf (stream, "%-10s = %16llu\n", perfmon_stat_lock_mode_name (lock_mode), (long long unsigned int) counter);
2835  }
2836 }
2837 
2838 /*
2839  * perfmon_stat_dump_in_buffer_obj_lock_array_stat () -
2840  *
2841  * stats_ptr(in): start of array values
2842  * s(in/out): output string (NULL if not used)
2843  * remaining_size(in/out): remaining size in string s (NULL if not used)
2844  *
2845  */
2846 static void
2847 perfmon_stat_dump_in_buffer_flushed_block_volumes_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size)
2848 {
2849  unsigned int flushed_block_volumes;
2850  UINT64 counter = 0;
2851  int ret;
2852  char buffer[15];
2853 
2854  assert (remaining_size != NULL);
2855  assert (s != NULL);
2856 
2857  if (*s != NULL)
2858  {
2859  for (flushed_block_volumes = (unsigned int) 0;
2860  flushed_block_volumes < (unsigned int) PERF_DWB_FLUSHED_BLOCK_VOLUMES_CNT; flushed_block_volumes++)
2861  {
2862  counter = stats_ptr[flushed_block_volumes];
2863  if (counter == 0)
2864  {
2865  continue;
2866  }
2867 
2868  sprintf (buffer, "%d Volumes", flushed_block_volumes);
2869  ret = snprintf (*s, *remaining_size, "%-15s = %16llu\n", buffer, (long long unsigned int) counter);
2870  *remaining_size -= ret;
2871  *s += ret;
2872  if (*remaining_size <= 0)
2873  {
2874  return;
2875  }
2876  }
2877  }
2878 }
2879 
2880 /*
2881  * perfmon_stat_dump_in_file_flushed_block_volumes_array_stat () -
2882  *
2883  * stream(in): output file
2884  * stats_ptr(in): start of array values
2885  *
2886  */
2887 static void
2888 perfmon_stat_dump_in_file_flushed_block_volumes_array_stat (FILE * stream, const UINT64 * stats_ptr)
2889 {
2890  unsigned int flushed_block_volumes;
2891  UINT64 counter = 0;
2892  char buffer[15];
2893 
2894  assert (stream != NULL);
2895 
2896  for (flushed_block_volumes = (unsigned int) 0;
2897  flushed_block_volumes < (unsigned int) PERF_DWB_FLUSHED_BLOCK_VOLUMES_CNT; flushed_block_volumes++)
2898  {
2899  counter = stats_ptr[flushed_block_volumes];
2900  if (counter == 0)
2901  {
2902  continue;
2903  }
2904 
2905  sprintf (buffer, "%d Volumes", flushed_block_volumes);
2906  fprintf (stream, "%-15s = %16llu\n", buffer, (long long unsigned int) counter);
2907  }
2908 }
2909 
2910 /*
2911  * perfmon_stat_dump_in_buffer_snapshot_array_stat () -
2912  *
2913  * stats_ptr(in): start of array values
2914  * s(in/out): output string (NULL if not used)
2915  * remaining_size(in/out): remaining size in string s (NULL if not used)
2916  *
2917  */
2918 static void
2919 perfmon_stat_dump_in_buffer_snapshot_array_stat (const UINT64 * stats_ptr, char **s, int *remaining_size)
2920 {
2921  int module;
2922  int offset;
2923  UINT64 counter = 0;
2924  int ret;
2925 
2926  assert (remaining_size != NULL);
2927  assert (s != NULL);
2928  if (*s != NULL)
2929  {
2930  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2931  {
2932  offset = module;
2933 
2934  assert (offset < PERF_MODULE_CNT);
2935  counter = stats_ptr[offset];
2936  if (counter == 0)
2937  {
2938  continue;
2939  }
2940 
2941  ret = snprintf (*s, *remaining_size, "%-6s = %16llu\n", perfmon_stat_module_name (module),
2942  (long long unsigned int) counter);
2943  *remaining_size -= ret;
2944  *s += ret;
2945  if (*remaining_size <= 0)
2946  {
2947  return;
2948  }
2949  }
2950  }
2951 }
2952 
2953 /*
2954  * perfmon_stat_dump_in_file_snapshot_array_stat () -
2955  *
2956  * stream(in): output file
2957  * stats_ptr(in): start of array values
2958  *
2959  */
2960 static void
2961 perfmon_stat_dump_in_file_snapshot_array_stat (FILE * stream, const UINT64 * stats_ptr)
2962 {
2963  int module;
2964  int offset;
2965  UINT64 counter = 0;
2966 
2967  assert (stream != NULL);
2968  for (module = PERF_MODULE_SYSTEM; module < PERF_MODULE_CNT; module++)
2969  {
2970  offset = module;
2971 
2972  assert (offset < PERF_MODULE_CNT);
2973  counter = stats_ptr[offset];
2974  if (counter == 0)
2975  {
2976  continue;
2977  }
2978 
2979  fprintf (stream, "%-6s = %16llu\n", perfmon_stat_module_name (module), (long long unsigned int) counter);
2980  }
2981 }
2982 
2983 /*
2984  * perfmon_initialize () - Computes the metadata values & allocates/initializes global/transaction statistics values.
2985  *
2986  * return : NO_ERROR or ER_OUT_OF_VIRTUAL_MEMORY.
2987  * num_trans (in) : For server/stand-alone mode to allocate transactions.
2988  */
2989 int
2990 perfmon_initialize (int num_trans)
2991 {
2992  int idx = 0;
2993 #if defined (SERVER_MODE) || defined (SA_MODE)
2994  int memsize = 0;
2995 #endif
2996 
2997  pstat_Global.n_stat_values = 0;
2998  pstat_Global.global_stats = NULL;
2999  pstat_Global.n_trans = 0;
3000  pstat_Global.tran_stats = NULL;
3001  pstat_Global.is_watching = NULL;
3002  pstat_Global.n_watchers = 0;
3003  pstat_Global.initialized = false;
3005 
3006 #if defined (SERVER_MODE)
3008  {
3009  // always watching
3010  pstat_Global.n_watchers++;
3011  }
3012 #endif
3013 
3014  for (idx = 0; idx < PSTAT_COUNT; idx++)
3015  {
3016  assert (pstat_Metadata[idx].psid == (PERF_STAT_ID) idx);
3017  pstat_Metadata[idx].start_offset = pstat_Global.n_stat_values;
3018  switch (pstat_Metadata[idx].valtype)
3019  {
3022  /* Only one value stored. */
3023  pstat_Metadata[idx].n_vals = 1;
3024  break;
3026  /* Only one value stored. */
3027  pstat_Metadata[idx].n_vals = 1;
3028  break;
3030  /* We have:
3031  * 1. counter
3032  * 2. timer
3033  * 3. max time
3034  * 4. average time
3035  */
3036  pstat_Metadata[idx].n_vals = 4;
3037  break;
3038  case PSTAT_COMPLEX_VALUE:
3039  /* We should have a load function. */
3040  assert (pstat_Metadata[idx].f_load != NULL);
3041  pstat_Metadata[idx].n_vals = pstat_Metadata[idx].f_load ();
3042  if (pstat_Metadata[idx].n_vals < 0)
3043  {
3044  /* Error. */
3045  ASSERT_ERROR ();
3046  return pstat_Metadata[idx].n_vals;
3047  }
3048  /* Debug check: we should have dump/compute too. */
3049  assert (pstat_Metadata[idx].f_dump_in_file != NULL);
3050  assert (pstat_Metadata[idx].f_dump_in_buffer != NULL);
3051  }
3052  pstat_Global.n_stat_values += pstat_Metadata[idx].n_vals;
3053  }
3054 
3055 #if defined (SERVER_MODE) || defined (SA_MODE)
3056 
3057 #if !defined (HAVE_ATOMIC_BUILTINS)
3058  (void) pthread_mutex_init (&pstat_Global.watch_lock, NULL);
3059 #endif /* !HAVE_ATOMIC_BUILTINS */
3060 
3061  /* Allocate global stats. */
3062  pstat_Global.global_stats = (UINT64 *) malloc (PERFMON_VALUES_MEMSIZE);
3063  if (pstat_Global.global_stats == NULL)
3064  {
3066  goto error;
3067  }
3068  memset (pstat_Global.global_stats, 0, PERFMON_VALUES_MEMSIZE);
3069 
3070  assert (num_trans > 0);
3071 
3072  pstat_Global.n_trans = num_trans + 1; /* 1 more for easier indexing with tran_index */
3073  memsize = pstat_Global.n_trans * sizeof (UINT64 *);
3074  pstat_Global.tran_stats = (UINT64 **) malloc (memsize);
3075  if (pstat_Global.tran_stats == NULL)
3076  {
3078  goto error;
3079  }
3080  memsize = pstat_Global.n_trans * PERFMON_VALUES_MEMSIZE;
3081  pstat_Global.tran_stats[0] = (UINT64 *) malloc (memsize);
3082  if (pstat_Global.tran_stats[0] == NULL)
3083  {
3085  goto error;
3086  }
3087  memset (pstat_Global.tran_stats[0], 0, memsize);
3088 
3089  for (idx = 1; idx < pstat_Global.n_trans; idx++)
3090  {
3091  pstat_Global.tran_stats[idx] = pstat_Global.tran_stats[0] + pstat_Global.n_stat_values * idx;
3092  }
3093 
3094  memsize = pstat_Global.n_trans * sizeof (bool);
3095  pstat_Global.is_watching = (bool *) malloc (memsize);
3096  if (pstat_Global.is_watching == NULL)
3097  {
3099  goto error;
3100  }
3101  memset (pstat_Global.is_watching, 0, memsize);
3102 
3103  pstat_Global.n_watchers = 0;
3104  pstat_Global.initialized = true;
3105  return NO_ERROR;
3106 
3107 error:
3108  perfmon_finalize ();
3109  return ER_OUT_OF_VIRTUAL_MEMORY;
3110 #else
3111  pstat_Global.initialized = true;
3112  return NO_ERROR;
3113 #endif /* SERVER_MODE || SA_MODE */
3114 }
3115 
3116 /*
3117  * perfmon_finalize () - Frees all the allocated memory for performance monitor data structures
3118  *
3119  * return :
3120  */
3121 
3122 void
3124 {
3125  if (pstat_Global.tran_stats != NULL)
3126  {
3127  if (pstat_Global.tran_stats[0] != NULL)
3128  {
3129  free_and_init (pstat_Global.tran_stats[0]);
3130  }
3131  free_and_init (pstat_Global.tran_stats);
3132  }
3133  if (pstat_Global.is_watching != NULL)
3134  {
3135  free_and_init (pstat_Global.is_watching);
3136  }
3137  if (pstat_Global.global_stats != NULL)
3138  {
3139  free_and_init (pstat_Global.global_stats);
3140  }
3141 #if defined (SERVER_MODE) || defined (SA_MODE)
3142 #if !defined (HAVE_ATOMIC_BUILTINS)
3143  pthread_mutex_destroy (&pstat_Global.watch_lock);
3144 #endif /* !HAVE_ATOMIC_BUILTINS */
3145 #endif /* SERVER_MODE || SA_MODE */
3146 }
3147 
3148 /*
3149  * Watcher section.
3150  */
3151 
3152 #if defined (SERVER_MODE) || defined (SA_MODE)
3153 /*
3154  * perfmon_start_watch () - Start watching performance statistics.
3155  *
3156  * return : Void.
3157  * thread_p (in) : Thread entry.
3158  */
3159 void
3160 perfmon_start_watch (THREAD_ENTRY * thread_p)
3161 {
3162  int tran_index;
3163 
3164  assert (pstat_Global.initialized);
3165 
3166  tran_index = LOG_FIND_THREAD_TRAN_INDEX (thread_p);
3167  assert (tran_index >= 0 && tran_index < pstat_Global.n_trans);
3168 
3169  if (pstat_Global.is_watching[tran_index])
3170  {
3171  /* Already watching. */
3172  return;
3173  }
3174 
3175 #if defined (HAVE_ATOMIC_BUILTINS)
3176  ATOMIC_INC_32 (&pstat_Global.n_watchers, 1);
3177 #else /* !HAVE_ATOMIC_BUILTINS */
3178  pthread_mutex_lock (&pstat_Global.watch_lock);
3179  pstat_Global.n_watchers++;
3180  pthread_mutex_unlock (&pstat_Global.watch_lock);
3181 #endif /* !HAVE_ATOMIC_BUILTINS */
3182 
3183  memset (pstat_Global.tran_stats[tran_index], 0, PERFMON_VALUES_MEMSIZE);
3184  pstat_Global.is_watching[tran_index] = true;
3185 }
3186 
3187 /*
3188  * perfmon_stop_watch () - Stop watching performance statistics.
3189  *
3190  * return : Void.
3191  * thread_p (in) : Thread entry.
3192  */
3193 void
3194 perfmon_stop_watch (THREAD_ENTRY * thread_p)
3195 {
3196  int tran_index;
3197 
3198  assert (pstat_Global.initialized);
3199 
3200  tran_index = LOG_FIND_THREAD_TRAN_INDEX (thread_p);
3201  assert (tran_index >= 0 && tran_index < pstat_Global.n_trans);
3202 
3203  if (!pstat_Global.is_watching[tran_index])
3204  {
3205  /* Not watching. */
3206  return;
3207  }
3208 
3209 #if defined (HAVE_ATOMIC_BUILTINS)
3210  ATOMIC_INC_32 (&pstat_Global.n_watchers, -1);
3211 #else /* !HAVE_ATOMIC_BUILTINS */
3212  pthread_mutex_lock (&pstat_Global.watch_lock);
3213  pstat_Global.n_watchers--;
3214  pthread_mutex_unlock (&pstat_Global.watch_lock);
3215 #endif /* !HAVE_ATOMIC_BUILTINS */
3216 
3217  pstat_Global.is_watching[tran_index] = false;
3218 }
3219 #endif /* SERVER_MODE || SA_MODE */
3220 
3221 /*
3222  * perfmon_add_stat_at_offset () - Accumulate amount to statistic.
3223  *
3224  * return : Void.
3225  * thread_p (in) : Thread entry.
3226  * psid (in) : Statistic ID.
3227  * offset (in) : offset at which to add the amount
3228  * amount (in) : Amount to add.
3229  */
3230 STATIC_INLINE void
3231 perfmon_add_stat_at_offset (THREAD_ENTRY * thread_p, PERF_STAT_ID psid, const int offset, UINT64 amount)
3232 {
3233  assert (pstat_Global.initialized);
3234  assert (PSTAT_BASE < psid && psid < PSTAT_COUNT);
3235 
3236  /* Update statistics. */
3237  perfmon_add_at_offset (thread_p, pstat_Metadata[psid].start_offset + offset, amount);
3238 }
3239 
3240 /*
3241  * f_load_Num_data_page_fix_ext () - Get the number of values for Num_data_page_fix_ext statistic
3242  *
3243  */
3244 static int
3246 {
3247  return PERF_PAGE_FIX_COUNTERS;
3248 }
3249 
3250 /*
3251  * f_load_Num_data_page_promote_ext () - Get the number of values for Num_data_page_promote_ext statistic
3252  *
3253  */
3254 static int
3256 {
3258 }
3259 
3260 /*
3261  * f_load_Num_data_page_promote_time_ext () - Get the number of values for Num_data_page_promote_time_ext statistic
3262  *
3263  */
3264 static int
3266 {
3268 }
3269 
3270 /*
3271  * f_load_Num_data_page_unfix_ext () - Get the number of values for Num_data_page_unfix_ext statistic
3272  *
3273  */
3274 static int
3276 {
3277  return PERF_PAGE_UNFIX_COUNTERS;
3278 }
3279 
3280 /*
3281  * f_load_Time_data_page_lock_acquire_time () - Get the number of values for Time_data_page_lock_acquire_time statistic
3282  *
3283  */
3284 static int
3286 {
3288 }
3289 
3290 /*
3291  * f_load_Time_data_page_hold_acquire_time () - Get the number of values for Time_data_page_hold_acquire_time statistic
3292  *
3293  */
3294 static int
3296 {
3298 }
3299 
3300 /*
3301  * f_load_Time_data_page_fix_acquire_time () - Get the number of values for Time_data_page_fix_acquire_time statistic
3302  *
3303  */
3304 static int
3306 {
3308 }
3309 
3310 /*
3311  * f_load_Num_mvcc_snapshot_ext () - Get the number of values for Num_mvcc_snapshot_ext statistic
3312  *
3313  */
3314 static int
3316 {
3318 }
3319 
3320 /*
3321  * f_load_Time_obj_lock_acquire_time () - Get the number of values for Time_obj_lock_acquire_time statistic
3322  *
3323  */
3324 static int
3326 {
3328 }
3329 
3330 /*
3331  * f_load_Num_dwb_flushed_block_volumes () - Get the number of values for Num_dwb_flushed_block_volumes statistic
3332  *
3333  */
3334 static int
3336 {
3338 }
3339 
3340 /*
3341  * f_load_Time_get_snapshot_acquire_time () - Get the number of values for Time_get_snapshot_acquire_time statistic
3342  *
3343  */
3344 static int
3346 {
3347  return PERF_MODULE_CNT;
3348 }
3349 
3350 /*
3351  * f_load_Count_get_snapshot_retry () - Get the number of values for Count_get_snapshot_retry statistic
3352  *
3353  */
3354 static int
3356 {
3357  return PERF_MODULE_CNT;
3358 }
3359 
3360 /*
3361  * f_load_Time_tran_complete_time () - Get the number of values for Time_tran_complete_time statistic
3362  *
3363  */
3364 static int
3366 {
3367  return PERF_MODULE_CNT;
3368 }
3369 
3370 /*
3371  * f_load_Time_get_oldest_mvcc_acquire_time () - Get the number of values for Time_get_oldest_mvcc_acquire_time
3372  * statistic
3373  *
3374  */
3375 static int
3377 {
3378  return PERF_MODULE_CNT;
3379 }
3380 
3381 /*
3382  * f_load_Count_get_oldest_mvcc_retry () - Get the number of values for Count_get_oldest_mvcc_retry statistic
3383  *
3384  */
3385 static int
3387 {
3388  return PERF_MODULE_CNT;
3389 }
3390 
3391 /*
3392  * f_dump_in_file_Num_data_page_fix_ext () - Write in file the values for Num_data_page_fix_ext statistic
3393  * f (out): File handle
3394  * stat_vals (in): statistics buffer
3395  *
3396  */
3397 static void
3398 f_dump_in_file_Num_data_page_fix_ext (FILE * f, const UINT64 * stat_vals)
3399 {
3401 }
3402 
3403 /*
3404  * f_dump_in_file_Num_data_page_promote_ext () - Write in file the values for Num_data_page_promote_ext statistic
3405  * f (out): File handle
3406  * stat_vals (in): statistics buffer
3407  *
3408  */
3409 static void
3410 f_dump_in_file_Num_data_page_promote_ext (FILE * f, const UINT64 * stat_vals)
3411 {
3413 }
3414 
3415 /*
3416  * f_dump_in_file_Num_data_page_promote_time_ext () - Write in file the values for Num_data_page_promote_time_ext
3417  * statistic
3418  * f (out): File handle
3419  * stat_vals (in): statistics buffer
3420  *
3421  */
3422 static void
3423 f_dump_in_file_Num_data_page_promote_time_ext (FILE * f, const UINT64 * stat_vals)
3424 {
3426 }
3427 
3428 /*
3429  * f_dump_in_file_Num_data_page_unfix_ext () - Write in file the values for Num_data_page_unfix_ext
3430  * statistic
3431  * f (out): File handle
3432  * stat_vals (in): statistics buffer
3433  *
3434  */
3435 static void
3436 f_dump_in_file_Num_data_page_unfix_ext (FILE * f, const UINT64 * stat_vals)
3437 {
3439 }
3440 
3441 /*
3442  * f_dump_in_file_Time_data_page_lock_acquire_time () - Write in file the values for Time_data_page_lock_acquire_time
3443  * statistic
3444  * f (out): File handle
3445  * stat_vals (in): statistics buffer
3446  *
3447  */
3448 static void
3449 f_dump_in_file_Time_data_page_lock_acquire_time (FILE * f, const UINT64 * stat_vals)
3450 {
3452 }
3453 
3454 /*
3455  * f_dump_in_file_Time_data_page_hold_acquire_time () - Write in file the values for Time_data_page_hold_acquire_time
3456  * statistic
3457  * f (out): File handle
3458  * stat_vals (in): statistics buffer
3459  *
3460  */
3461 static void
3462 f_dump_in_file_Time_data_page_hold_acquire_time (FILE * f, const UINT64 * stat_vals)
3463 {
3465 }
3466 
3467 /*
3468  * f_dump_in_file_Time_data_page_fix_acquire_time () - Write in file the values for Time_data_page_fix_acquire_time
3469  * statistic
3470  * f (out): File handle
3471  * stat_vals (in): statistics buffer
3472  *
3473  */
3474 static void
3475 f_dump_in_file_Time_data_page_fix_acquire_time (FILE * f, const UINT64 * stat_vals)
3476 {
3478 }
3479 
3480 /*
3481  * f_dump_in_file_Num_mvcc_snapshot_ext () - Write in file the values for Num_mvcc_snapshot_ext
3482  * statistic
3483  * f (out): File handle
3484  * stat_vals (in): statistics buffer
3485  *
3486  */
3487 static void
3488 f_dump_in_file_Num_mvcc_snapshot_ext (FILE * f, const UINT64 * stat_vals)
3489 {
3491  {
3493  }
3494 }
3495 
3496 /*
3497  * f_dump_in_file_Time_obj_lock_acquire_time () - Write in file the values for Time_obj_lock_acquire_time
3498  * statistic
3499  * f (out): File handle
3500  * stat_vals (in): statistics buffer
3501  *
3502  */
3503 static void
3504 f_dump_in_file_Time_obj_lock_acquire_time (FILE * f, const UINT64 * stat_vals)
3505 {
3507  {
3509  }
3510 }
3511 
3512 /*
3513  * f_dump_in_file_Num_dwb_flushed_block_volumes () - Write in file the values for Num_dwb_flushed_block_volumes
3514  * statistic
3515  * f (out): File handle
3516  * stat_vals (in): statistics buffer
3517  *
3518  */
3519 static void
3520 f_dump_in_file_Num_dwb_flushed_block_volumes (FILE * f, const UINT64 * stat_vals)
3521 {
3523  {
3525  }
3526 }
3527 
3528 /*
3529  * f_dump_in_buffer_Num_data_page_fix_ext () - Write to a buffer the values for Num_data_page_fix_ext
3530  * statistic
3531  * s (out): Buffer to write to
3532  * stat_vals (in): statistics buffer
3533  * remaining_size (in): size of input buffer
3534  *
3535  */
3536 static void
3537 f_dump_in_buffer_Num_data_page_fix_ext (char **s, const UINT64 * stat_vals, int *remaining_size)
3538 {
3539  perfmon_stat_dump_in_buffer_fix_page_array_stat (stat_vals, s, remaining_size);
3540 }
3541 
3542 /*
3543  * f_dump_in_buffer_Num_data_page_promote_ext () - Write to a buffer the values for Num_data_page_promote_ext
3544  * statistic
3545  * s (out): Buffer to write to
3546  * stat_vals (in): statistics buffer
3547  * remaining_size (in): size of input buffer
3548  *
3549  */
3550 static void
3551 f_dump_in_buffer_Num_data_page_promote_ext (char **s, const UINT64 * stat_vals, int *remaining_size)
3552 {
3553  perfmon_stat_dump_in_buffer_promote_page_array_stat (stat_vals, s, remaining_size);
3554 }
3555 
3556 /*
3557  * f_dump_in_buffer_Num_data_page_promote_time_ext () - Write to a buffer the values for Num_data_page_promote_time_ext
3558  * statistic
3559  * s (out): Buffer to write to
3560  * stat_vals (in): statistics buffer
3561  * remaining_size (in): size of input buffer
3562  *
3563  */
3564 static void
3565 f_dump_in_buffer_Num_data_page_promote_time_ext (char **s, const UINT64 * stat_vals, int *remaining_size)
3566 {
3567  perfmon_stat_dump_in_buffer_promote_page_array_stat (stat_vals, s, remaining_size);
3568 }
3569 
3570 /*
3571  * f_dump_in_buffer_Num_data_page_unfix_ext () - Write to a buffer the values for Num_data_page_unfix_ext
3572  * statistic
3573  * s (out): Buffer to write to
3574  * stat_vals (in): statistics buffer
3575  * remaining_size (in): size of input buffer
3576  *
3577  */
3578 static void
3579 f_dump_in_buffer_Num_data_page_unfix_ext (char **s, const UINT64 * stat_vals, int *remaining_size)
3580 {
3581  perfmon_stat_dump_in_buffer_unfix_page_array_stat (stat_vals, s, remaining_size);
3582 }
3583 
3584 /*
3585  * f_dump_in_buffer_Time_data_page_lock_acquire_time () - Write to a buffer the values for
3586  * Time_data_page_lock_acquire_time statistic
3587  *
3588  * s (out): Buffer to write to
3589  * stat_vals (in): statistics buffer
3590  * remaining_size (in): size of input buffer
3591  *
3592  */
3593 static void
3594 f_dump_in_buffer_Time_data_page_lock_acquire_time (char **s, const UINT64 * stat_vals, int *remaining_size)
3595 {
3596  perfmon_stat_dump_in_buffer_page_lock_time_array_stat (stat_vals, s, remaining_size);
3597 }
3598 
3599 /*
3600  * f_dump_in_buffer_Time_data_page_hold_acquire_time () - Write to a buffer the values for
3601  * Time_data_page_hold_acquire_time statistic
3602  *
3603  * s (out): Buffer to write to
3604  * stat_vals (in): statistics buffer
3605  * remaining_size (in): size of input buffer
3606  *
3607  */
3608 static void
3609 f_dump_in_buffer_Time_data_page_hold_acquire_time (char **s, const UINT64 * stat_vals, int *remaining_size)
3610 {
3611  perfmon_stat_dump_in_buffer_page_hold_time_array_stat (stat_vals, s, remaining_size);
3612 }
3613 
3614 /*
3615  * f_dump_in_buffer_Time_data_page_fix_acquire_time () - Write to a buffer the values for
3616  * Time_data_page_fix_acquire_time statistic
3617  *
3618  * s (out): Buffer to write to
3619  * stat_vals (in): statistics buffer
3620  * remaining_size (in): size of input buffer
3621  *
3622  */
3623 static void
3624 f_dump_in_buffer_Time_data_page_fix_acquire_time (char **s, const UINT64 * stat_vals, int *remaining_size)
3625 {
3626  perfmon_stat_dump_in_buffer_page_fix_time_array_stat (stat_vals, s, remaining_size);
3627 }
3628 
3629 /*
3630  * f_dump_in_buffer_Num_mvcc_snapshot_ext () - Write to a buffer the values for Num_mvcc_snapshot_ext
3631  * statistic
3632  * s (out): Buffer to write to
3633  * stat_vals (in): statistics buffer
3634  * remaining_size (in): size of input buffer
3635  *
3636  */
3637 static void
3638 f_dump_in_buffer_Num_mvcc_snapshot_ext (char **s, const UINT64 * stat_vals, int *remaining_size)
3639 {
3641  {
3642  perfmon_stat_dump_in_buffer_mvcc_snapshot_array_stat (stat_vals, s, remaining_size);
3643  }
3644 }
3645 
3646 /*
3647  * f_dump_in_buffer_Time_obj_lock_acquire_time () - Write to a buffer the values for Time_obj_lock_acquire_time
3648  * statistic
3649  * s (out): Buffer to write to
3650  * stat_vals (in): statistics buffer
3651  * remaining_size (in): size of input buffer
3652  *
3653  */
3654 static void
3655 f_dump_in_buffer_Time_obj_lock_acquire_time (char **s, const UINT64 * stat_vals, int *remaining_size)
3656 {
3658  {
3659  perfmon_stat_dump_in_buffer_obj_lock_array_stat (stat_vals, s, remaining_size);
3660  }
3661 }
3662 
3663 /*
3664  * f_dump_in_buffer_Num_dwb_flushed_block_volumes () - Write to a buffer the values for Num_dwb_flushed_block_volumes
3665  * statistic
3666  * s (out): Buffer to write to
3667  * stat_vals (in): statistics buffer
3668  * remaining_size (in): size of input buffer
3669  *
3670  */
3671 static void
3672 f_dump_in_buffer_Num_dwb_flushed_block_volumes (char **s, const UINT64 * stat_vals, int *remaining_size)
3673 {
3675  {
3676  perfmon_stat_dump_in_buffer_fix_page_array_stat (stat_vals, s, remaining_size);
3677  }
3678 }
3679 
3680 /*
3681  * perfmon_get_number_of_statistic_values () - Get the number of entries in the statistic array
3682  *
3683  */
3684 int
3686 {
3687  return pstat_Global.n_stat_values;
3688 }
3689 
3690 /*
3691  * perfmon_allocate_values () - Allocate PERFMON_VALUES_MEMSIZE bytes
3692  *
3693  */
3694 UINT64 *
3696 {
3697  UINT64 *vals;
3698 
3699  vals = (UINT64 *) malloc (PERFMON_VALUES_MEMSIZE);
3700  if (vals == NULL)
3701  {
3703  }
3704 
3705  return vals;
3706 }
3707 
3708 /*
3709  * perfmon_allocate_packed_values_buffer () - Allocate PERFMON_VALUES_MEMSIZE bytes and verify alignment
3710  *
3711  */
3712 char *
3714 {
3715  char *buf;
3716 
3717  buf = (char *) malloc (PERFMON_VALUES_MEMSIZE);
3718  if (buf == NULL)
3719  {
3721  }
3722  ASSERT_ALIGN (buf, MAX_ALIGNMENT);
3723 
3724  return buf;
3725 }
3726 
3727 /*
3728  * perfmon_copy_values () -
3729  *
3730  * dest (in/out): destination buffer
3731  * source (in): source buffer
3732  *
3733  */
3734 void
3735 perfmon_copy_values (UINT64 * dest, UINT64 * src)
3736 {
3737  memcpy (dest, src, PERFMON_VALUES_MEMSIZE);
3738 }
3739 
3740 /*
3741  * perfmon_pack_stats - Pack the statistic values in the buffer
3742  *
3743  * return:
3744  *
3745  * buf (in):
3746  * stats (in):
3747  *
3748  *
3749  */
3750 char *
3751 perfmon_pack_stats (char *buf, UINT64 * stats)
3752 {
3753  char *ptr;
3754  int i;
3755 
3756  ptr = buf;
3757 
3758  for (i = 0; i < pstat_Global.n_stat_values; i++)
3759  {
3760  OR_PUT_INT64 (ptr, &(stats[i]));
3761  ptr += OR_INT64_SIZE;
3762  }
3763 
3764  return (ptr);
3765 }
3766 
3767 /*
3768  * perfmon_unpack_stats - Unpack the values from the buffer in the statistics array
3769  *
3770  * return:
3771  *
3772  * buf (in):
3773  * stats (out):
3774  *
3775  */
3776 char *
3777 perfmon_unpack_stats (char *buf, UINT64 * stats)
3778 {
3779  char *ptr;
3780  int i;
3781 
3782  ptr = buf;
3783 
3784  for (i = 0; i < pstat_Global.n_stat_values; i++)
3785  {
3786  OR_GET_INT64 (ptr, &(stats[i]));
3787  ptr += OR_INT64_SIZE;
3788  }
3789 
3790  return (ptr);
3791 }
3792 
3793 /*
3794  * perfmon_get_peek_stats - Copy into the statistics array the values of the peek statistics
3795  *
3796  * return: void
3797  *
3798  * stats (in): statistics array
3799  */
3800 STATIC_INLINE void
3801 perfmon_get_peek_stats (UINT64 * stats)
3802 {
3803  /* fixme(rem) - will be fixed in stattool patch */
3804 #if defined (SERVER_MODE) || defined (SA_MODE)
3806  stats[pstat_Metadata[PSTAT_HF_NUM_STATS_ENTRIES].start_offset] = heap_get_best_space_num_stats_entries ();
3807  stats[pstat_Metadata[PSTAT_QM_NUM_HOLDABLE_CURSORS].start_offset] = session_get_number_of_holdable_cursors ();
3808 #endif /* defined (SERVER_MODE) || defined (SA_MODE) */
3809 }
3810 
3811 /*
3812  * perfmon_print_timer_to_file - Print in a file the statistic values for a timer type statistic
3813  *
3814  * stream (in/out): input file
3815  * stat_index (in): statistic index
3816  * stats_ptr (in) : statistic values array
3817  *
3818  * return: void
3819  *
3820  */
3821 static void
3822 perfmon_print_timer_to_file (FILE * stream, int stat_index, UINT64 * stats_ptr)
3823 {
3824  int offset = pstat_Metadata[stat_index].start_offset;
3825 
3826  assert (pstat_Metadata[stat_index].valtype == PSTAT_COUNTER_TIMER_VALUE);
3827  fprintf (stream, "The timer values for %s are:\n", pstat_Metadata[stat_index].stat_name);
3828  fprintf (stream, "Num_%-25s = %10llu\n", pstat_Metadata[stat_index].stat_name,
3829  (unsigned long long) stats_ptr[PSTAT_COUNTER_TIMER_COUNT_VALUE (offset)]);
3830  fprintf (stream, "Total_time_%-18s = %10llu\n", pstat_Metadata[stat_index].stat_name,
3831  (unsigned long long) stats_ptr[PSTAT_COUNTER_TIMER_TOTAL_TIME_VALUE (offset)]);
3832  fprintf (stream, "Max_time_%-20s = %10llu\n", pstat_Metadata[stat_index].stat_name,
3833  (unsigned long long) stats_ptr[PSTAT_COUNTER_TIMER_MAX_TIME_VALUE (offset)]);
3834  fprintf (stream, "Avg_time_%-20s = %10llu\n", pstat_Metadata[stat_index].stat_name,
3835  (unsigned long long) stats_ptr[PSTAT_COUNTER_TIMER_AVG_TIME_VALUE (offset)]);
3836 }
3837 
3838 /*
3839  * perfmon_print_timer_to_buffer - Print in a buffer the statistic values for a timer type statistic
3840  *
3841  * s (in/out): input stream
3842  * stat_index (in): statistic index
3843  * stats_ptr (in): statistic values array
3844  * offset (in): offset in the statistics array
3845  * remained_size (in/out): remained size to write in the buffer
3846  *
3847  * return: void
3848  *
3849  */
3850 static void
3851 perfmon_print_timer_to_buffer (char **s, int stat_index, UINT64 * stats_ptr, int *remained_size)
3852 {
3853  int ret;
3854  int offset = pstat_Metadata[stat_index].start_offset;
3855 
3856  assert (pstat_Metadata[stat_index].valtype == PSTAT_COUNTER_TIMER_VALUE);
3857  ret = snprintf (*s, *remained_size, "The timer values for %s are:\n", pstat_Metadata[stat_index].stat_name);
3858  *remained_size -= ret;
3859  *s += ret;
3860  ret = snprintf (*s, *remained_size, "Num_%-25s = %10llu\n", pstat_Metadata[stat_index].stat_name,
3861  (unsigned long long) stats_ptr[PSTAT_COUNTER_TIMER_COUNT_VALUE (offset)]);
3862  *remained_size -= ret;
3863  *s += ret;
3864  ret = snprintf (*s, *remained_size, "Total_time_%-18s = %10llu\n", pstat_Metadata[stat_index].stat_name,
3865  (unsigned long long) stats_ptr[PSTAT_COUNTER_TIMER_TOTAL_TIME_VALUE (offset)]);
3866  *remained_size -= ret;
3867  *s += ret;
3868  ret = snprintf (*s, *remained_size, "Max_time_%-20s = %10llu\n", pstat_Metadata[stat_index].stat_name,
3869  (unsigned long long) stats_ptr[PSTAT_COUNTER_TIMER_MAX_TIME_VALUE (offset)]);
3870  *remained_size -= ret;
3871  *s += ret;
3872  ret = snprintf (*s, *remained_size, "Avg_time_%-20s = %10llu\n", pstat_Metadata[stat_index].stat_name,
3873  (unsigned long long) stats_ptr[PSTAT_COUNTER_TIMER_AVG_TIME_VALUE (offset)]);
3874  *remained_size -= ret;
3875  *s += ret;
3876 }
3877 
3878 // *INDENT-OFF*
3880 // thread workers section
3882 
3883 // note - current monitor implementation requires a single point to manage all statistics meta information (stats
3884 // count and names). this prevents us from isolating statistics management per each module, because some
3885 // modules are restricted to server only, while the monitor implementation is same for server and client.
3886 //
3887 // ideally, meta information should be fetched from server and not necessarily known from start by client.
3888 // this would prevent any miss-matches between server and clients and better module encapsulation. performance
3889 // monitor would only store the values and collect from all modules rather than keeping extended information
3890 // on each module (like it does now with page buffer, thread and others)
3891 //
3892 // for now, we are forced to duplicate here some information about thread workers and daemons that is normally
3893 // restricted to server
3894 //
3895 
3896 // NOTE - should match cubthread::Worker_pool_statdef
3898  {
3899  "Counter_start_thread",
3900  "Timer_start_thread",
3901  "Counter_create_context",
3902  "Timer_create_context",
3903  "Counter_execute_task",
3904  "Timer_execute_task",
3905  "Counter_retire_task",
3906  "Timer_retire_task",
3907  "Counter_found_task_in_queue",
3908  "Timer_found_task_in_queue",
3909  "Counter_wakeup_with_task",
3910  "Timer_wakeup_with_task",
3911  "Counter_recycle_context",
3912  "Timer_recycle_context",
3913  "Counter_retire_context",
3914  "Timer_retire_context"
3915  };
3917  sizeof (perfmon_Portable_worker_stat_names) / sizeof (const char *);
3918 
3919 static size_t
3920 thread_stats_count (void)
3921 {
3922 #if defined (SERVER_MODE)
3923  assert (PERFMON_PORTABLE_WORKER_STAT_COUNT == cubthread::wp_worker_statset_get_count ());
3924  static bool check_names = true;
3925  if (check_names)
3926  {
3927  for (size_t index = 0; index < PERFMON_PORTABLE_WORKER_STAT_COUNT; index++)
3928  {
3929  if (std::strcmp (perfmon_Portable_worker_stat_names[index], cubthread::wp_worker_statset_get_name (index)) != 0)
3930  {
3931  assert (false);
3933  "Warning - Monitoring thread worker statistics; statistics name not matching for %zu\n"
3934  "\t\tperfmon name = %s\n" "\t\tdaemon name = %s\n", index,
3935  perfmon_Portable_worker_stat_names[index], cubthread::wp_worker_statset_get_name (index));
3936  }
3937  }
3938  check_names = false;
3939  }
3940 #endif // SERVER_MODE
3942 }
3943 
3944 static int
3946 {
3947  return (int) thread_stats_count ();
3948 }
3949 
3950 static const char *
3952 {
3953  return perfmon_Portable_worker_stat_names[index];
3954 }
3955 
3956 /*
3957  * f_dump_in_file_thread_stats () - Write in file the values for thread statistic
3958  *
3959  * f (out): File handle
3960  * stat_vals (in): statistics buffer
3961  *
3962  */
3963 static void
3964 f_dump_in_file_thread_stats (FILE * f, const UINT64 * stat_vals)
3965 {
3967  {
3969  }
3970 }
3971 
3972 /*
3973  * perfmon_stat_dump_in_file_thread_stats () -
3974  *
3975  * stream(in): output file
3976  * stats_ptr(in): start of array values
3977  *
3978  */
3979 static void
3980 perfmon_stat_dump_in_file_thread_stats (FILE * stream, const UINT64 * stats_ptr)
3981 {
3982  UINT64 value = 0;
3983 
3984  assert (stream != NULL);
3985 
3986  for (size_t it = 0; it < thread_stats_count (); it++)
3987  {
3988  value = stats_ptr[it];
3989  if (value == 0)
3990  {
3991  continue;
3992  }
3993  fprintf (stream, "%-10s = %16llu\n", perfmon_stat_thread_stat_name (it), (long long unsigned int) value);
3994  }
3995 }
3996 
3997 /*
3998  * f_dump_in_buffer_thread_stats () - Write to a buffer the values for thread statistic
3999  * s (out): Buffer to write to
4000  * stat_vals (in): statistics buffer
4001  * remaining_size (in): size of input buffer
4002  *
4003  */
4004 static void
4005 f_dump_in_buffer_thread_stats (char **s, const UINT64 * stat_vals, int *remaining_size)
4006 {
4008  {
4009  perfmon_stat_dump_in_buffer_thread_stats (stat_vals, s, remaining_size);
4010  }
4011 }
4012 
4013 /*
4014  * perfmon_stat_dump_in_buffer_thread_stats () -
4015  *
4016  * stats_ptr(in): start of array values
4017  * s(in/out): output string (NULL if not used)
4018  * remaining_size(in/out): remaining size in string s (NULL if not used)
4019  *
4020  */
4021 static void
4022 perfmon_stat_dump_in_buffer_thread_stats (const UINT64 * stats_ptr, char **s, int *remaining_size)
4023 {
4024  UINT64 value = 0;
4025  int ret;
4026 
4027  assert (s != NULL);
4028  assert (remaining_size != NULL);
4029 
4030  for (size_t it = 0; it < thread_stats_count (); it++)
4031  {
4032  value = stats_ptr[it];
4033  if (value == 0)
4034  {
4035  continue;
4036  }
4037  ret = snprintf (*s, *remaining_size, "%-10s = %16llu\n", perfmon_stat_thread_stat_name (it),
4038  (long long unsigned int) value);
4039 
4040  *remaining_size -= ret;
4041  *s += ret;
4042  if (*remaining_size <= 0)
4043  {
4044  return;
4045  }
4046  }
4047 }
4048 
4050 // Thread daemons section
4052 
4053 // NOTE - should match cubthread::daemon + cubthread::looper + cubthread::waiter statistics
4054 static const char *perfmon_Portable_daemon_stat_names [] =
4055 {
4056  // daemon
4057  "daemon_loop_count",
4058  "daemon_execute_time",
4059  "daemon_pause_time",
4060 
4061  // looper
4062  "looper_sleep_count",
4063  "looper_sleep_time",
4064  "looper_reset_count",
4065 
4066  // waiter
4067  "waiter_wakeup_count",
4068  "waiter_lock_wakeup_count",
4069  "waiter_sleep_count",
4070  "waiter_timeout_count",
4071  "waiter_no_sleep_count",
4072  "waiter_awake_count",
4073  "waiter_wakeup_delay_time",
4074 
4075  // todo - probably has to be moved to thread_daemon.hpp
4076 };
4078  sizeof (perfmon_Portable_daemon_stat_names) / sizeof (const char *);
4079 
4080 static const char *perfmon_Portable_daemon_names [] =
4081 {
4082  "Page_flush_daemon_thread",
4083  "Page_post_flush_daemon_thread",
4084  "Page_flush_control_daemon_thread",
4085  "Page_maintenance_daemon_thread",
4086  "Deadlock_detect_daemon_thread",
4087  "Log_flush_daemon_thread",
4088 };
4089 static const size_t PERFMON_PORTABLE_DAEMON_COUNT = sizeof (perfmon_Portable_daemon_names) / sizeof (const char *);
4090 
4091 static size_t
4093 {
4094 #if defined (SERVER_MODE) && !defined (NDEBUG)
4095  assert (PERFMON_PORTABLE_DAEMON_STAT_COUNT == cubthread::daemon::get_stats_value_count ());
4096 
4097  static bool check_names = true;
4098  if (check_names)
4099  {
4100  for (size_t index = 0; index < PERFMON_PORTABLE_DAEMON_STAT_COUNT; index++)
4101  {
4102  if (std::strcmp (perfmon_Portable_daemon_stat_names[index], cubthread::daemon::get_stat_name (index)) != 0)
4103  {
4104  assert (false);
4106  "Warning - Monitoring daemon statistics; statistics name not matching for %zu\n"
4107  "\t\tperfmon name = %s\n" "\t\tdaemon name = %s\n", index,
4108  perfmon_Portable_daemon_stat_names[index], cubthread::daemon::get_stat_name (index));
4109  }
4110  }
4111  check_names = false;
4112  }
4113 #endif // SERVER_MODE and DEBUG
4115 }
4116 
4117 static size_t
4119 {
4120  return PERFMON_PORTABLE_DAEMON_COUNT * perfmon_per_daemon_stat_count ();
4121 }
4122 
4123 static const char *
4125 {
4126  assert (index < PERFMON_PORTABLE_DAEMON_STAT_COUNT);
4127  return perfmon_Portable_daemon_stat_names[index];
4128 }
4129 
4130 static int
4132 {
4133  return (int) perfmon_thread_daemon_stats_count ();
4134 }
4135 
4136 /*
4137  * f_dump_in_file_thread_daemon_stats () - Write in file the values for daemon statistic
4138  *
4139  * f (out): File handle
4140  * stat_vals (in): statistics buffer
4141  *
4142  */
4143 static void
4144 f_dump_in_file_thread_daemon_stats (FILE * f, const UINT64 * stat_vals)
4145 {
4147  {
4149  }
4150 }
4151 
4152 /*
4153  * perfmon_stat_dump_in_file_thread_daemon_stats () -
4154  *
4155  * stream(in): output file
4156  * stats_ptr(in): start of array values
4157  *
4158  */
4159 static void
4160 perfmon_stat_dump_in_file_thread_daemon_stats (FILE * stream, const UINT64 * stats_ptr)
4161 {
4162  UINT64 value = 0;
4163 
4164  assert (stream != NULL);
4165 
4166  for (size_t daemon_it = 0; daemon_it < PERFMON_PORTABLE_DAEMON_COUNT; daemon_it++)
4167  {
4168  for (size_t stat_it = 0; stat_it < perfmon_per_daemon_stat_count (); stat_it++)
4169  {
4170  value = stats_ptr[daemon_it * perfmon_per_daemon_stat_count () + stat_it];
4171  fprintf (stream, "%s.%s = %16llu\n", perfmon_Portable_daemon_names[daemon_it],
4172  perfmon_thread_daemon_name (stat_it), (long long unsigned int) value);
4173  }
4174  }
4175 }
4176 
4177 /*
4178  * f_dump_in_buffer_thread_daemon_stats () - Write to a buffer the values for daemon statistics
4179  *
4180  * s (out): Buffer to write to
4181  * stat_vals (in): statistics buffer
4182  * remaining_size (in): size of input buffer
4183  *
4184  */
4185 static void
4186 f_dump_in_buffer_thread_daemon_stats (char **s, const UINT64 * stat_vals, int *remaining_size)
4187 {
4189  {
4190  perfmon_stat_dump_in_buffer_thread_daemon_stats (stat_vals, s, remaining_size);
4191  }
4192 }
4193 
4194 /*
4195  * perfmon_stat_dump_in_buffer_thread_daemon_stats () -
4196  *
4197  * stats_ptr(in): start of array values
4198  * s(in/out): output string (NULL if not used)
4199  * remaining_size(in/out): remaining size in string s (NULL if not used)
4200  *
4201  */
4202 static void
4203 perfmon_stat_dump_in_buffer_thread_daemon_stats (const UINT64 * stats_ptr, char **s, int *remaining_size)
4204 {
4205  UINT64 value = 0;
4206  int ret;
4207 
4208  assert (s != NULL);
4209  assert (remaining_size != NULL);
4210 
4211  for (size_t daemon_it = 0; daemon_it < PERFMON_PORTABLE_DAEMON_COUNT; daemon_it++)
4212  {
4213  for (size_t stat_it = 0; stat_it < perfmon_per_daemon_stat_count (); stat_it++)
4214  {
4215  value = stats_ptr[daemon_it * perfmon_per_daemon_stat_count () + stat_it];
4216  ret = snprintf (*s, *remaining_size, "%s.%s = %16llu\n", perfmon_Portable_daemon_names[daemon_it],
4217  perfmon_thread_daemon_name (stat_it), (long long unsigned int) value);
4218 
4219  *remaining_size -= ret;
4220  *s += ret;
4221  if (*remaining_size <= 0)
4222  {
4223  return;
4224  }
4225  }
4226  }
4227 }
4228 
4229 #if defined (SERVER_MODE)
4230 static void
4231 perfmon_peek_thread_daemon_stats (UINT64 * stats)
4232 {
4233  UINT64 *statsp = &stats[pstat_Metadata[PSTAT_THREAD_DAEMON_STATS].start_offset];
4234  pgbuf_daemons_get_stats (statsp); // 4 x daemons
4235  statsp += 4 * perfmon_per_daemon_stat_count ();
4236 
4237  // get deadlock stats
4238  lock_deadlock_detect_daemon_get_stats (statsp);
4239  statsp += perfmon_per_daemon_stat_count ();
4240 
4241  // get log flush stats
4242  log_flush_daemon_get_stats (statsp);
4243  statsp += perfmon_per_daemon_stat_count ();
4244 }
4245 #endif // SERVER_MODE
4246 
4247 #if defined (SERVER_MODE) || defined (SA_MODE)
4248 void
4249 perfmon_er_log_current_stats (THREAD_ENTRY * thread_p)
4250 {
4251  UINT64 *stats = perfmon_allocate_values ();
4252  if (stats == NULL)
4253  {
4254  assert (false);
4255  return;
4256  }
4257 
4259 
4260  const size_t STATS_DUMP_MAX_SIZE = ONE_M; // a mega-byte
4261  char *strbuf = new char[STATS_DUMP_MAX_SIZE];
4262  strbuf[0] = '\0';
4263 
4264  perfmon_server_dump_stats_to_buffer (stats, strbuf, STATS_DUMP_MAX_SIZE, NULL);
4265 
4266  _er_log_debug (ARG_FILE_LINE, "%s\n", strbuf);
4267 
4268  delete strbuf;
4269 }
4270 #endif // SERVER_MODE || SA_MODE
4271 // *INDENT-ON*
static std::size_t get_stats_value_count(void)
STATIC_INLINE const char * perfmon_stat_module_name(const int module) __attribute__((ALWAYS_INLINE))
int perfmon_server_start_stats(void)
static void perfmon_stat_dump_in_file_flushed_block_volumes_array_stat(FILE *stream, const UINT64 *stats_ptr)
static void perfmon_stat_dump_in_file_mvcc_snapshot_array_stat(FILE *stream, const UINT64 *stats_ptr)
static void perfmon_print_timer_to_buffer(char **s, int stat_index, UINT64 *stats_ptr, int *remained_size)
static void perfmon_stat_dump_in_buffer_page_lock_time_array_stat(const UINT64 *stats_ptr, char **s, int *remaining_size)
static void f_dump_in_buffer_Num_data_page_promote_time_ext(char **, const UINT64 *stat_vals, int *remaining_size)
static void perfmon_stat_dump_in_file_obj_lock_array_stat(FILE *stream, const UINT64 *stats_ptr)
UINT64 * global_stats
Definition: perf_monitor.h:661
cubthread::entry * thread_get_thread_entry_info(void)
#define NO_ERROR
Definition: error_code.h:46
#define __attribute__(X)
Definition: porting.h:36
char * perfmon_pack_stats(char *buf, UINT64 *stats)
int perfmon_server_copy_global_stats(UINT64 *to_stats)
static const char * perfmon_Portable_daemon_names[]
void worker_manager_get_stats(UINT64 *stats_out)
#define ASSERT_ERROR()
std::size_t wp_worker_statset_get_count(void)
#define pthread_mutex_init(a, b)
Definition: area_alloc.c:48
static void f_dump_in_file_Num_data_page_unfix_ext(FILE *, const UINT64 *stat_vals)
static int f_load_thread_daemon_stats(void)
#define PSTAT_COUNTER_TIMER_TOTAL_TIME_VALUE(startvalp)
Definition: perf_monitor.h:139
static int f_load_Num_data_page_promote_ext(void)
PSTAT_DUMP_IN_BUFFER_FUNC f_dump_in_buffer
Definition: perf_monitor.h:720
PSTAT_LOAD_FUNC f_load
Definition: perf_monitor.h:721
bool * is_watching
Definition: perf_monitor.h:666
#define SAFE_DIV(a, b)
Definition: perf_monitor.h:135
static int f_load_Count_get_snapshot_retry(void)
static int f_load_Time_tran_complete_time(void)
void perfmon_get_current_times(time_t *cpu_user_time, time_t *cpu_sys_time, time_t *elapsed_time)
#define ER_FAILED
Definition: error_code.h:47
int perfmon_calc_diff_stats(UINT64 *stats_diff, UINT64 *new_stats, UINT64 *old_stats)
#define ALWAYS_INLINE
static void f_dump_in_file_Time_data_page_fix_acquire_time(FILE *, const UINT64 *stat_vals)
#define pthread_mutex_unlock(a)
Definition: area_alloc.c:51
static int f_load_Time_get_snapshot_acquire_time(void)
static int f_load_Time_data_page_lock_acquire_time(void)
PSTAT_METADATA pstat_Metadata[]
static void f_dump_in_buffer_Num_data_page_fix_ext(char **, const UINT64 *stat_vals, int *remaining_size)
static void f_dump_in_buffer_Time_data_page_lock_acquire_time(char **, const UINT64 *stat_vals, int *remaining_size)
static int f_load_Time_get_oldest_mvcc_acquire_time(void)
static void f_dump_in_file_Time_data_page_hold_acquire_time(FILE *, const UINT64 *stat_vals)
static void perfmon_stat_dump_in_file_snapshot_array_stat(FILE *, const UINT64 *stats_ptr)
#define PERF_PAGE_UNFIX_COUNTERS
Definition: perf_monitor.h:83
static void perfmon_stat_dump_in_file_page_fix_time_array_stat(FILE *, const UINT64 *stats_ptr)
static int f_load_Num_data_page_unfix_ext(void)
#define PERF_PAGE_HOLD_TIME_OFFSET(module, page_type, page_found_mode, latch_mode)
Definition: perf_monitor.h:116
static int f_load_Num_mvcc_snapshot_ext(void)
#define PSTAT_COUNTER_TIMER_MAX_TIME_VALUE(startvalp)
Definition: perf_monitor.h:140
const char * perfmon_Portable_worker_stat_names[]
#define OR_INT64_SIZE
int heap_get_best_space_num_stats_entries(void)
Definition: heap_file.c:24829
static void perfmon_stat_dump_in_buffer_thread_stats(const UINT64 *stats_ptr, char **s, int *remaining_size)
#define PSTAT_COUNTER_TIMER_AVG_TIME_VALUE(startvalp)
Definition: perf_monitor.h:141
static void perfmon_stat_dump_in_buffer_page_hold_time_array_stat(const UINT64 *stats_ptr, char **s, int *remaining_size)
static void perfmon_stat_dump_in_buffer_thread_daemon_stats(const UINT64 *stats_ptr, char **s, int *remaining_size)
#define bool
Definition: dbi_compat.h:31
#define PERF_PAGE_HOLD_TIME_COUNTERS
Definition: perf_monitor.h:88
const char * stat_name
Definition: perf_monitor.h:712
STATIC_INLINE const char * perfmon_stat_cond_type_name(const int cond_type) __attribute__((ALWAYS_INLINE))
void _er_log_debug(const char *file_name, const int line_no, const char *fmt,...)
#define MAX_ALIGNMENT
Definition: memory_alloc.h:70
static const char * perfmon_thread_daemon_name(size_t index)
static void perfmon_stat_dump_in_buffer_snapshot_array_stat(const UINT64 *stats_ptr, char **s, int *remaining_size)
static void perfmon_stat_dump_in_file_page_lock_time_array_stat(FILE *, const UINT64 *stats_ptr)
#define PERF_PAGE_PROMOTE_STAT_OFFSET(module, page_type, promote_cond, holder_latch, success)
Definition: perf_monitor.h:99
pthread_mutex_t watch_lock
Definition: perf_monitor.h:668
void THREAD_ENTRY
#define PERF_PAGE_FIX_STAT_OFFSET(module, page_type, page_found_mode, latch_mode, cond_type)
Definition: perf_monitor.h:93
#define PERF_DWB_FLUSHED_BLOCK_VOLUMES_CNT
Definition: perf_monitor.h:133
char * perfmon_allocate_packed_values_buffer(void)
static void f_dump_in_file_Num_dwb_flushed_block_volumes(FILE *, const UINT64 *stat_vals)
static void perfmon_stat_dump_in_file_fix_page_array_stat(FILE *, const UINT64 *stats_ptr)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
#define assert(x)
PSTAT_DUMP_IN_FILE_FUNC f_dump_in_file
Definition: perf_monitor.h:719
#define ASSERT_ALIGN(ptr, alignment)
static void perfmon_stat_dump_in_buffer_flushed_block_volumes_array_stat(const UINT64 *stats_ptr, char **s, int *remaining_size)
int prm_get_integer_value(PARAM_ID prm_id)
char * perfmon_unpack_stats(char *buf, UINT64 *stats)
#define STATIC_INLINE
static void perfmon_server_calc_stats(UINT64 *stats)
static const size_t PERFMON_PORTABLE_WORKER_STAT_COUNT
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
static void f_dump_in_file_Time_data_page_lock_acquire_time(FILE *, const UINT64 *stat_vals)
#define PSTAT_METADATA_INIT_COUNTER_TIMER(id, name)
Definition: perf_monitor.c:107
STATIC_INLINE void perfmon_add_stat_at_offset(THREAD_ENTRY *thread_p, PERF_STAT_ID psid, const int offset, UINT64 amount) __attribute__((ALWAYS_INLINE))
int perfmon_get_number_of_statistic_values(void)
static void perfmon_stat_dump_in_buffer_page_fix_time_array_stat(const UINT64 *stats_ptr, char **s, int *remaining_size)
int substr(std::string &result, bool &is_matched, const cub_regex_object &reg, const std::string &src, const int position, const int occurrence, const INTL_CODESET codeset)
static int f_load_Time_data_page_fix_acquire_time(void)
int perfmon_initialize(int num_trans)
static int rv
Definition: area_alloc.c:52
static const size_t PERFMON_PORTABLE_DAEMON_STAT_COUNT
static void perfmon_stat_dump_in_file_thread_stats(FILE *stream, const UINT64 *stats_ptr)
#define NULL
Definition: freelistheap.h:34
const char * wp_worker_statset_get_name(std::size_t stat_index)
static void perfmon_stat_dump_in_file_promote_page_array_stat(FILE *, const UINT64 *stats_ptr)
#define PSTAT_METADATA_INIT_COMPUTED_RATIO(id, name)
Definition: perf_monitor.c:108
#define PERF_PAGE_LOCK_TIME_OFFSET(module, page_type, page_found_mode, latch_mode, cond_type)
Definition: perf_monitor.h:113
#define PERF_PAGE_PROMOTE_COUNTERS
Definition: perf_monitor.h:79
static void f_dump_in_buffer_Num_dwb_flushed_block_volumes(char **s, const UINT64 *stat_vals, int *remaining_size)
static int success()
#define PERF_PAGE_FIX_COUNTERS
Definition: perf_monitor.h:76
#define err(fd,...)
Definition: porting.h:431
void perfmon_finalize(void)
static const size_t PERFMON_PORTABLE_DAEMON_COUNT
static size_t perfmon_thread_daemon_stats_count(void)
static void f_dump_in_file_Num_data_page_fix_ext(FILE *, const UINT64 *stat_vals)
static void perfmon_stat_dump_in_buffer_obj_lock_array_stat(const UINT64 *stats_ptr, char **s, int *remaining_size)
#define ONE_M
Definition: porting.h:63
static void perfmon_stat_dump_in_buffer_mvcc_snapshot_array_stat(const UINT64 *stats_ptr, char **s, int *remaining_size)
void xperfmon_server_copy_stats(THREAD_ENTRY *thread_p, UINT64 *to_stats)
static void f_dump_in_buffer_thread_stats(char **s, const UINT64 *stat_vals, int *remaining_size)
#define OR_GET_INT64(ptr, val)
STATIC_INLINE const char * perfmon_stat_holder_latch_name(const int holder_latch) __attribute__((ALWAYS_INLINE))
STATIC_INLINE const char * perfmon_stat_page_type_name(const int page_type) __attribute__((ALWAYS_INLINE))
int perfmon_server_stop_stats(void)
static void f_dump_in_file_Time_obj_lock_acquire_time(FILE *, const UINT64 *stat_vals)
static int f_load_thread_stats(void)
static void f_dump_in_buffer_Num_data_page_promote_ext(char **, const UINT64 *stat_vals, int *remaining_size)
#define PERF_OBJ_LOCK_STAT_COUNTERS
Definition: perf_monitor.h:132
#define PSTAT_METADATA_INIT_SINGLE_ACC(id, name)
Definition: perf_monitor.c:104
#define PERF_MVCC_SNAPSHOT_OFFSET(snapshot, rec_type, visibility)
Definition: perf_monitor.h:128
STATIC_INLINE const char * perfmon_stat_promote_cond_name(const int cond_type) __attribute__((ALWAYS_INLINE))
#define PERF_MVCC_SNAPSHOT_COUNTERS
Definition: perf_monitor.h:125
static int f_load_Num_data_page_promote_time_ext(void)
static void error(const char *msg)
Definition: gencat.c:331
static const char * perfmon_Portable_daemon_stat_names[]
STATIC_INLINE const char * perfmon_stat_snapshot_record_type(const int rec_type) __attribute__((ALWAYS_INLINE))
static void f_dump_in_buffer_Num_mvcc_snapshot_ext(char **, const UINT64 *stat_vals, int *remaining_size)
int perfmon_server_copy_stats(UINT64 *to_stats)
void css_get_thread_stats(UINT64 *stats_out)
#define LOG_FIND_THREAD_TRAN_INDEX(thrd)
Definition: perf_monitor.h:158
static int f_load_Time_obj_lock_acquire_time(void)
int session_get_number_of_holdable_cursors(void)
Definition: session.c:3070
#define ARG_FILE_LINE
Definition: error_manager.h:44
void pgbuf_daemons_get_stats(UINT64 *stats_out)
static void f_dump_in_file_thread_daemon_stats(FILE *f, const UINT64 *stat_vals)
static void f_dump_in_buffer_Num_data_page_unfix_ext(char **, const UINT64 *stat_vals, int *remaining_size)
static void f_dump_in_buffer_Time_obj_lock_acquire_time(char **, const UINT64 *stat_vals, int *remaining_size)
int xcache_get_entry_count(void)
Definition: xasl_cache.c:2457
static void perfmon_stat_dump_in_buffer_promote_page_array_stat(const UINT64 *stats_ptr, char **s, int *remaining_size)
#define PERF_PAGE_FIX_TIME_OFFSET(module, page_type, page_found_mode, latch_mode, cond_type)
Definition: perf_monitor.h:122
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define OR_PUT_INT64(ptr, val)
static void perfmon_stat_dump_in_buffer_unfix_page_array_stat(const UINT64 *stats_ptr, char **s, int *remaining_size)
static void perfmon_stat_dump_in_file_unfix_page_array_stat(FILE *, const UINT64 *stats_ptr)
static int f_load_Num_dwb_flushed_block_volumes(void)
STATIC_INLINE size_t thread_stats_count(void)
Definition: perf_monitor.c:186
STATIC_INLINE const char * perfmon_stat_page_mode_name(const int page_mode) __attribute__((ALWAYS_INLINE))
void perfmon_server_dump_stats(const UINT64 *stats, FILE *stream, const char *substr)
bool prm_get_bool_value(PARAM_ID prm_id)
static void perfmon_stat_dump_in_file_thread_daemon_stats(FILE *stream, const UINT64 *stats_ptr)
#define PSTAT_COUNTER_TIMER_COUNT_VALUE(startvalp)
Definition: perf_monitor.h:138
static void f_dump_in_buffer_Time_data_page_fix_acquire_time(char **, const UINT64 *stat_vals, int *remaining_size)
PSTAT_GLOBAL pstat_Global
void perfmon_server_dump_stats_to_buffer(const UINT64 *stats, char *buffer, int buf_size, const char *substr)
static int f_load_Num_data_page_fix_ext(void)
#define PERF_PAGE_FIX_TIME_COUNTERS
Definition: perf_monitor.h:91
static void f_dump_in_buffer_Time_data_page_hold_acquire_time(char **, const UINT64 *stat_vals, int *remaining_size)
int i
Definition: dynamic_load.c:954
UINT64 * perfmon_allocate_values(void)
static void f_dump_in_buffer_thread_daemon_stats(char **s, const UINT64 *stat_vals, int *remaining_size)
static void f_dump_in_file_Num_data_page_promote_ext(FILE *, const UINT64 *stat_vals)
STATIC_INLINE void perfmon_add_stat(THREAD_ENTRY *thread_p, PERF_STAT_ID psid, UINT64 amount) __attribute__((ALWAYS_INLINE))
static void f_dump_in_file_thread_stats(FILE *f, const UINT64 *stat_vals)
#define pthread_mutex_lock(a)
Definition: area_alloc.c:50
void xperfmon_server_copy_global_stats(UINT64 *to_stats)
STATIC_INLINE const char * perfmon_stat_lock_mode_name(const int lock_mode) __attribute__((ALWAYS_INLINE))
static size_t perfmon_per_daemon_stat_count(void)
static const char * get_stat_name(std::size_t stat_index)
static void perfmon_stat_dump_in_buffer_fix_page_array_stat(const UINT64 *stats_ptr, char **s, int *remaining_size)
PERF_STAT_ID
Definition: perf_monitor.h:268
#define PERF_PAGE_UNFIX_STAT_OFFSET(module, page_type, buf_dirty, dirtied_by_holder, holder_latch)
Definition: perf_monitor.h:106
#define PERF_PAGE_LOCK_TIME_COUNTERS
Definition: perf_monitor.h:86
STATIC_INLINE void perfmon_get_peek_stats(UINT64 *stats) __attribute__((ALWAYS_INLINE))
INT32 n_watchers
Definition: perf_monitor.h:671
void pgbuf_peek_stats(UINT64 *fixed_cnt, UINT64 *dirty_cnt, UINT64 *lru1_cnt, UINT64 *lru2_cnt, UINT64 *lru3_cnt, UINT64 *victim_candidates, UINT64 *avoid_dealloc_cnt, UINT64 *avoid_victim_cnt, UINT64 *private_quota, UINT64 *private_cnt, UINT64 *alloc_bcb_waiter_high, UINT64 *alloc_bcb_waiter_med, UINT64 *flushed_bcbs_waiting_direct_assign, UINT64 *lfcq_big_prv_num, UINT64 *lfcq_prv_num, UINT64 *lfcq_shr_num)
static void f_dump_in_file_Num_data_page_promote_time_ext(FILE *, const UINT64 *stat_vals)
static void perfmon_print_timer_to_file(FILE *stream, int stat_index, UINT64 *stats_ptr)
static int f_load_Count_get_oldest_mvcc_retry(void)
#define PERFMON_VALUES_MEMSIZE
Definition: perf_monitor.c:113
#define PSTAT_METADATA_INIT_COMPLEX(id, name, f_dump_in_file, f_dump_in_buffer, f_load)
Definition: perf_monitor.c:110
const char ** p
Definition: dynamic_load.c:945
UINT64 ** tran_stats
Definition: perf_monitor.h:664
#define PSTAT_METADATA_INIT_SINGLE_PEEK(id, name)
Definition: perf_monitor.c:105
static void perfmon_stat_dump_in_file_page_hold_time_array_stat(FILE *, const UINT64 *stats_ptr)
static const char * perfmon_stat_thread_stat_name(size_t index)
void perfmon_copy_values(UINT64 *dest, UINT64 *src)
STATIC_INLINE void perfmon_add_at_offset(THREAD_ENTRY *thread_p, int offset, UINT64 amount) __attribute__((ALWAYS_INLINE))
static int f_load_Time_data_page_hold_acquire_time(void)
#define pthread_mutex_destroy(a)
Definition: area_alloc.c:49
static void f_dump_in_file_Num_mvcc_snapshot_ext(FILE *, const UINT64 *stat_vals)
STATIC_INLINE const char * perfmon_stat_snapshot_name(const int snapshot) __attribute__((ALWAYS_INLINE))