MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pfs_server.cc
Go to the documentation of this file.
1 /* Copyright (c) 2008, 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 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 Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
21 #include "my_global.h"
22 #include "my_sys.h"
23 #include "mysys_err.h"
24 #include "pfs_server.h"
25 #include "pfs.h"
26 #include "pfs_global.h"
27 #include "pfs_instr_class.h"
28 #include "pfs_instr.h"
29 #include "pfs_events_waits.h"
30 #include "pfs_events_stages.h"
31 #include "pfs_events_statements.h"
32 #include "pfs_timer.h"
33 #include "pfs_setup_actor.h"
34 #include "pfs_setup_object.h"
35 #include "pfs_host.h"
36 #include "pfs_user.h"
37 #include "pfs_account.h"
38 #include "pfs_defaults.h"
39 #include "pfs_digest.h"
40 
42 
43 PFS_table_stat PFS_table_stat::g_reset_template;
44 
45 C_MODE_START
46 static void destroy_pfs_thread(void *key);
47 C_MODE_END
48 
49 static void cleanup_performance_schema(void);
50 void cleanup_instrument_config(void);
51 
52 struct PSI_bootstrap*
54 {
55  pfs_initialized= false;
56 
57  PFS_table_stat::g_reset_template.reset();
58  global_idle_stat.reset();
59  global_table_io_stat.reset();
60  global_table_lock_stat.reset();
61 
62  pfs_automated_sizing(param);
63 
64  if (! param->m_enabled)
65  {
66  /*
67  The performance schema is disabled in the startup command line.
68  All the instrumentation is turned off.
69  */
70  return NULL;
71  }
72 
73  init_timers();
75 
76  init_event_name_sizing(param);
77  register_global_classes();
78 
79  if (pthread_key_create(&THR_PFS, destroy_pfs_thread))
80  return NULL;
81 
82  THR_PFS_initialized= true;
83 
85  param->m_rwlock_class_sizing,
86  param->m_cond_class_sizing) ||
93  init_instruments(param) ||
100  init_file_hash() ||
102  init_setup_actor(param) ||
104  init_setup_object(param) ||
106  init_host(param) ||
107  init_host_hash() ||
108  init_user(param) ||
109  init_user_hash() ||
110  init_account(param) ||
111  init_account_hash() ||
112  init_digest(param) ||
113  init_digest_hash())
114  {
115  /*
116  The performance schema initialization failed.
117  Free the memory used, and disable the instrumentation.
118  */
119  cleanup_performance_schema();
120  return NULL;
121  }
122 
123  pfs_initialized= true;
124 
127  flag_events_stages_history= param->m_consumer_events_stages_history_enabled;
128  flag_events_stages_history_long= param->m_consumer_events_stages_history_long_enabled;
129  flag_events_statements_current= param->m_consumer_events_statements_current_enabled;
130  flag_events_statements_history= param->m_consumer_events_statements_history_enabled;
131  flag_events_statements_history_long= param->m_consumer_events_statements_history_long_enabled;
132  flag_events_waits_current= param->m_consumer_events_waits_current_enabled;
133  flag_events_waits_history= param->m_consumer_events_waits_history_enabled;
134  flag_events_waits_history_long= param->m_consumer_events_waits_history_long_enabled;
135  flag_global_instrumentation= param->m_consumer_global_instrumentation_enabled;
136  flag_thread_instrumentation= param->m_consumer_thread_instrumentation_enabled;
137  flag_statements_digest= param->m_consumer_statement_digest_enabled;
138 
140  return &PFS_bootstrap;
141 }
142 
143 static void destroy_pfs_thread(void *key)
144 {
145  PFS_thread* pfs= reinterpret_cast<PFS_thread*> (key);
146  DBUG_ASSERT(pfs);
147  /*
148  This automatic cleanup is a last resort and best effort to avoid leaks,
149  and may not work on windows due to the implementation of pthread_key_create().
150  Please either use:
151  - my_thread_end()
152  - or PSI_server->delete_current_thread()
153  in the instrumented code, to explicitly cleanup the instrumentation.
154 
155  Avoid invalid writes when the main() thread completes after shutdown:
156  the memory pointed by pfs is already released.
157  */
158  if (pfs_initialized)
159  destroy_thread(pfs);
160 }
161 
162 static void cleanup_performance_schema(void)
163 {
165 /* Disabled: Bug#5666
166  cleanup_instruments();
167  cleanup_sync_class();
168  cleanup_thread_class();
169  cleanup_table_share();
170  cleanup_file_class();
171  cleanup_stage_class();
172  cleanup_statement_class();
173  cleanup_socket_class();
174  cleanup_events_waits_history_long();
175  cleanup_events_stages_history_long();
176  cleanup_events_statements_history_long();
177  cleanup_table_share_hash();
178  cleanup_file_hash();
179  cleanup_setup_actor();
180  cleanup_setup_actor_hash();
181  cleanup_setup_object();
182  cleanup_setup_object_hash();
183  cleanup_host();
184  cleanup_host_hash();
185  cleanup_user();
186  cleanup_user_hash();
187  cleanup_account();
188  cleanup_account_hash();
189  cleanup_digest();
190  PFS_atomic::cleanup();
191 */
192 }
193 
195 {
196  pfs_initialized= false;
197  cleanup_performance_schema();
198 #if 0
199  /*
200  Be careful to not delete un-initialized keys,
201  this would affect key 0, which is THR_KEY_mysys,
202  */
204  {
205  my_pthread_setspecific_ptr(THR_PFS, NULL);
206  pthread_key_delete(THR_PFS);
207  THR_PFS_initialized= false;
208  }
209 #endif
210 }
211 
217 {
218  my_init_dynamic_array(&pfs_instr_config_array, sizeof(PFS_instr_config*), 10, 10);
219  pfs_instr_config_state= PFS_INSTR_CONFIG_ALLOCATED;
220 }
221 
227 {
228  int desired_state= PFS_INSTR_CONFIG_ALLOCATED;
229 
230  /* Ignore if another thread has already deallocated the array */
231  if (my_atomic_cas32(&pfs_instr_config_state, &desired_state, PFS_INSTR_CONFIG_DEALLOCATED))
232  delete_dynamic(&pfs_instr_config_array);
233 }
234 
245 int add_pfs_instr_to_array(const char* name, const char* value)
246 {
247  int name_length= strlen(name);
248  int value_length= strlen(value);
249 
250  /* Allocate structure plus string buffers plus null terminators */
251  PFS_instr_config* e = (PFS_instr_config*)my_malloc(sizeof(PFS_instr_config)
252  + name_length + 1 + value_length + 1, MYF(MY_WME));
253  if (!e) return 1;
254 
255  /* Copy the instrument name */
256  e->m_name= (char*)e + sizeof(PFS_instr_config);
257  memcpy(e->m_name, name, name_length);
258  e->m_name_length= name_length;
259  e->m_name[name_length]= '\0';
260 
261  /* Set flags accordingly */
262  if (!my_strcasecmp(&my_charset_latin1, value, "counted"))
263  {
264  e->m_enabled= true;
265  e->m_timed= false;
266  }
267  else
268  if (!my_strcasecmp(&my_charset_latin1, value, "true") ||
269  !my_strcasecmp(&my_charset_latin1, value, "on") ||
270  !my_strcasecmp(&my_charset_latin1, value, "1") ||
271  !my_strcasecmp(&my_charset_latin1, value, "yes"))
272  {
273  e->m_enabled= true;
274  e->m_timed= true;
275  }
276  else
277  if (!my_strcasecmp(&my_charset_latin1, value, "false") ||
278  !my_strcasecmp(&my_charset_latin1, value, "off") ||
279  !my_strcasecmp(&my_charset_latin1, value, "0") ||
280  !my_strcasecmp(&my_charset_latin1, value, "no"))
281  {
282  e->m_enabled= false;
283  e->m_timed= false;
284  }
285  else
286  {
287  my_free(e);
288  return 1;
289  }
290 
291  /* Add to the array of default startup options */
292  if (insert_dynamic(&pfs_instr_config_array, &e))
293  {
294  my_free(e);
295  return 1;
296  }
297 
298  return 0;
299 }