1 /* Copyright (c) 2008, 2021, Oracle and/or its affiliates.
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 Foundation,
21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 /**
24 @file storage/perfschema/table_setup_instruments.cc
25 Table SETUP_INSTRUMENTS (implementation).
26 */
27
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "pfs_instr_class.h"
31 #include "pfs_builtin_memory.h"
32 #include "pfs_instr.h"
33 #include "pfs_column_types.h"
34 #include "pfs_column_values.h"
35 #include "table_setup_instruments.h"
36 #include "pfs_global.h"
37 #include "pfs_setup_object.h"
38 #include "field.h"
39
40 THR_LOCK table_setup_instruments::m_table_lock;
41
42 static const TABLE_FIELD_TYPE field_types[]=
43 {
44 {
45 { C_STRING_WITH_LEN("NAME") },
46 { C_STRING_WITH_LEN("varchar(128)") },
47 { NULL, 0}
48 },
49 {
50 { C_STRING_WITH_LEN("ENABLED") },
51 { C_STRING_WITH_LEN("enum(\'YES\',\'NO\')") },
52 { NULL, 0}
53 },
54 {
55 { C_STRING_WITH_LEN("TIMED") },
56 { C_STRING_WITH_LEN("enum(\'YES\',\'NO\')") },
57 { NULL, 0}
58 }
59 };
60
61 TABLE_FIELD_DEF
62 table_setup_instruments::m_field_def=
63 { 3, field_types };
64
65 PFS_engine_table_share
66 table_setup_instruments::m_share=
67 {
68 { C_STRING_WITH_LEN("setup_instruments") },
69 &pfs_updatable_acl,
70 table_setup_instruments::create,
71 NULL, /* write_row */
72 NULL, /* delete_all_rows */
73 table_setup_instruments::get_row_count,
74 sizeof(pos_setup_instruments),
75 &m_table_lock,
76 &m_field_def,
77 false, /* checked */
78 false /* perpetual */
79 };
80
create(void)81 PFS_engine_table* table_setup_instruments::create(void)
82 {
83 return new table_setup_instruments();
84 }
85
86 ha_rows
get_row_count(void)87 table_setup_instruments::get_row_count(void)
88 {
89 return wait_class_max
90 + stage_class_max
91 + statement_class_max
92 + transaction_class_max
93 + memory_class_max;
94 }
95
table_setup_instruments()96 table_setup_instruments::table_setup_instruments()
97 : PFS_engine_table(&m_share, &m_pos),
98 m_pos(), m_next_pos()
99 {}
100
reset_position(void)101 void table_setup_instruments::reset_position(void)
102 {
103 m_pos.reset();
104 m_next_pos.reset();
105 }
106
rnd_next(void)107 int table_setup_instruments::rnd_next(void)
108 {
109 PFS_instr_class *instr_class= NULL;
110 PFS_builtin_memory_class *pfs_builtin;
111 bool update_enabled;
112 bool update_timed;
113
114 /* Do not advertise hard coded instruments when disabled. */
115 if (! pfs_initialized)
116 return HA_ERR_END_OF_FILE;
117
118 for (m_pos.set_at(&m_next_pos);
119 m_pos.has_more_view();
120 m_pos.next_view())
121 {
122 update_enabled= true;
123 update_timed= true;
124
125 switch (m_pos.m_index_1)
126 {
127 case pos_setup_instruments::VIEW_MUTEX:
128 instr_class= find_mutex_class(m_pos.m_index_2);
129 break;
130 case pos_setup_instruments::VIEW_RWLOCK:
131 instr_class= find_rwlock_class(m_pos.m_index_2);
132 break;
133 case pos_setup_instruments::VIEW_COND:
134 instr_class= find_cond_class(m_pos.m_index_2);
135 break;
136 case pos_setup_instruments::VIEW_THREAD:
137 /* Not used yet */
138 break;
139 case pos_setup_instruments::VIEW_FILE:
140 instr_class= find_file_class(m_pos.m_index_2);
141 break;
142 case pos_setup_instruments::VIEW_TABLE:
143 instr_class= find_table_class(m_pos.m_index_2);
144 break;
145 case pos_setup_instruments::VIEW_STAGE:
146 instr_class= find_stage_class(m_pos.m_index_2);
147 break;
148 case pos_setup_instruments::VIEW_STATEMENT:
149 instr_class= find_statement_class(m_pos.m_index_2);
150 break;
151 case pos_setup_instruments::VIEW_TRANSACTION:
152 instr_class= find_transaction_class(m_pos.m_index_2);
153 break;
154 case pos_setup_instruments::VIEW_SOCKET:
155 instr_class= find_socket_class(m_pos.m_index_2);
156 break;
157 case pos_setup_instruments::VIEW_IDLE:
158 instr_class= find_idle_class(m_pos.m_index_2);
159 break;
160 case pos_setup_instruments::VIEW_BUILTIN_MEMORY:
161 update_enabled= false;
162 update_timed= false;
163 pfs_builtin= find_builtin_memory_class(m_pos.m_index_2);
164 if (pfs_builtin != NULL)
165 instr_class= & pfs_builtin->m_class;
166 else
167 instr_class= NULL;
168 break;
169 case pos_setup_instruments::VIEW_MEMORY:
170 update_timed= false;
171 instr_class= find_memory_class(m_pos.m_index_2);
172 break;
173 case pos_setup_instruments::VIEW_METADATA:
174 instr_class= find_metadata_class(m_pos.m_index_2);
175 break;
176 }
177 if (instr_class)
178 {
179 make_row(instr_class, update_enabled, update_timed);
180 m_next_pos.set_after(&m_pos);
181 return 0;
182 }
183 }
184
185 return HA_ERR_END_OF_FILE;
186 }
187
rnd_pos(const void * pos)188 int table_setup_instruments::rnd_pos(const void *pos)
189 {
190 PFS_instr_class *instr_class= NULL;
191 PFS_builtin_memory_class *pfs_builtin;
192 bool update_enabled;
193 bool update_timed;
194
195 /* Do not advertise hard coded instruments when disabled. */
196 if (! pfs_initialized)
197 return HA_ERR_END_OF_FILE;
198
199 set_position(pos);
200
201 update_enabled= true;
202 update_timed= true;
203
204 switch (m_pos.m_index_1)
205 {
206 case pos_setup_instruments::VIEW_MUTEX:
207 instr_class= find_mutex_class(m_pos.m_index_2);
208 break;
209 case pos_setup_instruments::VIEW_RWLOCK:
210 instr_class= find_rwlock_class(m_pos.m_index_2);
211 break;
212 case pos_setup_instruments::VIEW_COND:
213 instr_class= find_cond_class(m_pos.m_index_2);
214 break;
215 case pos_setup_instruments::VIEW_THREAD:
216 /* Not used yet */
217 break;
218 case pos_setup_instruments::VIEW_FILE:
219 instr_class= find_file_class(m_pos.m_index_2);
220 break;
221 case pos_setup_instruments::VIEW_TABLE:
222 instr_class= find_table_class(m_pos.m_index_2);
223 break;
224 case pos_setup_instruments::VIEW_STAGE:
225 instr_class= find_stage_class(m_pos.m_index_2);
226 break;
227 case pos_setup_instruments::VIEW_STATEMENT:
228 instr_class= find_statement_class(m_pos.m_index_2);
229 break;
230 case pos_setup_instruments::VIEW_TRANSACTION:
231 instr_class= find_transaction_class(m_pos.m_index_2);
232 break;
233 case pos_setup_instruments::VIEW_SOCKET:
234 instr_class= find_socket_class(m_pos.m_index_2);
235 break;
236 case pos_setup_instruments::VIEW_IDLE:
237 instr_class= find_idle_class(m_pos.m_index_2);
238 break;
239 case pos_setup_instruments::VIEW_BUILTIN_MEMORY:
240 update_enabled= false;
241 update_timed= false;
242 pfs_builtin= find_builtin_memory_class(m_pos.m_index_2);
243 if (pfs_builtin != NULL)
244 instr_class= & pfs_builtin->m_class;
245 else
246 instr_class= NULL;
247 break;
248 case pos_setup_instruments::VIEW_MEMORY:
249 update_timed= false;
250 instr_class= find_memory_class(m_pos.m_index_2);
251 break;
252 case pos_setup_instruments::VIEW_METADATA:
253 instr_class= find_metadata_class(m_pos.m_index_2);
254 break;
255 }
256 if (instr_class)
257 {
258 make_row(instr_class, update_enabled, update_timed);
259 return 0;
260 }
261
262 return HA_ERR_RECORD_DELETED;
263 }
264
make_row(PFS_instr_class * klass,bool update_enabled,bool update_timed)265 void table_setup_instruments::make_row(PFS_instr_class *klass, bool update_enabled, bool update_timed)
266 {
267 m_row.m_instr_class= klass;
268 m_row.m_update_enabled= update_enabled;
269 m_row.m_update_timed= update_timed;
270 }
271
read_row_values(TABLE * table,unsigned char *,Field ** fields,bool read_all)272 int table_setup_instruments::read_row_values(TABLE *table,
273 unsigned char *,
274 Field **fields,
275 bool read_all)
276 {
277 Field *f;
278
279 assert(table->s->null_bytes == 0);
280
281 /*
282 The row always exist, the instrument classes
283 are static and never disappear.
284 */
285
286 for (; (f= *fields) ; fields++)
287 {
288 if (read_all || bitmap_is_set(table->read_set, f->field_index))
289 {
290 switch(f->field_index)
291 {
292 case 0: /* NAME */
293 set_field_varchar_utf8(f, m_row.m_instr_class->m_name, m_row.m_instr_class->m_name_length);
294 break;
295 case 1: /* ENABLED */
296 set_field_enum(f, m_row.m_instr_class->m_enabled ? ENUM_YES : ENUM_NO);
297 break;
298 case 2: /* TIMED */
299 set_field_enum(f, m_row.m_instr_class->m_timed ? ENUM_YES : ENUM_NO);
300 break;
301 default:
302 assert(false);
303 }
304 }
305 }
306
307 return 0;
308 }
309
update_row_values(TABLE * table,const unsigned char *,unsigned char *,Field ** fields)310 int table_setup_instruments::update_row_values(TABLE *table,
311 const unsigned char *,
312 unsigned char *,
313 Field **fields)
314 {
315 Field *f;
316 enum_yes_no value;
317
318 for (; (f= *fields) ; fields++)
319 {
320 if (bitmap_is_set(table->write_set, f->field_index))
321 {
322 switch(f->field_index)
323 {
324 case 0: /* NAME */
325 return HA_ERR_WRONG_COMMAND;
326 case 1: /* ENABLED */
327 /* Do not raise error if m_update_enabled is false, silently ignore. */
328 if (m_row.m_update_enabled)
329 {
330 value= (enum_yes_no) get_field_enum(f);
331 m_row.m_instr_class->m_enabled= (value == ENUM_YES) ? true : false;
332 }
333 break;
334 case 2: /* TIMED */
335 /* Do not raise error if m_update_timed is false, silently ignore. */
336 if (m_row.m_update_timed)
337 {
338 value= (enum_yes_no) get_field_enum(f);
339 m_row.m_instr_class->m_timed= (value == ENUM_YES) ? true : false;
340 }
341 break;
342 default:
343 assert(false);
344 }
345 }
346 }
347
348 switch (m_pos.m_index_1)
349 {
350 case pos_setup_instruments::VIEW_MUTEX:
351 update_mutex_derived_flags();
352 break;
353 case pos_setup_instruments::VIEW_RWLOCK:
354 update_rwlock_derived_flags();
355 break;
356 case pos_setup_instruments::VIEW_COND:
357 update_cond_derived_flags();
358 break;
359 case pos_setup_instruments::VIEW_THREAD:
360 /* Not used yet */
361 break;
362 case pos_setup_instruments::VIEW_FILE:
363 update_file_derived_flags();
364 break;
365 case pos_setup_instruments::VIEW_TABLE:
366 update_table_derived_flags();
367 break;
368 case pos_setup_instruments::VIEW_STAGE:
369 case pos_setup_instruments::VIEW_STATEMENT:
370 case pos_setup_instruments::VIEW_TRANSACTION:
371 /* No flag to update. */
372 break;
373 case pos_setup_instruments::VIEW_SOCKET:
374 update_socket_derived_flags();
375 break;
376 case pos_setup_instruments::VIEW_IDLE:
377 /* No flag to update. */
378 break;
379 case pos_setup_instruments::VIEW_BUILTIN_MEMORY:
380 case pos_setup_instruments::VIEW_MEMORY:
381 /* No flag to update. */
382 break;
383 case pos_setup_instruments::VIEW_METADATA:
384 update_metadata_derived_flags();
385 break;
386 default:
387 assert(false);
388 break;
389 }
390
391 return 0;
392 }
393
394