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 02111-1301 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
25ulong opt_query_response_time_range_base= QRT_DEFAULT_BASE;
26my_bool opt_query_response_time_stats= 0;
27static my_bool opt_query_response_time_flush= 0;
28
29
30static 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
40static 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);
45static 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);
49static 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
55static 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
62static 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
74ST_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
83static 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
94static 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
102static struct st_mysql_information_schema query_response_time_info_descriptor=
103{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
104
105
106static 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
127static 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
134maria_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}
165maria_declare_plugin_end;
166