1 /* Copyright (c) 2010, 2012, 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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
22
23 /**
24 @file storage/perfschema/table_os_global_by_type.cc
25 Table OBJECTS_SUMMARY_GLOBAL_BY_TYPE (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_os_global_by_type.h"
34 #include "pfs_global.h"
35
36 THR_LOCK table_os_global_by_type::m_table_lock;
37
38 static const TABLE_FIELD_TYPE field_types[]=
39 {
40 {
41 { C_STRING_WITH_LEN("OBJECT_TYPE") },
42 { C_STRING_WITH_LEN("varchar(64)") },
43 { NULL, 0}
44 },
45 {
46 { C_STRING_WITH_LEN("OBJECT_SCHEMA") },
47 { C_STRING_WITH_LEN("varchar(64)") },
48 { NULL, 0}
49 },
50 {
51 { C_STRING_WITH_LEN("OBJECT_NAME") },
52 { C_STRING_WITH_LEN("varchar(64)") },
53 { NULL, 0}
54 },
55 {
56 { C_STRING_WITH_LEN("COUNT_STAR") },
57 { C_STRING_WITH_LEN("bigint(20)") },
58 { NULL, 0}
59 },
60 {
61 { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
62 { C_STRING_WITH_LEN("bigint(20)") },
63 { NULL, 0}
64 },
65 {
66 { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
67 { C_STRING_WITH_LEN("bigint(20)") },
68 { NULL, 0}
69 },
70 {
71 { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
72 { C_STRING_WITH_LEN("bigint(20)") },
73 { NULL, 0}
74 },
75 {
76 { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
77 { C_STRING_WITH_LEN("bigint(20)") },
78 { NULL, 0}
79 }
80 };
81
82 TABLE_FIELD_DEF
83 table_os_global_by_type::m_field_def=
84 { 8, field_types };
85
86 PFS_engine_table_share
87 table_os_global_by_type::m_share=
88 {
89 { C_STRING_WITH_LEN("objects_summary_global_by_type") },
90 &pfs_truncatable_acl,
91 table_os_global_by_type::create,
92 NULL, /* write_row */
93 table_os_global_by_type::delete_all_rows,
94 NULL, /* get_row_count */
95 1000, /* records */
96 sizeof(pos_os_global_by_type),
97 &m_table_lock,
98 &m_field_def,
99 false /* checked */
100 };
101
102 PFS_engine_table*
create(void)103 table_os_global_by_type::create(void)
104 {
105 return new table_os_global_by_type();
106 }
107
108 int
delete_all_rows(void)109 table_os_global_by_type::delete_all_rows(void)
110 {
111 reset_table_waits_by_table_handle();
112 reset_table_waits_by_table();
113 return 0;
114 }
115
table_os_global_by_type()116 table_os_global_by_type::table_os_global_by_type()
117 : PFS_engine_table(&m_share, &m_pos),
118 m_row_exists(false), m_pos(), m_next_pos()
119 {}
120
reset_position(void)121 void table_os_global_by_type::reset_position(void)
122 {
123 m_pos.reset();
124 m_next_pos.reset();
125 }
126
rnd_next(void)127 int table_os_global_by_type::rnd_next(void)
128 {
129 PFS_table_share *table_share;
130
131 for (m_pos.set_at(&m_next_pos);
132 m_pos.has_more_view();
133 m_pos.next_view())
134 {
135 switch (m_pos.m_index_1) {
136 case pos_os_global_by_type::VIEW_TABLE:
137 for ( ; m_pos.m_index_2 < table_share_max; m_pos.m_index_2++)
138 {
139 table_share= &table_share_array[m_pos.m_index_2];
140 if (table_share->m_lock.is_populated())
141 {
142 make_row(table_share);
143 m_next_pos.set_after(&m_pos);
144 return 0;
145 }
146 }
147 break;
148 default:
149 break;
150 }
151 }
152
153 return HA_ERR_END_OF_FILE;
154 }
155
156 int
rnd_pos(const void * pos)157 table_os_global_by_type::rnd_pos(const void *pos)
158 {
159 PFS_table_share *table_share;
160
161 set_position(pos);
162
163 switch (m_pos.m_index_1) {
164 case pos_os_global_by_type::VIEW_TABLE:
165 DBUG_ASSERT(m_pos.m_index_2 < table_share_max);
166 table_share= &table_share_array[m_pos.m_index_2];
167 if (table_share->m_lock.is_populated())
168 {
169 make_row(table_share);
170 return 0;
171 }
172 break;
173 default:
174 break;
175 }
176
177 return HA_ERR_RECORD_DELETED;
178 }
179
make_row(PFS_table_share * share)180 void table_os_global_by_type::make_row(PFS_table_share *share)
181 {
182 pfs_lock lock;
183 PFS_single_stat cumulated_stat;
184 uint safe_key_count;
185
186 m_row_exists= false;
187
188 share->m_lock.begin_optimistic_lock(&lock);
189
190 m_row.m_object_type= share->get_object_type();
191 memcpy(m_row.m_schema_name, share->m_schema_name, share->m_schema_name_length);
192 m_row.m_schema_name_length= share->m_schema_name_length;
193 memcpy(m_row.m_object_name, share->m_table_name, share->m_table_name_length);
194 m_row.m_object_name_length= share->m_table_name_length;
195
196 /* This is a dirty read, some thread can write data while we are reading it */
197 safe_key_count= sanitize_index_count(share->m_key_count);
198
199 share->m_table_stat.sum(& cumulated_stat, safe_key_count);
200
201 if (! share->m_lock.end_optimistic_lock(&lock))
202 return;
203
204 m_row_exists= true;
205
206 if (share->get_refcount() > 0)
207 {
208 /* For all the table handles still opened ... */
209 PFS_table *table= table_array;
210 PFS_table *table_last= table_array + table_max;
211 for ( ; table < table_last ; table++)
212 {
213 if ((table->m_share == share) && (table->m_lock.is_populated()))
214 {
215 /*
216 If the opened table handle is for this table share,
217 aggregate the table handle statistics.
218 */
219 table->m_table_stat.sum(& cumulated_stat, safe_key_count);
220 }
221 }
222 }
223
224 time_normalizer *normalizer= time_normalizer::get(wait_timer);
225 m_row.m_stat.set(normalizer, &cumulated_stat);
226 }
227
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)228 int table_os_global_by_type::read_row_values(TABLE *table,
229 unsigned char *buf,
230 Field **fields,
231 bool read_all)
232 {
233 Field *f;
234
235 if (unlikely(! m_row_exists))
236 return HA_ERR_RECORD_DELETED;
237
238 /* Set the null bits */
239 DBUG_ASSERT(table->s->null_bytes == 1);
240 buf[0]= 0;
241
242 for (; (f= *fields) ; fields++)
243 {
244 if (read_all || bitmap_is_set(table->read_set, f->field_index))
245 {
246 switch(f->field_index)
247 {
248 case 0: /* OBJECT_TYPE */
249 set_field_object_type(f, m_row.m_object_type);
250 break;
251 case 1: /* SCHEMA_NAME */
252 set_field_varchar_utf8(f, m_row.m_schema_name,
253 m_row.m_schema_name_length);
254 break;
255 case 2: /* OBJECT_NAME */
256 set_field_varchar_utf8(f, m_row.m_object_name,
257 m_row.m_object_name_length);
258 break;
259 case 3: /* COUNT */
260 set_field_ulonglong(f, m_row.m_stat.m_count);
261 break;
262 case 4: /* SUM */
263 set_field_ulonglong(f, m_row.m_stat.m_sum);
264 break;
265 case 5: /* MIN */
266 set_field_ulonglong(f, m_row.m_stat.m_min);
267 break;
268 case 6: /* AVG */
269 set_field_ulonglong(f, m_row.m_stat.m_avg);
270 break;
271 case 7: /* MAX */
272 set_field_ulonglong(f, m_row.m_stat.m_max);
273 break;
274 default:
275 DBUG_ASSERT(false);
276 }
277 }
278 }
279
280 return 0;
281 }
282
283