MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_profile.h
1 /* Copyright (c) 2007, 2010, 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 
16 #ifndef _SQL_PROFILE_H
17 #define _SQL_PROFILE_H
18 
19 class Item;
20 struct TABLE_LIST;
21 class THD;
22 typedef struct st_field_info ST_FIELD_INFO;
23 typedef struct st_schema_table ST_SCHEMA_TABLE;
24 
25 extern ST_FIELD_INFO query_profile_statistics_info[];
26 int fill_query_profile_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
27 int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table);
28 
29 
30 #define PROFILE_NONE (uint)0
31 #define PROFILE_CPU (uint)(1<<0)
32 #define PROFILE_MEMORY (uint)(1<<1)
33 #define PROFILE_BLOCK_IO (uint)(1<<2)
34 #define PROFILE_CONTEXT (uint)(1<<3)
35 #define PROFILE_PAGE_FAULTS (uint)(1<<4)
36 #define PROFILE_IPC (uint)(1<<5)
37 #define PROFILE_SWAPS (uint)(1<<6)
38 #define PROFILE_SOURCE (uint)(1<<16)
39 #define PROFILE_ALL (uint)(~0)
40 
41 
42 #if defined(ENABLED_PROFILING)
43 #include "sql_priv.h"
44 #include "unireg.h"
45 
46 #ifdef HAVE_SYS_RESOURCE_H
47 #include <sys/resource.h>
48 #endif
49 
50 
51 class PROF_MEASUREMENT;
52 class QUERY_PROFILE;
53 class PROFILING;
54 
55 
60 template <class T> class Queue
61 {
62 private:
63 
64  struct queue_item
65  {
66  T *payload;
67  struct queue_item *next, *previous;
68  };
69 
70  struct queue_item *first, *last;
71 
72 public:
73  Queue()
74  {
75  elements= 0;
76  first= last= NULL;
77  }
78 
79  void empty()
80  {
81  struct queue_item *i, *after_i;
82  for (i= first; i != NULL; i= after_i)
83  {
84  after_i= i->next;
85  my_free(i);
86  }
87  elements= 0;
88  }
89 
90  ulong elements; /* The count of items in the Queue */
91 
92  void push_back(T *payload)
93  {
94  struct queue_item *new_item;
95 
96  new_item= (struct queue_item *) my_malloc(sizeof(struct queue_item), MYF(0));
97 
98  new_item->payload= payload;
99 
100  if (first == NULL)
101  first= new_item;
102  if (last != NULL)
103  {
104  DBUG_ASSERT(last->next == NULL);
105  last->next= new_item;
106  }
107  new_item->previous= last;
108  new_item->next= NULL;
109  last= new_item;
110 
111  elements++;
112  }
113 
114  T *pop()
115  {
116  struct queue_item *old_item= first;
117  T *ret= NULL;
118 
119  if (first == NULL)
120  {
121  DBUG_PRINT("warning", ("tried to pop nonexistent item from Queue"));
122  return NULL;
123  }
124 
125  ret= old_item->payload;
126  if (first->next != NULL)
127  first->next->previous= NULL;
128  else
129  last= NULL;
130  first= first->next;
131 
132  my_free(old_item);
133  elements--;
134 
135  return ret;
136  }
137 
138  bool is_empty()
139  {
140  DBUG_ASSERT(((elements > 0) && (first != NULL)) || ((elements == 0) || (first == NULL)));
141  return (elements == 0);
142  }
143 
144  void *new_iterator()
145  {
146  return first;
147  }
148 
149  void *iterator_next(void *current)
150  {
151  return ((struct queue_item *) current)->next;
152  }
153 
154  T *iterator_value(void *current)
155  {
156  return ((struct queue_item *) current)->payload;
157  }
158 
159 };
160 
161 
165 class PROF_MEASUREMENT
166 {
167 private:
168  friend class QUERY_PROFILE;
169  friend class PROFILING;
170 
171  QUERY_PROFILE *profile;
172  char *status;
173 #ifdef HAVE_GETRUSAGE
174  struct rusage rusage;
175 #elif defined(_WIN32)
176  FILETIME ftKernel, ftUser;
177 #endif
178 
179  char *function;
180  char *file;
181  unsigned int line;
182 
183  ulong m_seq;
184  double time_usecs;
185  char *allocated_status_memory;
186 
187  void set_label(const char *status_arg, const char *function_arg,
188  const char *file_arg, unsigned int line_arg);
189  void clean_up();
190 
191  PROF_MEASUREMENT();
192  PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg);
193  PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg,
194  const char *function_arg,
195  const char *file_arg, unsigned int line_arg);
196  ~PROF_MEASUREMENT();
197  void collect();
198 };
199 
200 
205 class QUERY_PROFILE
206 {
207 private:
208  friend class PROFILING;
209 
210  PROFILING *profiling;
211 
212  query_id_t profiling_query_id; /* Session-specific id. */
213  char *query_source;
214 
215  double m_start_time_usecs;
216  double m_end_time_usecs;
217  ulong m_seq_counter;
218  Queue<PROF_MEASUREMENT> entries;
219 
220 
221  QUERY_PROFILE(PROFILING *profiling_arg, const char *status_arg);
222  ~QUERY_PROFILE();
223 
224  void set_query_source(char *query_source_arg, uint query_length_arg);
225 
226  /* Add a profile status change to the current profile. */
227  void new_status(const char *status_arg,
228  const char *function_arg,
229  const char *file_arg, unsigned int line_arg);
230 
231  /* Reset the contents of this profile entry. */
232  void reset();
233 
234  /* Show this profile. This is called by PROFILING. */
235  bool show(uint options);
236 };
237 
238 
242 class PROFILING
243 {
244 private:
245  friend class PROF_MEASUREMENT;
246  friend class QUERY_PROFILE;
247 
248  /*
249  Not the system query_id, but a counter unique to profiling.
250  */
251  query_id_t profile_id_counter;
252  THD *thd;
253  bool keeping;
254  bool enabled;
255 
256  QUERY_PROFILE *current;
257  QUERY_PROFILE *last;
258  Queue<QUERY_PROFILE> history;
259 
260  query_id_t next_profile_id() { return(profile_id_counter++); }
261 
262 public:
263  PROFILING();
264  ~PROFILING();
265  void set_query_source(char *query_source_arg, uint query_length_arg);
266 
267  void start_new_query(const char *initial_state= "starting");
268 
269  void discard_current_query();
270 
271  void finish_current_query();
272 
273  void status_change(const char *status_arg,
274  const char *function_arg,
275  const char *file_arg, unsigned int line_arg);
276 
277  inline void set_thd(THD *thd_arg) { thd= thd_arg; };
278 
279  /* SHOW PROFILES */
280  bool show_profiles();
281 
282  /* ... from INFORMATION_SCHEMA.PROFILING ... */
283  int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
284 };
285 
286 # endif /* HAVE_PROFILING */
287 #endif /* _SQL_PROFILE_H */