1 /* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /**
24 @file storage/perfschema/table_tiws_by_index_usage.cc
25 Table TABLE_IO_WAITS_SUMMARY_BY_INDEX_USAGE (implementation).
26 */
27
28 #include "my_global.h"
29 #include "my_pthread.h"
30 #include "pfs_instr_class.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "table_tiws_by_index_usage.h"
34 #include "pfs_global.h"
35 #include "pfs_visitor.h"
36
37 THR_LOCK table_tiws_by_index_usage::m_table_lock;
38
39 static const TABLE_FIELD_TYPE field_types[]=
40 {
41 {
42 { C_STRING_WITH_LEN("OBJECT_TYPE") },
43 { C_STRING_WITH_LEN("varchar(64)") },
44 { NULL, 0}
45 },
46 {
47 { C_STRING_WITH_LEN("OBJECT_SCHEMA") },
48 { C_STRING_WITH_LEN("varchar(64)") },
49 { NULL, 0}
50 },
51 {
52 { C_STRING_WITH_LEN("OBJECT_NAME") },
53 { C_STRING_WITH_LEN("varchar(64)") },
54 { NULL, 0}
55 },
56 {
57 { C_STRING_WITH_LEN("INDEX_NAME") },
58 { C_STRING_WITH_LEN("varchar(64)") },
59 { NULL, 0}
60 },
61 {
62 { C_STRING_WITH_LEN("COUNT_STAR") },
63 { C_STRING_WITH_LEN("bigint(20)") },
64 { NULL, 0}
65 },
66 {
67 { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
68 { C_STRING_WITH_LEN("bigint(20)") },
69 { NULL, 0}
70 },
71 {
72 { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
73 { C_STRING_WITH_LEN("bigint(20)") },
74 { NULL, 0}
75 },
76 {
77 { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
78 { C_STRING_WITH_LEN("bigint(20)") },
79 { NULL, 0}
80 },
81 {
82 { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
83 { C_STRING_WITH_LEN("bigint(20)") },
84 { NULL, 0}
85 },
86 {
87 { C_STRING_WITH_LEN("COUNT_READ") },
88 { C_STRING_WITH_LEN("bigint(20)") },
89 { NULL, 0}
90 },
91 {
92 { C_STRING_WITH_LEN("SUM_TIMER_READ") },
93 { C_STRING_WITH_LEN("bigint(20)") },
94 { NULL, 0}
95 },
96 {
97 { C_STRING_WITH_LEN("MIN_TIMER_READ") },
98 { C_STRING_WITH_LEN("bigint(20)") },
99 { NULL, 0}
100 },
101 {
102 { C_STRING_WITH_LEN("AVG_TIMER_READ") },
103 { C_STRING_WITH_LEN("bigint(20)") },
104 { NULL, 0}
105 },
106 {
107 { C_STRING_WITH_LEN("MAX_TIMER_READ") },
108 { C_STRING_WITH_LEN("bigint(20)") },
109 { NULL, 0}
110 },
111 {
112 { C_STRING_WITH_LEN("COUNT_WRITE") },
113 { C_STRING_WITH_LEN("bigint(20)") },
114 { NULL, 0}
115 },
116 {
117 { C_STRING_WITH_LEN("SUM_TIMER_WRITE") },
118 { C_STRING_WITH_LEN("bigint(20)") },
119 { NULL, 0}
120 },
121 {
122 { C_STRING_WITH_LEN("MIN_TIMER_WRITE") },
123 { C_STRING_WITH_LEN("bigint(20)") },
124 { NULL, 0}
125 },
126 {
127 { C_STRING_WITH_LEN("AVG_TIMER_WRITE") },
128 { C_STRING_WITH_LEN("bigint(20)") },
129 { NULL, 0}
130 },
131 {
132 { C_STRING_WITH_LEN("MAX_TIMER_WRITE") },
133 { C_STRING_WITH_LEN("bigint(20)") },
134 { NULL, 0}
135 },
136 {
137 { C_STRING_WITH_LEN("COUNT_FETCH") },
138 { C_STRING_WITH_LEN("bigint(20)") },
139 { NULL, 0}
140 },
141 {
142 { C_STRING_WITH_LEN("SUM_TIMER_FETCH") },
143 { C_STRING_WITH_LEN("bigint(20)") },
144 { NULL, 0}
145 },
146 {
147 { C_STRING_WITH_LEN("MIN_TIMER_FETCH") },
148 { C_STRING_WITH_LEN("bigint(20)") },
149 { NULL, 0}
150 },
151 {
152 { C_STRING_WITH_LEN("AVG_TIMER_FETCH") },
153 { C_STRING_WITH_LEN("bigint(20)") },
154 { NULL, 0}
155 },
156 {
157 { C_STRING_WITH_LEN("MAX_TIMER_FETCH") },
158 { C_STRING_WITH_LEN("bigint(20)") },
159 { NULL, 0}
160 },
161 {
162 { C_STRING_WITH_LEN("COUNT_INSERT") },
163 { C_STRING_WITH_LEN("bigint(20)") },
164 { NULL, 0}
165 },
166 {
167 { C_STRING_WITH_LEN("SUM_TIMER_INSERT") },
168 { C_STRING_WITH_LEN("bigint(20)") },
169 { NULL, 0}
170 },
171 {
172 { C_STRING_WITH_LEN("MIN_TIMER_INSERT") },
173 { C_STRING_WITH_LEN("bigint(20)") },
174 { NULL, 0}
175 },
176 {
177 { C_STRING_WITH_LEN("AVG_TIMER_INSERT") },
178 { C_STRING_WITH_LEN("bigint(20)") },
179 { NULL, 0}
180 },
181 {
182 { C_STRING_WITH_LEN("MAX_TIMER_INSERT") },
183 { C_STRING_WITH_LEN("bigint(20)") },
184 { NULL, 0}
185 },
186 {
187 { C_STRING_WITH_LEN("COUNT_UPDATE") },
188 { C_STRING_WITH_LEN("bigint(20)") },
189 { NULL, 0}
190 },
191 {
192 { C_STRING_WITH_LEN("SUM_TIMER_UPDATE") },
193 { C_STRING_WITH_LEN("bigint(20)") },
194 { NULL, 0}
195 },
196 {
197 { C_STRING_WITH_LEN("MIN_TIMER_UPDATE") },
198 { C_STRING_WITH_LEN("bigint(20)") },
199 { NULL, 0}
200 },
201 {
202 { C_STRING_WITH_LEN("AVG_TIMER_UPDATE") },
203 { C_STRING_WITH_LEN("bigint(20)") },
204 { NULL, 0}
205 },
206 {
207 { C_STRING_WITH_LEN("MAX_TIMER_UPDATE") },
208 { C_STRING_WITH_LEN("bigint(20)") },
209 { NULL, 0}
210 },
211 {
212 { C_STRING_WITH_LEN("COUNT_DELETE") },
213 { C_STRING_WITH_LEN("bigint(20)") },
214 { NULL, 0}
215 },
216 {
217 { C_STRING_WITH_LEN("SUM_TIMER_DELETE") },
218 { C_STRING_WITH_LEN("bigint(20)") },
219 { NULL, 0}
220 },
221 {
222 { C_STRING_WITH_LEN("MIN_TIMER_DELETE") },
223 { C_STRING_WITH_LEN("bigint(20)") },
224 { NULL, 0}
225 },
226 {
227 { C_STRING_WITH_LEN("AVG_TIMER_DELETE") },
228 { C_STRING_WITH_LEN("bigint(20)") },
229 { NULL, 0}
230 },
231 {
232 { C_STRING_WITH_LEN("MAX_TIMER_DELETE") },
233 { C_STRING_WITH_LEN("bigint(20)") },
234 { NULL, 0}
235 }
236 };
237
238 TABLE_FIELD_DEF
239 table_tiws_by_index_usage::m_field_def=
240 { 39, field_types };
241
242 PFS_engine_table_share
243 table_tiws_by_index_usage::m_share=
244 {
245 { C_STRING_WITH_LEN("table_io_waits_summary_by_index_usage") },
246 &pfs_truncatable_acl,
247 table_tiws_by_index_usage::create,
248 NULL, /* write_row */
249 table_tiws_by_index_usage::delete_all_rows,
250 NULL, /* get_row_count */
251 1000, /* records */
252 sizeof(pos_tiws_by_index_usage),
253 &m_table_lock,
254 &m_field_def,
255 false /* checked */
256 };
257
258 PFS_engine_table*
create(void)259 table_tiws_by_index_usage::create(void)
260 {
261 return new table_tiws_by_index_usage();
262 }
263
264 int
delete_all_rows(void)265 table_tiws_by_index_usage::delete_all_rows(void)
266 {
267 reset_table_io_waits_by_table_handle();
268 reset_table_io_waits_by_table();
269 return 0;
270 }
271
table_tiws_by_index_usage()272 table_tiws_by_index_usage::table_tiws_by_index_usage()
273 : PFS_engine_table(&m_share, &m_pos),
274 m_row_exists(false), m_pos(), m_next_pos()
275 {}
276
reset_position(void)277 void table_tiws_by_index_usage::reset_position(void)
278 {
279 m_pos.reset();
280 m_next_pos.reset();
281 }
282
rnd_init(bool scan)283 int table_tiws_by_index_usage::rnd_init(bool scan)
284 {
285 m_normalizer= time_normalizer::get(wait_timer);
286 return 0;
287 }
288
rnd_next(void)289 int table_tiws_by_index_usage::rnd_next(void)
290 {
291 PFS_table_share *table_share;
292
293 for (m_pos.set_at(&m_next_pos);
294 m_pos.has_more_table();
295 m_pos.next_table())
296 {
297 table_share= &table_share_array[m_pos.m_index_1];
298 if (table_share->m_lock.is_populated())
299 {
300 uint safe_key_count= sanitize_index_count(table_share->m_key_count);
301 if (m_pos.m_index_2 < safe_key_count)
302 {
303 make_row(table_share, m_pos.m_index_2);
304 m_next_pos.set_after(&m_pos);
305 return 0;
306 }
307 if (m_pos.m_index_2 <= MAX_INDEXES)
308 {
309 m_pos.m_index_2= MAX_INDEXES;
310 make_row(table_share, m_pos.m_index_2);
311 m_next_pos.set_after(&m_pos);
312 return 0;
313 }
314 }
315 }
316
317 return HA_ERR_END_OF_FILE;
318 }
319
320 int
rnd_pos(const void * pos)321 table_tiws_by_index_usage::rnd_pos(const void *pos)
322 {
323 PFS_table_share *table_share;
324
325 set_position(pos);
326
327 table_share= &table_share_array[m_pos.m_index_1];
328 if (table_share->m_lock.is_populated())
329 {
330 uint safe_key_count= sanitize_index_count(table_share->m_key_count);
331 if (m_pos.m_index_2 < safe_key_count)
332 {
333 make_row(table_share, m_pos.m_index_2);
334 return 0;
335 }
336 if (m_pos.m_index_2 == MAX_INDEXES)
337 {
338 make_row(table_share, m_pos.m_index_2);
339 return 0;
340 }
341 }
342
343 return HA_ERR_RECORD_DELETED;
344 }
345
make_row(PFS_table_share * share,uint index)346 void table_tiws_by_index_usage::make_row(PFS_table_share *share, uint index)
347 {
348 pfs_lock lock;
349
350 m_row_exists= false;
351
352 share->m_lock.begin_optimistic_lock(&lock);
353
354 if (m_row.m_index.make_row(share, index))
355 return;
356
357 PFS_index_io_stat_visitor visitor;
358 PFS_object_iterator::visit_table_indexes(share, index, & visitor);
359
360 if (! share->m_lock.end_optimistic_lock(&lock))
361 return;
362
363 m_row_exists= true;
364 m_row.m_stat.set(m_normalizer, & visitor.m_stat);
365 }
366
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)367 int table_tiws_by_index_usage::read_row_values(TABLE *table,
368 unsigned char *buf,
369 Field **fields,
370 bool read_all)
371 {
372 Field *f;
373
374 if (unlikely(! m_row_exists))
375 return HA_ERR_RECORD_DELETED;
376
377 /* Set the null bits */
378 DBUG_ASSERT(table->s->null_bytes == 1);
379 buf[0]= 0;
380
381 for (; (f= *fields) ; fields++)
382 {
383 if (read_all || bitmap_is_set(table->read_set, f->field_index))
384 {
385 switch(f->field_index)
386 {
387 case 0: /* OBJECT_TYPE */
388 case 1: /* SCHEMA_NAME */
389 case 2: /* OBJECT_NAME */
390 case 3: /* INDEX_NAME */
391 m_row.m_index.set_field(f->field_index, f);
392 break;
393 case 4: /* COUNT_STAR */
394 set_field_ulonglong(f, m_row.m_stat.m_all.m_count);
395 break;
396 case 5: /* SUM */
397 set_field_ulonglong(f, m_row.m_stat.m_all.m_sum);
398 break;
399 case 6: /* MIN */
400 set_field_ulonglong(f, m_row.m_stat.m_all.m_min);
401 break;
402 case 7: /* AVG */
403 set_field_ulonglong(f, m_row.m_stat.m_all.m_avg);
404 break;
405 case 8: /* MAX */
406 set_field_ulonglong(f, m_row.m_stat.m_all.m_max);
407 break;
408 case 9: /* COUNT_READ */
409 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_count);
410 break;
411 case 10: /* SUM_READ */
412 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_sum);
413 break;
414 case 11: /* MIN_READ */
415 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_min);
416 break;
417 case 12: /* AVG_READ */
418 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_avg);
419 break;
420 case 13: /* MAX_READ */
421 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_max);
422 break;
423 case 14: /* COUNT_WRITE */
424 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_count);
425 break;
426 case 15: /* SUM_WRITE */
427 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_sum);
428 break;
429 case 16: /* MIN_WRITE */
430 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_min);
431 break;
432 case 17: /* AVG_WRITE */
433 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_avg);
434 break;
435 case 18: /* MAX_WRITE */
436 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_max);
437 break;
438 case 19: /* COUNT_FETCH */
439 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_count);
440 break;
441 case 20: /* SUM_FETCH */
442 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_sum);
443 break;
444 case 21: /* MIN_FETCH */
445 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_min);
446 break;
447 case 22: /* AVG_FETCH */
448 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_avg);
449 break;
450 case 23: /* MAX_FETCH */
451 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_max);
452 break;
453 case 24: /* COUNT_INSERT */
454 set_field_ulonglong(f, m_row.m_stat.m_insert.m_count);
455 break;
456 case 25: /* SUM_INSERT */
457 set_field_ulonglong(f, m_row.m_stat.m_insert.m_sum);
458 break;
459 case 26: /* MIN_INSERT */
460 set_field_ulonglong(f, m_row.m_stat.m_insert.m_min);
461 break;
462 case 27: /* AVG_INSERT */
463 set_field_ulonglong(f, m_row.m_stat.m_insert.m_avg);
464 break;
465 case 28: /* MAX_INSERT */
466 set_field_ulonglong(f, m_row.m_stat.m_insert.m_max);
467 break;
468 case 29: /* COUNT_UPDATE */
469 set_field_ulonglong(f, m_row.m_stat.m_update.m_count);
470 break;
471 case 30: /* SUM_UPDATE */
472 set_field_ulonglong(f, m_row.m_stat.m_update.m_sum);
473 break;
474 case 31: /* MIN_UPDATE */
475 set_field_ulonglong(f, m_row.m_stat.m_update.m_min);
476 break;
477 case 32: /* AVG_UPDATE */
478 set_field_ulonglong(f, m_row.m_stat.m_update.m_avg);
479 break;
480 case 33: /* MAX_UPDATE */
481 set_field_ulonglong(f, m_row.m_stat.m_update.m_max);
482 break;
483 case 34: /* COUNT_DELETE */
484 set_field_ulonglong(f, m_row.m_stat.m_delete.m_count);
485 break;
486 case 35: /* SUM_DELETE */
487 set_field_ulonglong(f, m_row.m_stat.m_delete.m_sum);
488 break;
489 case 36: /* MIN_DELETE */
490 set_field_ulonglong(f, m_row.m_stat.m_delete.m_min);
491 break;
492 case 37: /* AVG_DELETE */
493 set_field_ulonglong(f, m_row.m_stat.m_delete.m_avg);
494 break;
495 case 38: /* MAX_DELETE */
496 set_field_ulonglong(f, m_row.m_stat.m_delete.m_max);
497 break;
498 default:
499 DBUG_ASSERT(false);
500 }
501 }
502 }
503
504 return 0;
505 }
506
507