1 /* Copyright (C) 2013 Percona and Sergey Vojtovich
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
14    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
15 
16 #define MYSQL_SERVER
17 #include <my_global.h>
18 #include <sql_class.h>
19 #include <table.h>
20 #include <sql_show.h>
21 #include <mysql/plugin_audit.h>
22 #include "query_response_time.h"
23 
24 
25 ulong opt_query_response_time_range_base= QRT_DEFAULT_BASE;
26 my_bool opt_query_response_time_stats= 0;
27 static my_bool opt_query_response_time_flush= 0;
28 
29 
query_response_time_flush_update(MYSQL_THD thd,struct st_mysql_sys_var * var,void * tgt,const void * save)30 static void query_response_time_flush_update(
31               MYSQL_THD thd __attribute__((unused)),
32               struct st_mysql_sys_var *var __attribute__((unused)),
33               void *tgt __attribute__((unused)),
34               const void *save __attribute__((unused)))
35 {
36   query_response_time_flush();
37 }
38 
39 
40 static MYSQL_SYSVAR_ULONG(range_base, opt_query_response_time_range_base,
41        PLUGIN_VAR_RQCMDARG,
42        "Select base of log for query_response_time ranges. WARNING: variable "
43        "change affect only after flush",
44        NULL, NULL, QRT_DEFAULT_BASE, 2, QRT_MAXIMUM_BASE, 1);
45 static MYSQL_SYSVAR_BOOL(stats, opt_query_response_time_stats,
46        PLUGIN_VAR_OPCMDARG,
47        "Enable or disable query response time statisics collecting",
48        NULL, NULL, FALSE);
49 static MYSQL_SYSVAR_BOOL(flush, opt_query_response_time_flush,
50        PLUGIN_VAR_NOCMDOPT,
51        "Update of this variable flushes statistics and re-reads "
52        "query_response_time_range_base",
53        NULL, query_response_time_flush_update, FALSE);
54 #ifndef DBUG_OFF
55 static MYSQL_THDVAR_ULONGLONG(exec_time_debug, PLUGIN_VAR_NOCMDOPT,
56        "Pretend queries take this many microseconds. When 0 (the default) use "
57        "the actual execution time. Used only for debugging.",
58        NULL, NULL, 0, 0, LONG_TIMEOUT, 1);
59 #endif
60 
61 
62 static struct st_mysql_sys_var *query_response_time_info_vars[]=
63 {
64   MYSQL_SYSVAR(range_base),
65   MYSQL_SYSVAR(stats),
66   MYSQL_SYSVAR(flush),
67 #ifndef DBUG_OFF
68   MYSQL_SYSVAR(exec_time_debug),
69 #endif
70   NULL
71 };
72 
73 
74 ST_FIELD_INFO query_response_time_fields_info[] =
75 {
76   { "TIME",  QRT_TIME_STRING_LENGTH,      MYSQL_TYPE_STRING,  0, 0,               "Time", 0 },
77   { "COUNT", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG,    0, MY_I_S_UNSIGNED, "Count", 0 },
78   { "TOTAL", QRT_TIME_STRING_LENGTH,      MYSQL_TYPE_STRING,  0, 0,               "Total", 0 },
79   { 0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0 }
80 };
81 
82 
query_response_time_info_init(void * p)83 static int query_response_time_info_init(void *p)
84 {
85   ST_SCHEMA_TABLE *i_s_query_response_time= (ST_SCHEMA_TABLE *) p;
86   i_s_query_response_time->fields_info= query_response_time_fields_info;
87   i_s_query_response_time->fill_table= query_response_time_fill;
88   i_s_query_response_time->reset_table= query_response_time_flush;
89   query_response_time_init();
90   return 0;
91 }
92 
93 
query_response_time_info_deinit(void * arg)94 static int query_response_time_info_deinit(void *arg __attribute__((unused)))
95 {
96   opt_query_response_time_stats= 0;
97   query_response_time_free();
98   return 0;
99 }
100 
101 
102 static struct st_mysql_information_schema query_response_time_info_descriptor=
103 { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
104 
105 
query_response_time_audit_notify(MYSQL_THD thd,unsigned int event_class,const void * event)106 static void query_response_time_audit_notify(MYSQL_THD thd,
107                                              unsigned int event_class,
108                                              const void *event)
109 {
110   const struct mysql_event_general *event_general=
111     (const struct mysql_event_general *) event;
112   DBUG_ASSERT(event_class == MYSQL_AUDIT_GENERAL_CLASS);
113   if (event_general->event_subclass == MYSQL_AUDIT_GENERAL_STATUS &&
114       opt_query_response_time_stats)
115   {
116 #ifndef DBUG_OFF
117     if (THDVAR(thd, exec_time_debug))
118       query_response_time_collect(thd->lex->sql_command != SQLCOM_SET_OPTION ?
119                                   THDVAR(thd, exec_time_debug) : 0);
120     else
121 #endif
122     query_response_time_collect(thd->utime_after_query - thd->utime_after_lock);
123   }
124 }
125 
126 
127 static struct st_mysql_audit query_response_time_audit_descriptor=
128 {
129   MYSQL_AUDIT_INTERFACE_VERSION, NULL, query_response_time_audit_notify,
130   { (unsigned long) MYSQL_AUDIT_GENERAL_CLASSMASK }
131 };
132 
133 
maria_declare_plugin(query_response_time)134 maria_declare_plugin(query_response_time)
135 {
136   MYSQL_INFORMATION_SCHEMA_PLUGIN,
137   &query_response_time_info_descriptor,
138   "QUERY_RESPONSE_TIME",
139   "Percona and Sergey Vojtovich",
140   "Query Response Time Distribution INFORMATION_SCHEMA Plugin",
141   PLUGIN_LICENSE_GPL,
142   query_response_time_info_init,
143   query_response_time_info_deinit,
144   0x0100,
145   NULL,
146   query_response_time_info_vars,
147   "1.0",
148   MariaDB_PLUGIN_MATURITY_STABLE
149 },
150 {
151   MYSQL_AUDIT_PLUGIN,
152   &query_response_time_audit_descriptor,
153   "QUERY_RESPONSE_TIME_AUDIT",
154   "Percona and Sergey Vojtovich",
155   "Query Response Time Distribution Audit Plugin",
156   PLUGIN_LICENSE_GPL,
157   NULL,
158   NULL,
159   0x0100,
160   NULL,
161   NULL,
162   "1.0",
163   MariaDB_PLUGIN_MATURITY_STABLE
164 }
165 maria_declare_plugin_end;
166