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