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 as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15
16/**
17 @file storage/perfschema/table_tiws_by_index_usage.cc
18 Table TABLE_IO_WAITS_SUMMARY_BY_INDEX_USAGE (implementation).
19*/
20
21#include "my_global.h"
22#include "my_pthread.h"
23#include "pfs_instr_class.h"
24#include "pfs_column_types.h"
25#include "pfs_column_values.h"
26#include "table_tiws_by_index_usage.h"
27#include "pfs_global.h"
28#include "pfs_visitor.h"
29
30THR_LOCK table_tiws_by_index_usage::m_table_lock;
31
32PFS_engine_table_share
33table_tiws_by_index_usage::m_share=
34{
35 { C_STRING_WITH_LEN("table_io_waits_summary_by_index_usage") },
36 &pfs_truncatable_acl,
37 table_tiws_by_index_usage::create,
38 NULL, /* write_row */
39 table_tiws_by_index_usage::delete_all_rows,
40 NULL, /* get_row_count */
41 1000, /* records */
42 sizeof(pos_tiws_by_index_usage),
43 &m_table_lock,
44 { C_STRING_WITH_LEN("CREATE TABLE table_io_waits_summary_by_index_usage("
45 "OBJECT_TYPE VARCHAR(64),"
46 "OBJECT_SCHEMA VARCHAR(64),"
47 "OBJECT_NAME VARCHAR(64),"
48 "INDEX_NAME VARCHAR(64),"
49 "COUNT_STAR BIGINT unsigned not null,"
50 "SUM_TIMER_WAIT BIGINT unsigned not null,"
51 "MIN_TIMER_WAIT BIGINT unsigned not null,"
52 "AVG_TIMER_WAIT BIGINT unsigned not null,"
53 "MAX_TIMER_WAIT BIGINT unsigned not null,"
54 "COUNT_READ BIGINT unsigned not null,"
55 "SUM_TIMER_READ BIGINT unsigned not null,"
56 "MIN_TIMER_READ BIGINT unsigned not null,"
57 "AVG_TIMER_READ BIGINT unsigned not null,"
58 "MAX_TIMER_READ BIGINT unsigned not null,"
59 "COUNT_WRITE BIGINT unsigned not null,"
60 "SUM_TIMER_WRITE BIGINT unsigned not null,"
61 "MIN_TIMER_WRITE BIGINT unsigned not null,"
62 "AVG_TIMER_WRITE BIGINT unsigned not null,"
63 "MAX_TIMER_WRITE BIGINT unsigned not null,"
64 "COUNT_FETCH BIGINT unsigned not null,"
65 "SUM_TIMER_FETCH BIGINT unsigned not null,"
66 "MIN_TIMER_FETCH BIGINT unsigned not null,"
67 "AVG_TIMER_FETCH BIGINT unsigned not null,"
68 "MAX_TIMER_FETCH BIGINT unsigned not null,"
69 "COUNT_INSERT BIGINT unsigned not null,"
70 "SUM_TIMER_INSERT BIGINT unsigned not null,"
71 "MIN_TIMER_INSERT BIGINT unsigned not null,"
72 "AVG_TIMER_INSERT BIGINT unsigned not null,"
73 "MAX_TIMER_INSERT BIGINT unsigned not null,"
74 "COUNT_UPDATE BIGINT unsigned not null,"
75 "SUM_TIMER_UPDATE BIGINT unsigned not null,"
76 "MIN_TIMER_UPDATE BIGINT unsigned not null,"
77 "AVG_TIMER_UPDATE BIGINT unsigned not null,"
78 "MAX_TIMER_UPDATE BIGINT unsigned not null,"
79 "COUNT_DELETE BIGINT unsigned not null,"
80 "SUM_TIMER_DELETE BIGINT unsigned not null,"
81 "MIN_TIMER_DELETE BIGINT unsigned not null,"
82 "AVG_TIMER_DELETE BIGINT unsigned not null,"
83 "MAX_TIMER_DELETE BIGINT unsigned not null)") }
84};
85
86PFS_engine_table*
87table_tiws_by_index_usage::create(void)
88{
89 return new table_tiws_by_index_usage();
90}
91
92int
93table_tiws_by_index_usage::delete_all_rows(void)
94{
95 reset_table_io_waits_by_table_handle();
96 reset_table_io_waits_by_table();
97 return 0;
98}
99
100table_tiws_by_index_usage::table_tiws_by_index_usage()
101 : PFS_engine_table(&m_share, &m_pos),
102 m_row_exists(false), m_pos(), m_next_pos()
103{}
104
105void table_tiws_by_index_usage::reset_position(void)
106{
107 m_pos.reset();
108 m_next_pos.reset();
109}
110
111int table_tiws_by_index_usage::rnd_init(bool scan)
112{
113 m_normalizer= time_normalizer::get(wait_timer);
114 return 0;
115}
116
117int table_tiws_by_index_usage::rnd_next(void)
118{
119 PFS_table_share *table_share;
120
121 for (m_pos.set_at(&m_next_pos);
122 m_pos.has_more_table();
123 m_pos.next_table())
124 {
125 table_share= &table_share_array[m_pos.m_index_1];
126 if (table_share->m_lock.is_populated())
127 {
128 uint safe_key_count= sanitize_index_count(table_share->m_key_count);
129 if (m_pos.m_index_2 < safe_key_count)
130 {
131 make_row(table_share, m_pos.m_index_2);
132 m_next_pos.set_after(&m_pos);
133 return 0;
134 }
135 if (m_pos.m_index_2 <= MAX_INDEXES)
136 {
137 m_pos.m_index_2= MAX_INDEXES;
138 make_row(table_share, m_pos.m_index_2);
139 m_next_pos.set_after(&m_pos);
140 return 0;
141 }
142 }
143 }
144
145 return HA_ERR_END_OF_FILE;
146}
147
148int
149table_tiws_by_index_usage::rnd_pos(const void *pos)
150{
151 PFS_table_share *table_share;
152
153 set_position(pos);
154
155 table_share= &table_share_array[m_pos.m_index_1];
156 if (table_share->m_lock.is_populated())
157 {
158 uint safe_key_count= sanitize_index_count(table_share->m_key_count);
159 if (m_pos.m_index_2 < safe_key_count)
160 {
161 make_row(table_share, m_pos.m_index_2);
162 return 0;
163 }
164 if (m_pos.m_index_2 == MAX_INDEXES)
165 {
166 make_row(table_share, m_pos.m_index_2);
167 return 0;
168 }
169 }
170
171 return HA_ERR_RECORD_DELETED;
172}
173
174void table_tiws_by_index_usage::make_row(PFS_table_share *share, uint index)
175{
176 pfs_lock lock;
177
178 m_row_exists= false;
179
180 share->m_lock.begin_optimistic_lock(&lock);
181
182 if (m_row.m_index.make_row(share, index))
183 return;
184
185 PFS_index_io_stat_visitor visitor;
186 PFS_object_iterator::visit_table_indexes(share, index, & visitor);
187
188 if (! share->m_lock.end_optimistic_lock(&lock))
189 return;
190
191 m_row_exists= true;
192 m_row.m_stat.set(m_normalizer, & visitor.m_stat);
193}
194
195int table_tiws_by_index_usage::read_row_values(TABLE *table,
196 unsigned char *buf,
197 Field **fields,
198 bool read_all)
199{
200 Field *f;
201
202 if (unlikely(! m_row_exists))
203 return HA_ERR_RECORD_DELETED;
204
205 /* Set the null bits */
206 DBUG_ASSERT(table->s->null_bytes == 1);
207 buf[0]= 0;
208
209 for (; (f= *fields) ; fields++)
210 {
211 if (read_all || bitmap_is_set(table->read_set, f->field_index))
212 {
213 switch(f->field_index)
214 {
215 case 0: /* OBJECT_TYPE */
216 case 1: /* SCHEMA_NAME */
217 case 2: /* OBJECT_NAME */
218 case 3: /* INDEX_NAME */
219 m_row.m_index.set_field(f->field_index, f);
220 break;
221 case 4: /* COUNT_STAR */
222 set_field_ulonglong(f, m_row.m_stat.m_all.m_count);
223 break;
224 case 5: /* SUM */
225 set_field_ulonglong(f, m_row.m_stat.m_all.m_sum);
226 break;
227 case 6: /* MIN */
228 set_field_ulonglong(f, m_row.m_stat.m_all.m_min);
229 break;
230 case 7: /* AVG */
231 set_field_ulonglong(f, m_row.m_stat.m_all.m_avg);
232 break;
233 case 8: /* MAX */
234 set_field_ulonglong(f, m_row.m_stat.m_all.m_max);
235 break;
236 case 9: /* COUNT_READ */
237 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_count);
238 break;
239 case 10: /* SUM_READ */
240 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_sum);
241 break;
242 case 11: /* MIN_READ */
243 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_min);
244 break;
245 case 12: /* AVG_READ */
246 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_avg);
247 break;
248 case 13: /* MAX_READ */
249 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_max);
250 break;
251 case 14: /* COUNT_WRITE */
252 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_count);
253 break;
254 case 15: /* SUM_WRITE */
255 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_sum);
256 break;
257 case 16: /* MIN_WRITE */
258 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_min);
259 break;
260 case 17: /* AVG_WRITE */
261 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_avg);
262 break;
263 case 18: /* MAX_WRITE */
264 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_max);
265 break;
266 case 19: /* COUNT_FETCH */
267 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_count);
268 break;
269 case 20: /* SUM_FETCH */
270 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_sum);
271 break;
272 case 21: /* MIN_FETCH */
273 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_min);
274 break;
275 case 22: /* AVG_FETCH */
276 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_avg);
277 break;
278 case 23: /* MAX_FETCH */
279 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_max);
280 break;
281 case 24: /* COUNT_INSERT */
282 set_field_ulonglong(f, m_row.m_stat.m_insert.m_count);
283 break;
284 case 25: /* SUM_INSERT */
285 set_field_ulonglong(f, m_row.m_stat.m_insert.m_sum);
286 break;
287 case 26: /* MIN_INSERT */
288 set_field_ulonglong(f, m_row.m_stat.m_insert.m_min);
289 break;
290 case 27: /* AVG_INSERT */
291 set_field_ulonglong(f, m_row.m_stat.m_insert.m_avg);
292 break;
293 case 28: /* MAX_INSERT */
294 set_field_ulonglong(f, m_row.m_stat.m_insert.m_max);
295 break;
296 case 29: /* COUNT_UPDATE */
297 set_field_ulonglong(f, m_row.m_stat.m_update.m_count);
298 break;
299 case 30: /* SUM_UPDATE */
300 set_field_ulonglong(f, m_row.m_stat.m_update.m_sum);
301 break;
302 case 31: /* MIN_UPDATE */
303 set_field_ulonglong(f, m_row.m_stat.m_update.m_min);
304 break;
305 case 32: /* AVG_UPDATE */
306 set_field_ulonglong(f, m_row.m_stat.m_update.m_avg);
307 break;
308 case 33: /* MAX_UPDATE */
309 set_field_ulonglong(f, m_row.m_stat.m_update.m_max);
310 break;
311 case 34: /* COUNT_DELETE */
312 set_field_ulonglong(f, m_row.m_stat.m_delete.m_count);
313 break;
314 case 35: /* SUM_DELETE */
315 set_field_ulonglong(f, m_row.m_stat.m_delete.m_sum);
316 break;
317 case 36: /* MIN_DELETE */
318 set_field_ulonglong(f, m_row.m_stat.m_delete.m_min);
319 break;
320 case 37: /* AVG_DELETE */
321 set_field_ulonglong(f, m_row.m_stat.m_delete.m_avg);
322 break;
323 case 38: /* MAX_DELETE */
324 set_field_ulonglong(f, m_row.m_stat.m_delete.m_max);
325 break;
326 default:
327 DBUG_ASSERT(false);
328 }
329 }
330 }
331
332 return 0;
333}
334
335