diff options
Diffstat (limited to 'sql/sql_profile.h')
-rw-r--r-- | sql/sql_profile.h | 248 |
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 */ |