summaryrefslogtreecommitdiff
path: root/sql/sql_profile.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_profile.h')
-rw-r--r--sql/sql_profile.h248
1 files changed, 151 insertions, 97 deletions
diff --git a/sql/sql_profile.h b/sql/sql_profile.h
index 698a80f07e4..006760cab79 100644
--- a/sql/sql_profile.h
+++ b/sql/sql_profile.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 MySQL AB
+/* Copyright (C) 2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -14,99 +14,135 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifndef SQL_PROFILE_H
-#define SQL_PROFILE_H
-
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#if 1
-#define THD_PROC_INFO(thd, msg) do { if(unlikely((thd)->profiling.enabled)) { (thd)->profiling.status((msg), __FUNCTION__, __FILE__, __LINE__); } else { (thd)->proc_info= (msg); } } while (0)
+#ifndef _SQL_PROFILE_H
+#define _SQL_PROFILE_H
+
+#if __STDC_VERSION__ < 199901L
+# if __GNUC__ >= 2
+# define __func__ __FUNCTION__
+# else
+# define __func__ _db_func_
+extern const char *_db_func_;
+# endif
+#elif defined(_MSC_VER)
+# if _MSC_VER < 1300
+# define __func__ _db_func_
+extern const char *_db_func_;
+# else
+# define __func__ __FUNCTION__
+# endif
+#elif defined(__BORLANDC__)
+# define __func__ __FUNC__
#else
-#define THD_PROC_INFO(thd, msg) do { (thd)->proc_info= (msg); } while (0)
+# define __func__ _db_func_
+extern const char *_db_func_;
#endif
-#if 0
-
- struct rusage {
- struct timeval ru_utime; /* user time used */
- struct timeval ru_stime; /* system time used */
- long ru_maxrss; /* integral max resident set size */
- long ru_ixrss; /* integral shared text memory size */
- long ru_idrss; /* integral unshared data size */
- long ru_isrss; /* integral unshared stack size */
- long ru_minflt; /* page reclaims */
- long ru_majflt; /* page faults */
- long ru_nswap; /* swaps */
- long ru_inblock; /* block input operations */
- long ru_oublock; /* block output operations */
- long ru_msgsnd; /* messages sent */
- long ru_msgrcv; /* messages received */
- long ru_nsignals; /* signals received */
- long ru_nvcsw; /* voluntary context switches */
- long ru_nivcsw; /* involuntary context switches */
- };
+extern ST_FIELD_INFO query_profile_statistics_info[];
+int fill_query_profile_statistics_info(THD *thd, struct st_table_list *tables, Item *cond);
-#endif
#define PROFILE_NONE 0
-#define PROFILE_CPU 1
-#define PROFILE_MEMORY 2
-#define PROFILE_BLOCK_IO 4
-#define PROFILE_CONTEXT 8
-#define PROFILE_PAGE_FAULTS 16
-#define PROFILE_IPC 32
-#define PROFILE_SWAPS 64
-#define PROFILE_SOURCE 16384
-#define PROFILE_ALL 32767
+#define PROFILE_CPU (1<<0)
+#define PROFILE_MEMORY (1<<1)
+#define PROFILE_BLOCK_IO (1<<2)
+#define PROFILE_CONTEXT (1<<3)
+#define PROFILE_PAGE_FAULTS (1<<4)
+#define PROFILE_IPC (1<<5)
+#define PROFILE_SWAPS (1<<6)
+#define PROFILE_SOURCE (1<<16)
+#define PROFILE_ALL (~0)
+
+
+#ifndef ENABLED_PROFILING
+
+# define thd_proc_info(thd, msg) do { (thd)->proc_info= (msg); } while (0)
+
+#else
+
+# define thd_proc_info(thd, msg) \
+ do { \
+ if (unlikely(((thd)->options & OPTION_PROFILING) != 0)) \
+ { \
+ (thd)->profiling.status_change((msg), __func__, __FILE__, __LINE__); \
+ } \
+ else \
+ { \
+ (thd)->proc_info= (msg); \
+ } \
+ } while (0)
+
+#include "mysql_priv.h"
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
class PROFILE_ENTRY;
-class PROFILE;
+class QUERY_PROFILE;
class PROFILING;
-/*
+
+/**
A single entry in a single profile.
*/
-
-class PROFILE_ENTRY: public Sql_alloc
+class PROFILE_ENTRY
{
-public:
- PROFILE *profile;
- char *status;
- ulonglong time;
+private:
+ friend class QUERY_PROFILE;
+ friend class PROFILING;
+
+ QUERY_PROFILE *profile;
+ char *status;
+#ifdef HAVE_GETRUSAGE
struct rusage rusage;
+#endif
char *function;
char *file;
unsigned int line;
+
+ double time_usecs;
+ char *allocated_status_memory;
+
+ void set_status(const char *status_arg, const char *function_arg,
+ const char *file_arg, unsigned int line_arg);
+ void clean_up();
PROFILE_ENTRY();
- PROFILE_ENTRY(PROFILE *profile_arg, const char *status_arg);
- PROFILE_ENTRY(PROFILE *profile_arg, const char *status_arg,
+ PROFILE_ENTRY(QUERY_PROFILE *profile_arg, const char *status_arg);
+ PROFILE_ENTRY(QUERY_PROFILE *profile_arg, const char *status_arg,
const char *function_arg,
const char *file_arg, unsigned int line_arg);
~PROFILE_ENTRY();
-
- void set_status(const char *status_arg);
void collect();
};
-/*
- The full profile for a single query. Includes multiple PROFILE_ENTRY
+
+/**
+ The full profile for a single query, and includes multiple PROFILE_ENTRY
objects.
*/
-
-class PROFILE: public Sql_alloc
+class QUERY_PROFILE
{
-public:
+private:
+ friend class PROFILING;
+
PROFILING *profiling;
- query_id_t query_id;
+
+ query_id_t server_query_id; /* Global id. */
+ query_id_t profiling_query_id; /* Session-specific id. */
+ char *query_source;
PROFILE_ENTRY profile_start;
PROFILE_ENTRY *profile_end;
List<PROFILE_ENTRY> entries;
- PROFILE(PROFILING *profiling_arg);
- ~PROFILE();
+
+ QUERY_PROFILE(PROFILING *profiling_arg, char *query_source_arg, uint query_length_arg);
+ ~QUERY_PROFILE();
+
+ void set_query_source(char *query_source_arg, uint query_length_arg);
/* Add a profile status change to the current profile. */
void status(const char *status_arg,
@@ -120,68 +156,86 @@ public:
bool show(uint options);
};
-/*
- Profiling state for a single THD. Contains multiple PROFILE objects.
-*/
-class PROFILING: public Sql_alloc
+/**
+ Profiling state for a single THD; contains multiple QUERY_PROFILE objects.
+*/
+class PROFILING
{
-public:
- MEM_ROOT root;
+private:
+ friend class PROFILE_ENTRY;
+ friend class QUERY_PROFILE;
+
+ /*
+ Not the system query_id, but a counter unique to profiling.
+ */
+ query_id_t profile_id_counter;
+ MEM_ROOT mem_root;
THD *thd;
- bool enabled;
bool keeping;
- PROFILE *current;
- PROFILE *last;
- List<PROFILE> history;
+ QUERY_PROFILE *current;
+ QUERY_PROFILE *last;
+ List<QUERY_PROFILE> history;
+
+ query_id_t next_profile_id() { return(profile_id_counter++); }
+public:
PROFILING();
~PROFILING();
+ void set_query_source(char *query_source_arg, uint query_length_arg);
- inline void set_thd(THD *thd_arg) { thd= thd_arg; };
-
- /*
- Should we try to collect profiling information at all?
-
- If we disable profiling, we cannot later decide to turn it back
- on for the same query.
- */
- inline void enable() { enabled= 1; };
- inline void disable() { enabled= 0; };
+ /** Reset the current profile and state of profiling for the next query. */
+ void reset();
- /*
+ /**
Do we intend to keep the currently collected profile?
- We don't keep profiles for some commands, such as SHOW PROFILE,
- SHOW PROFILES, and some SQLCOM commands which aren't useful to
- profile. The keep() and discard() functions can be called many
- times, only the final setting when the query finishes is used
- to decide whether to discard the profile.
+ We don't keep profiles for some commands, such as SHOW PROFILE, SHOW
+ PROFILES, and some SQLCOM commands which aren't useful to profile. The
+ keep() and discard() functions can be called many times, only the final
+ setting when the query finishes is used to decide whether to discard the
+ profile.
The default is to keep the profile for all queries.
*/
- inline void keep() { keeping= 1; };
- inline void discard() { keeping= 0; };
+ inline void keep() { keeping= true; };
- void status(const char *status_arg,
- const char *function_arg,
- const char *file_arg, unsigned int line_arg);
+ /**
+ Do we intend to keep the currently collected profile?
+ @see keep()
+ */
+ inline void discard() { keeping= false; };
- /* Stash this profile in the profile history. */
+ /**
+ Stash this profile in the profile history and remove the oldest
+ profile if the history queue is full, as defined by the
+ profiling_history_size system variable.
+ */
void store();
-
- /* Reset the current profile and state of profiling for the next query. */
- void reset();
+
+ /**
+ Called with every update of the status via thd_proc_info() , and is
+ therefore the main hook into the profiling code.
+ */
+ void status_change(const char *status_arg,
+ const char *function_arg,
+ const char *file_arg, unsigned int line_arg);
+
+ inline void set_thd(THD *thd_arg) { thd= thd_arg; };
/* SHOW PROFILES */
bool show_profiles();
/* SHOW PROFILE FOR QUERY query_id */
- bool show(uint options, uint query_id);
+ bool show(uint options, uint profiling_query_id);
/* SHOW PROFILE */
bool show_last(uint options);
+
+ /* ... from INFORMATION_SCHEMA.PROFILING ... */
+ int fill_statistics_info(THD *thd, struct st_table_list *tables, Item *cond);
};
-#endif /* SQL_PROFILE_H */
+# endif /* HAVE_PROFILING */
+#endif /* _SQL_PROFILE_H */