]> git.pld-linux.org Git - packages/mysql.git/blame - slow_extended.patch
- sphinx 2.0.1 beta
[packages/mysql.git] / slow_extended.patch
CommitLineData
b4e1fa2c
AM
1# name : slow_extended.patch
2# introduced : 11 or before
3# maintainer : Oleg
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
db82db79
AM
8--- a/include/mysql/plugin_audit.h.pp
9+++ b/include/mysql/plugin_audit.h.pp
10@@ -185,6 +185,16 @@
b4e1fa2c
AM
11 char *thd_security_context(void* thd, char *buffer, unsigned int length,
12 unsigned int max_query_len);
13 void thd_inc_row_count(void* thd);
14+void increment_thd_innodb_stats(void* thd,
15+ unsigned long long trx_id,
16+ long io_reads,
17+ long long io_read,
18+ long io_reads_wait_timer,
19+ long lock_que_wait_timer,
20+ long que_wait_timer,
21+ long page_access);
22+unsigned long thd_log_slow_verbosity(const void* thd);
23+int thd_opt_slow_log();
24 int mysql_tmpfile(const char *prefix);
25 int thd_killed(const void* thd);
26 unsigned long thd_get_thread_id(const void* thd);
db82db79
AM
27--- a/include/mysql/plugin_auth.h.pp
28+++ b/include/mysql/plugin_auth.h.pp
29@@ -185,6 +185,16 @@
b4e1fa2c
AM
30 char *thd_security_context(void* thd, char *buffer, unsigned int length,
31 unsigned int max_query_len);
32 void thd_inc_row_count(void* thd);
33+void increment_thd_innodb_stats(void* thd,
34+ unsigned long long trx_id,
35+ long io_reads,
36+ long long io_read,
37+ long io_reads_wait_timer,
38+ long lock_que_wait_timer,
39+ long que_wait_timer,
40+ long page_access);
41+unsigned long thd_log_slow_verbosity(const void* thd);
42+int thd_opt_slow_log();
43 int mysql_tmpfile(const char *prefix);
44 int thd_killed(const void* thd);
45 unsigned long thd_get_thread_id(const void* thd);
db82db79
AM
46--- a/include/mysql/plugin_ftparser.h.pp
47+++ b/include/mysql/plugin_ftparser.h.pp
48@@ -138,6 +138,16 @@
b4e1fa2c
AM
49 char *thd_security_context(void* thd, char *buffer, unsigned int length,
50 unsigned int max_query_len);
51 void thd_inc_row_count(void* thd);
52+void increment_thd_innodb_stats(void* thd,
53+ unsigned long long trx_id,
54+ long io_reads,
55+ long long io_read,
56+ long io_reads_wait_timer,
57+ long lock_que_wait_timer,
58+ long que_wait_timer,
59+ long page_access);
60+unsigned long thd_log_slow_verbosity(const void* thd);
61+int thd_opt_slow_log();
62 int mysql_tmpfile(const char *prefix);
63 int thd_killed(const void* thd);
64 unsigned long thd_get_thread_id(const void* thd);
db82db79
AM
65--- a/include/mysql/plugin.h
66+++ b/include/mysql/plugin.h
b4e1fa2c
AM
67@@ -536,6 +536,17 @@
68 /* Increments the row counter, see THD::row_count */
69 void thd_inc_row_count(MYSQL_THD thd);
70
71+void increment_thd_innodb_stats(MYSQL_THD thd,
72+ unsigned long long trx_id,
73+ long io_reads,
74+ long long io_read,
75+ long io_reads_wait_timer,
76+ long lock_que_wait_timer,
77+ long que_wait_timer,
78+ long page_access);
79+unsigned long thd_log_slow_verbosity(const MYSQL_THD thd);
80+int thd_opt_slow_log();
81+#define EXTENDED_SLOWLOG
82 /**
83 Create a temporary file.
84
db82db79
AM
85--- /dev/null
86+++ b/patch_info/slow_extended.info
b4e1fa2c
AM
87@@ -0,0 +1,25 @@
88+File=slow_extended.patch
89+Name=Extended statistics in slow.log (not InnoDB part)
90+Version=1.3
91+Author=Percona <info@percona.com>
92+License=GPL
93+Comment=
94+Changelog
95+2008-11-26
96+YK: Fix inefficient determination of trx, Make not to call useless gettimeofday when don't use slow log. Make log_slow_queries dynamic (bool).
97+
98+2008-11-07
99+VT: Moved log_slow_rate_limit in SHOW VARIABLE into right place
100+
101+2008-11
102+Arjen Lentz: Fixups (backward compatibility) by Arjen Lentz <arjen@openquery.com.au>
103+
104+2010-07
105+1) Fix overflow of query time and lock time (Bug 600360) (slow_extended_fix_overflow.patch merged)
106+2) Control global slow feature merged (control_global_slow.patch merged)
107+3) Microseconds in slow query log merged (microseconds_in_slow_query_log.patch merged)
108+4) Now use_global_long_query_time and use_global_log_slow_control are synonims. Add value "all" for use_global_log_slow_control (contol-global_slow-2.patch merged)
109+5) Fix innodb_stats on replication (Bug 600684)
110+6) Change variable types (system/command-line)
a9ee80b9 111+2011-01
b4e1fa2c 112+Patch profiling_slow.patch was merged
db82db79
AM
113--- a/scripts/mysqldumpslow.sh
114+++ b/scripts/mysqldumpslow.sh
115@@ -102,8 +102,8 @@
b4e1fa2c
AM
116 s/^#? Time: \d{6}\s+\d+:\d+:\d+.*\n//;
117 my ($user,$host) = s/^#? User\@Host:\s+(\S+)\s+\@\s+(\S+).*\n// ? ($1,$2) : ('','');
118
119- s/^# Query_time: ([0-9.]+)\s+Lock_time: ([0-9.]+)\s+Rows_sent: ([0-9.]+).*\n//;
120- my ($t, $l, $r) = ($1, $2, $3);
121+ s/^# Query_time: (\d+(\.\d+)?) Lock_time: (\d+(\.\d+)?) Rows_sent: (\d+(\.\d+)?).*\n//;
122+ my ($t, $l, $r) = ($1, $3, $5);
123 $t -= $l unless $opt{l};
124
125 # remove fluff that mysqld writes to log when it (re)starts:
db82db79
AM
126--- a/sql/event_scheduler.cc
127+++ b/sql/event_scheduler.cc
b4e1fa2c
AM
128@@ -195,6 +195,7 @@
129 thd->client_capabilities|= CLIENT_MULTI_RESULTS;
130 mysql_mutex_lock(&LOCK_thread_count);
131 thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
132+ thd->write_to_slow_log = TRUE;
133 mysql_mutex_unlock(&LOCK_thread_count);
134
135 /*
db82db79
AM
136--- a/sql/filesort.cc
137+++ b/sql/filesort.cc
11822e22 138@@ -195,6 +195,7 @@
b4e1fa2c
AM
139 {
140 status_var_increment(thd->status_var.filesort_scan_count);
141 }
142+ thd->query_plan_flags|= QPLAN_FILESORT;
143 #ifdef CAN_TRUST_RANGE
144 if (select && select->quick && select->quick->records > 0L)
145 {
11822e22 146@@ -260,6 +261,7 @@
b4e1fa2c
AM
147 }
148 else
149 {
150+ thd->query_plan_flags|= QPLAN_FILESORT_DISK;
151 if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
152 {
153 my_free(table_sort.buffpek);
11822e22 154@@ -1219,6 +1221,7 @@
b4e1fa2c
AM
155 DBUG_ENTER("merge_buffers");
156
157 status_var_increment(current_thd->status_var.filesort_merge_passes);
158+ current_thd->query_plan_fsort_passes++;
159 if (param->not_killable)
160 {
161 killed= &not_killable;
db82db79
AM
162--- a/sql/log.cc
163+++ b/sql/log.cc
d8778560 164@@ -715,11 +715,13 @@
b4e1fa2c
AM
165 */
166
167 bool Log_to_csv_event_handler::
168- log_slow(THD *thd, time_t current_time, time_t query_start_arg,
169+ log_slow(THD *thd, ulonglong current_utime, time_t query_start_arg,
170 const char *user_host, uint user_host_len,
171 ulonglong query_utime, ulonglong lock_utime, bool is_command,
172 const char *sql_text, uint sql_text_len)
173 {
174+ time_t current_time= my_time_possible_from_micro(current_utime);
175+
176 TABLE_LIST table_list;
177 TABLE *table;
178 bool result= TRUE;
d8778560 179@@ -935,14 +937,14 @@
b4e1fa2c
AM
180 /** Wrapper around MYSQL_LOG::write() for slow log. */
181
182 bool Log_to_file_event_handler::
183- log_slow(THD *thd, time_t current_time, time_t query_start_arg,
184+ log_slow(THD *thd, ulonglong current_utime, time_t query_start_arg,
185 const char *user_host, uint user_host_len,
186 ulonglong query_utime, ulonglong lock_utime, bool is_command,
187 const char *sql_text, uint sql_text_len)
188 {
189 Silence_log_table_errors error_handler;
190 thd->push_internal_handler(&error_handler);
191- bool retval= mysql_slow_log.write(thd, current_time, query_start_arg,
192+ bool retval= mysql_slow_log.write(thd, current_utime, query_start_arg,
193 user_host, user_host_len,
194 query_utime, lock_utime, is_command,
195 sql_text, sql_text_len);
d8778560 196@@ -1216,7 +1218,7 @@
b4e1fa2c
AM
197 /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
198 user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
199 sctx->priv_user ? sctx->priv_user : "", "[",
200- sctx->user ? sctx->user : "", "] @ ",
201+ sctx->user ? sctx->user : (thd->slave_thread ? "SQL_SLAVE" : ""), "] @ ",
202 sctx->host ? sctx->host : "", " [",
203 sctx->ip ? sctx->ip : "", "]", NullS) -
204 user_host_buff);
d8778560 205@@ -1224,8 +1226,22 @@
b4e1fa2c
AM
206 current_time= my_time_possible_from_micro(current_utime);
207 if (thd->start_utime)
208 {
209- query_utime= (current_utime - thd->start_utime);
210- lock_utime= (thd->utime_after_lock - thd->start_utime);
211+ if(current_utime < thd->start_utime)
212+ {
213+ query_utime= 0;
214+ }
215+ else
216+ {
217+ query_utime= (current_utime - thd->start_utime);
218+ }
219+ if(thd->utime_after_lock < thd->start_utime)
220+ {
221+ lock_utime= 0;
222+ }
223+ else
224+ {
225+ lock_utime= (thd->utime_after_lock - thd->start_utime);
226+ }
227 }
228 else
229 {
d8778560 230@@ -1239,8 +1255,20 @@
b4e1fa2c
AM
231 query_length= command_name[thd->command].length;
232 }
233
234+ if (!query_length)
235+ {
236+ thd->sent_row_count= thd->examined_row_count= 0;
237+ thd->sent_row_count= 0;
238+ thd->bytes_sent_old= thd->status_var.bytes_sent;
239+ thd->tmp_tables_used= thd->tmp_tables_disk_used= 0;
240+ thd->tmp_tables_size= 0;
241+ thd->innodb_was_used= FALSE;
242+ thd->query_plan_flags= QPLAN_NONE;
243+ thd->query_plan_fsort_passes= 0;
244+ }
245+
246 for (current_handler= slow_log_handler_list; *current_handler ;)
247- error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
248+ error= (*current_handler++)->log_slow(thd, current_utime, thd->start_time,
249 user_host_buff, user_host_len,
250 query_utime, lock_utime, is_command,
251 query, query_length) || error;
d8778560 252@@ -2656,12 +2684,13 @@
b4e1fa2c
AM
253 TRUE - error occured
254 */
255
256-bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
257+bool MYSQL_QUERY_LOG::write(THD *thd, ulonglong current_utime,
258 time_t query_start_arg, const char *user_host,
259 uint user_host_len, ulonglong query_utime,
260 ulonglong lock_utime, bool is_command,
261 const char *sql_text, uint sql_text_len)
262 {
263+ time_t current_time= my_time_possible_from_micro(current_utime);
264 bool error= 0;
265 DBUG_ENTER("MYSQL_QUERY_LOG::write");
266
d8778560 267@@ -2683,17 +2712,28 @@
b4e1fa2c
AM
268
269 if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT))
270 {
271- if (current_time != last_time)
a9ee80b9 272+ if (opt_slow_query_log_timestamp_always || current_time != last_time)
b4e1fa2c
AM
273 {
274 last_time= current_time;
275 struct tm start;
276 localtime_r(&current_time, &start);
277-
278- buff_len= my_snprintf(buff, sizeof buff,
279- "# Time: %02d%02d%02d %2d:%02d:%02d\n",
280- start.tm_year % 100, start.tm_mon + 1,
281- start.tm_mday, start.tm_hour,
282- start.tm_min, start.tm_sec);
a9ee80b9 283+ if(opt_slow_query_log_timestamp_precision & SLOG_MICROSECOND)
b4e1fa2c
AM
284+ {
285+ ulonglong microsecond = current_utime % (1000 * 1000);
286+ buff_len= snprintf(buff, sizeof buff,
287+ "# Time: %02d%02d%02d %2d:%02d:%02d.%010lld\n",
288+ start.tm_year % 100, start.tm_mon + 1,
289+ start.tm_mday, start.tm_hour,
290+ start.tm_min, start.tm_sec,microsecond);
291+ }
292+ else
293+ {
294+ buff_len= my_snprintf(buff, sizeof buff,
295+ "# Time: %02d%02d%02d %2d:%02d:%02d\n",
296+ start.tm_year % 100, start.tm_mon + 1,
297+ start.tm_mday, start.tm_hour,
298+ start.tm_min, start.tm_sec);
299+ }
300
301 /* Note that my_b_write() assumes it knows the length for this */
302 if (my_b_write(&log_file, (uchar*) buff, buff_len))
df1b5770 303@@ -2711,12 +2751,69 @@
b4e1fa2c
AM
304 sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0);
305 sprintf(lock_time_buff, "%.6f", ulonglong2double(lock_utime)/1000000.0);
306 if (my_b_printf(&log_file,
307- "# Query_time: %s Lock_time: %s"
308- " Rows_sent: %lu Rows_examined: %lu\n",
309+ "# Thread_id: %lu Schema: %s Last_errno: %u Killed: %u\n" \
310+ "# Query_time: %s Lock_time: %s Rows_sent: %lu Rows_examined: %lu Rows_affected: %lu Rows_read: %lu\n"
311+ "# Bytes_sent: %lu Tmp_tables: %lu Tmp_disk_tables: %lu Tmp_table_sizes: %lu\n",
312+ (ulong) thd->thread_id, (thd->db ? thd->db : ""),
313+ thd->last_errno, (uint) thd->killed,
314 query_time_buff, lock_time_buff,
315 (ulong) thd->sent_row_count,
316- (ulong) thd->examined_row_count) == (uint) -1)
317+ (ulong) thd->examined_row_count,
318+ ((long) thd->get_row_count_func() > 0 ) ? (ulong) thd->get_row_count_func() : 0,
319+ (ulong) thd->sent_row_count,
320+ (ulong) (thd->status_var.bytes_sent - thd->bytes_sent_old),
321+ (ulong) thd->tmp_tables_used,
322+ (ulong) thd->tmp_tables_disk_used,
323+ (ulong) thd->tmp_tables_size) == (uint) -1)
324 tmp_errno= errno;
325+
326+#if defined(ENABLED_PROFILING)
327+ thd->profiling.print_current(&log_file);
328+#endif
329+ if (thd->innodb_was_used)
330+ {
331+ char buf[20];
332+ snprintf(buf, 20, "%llX", thd->innodb_trx_id);
333+ if (my_b_printf(&log_file,
334+ "# InnoDB_trx_id: %s\n", buf) == (uint) -1)
335+ tmp_errno=errno;
336+ }
337+ if ((thd->variables.log_slow_verbosity & (ULL(1) << SLOG_V_QUERY_PLAN)) &&
338+ my_b_printf(&log_file,
339+ "# QC_Hit: %s Full_scan: %s Full_join: %s Tmp_table: %s Tmp_table_on_disk: %s\n" \
340+ "# Filesort: %s Filesort_on_disk: %s Merge_passes: %lu\n",
341+ ((thd->query_plan_flags & QPLAN_QC) ? "Yes" : "No"),
342+ ((thd->query_plan_flags & QPLAN_FULL_SCAN) ? "Yes" : "No"),
343+ ((thd->query_plan_flags & QPLAN_FULL_JOIN) ? "Yes" : "No"),
344+ ((thd->query_plan_flags & QPLAN_TMP_TABLE) ? "Yes" : "No"),
345+ ((thd->query_plan_flags & QPLAN_TMP_DISK) ? "Yes" : "No"),
346+ ((thd->query_plan_flags & QPLAN_FILESORT) ? "Yes" : "No"),
347+ ((thd->query_plan_flags & QPLAN_FILESORT_DISK) ? "Yes" : "No"),
348+ thd->query_plan_fsort_passes) == (uint) -1)
349+ tmp_errno=errno;
350+ if ((thd->variables.log_slow_verbosity & (ULL(1) << SLOG_V_INNODB)) && thd->innodb_was_used)
351+ {
352+ char buf[3][20];
353+ snprintf(buf[0], 20, "%.6f", thd->innodb_io_reads_wait_timer / 1000000.0);
354+ snprintf(buf[1], 20, "%.6f", thd->innodb_lock_que_wait_timer / 1000000.0);
355+ snprintf(buf[2], 20, "%.6f", thd->innodb_innodb_que_wait_timer / 1000000.0);
356+ if (my_b_printf(&log_file,
357+ "# InnoDB_IO_r_ops: %lu InnoDB_IO_r_bytes: %lu InnoDB_IO_r_wait: %s\n" \
358+ "# InnoDB_rec_lock_wait: %s InnoDB_queue_wait: %s\n" \
359+ "# InnoDB_pages_distinct: %lu\n",
360+ (ulong) thd->innodb_io_reads,
361+ (ulong) thd->innodb_io_read,
362+ buf[0], buf[1], buf[2],
363+ (ulong) thd->innodb_page_access) == (uint) -1)
364+ tmp_errno=errno;
365+ }
366+ else
367+ {
368+ if ((thd->variables.log_slow_verbosity & (ULL(1) << SLOG_V_INNODB)) &&
369+ my_b_printf(&log_file,"# No InnoDB statistics available for this query\n") == (uint) -1)
370+ tmp_errno=errno;
371+ }
372+
373 if (thd->db && strcmp(thd->db, db))
374 { // Database changed
375 if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
db82db79
AM
376--- a/sql/log.h
377+++ b/sql/log.h
b4e1fa2c
AM
378@@ -242,7 +242,7 @@
379 uint user_host_len, int thread_id,
380 const char *command_type, uint command_type_len,
381 const char *sql_text, uint sql_text_len);
382- bool write(THD *thd, time_t current_time, time_t query_start_arg,
383+ bool write(THD *thd, ulonglong current_time, time_t query_start_arg,
384 const char *user_host, uint user_host_len,
385 ulonglong query_utime, ulonglong lock_utime, bool is_command,
386 const char *sql_text, uint sql_text_len);
11822e22 387@@ -515,7 +515,7 @@
b4e1fa2c
AM
388 virtual bool init()= 0;
389 virtual void cleanup()= 0;
390
391- virtual bool log_slow(THD *thd, time_t current_time,
392+ virtual bool log_slow(THD *thd, ulonglong current_time,
393 time_t query_start_arg, const char *user_host,
394 uint user_host_len, ulonglong query_utime,
395 ulonglong lock_utime, bool is_command,
11822e22 396@@ -544,7 +544,7 @@
b4e1fa2c
AM
397 virtual bool init();
398 virtual void cleanup();
399
400- virtual bool log_slow(THD *thd, time_t current_time,
401+ virtual bool log_slow(THD *thd, ulonglong current_utime,
402 time_t query_start_arg, const char *user_host,
403 uint user_host_len, ulonglong query_utime,
404 ulonglong lock_utime, bool is_command,
11822e22 405@@ -576,7 +576,7 @@
b4e1fa2c
AM
406 virtual bool init();
407 virtual void cleanup();
408
409- virtual bool log_slow(THD *thd, time_t current_time,
410+ virtual bool log_slow(THD *thd, ulonglong current_utime,
411 time_t query_start_arg, const char *user_host,
412 uint user_host_len, ulonglong query_utime,
413 ulonglong lock_utime, bool is_command,
db82db79
AM
414--- a/sql/mysqld.cc
415+++ b/sql/mysqld.cc
416@@ -421,6 +421,10 @@
b4e1fa2c
AM
417 char* opt_secure_file_priv;
418 my_bool opt_log_slow_admin_statements= 0;
419 my_bool opt_log_slow_slave_statements= 0;
420+my_bool opt_log_slow_sp_statements= 0;
a9ee80b9
ER
421+my_bool opt_slow_query_log_timestamp_always= 0;
422+ulonglong opt_slow_query_log_use_global_control= 0;
adf0fb13 423+ulong opt_slow_query_log_timestamp_precision= 0;
b4e1fa2c
AM
424 my_bool lower_case_file_system= 0;
425 my_bool opt_large_pages= 0;
426 my_bool opt_super_large_pages= 0;
db82db79 427@@ -5896,10 +5900,10 @@
b4e1fa2c
AM
428 "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to "
429 "the slow log if it is open.", &opt_log_slow_admin_statements,
430 &opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
431- {"log-slow-slave-statements", 0,
432+ /*{"log-slow-slave-statements", 0,
433 "Log slow statements executed by slave thread to the slow log if it is open.",
434 &opt_log_slow_slave_statements, &opt_log_slow_slave_statements,
435- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
436+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},*/
437 {"log-slow-queries", OPT_SLOW_QUERY_LOG,
438 "Log slow queries to a table or log file. Defaults logging to table "
439 "mysql.slow_log or hostname-slow.log if --log-output=file is used. "
db82db79 440@@ -7288,6 +7292,10 @@
b4e1fa2c
AM
441
442 C_MODE_END
443
444+/* defined in sys_vars.cc */
445+extern void init_log_slow_verbosity();
a9ee80b9 446+extern void init_slow_query_log_use_global_control();
b4e1fa2c
AM
447+
448 /**
449 Get server options from the command line,
450 and perform related server initializations.
db82db79 451@@ -7437,6 +7445,8 @@
b4e1fa2c
AM
452 global_system_variables.long_query_time= (ulonglong)
453 (global_system_variables.long_query_time_double * 1e6);
454
455+ init_log_slow_verbosity();
a9ee80b9 456+ init_slow_query_log_use_global_control();
b4e1fa2c
AM
457 if (opt_short_log_format)
458 opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
459
db82db79
AM
460--- a/sql/mysqld.h
461+++ b/sql/mysqld.h
b4e1fa2c
AM
462@@ -116,6 +116,10 @@
463 extern char* opt_secure_backup_file_priv;
464 extern size_t opt_secure_backup_file_priv_len;
465 extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements;
466+extern my_bool opt_log_slow_sp_statements;
a9ee80b9
ER
467+extern my_bool opt_slow_query_log_timestamp_always;
468+extern ulonglong opt_slow_query_log_use_global_control;
adf0fb13 469+extern ulong opt_slow_query_log_timestamp_precision;
b4e1fa2c
AM
470 extern my_bool sp_automatic_privileges, opt_noacl;
471 extern my_bool opt_old_style_user_limits, trust_function_creators;
472 extern uint opt_crash_binlog_innodb;
db82db79
AM
473--- a/sql/slave.cc
474+++ b/sql/slave.cc
d8778560 475@@ -2038,6 +2038,7 @@
b4e1fa2c
AM
476 + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */
477 thd->slave_thread = 1;
478 thd->enable_slow_log= opt_log_slow_slave_statements;
479+ thd->write_to_slow_log= opt_log_slow_slave_statements;
480 set_slave_thread_options(thd);
481 thd->client_capabilities = CLIENT_LOCAL_FILES;
482 mysql_mutex_lock(&LOCK_thread_count);
db82db79
AM
483--- a/sql/sp_head.cc
484+++ b/sql/sp_head.cc
485@@ -2152,7 +2152,7 @@
b4e1fa2c
AM
486 DBUG_PRINT("info",(" %.*s: eval args done", (int) m_name.length,
487 m_name.str));
488 }
489- if (!(m_flags & LOG_SLOW_STATEMENTS) && thd->enable_slow_log)
490+ if (!(m_flags & LOG_SLOW_STATEMENTS || opt_log_slow_sp_statements) && thd->enable_slow_log)
491 {
492 DBUG_PRINT("info", ("Disabling slow log for the execution"));
493 save_enable_slow_log= true;
db82db79
AM
494--- a/sql/sql_cache.cc
495+++ b/sql/sql_cache.cc
b4e1fa2c
AM
496@@ -1756,6 +1756,7 @@
497 response, we can't handle it anyway.
498 */
499 (void) trans_commit_stmt(thd);
500+ thd->query_plan_flags|= QPLAN_QC;
501 if (!thd->stmt_da->is_set())
502 thd->stmt_da->disable_status();
503
504@@ -1766,6 +1767,7 @@
505 err_unlock:
506 unlock();
507 err:
508+ thd->query_plan_flags|= QPLAN_QC_NO;
509 MYSQL_QUERY_CACHE_MISS(thd->query());
510 DBUG_RETURN(0); // Query was not cached
511 }
db82db79
AM
512--- a/sql/sql_class.cc
513+++ b/sql/sql_class.cc
514@@ -616,6 +616,37 @@
b4e1fa2c
AM
515 thd->warning_info->inc_current_row_for_warning();
516 }
517
518+extern "C"
519+void increment_thd_innodb_stats(THD* thd,
520+ unsigned long long trx_id,
521+ long io_reads,
522+ long long io_read,
523+ long io_reads_wait_timer,
524+ long lock_que_wait_timer,
525+ long que_wait_timer,
526+ long page_access)
527+{
528+ thd->innodb_was_used = TRUE;
529+ thd->innodb_trx_id = trx_id;
530+ thd->innodb_io_reads += io_reads;
531+ thd->innodb_io_read += io_read;
532+ thd->innodb_io_reads_wait_timer += io_reads_wait_timer;
533+ thd->innodb_lock_que_wait_timer += lock_que_wait_timer;
534+ thd->innodb_innodb_que_wait_timer += que_wait_timer;
535+ thd->innodb_page_access += page_access;
536+}
537+
538+extern "C"
539+unsigned long thd_log_slow_verbosity(const THD *thd)
540+{
541+ return (unsigned long) thd->variables.log_slow_verbosity;
542+}
543+
544+extern "C"
545+int thd_opt_slow_log()
546+{
547+ return (int) opt_slow_log;
548+}
549
550 /**
551 Dumps a text description of a thread, its security context
db82db79 552@@ -912,6 +943,7 @@
b4e1fa2c
AM
553 *cond_hdl= NULL;
554 return FALSE;
555 }
556+ last_errno= sql_errno;
557
558 for (Internal_error_handler *error_handler= m_internal_handler;
559 error_handler;
db82db79 560@@ -3656,6 +3688,12 @@
b4e1fa2c
AM
561 first_successful_insert_id_in_prev_stmt;
562 backup->first_successful_insert_id_in_cur_stmt=
563 first_successful_insert_id_in_cur_stmt;
564+ backup->innodb_io_reads= innodb_io_reads;
565+ backup->innodb_io_read= innodb_io_read;
566+ backup->innodb_io_reads_wait_timer= innodb_io_reads_wait_timer;
567+ backup->innodb_lock_que_wait_timer= innodb_lock_que_wait_timer;
568+ backup->innodb_innodb_que_wait_timer= innodb_innodb_que_wait_timer;
569+ backup->innodb_page_access= innodb_page_access;
570
571 if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
572 !is_current_stmt_binlog_format_row())
db82db79 573@@ -3676,6 +3714,14 @@
b4e1fa2c
AM
574 cuted_fields= 0;
575 transaction.savepoints= 0;
576 first_successful_insert_id_in_cur_stmt= 0;
577+ last_errno= 0;
578+ innodb_trx_id= 0;
579+ innodb_io_reads= 0;
580+ innodb_io_read= 0;
581+ innodb_io_reads_wait_timer= 0;
582+ innodb_lock_que_wait_timer= 0;
583+ innodb_innodb_que_wait_timer= 0;
584+ innodb_page_access= 0;
585 }
586
587
db82db79 588@@ -3738,6 +3784,12 @@
b4e1fa2c
AM
589 */
590 examined_row_count+= backup->examined_row_count;
591 cuted_fields+= backup->cuted_fields;
592+ innodb_io_reads+= backup->innodb_io_reads;
593+ innodb_io_read+= backup->innodb_io_read;
594+ innodb_io_reads_wait_timer+= backup->innodb_io_reads_wait_timer;
595+ innodb_lock_que_wait_timer+= backup->innodb_lock_que_wait_timer;
596+ innodb_innodb_que_wait_timer+= backup->innodb_innodb_que_wait_timer;
597+ innodb_page_access+= backup->innodb_page_access;
598 DBUG_VOID_RETURN;
599 }
600
db82db79
AM
601--- a/sql/sql_class.h
602+++ b/sql/sql_class.h
a9ee80b9 603@@ -60,6 +60,33 @@
b4e1fa2c
AM
604 enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE };
605 enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
606 DELAY_KEY_WRITE_ALL };
a9ee80b9
ER
607+enum enum_slow_query_log_use_global_control {
608+ SLOG_UG_LOG_SLOW_FILTER, SLOG_UG_LOG_SLOW_RATE_LIMIT
609+ , SLOG_UG_LOG_SLOW_VERBOSITY, SLOG_UG_LONG_QUERY_TIME
610+ , SLOG_UG_MIN_EXAMINED_ROW_LIMIT, SLOG_UG_ALL
611+};
b4e1fa2c
AM
612+enum enum_log_slow_verbosity {
613+ SLOG_V_MICROTIME, SLOG_V_QUERY_PLAN, SLOG_V_INNODB,
614+ SLOG_V_PROFILING, SLOG_V_PROFILING_USE_GETRUSAGE,
615+ SLOG_V_MINIMAL, SLOG_V_STANDARD, SLOG_V_FULL
616+};
a9ee80b9
ER
617+enum enum_slow_query_log_timestamp_precision {
618+ SLOG_SECOND, SLOG_MICROSECOND
619+};
b4e1fa2c
AM
620+#define QPLAN_NONE 0
621+#define QPLAN_QC 1 << 0
622+#define QPLAN_QC_NO 1 << 1
623+#define QPLAN_FULL_SCAN 1 << 2
624+#define QPLAN_FULL_JOIN 1 << 3
625+#define QPLAN_TMP_TABLE 1 << 4
626+#define QPLAN_TMP_DISK 1 << 5
627+#define QPLAN_FILESORT 1 << 6
628+#define QPLAN_FILESORT_DISK 1 << 7
629+enum enum_log_slow_filter {
630+ SLOG_F_QC_NO, SLOG_F_FULL_SCAN, SLOG_F_FULL_JOIN,
631+ SLOG_F_TMP_TABLE, SLOG_F_TMP_DISK, SLOG_F_FILESORT,
632+ SLOG_F_FILESORT_DISK
633+};
634 enum enum_slave_exec_mode { SLAVE_EXEC_MODE_STRICT,
635 SLAVE_EXEC_MODE_IDEMPOTENT,
636 SLAVE_EXEC_MODE_LAST_BIT};
a9ee80b9 637@@ -508,6 +535,17 @@
b4e1fa2c
AM
638
639 my_bool sysdate_is_now;
640
641+ ulong log_slow_rate_limit;
642+ ulonglong log_slow_filter;
643+ ulonglong log_slow_verbosity;
644+
645+ ulong innodb_io_reads;
646+ ulonglong innodb_io_read;
647+ ulong innodb_io_reads_wait_timer;
648+ ulong innodb_lock_que_wait_timer;
649+ ulong innodb_innodb_que_wait_timer;
650+ ulong innodb_page_access;
651+
652 double long_query_time_double;
653
654 } SV;
db82db79 655@@ -1140,6 +1178,14 @@
b4e1fa2c
AM
656 uint in_sub_stmt;
657 bool enable_slow_log;
658 bool last_insert_id_used;
659+
660+ ulong innodb_io_reads;
661+ ulonglong innodb_io_read;
662+ ulong innodb_io_reads_wait_timer;
663+ ulong innodb_lock_que_wait_timer;
664+ ulong innodb_innodb_que_wait_timer;
665+ ulong innodb_page_access;
666+
667 SAVEPOINT *savepoints;
668 enum enum_check_fields count_cuted_fields;
669 };
db82db79 670@@ -1588,6 +1634,26 @@
b4e1fa2c
AM
671 thr_lock_type update_lock_default;
672 Delayed_insert *di;
673
674+ bool write_to_slow_log;
675+
676+ ulonglong bytes_sent_old;
677+ ulong tmp_tables_used;
678+ ulong tmp_tables_disk_used;
679+ ulonglong tmp_tables_size;
680+ bool innodb_was_used;
681+ ulonglong innodb_trx_id;
682+ ulong innodb_io_reads;
683+ ulonglong innodb_io_read;
684+ ulong innodb_io_reads_wait_timer;
685+ ulong innodb_lock_que_wait_timer;
686+ ulong innodb_innodb_que_wait_timer;
687+ ulong innodb_page_access;
688+
689+ ulong query_plan_flags;
690+ ulong query_plan_fsort_passes;
691+
692+ uint last_errno;
693+
694 /* <> 0 if we are inside of trigger or stored function. */
695 uint in_sub_stmt;
696
db82db79
AM
697--- a/sql/sql_connect.cc
698+++ b/sql/sql_connect.cc
699@@ -721,6 +721,15 @@
700 MYSQL_CONNECTION_START(thd->thread_id, &thd->security_ctx->priv_user[0],
701 (char *) thd->security_ctx->host_or_ip);
b4e1fa2c
AM
702
703+ /*
704+ If rate limiting of slow log writes is enabled, decide whether to log this
705+ new thread's queries or not. Uses extremely simple algorithm. :)
706+ */
707+ thd->write_to_slow_log= FALSE;
708+ if (thd->variables.log_slow_rate_limit <= 1 ||
709+ (thd->thread_id % thd->variables.log_slow_rate_limit) == 0)
710+ thd->write_to_slow_log= TRUE;
711+
db82db79
AM
712 prepare_new_connection_state(thd);
713 return FALSE;
714 }
715--- a/sql/sql_parse.cc
716+++ b/sql/sql_parse.cc
11822e22 717@@ -1430,7 +1430,6 @@
b4e1fa2c
AM
718 DBUG_RETURN(error);
719 }
720
721-
722 void log_slow_statement(THD *thd)
723 {
724 DBUG_ENTER("log_slow_statement");
11822e22 725@@ -1443,6 +1442,42 @@
b4e1fa2c
AM
726 if (unlikely(thd->in_sub_stmt))
727 DBUG_VOID_RETURN; // Don't set time for sub stmt
728
729+ /* Follow the slow log filter configuration. */
730+ if (thd->variables.log_slow_filter != 0 &&
731+ (!(thd->variables.log_slow_filter & thd->query_plan_flags) ||
732+ ((thd->variables.log_slow_filter & SLOG_F_QC_NO) &&
733+ (thd->query_plan_flags & QPLAN_QC))))
734+ DBUG_VOID_RETURN;
735+
736+ /*
737+ Low long_query_time value most likely means user is debugging stuff and even
738+ though some thread's queries are not supposed to be logged b/c of the rate
739+ limit, if one of them takes long enough (>= 1 second) it will be sensible
740+ to make an exception and write to slow log anyway.
741+ */
742+
743+ ulonglong end_utime_of_query= thd->current_utime();
744+#define USE_GLOBAL_UPDATE(variable_name,enum_value_name) \
a9ee80b9 745+ if (opt_slow_query_log_use_global_control & (ULL(1) << enum_value_name)) \
b4e1fa2c
AM
746+ { \
747+ thd->variables. variable_name= \
748+ global_system_variables. variable_name; \
749+ }
750+ USE_GLOBAL_UPDATE(log_slow_filter,SLOG_UG_LOG_SLOW_FILTER);
751+ USE_GLOBAL_UPDATE(log_slow_rate_limit,SLOG_UG_LOG_SLOW_RATE_LIMIT);
752+ USE_GLOBAL_UPDATE(log_slow_verbosity,SLOG_UG_LOG_SLOW_VERBOSITY);
753+ USE_GLOBAL_UPDATE(long_query_time,SLOG_UG_LONG_QUERY_TIME);
754+ USE_GLOBAL_UPDATE(long_query_time_double,SLOG_UG_LONG_QUERY_TIME);
755+ USE_GLOBAL_UPDATE(min_examined_row_limit,SLOG_UG_MIN_EXAMINED_ROW_LIMIT);
756+#undef USE_GLOBAL_UPDATE
757+
758+ /* Do not log this thread's queries due to rate limiting. */
759+ if (thd->write_to_slow_log != TRUE
760+ && (thd->variables.long_query_time >= 1000000
761+ || (ulong) (end_utime_of_query - thd->utime_after_lock) < 1000000))
762+ DBUG_VOID_RETURN;
763+
764+
765 /*
766 Do not log administrative statements unless the appropriate option is
767 set.
db82db79 768@@ -1879,6 +1914,9 @@
b4e1fa2c
AM
769 context.resolve_in_table_list_only(select_lex->
770 table_list.first);
771
772+ /* Reset the counter at all cases for the extended slow query log */
773+ thd->sent_row_count= 0;
774+
775 /*
776 Reset warning count for each query that uses tables
777 A better approach would be to reset this for any commands
db82db79 778@@ -5297,6 +5335,21 @@
b4e1fa2c
AM
779 thd->rand_used= 0;
780 thd->sent_row_count= thd->examined_row_count= 0;
781
782+ thd->bytes_sent_old= thd->status_var.bytes_sent;
783+ thd->tmp_tables_used= thd->tmp_tables_disk_used= 0;
784+ thd->tmp_tables_size= 0;
785+ thd->innodb_was_used= FALSE;
786+ thd->innodb_trx_id= 0;
787+ thd->innodb_io_reads= 0;
788+ thd->innodb_io_read= 0;
789+ thd->innodb_io_reads_wait_timer= 0;
790+ thd->innodb_lock_que_wait_timer= 0;
791+ thd->innodb_innodb_que_wait_timer= 0;
792+ thd->innodb_page_access= 0;
793+ thd->query_plan_flags= QPLAN_NONE;
794+ thd->query_plan_fsort_passes= 0;
795+ thd->last_errno= 0;
796+
797 thd->reset_current_stmt_binlog_format_row();
798 thd->binlog_unsafe_warning_flags= 0;
799
db82db79
AM
800--- a/sql/sql_select.cc
801+++ b/sql/sql_select.cc
adf0fb13 802@@ -6902,7 +6902,10 @@
b4e1fa2c
AM
803 {
804 join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
805 if (statistics)
806+ {
807 status_var_increment(join->thd->status_var.select_scan_count);
808+ join->thd->query_plan_flags|= QPLAN_FULL_SCAN;
809+ }
810 }
811 }
812 else
adf0fb13 813@@ -6916,7 +6919,10 @@
b4e1fa2c
AM
814 {
815 join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
816 if (statistics)
817+ {
818 status_var_increment(join->thd->status_var.select_full_join_count);
819+ join->thd->query_plan_flags|= QPLAN_FULL_JOIN;
820+ }
821 }
822 }
823 if (!table->no_keyread)
db82db79 824@@ -10264,6 +10270,7 @@
b4e1fa2c
AM
825 (ulong) rows_limit,test(group)));
826
827 status_var_increment(thd->status_var.created_tmp_tables);
828+ thd->query_plan_flags|= QPLAN_TMP_TABLE;
829
830 if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
831 temp_pool_slot = bitmap_lock_set_next(&temp_pool);
db82db79 832@@ -11162,6 +11169,7 @@
b4e1fa2c
AM
833 goto err;
834 }
835 status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
836+ table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
837 share->db_record_offset= 1;
838 DBUG_RETURN(0);
839 err:
db82db79 840@@ -11180,6 +11188,14 @@
b4e1fa2c
AM
841 save_proc_info=thd->proc_info;
842 thd_proc_info(thd, "removing tmp table");
843
844+ thd->tmp_tables_used++;
845+ if (entry->file)
846+ {
847+ thd->tmp_tables_size += entry->file->stats.data_file_length;
848+ if (entry->file->ht->db_type != DB_TYPE_HEAP)
849+ thd->tmp_tables_disk_used++;
850+ }
851+
852 // Release latches since this can take a long time
853 ha_release_temporary_latches(thd);
854
db82db79
AM
855--- a/sql/sql_show.cc
856+++ b/sql/sql_show.cc
adf0fb13 857@@ -1950,8 +1950,17 @@
b4e1fa2c
AM
858 table->field[4]->store(command_name[tmp->command].str,
859 command_name[tmp->command].length, cs);
860 /* MYSQL_TIME */
861- table->field[5]->store((longlong)(tmp->start_time ?
862- now - tmp->start_time : 0), FALSE);
863+ longlong value_in_time_column= 0;
864+ if(tmp->start_time)
865+ {
866+ value_in_time_column = (now - tmp->start_time);
867+ if(value_in_time_column > now)
868+ {
869+ value_in_time_column= 0;
870+ }
871+ }
872+ table->field[5]->store(value_in_time_column, FALSE);
873+
874 /* STATE */
875 if ((val= thread_state_info(tmp)))
876 {
db82db79
AM
877--- a/sql/sys_vars.cc
878+++ b/sql/sys_vars.cc
adf0fb13 879@@ -2898,6 +2898,117 @@
b4e1fa2c
AM
880 DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
881 ON_UPDATE(fix_log_state));
882
883+const char *log_slow_filter_name[]= { "qc_miss", "full_scan", "full_join",
884+ "tmp_table", "tmp_table_on_disk", "filesort", "filesort_on_disk", 0};
885+static Sys_var_set Sys_log_slow_filter(
886+ "log_slow_filter",
887+ "Log only the queries that followed certain execution plan. "
888+ "Multiple flags allowed in a comma-separated string. "
889+ "[qc_miss, full_scan, full_join, tmp_table, tmp_table_on_disk, "
890+ "filesort, filesort_on_disk]",
891+ SESSION_VAR(log_slow_filter), CMD_LINE(REQUIRED_ARG),
892+ log_slow_filter_name, DEFAULT(0));
893+static Sys_var_ulong sys_log_slow_rate_limit(
894+ "log_slow_rate_limit","Rate limit statement writes to slow log to only those from every (1/log_slow_rate_limit) session.",
895+ SESSION_VAR(log_slow_rate_limit), CMD_LINE(REQUIRED_ARG),
896+ VALID_RANGE(1, ULONG_MAX), DEFAULT(1), BLOCK_SIZE(1));
897+const char* log_slow_verbosity_name[] = {
898+ "microtime", "query_plan", "innodb",
899+ "profiling", "profling_use_getrusage",
900+ "minimal", "standard", "full", 0
901+};
902+static ulonglong update_log_slow_verbosity_replace(ulonglong value, ulonglong what, ulonglong by)
903+{
904+ if((value & what) == what)
905+ {
906+ value = value & (~what);
907+ value = value | by;
908+ }
909+ return value;
910+}
911+void update_log_slow_verbosity(ulonglong* value_ptr)
912+{
913+ ulonglong &value = *value_ptr;
914+ ulonglong microtime= ULL(1) << SLOG_V_MICROTIME;
915+ ulonglong query_plan= ULL(1) << SLOG_V_QUERY_PLAN;
916+ ulonglong innodb= ULL(1) << SLOG_V_INNODB;
917+ ulonglong minimal= ULL(1) << SLOG_V_MINIMAL;
918+ ulonglong standard= ULL(1) << SLOG_V_STANDARD;
919+ ulonglong full= ULL(1) << SLOG_V_FULL;
920+ value= update_log_slow_verbosity_replace(value,minimal,microtime);
921+ value= update_log_slow_verbosity_replace(value,standard,microtime | query_plan);
922+ value= update_log_slow_verbosity_replace(value,full,microtime | query_plan | innodb);
923+}
924+static bool update_log_slow_verbosity_helper(sys_var */*self*/, THD *thd,
925+ enum_var_type type)
926+{
927+ if(type == OPT_SESSION)
928+ {
929+ update_log_slow_verbosity(&(thd->variables.log_slow_verbosity));
930+ }
931+ else
932+ {
933+ update_log_slow_verbosity(&(global_system_variables.log_slow_verbosity));
934+ }
935+ return false;
936+}
a9ee80b9 937+void init_slow_query_log_use_global_control()
b4e1fa2c
AM
938+{
939+ update_log_slow_verbosity(&(global_system_variables.log_slow_verbosity));
940+}
941+static Sys_var_set Sys_log_slow_verbosity(
942+ "log_slow_verbosity",
943+ "Choose how verbose the messages to your slow log will be. "
944+ "Multiple flags allowed in a comma-separated string. [microtime, query_plan, innodb, profiling, profiling_use_getrusage]",
945+ SESSION_VAR(log_slow_verbosity), CMD_LINE(REQUIRED_ARG),
946+ log_slow_verbosity_name, DEFAULT(SLOG_V_MICROTIME),
947+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
948+ ON_UPDATE(update_log_slow_verbosity_helper));
949+static Sys_var_mybool Sys_log_slow_slave_statements(
950+ "log_slow_slave_statements",
951+ "Log queries replayed be the slave SQL thread",
952+ GLOBAL_VAR(opt_log_slow_slave_statements), CMD_LINE(OPT_ARG),
953+ DEFAULT(FALSE));
954+static Sys_var_mybool Sys_log_slow_sp_statements(
955+ "log_slow_sp_statements",
956+ "Log slow statements executed by stored procedure to the slow log if it is open.",
957+ GLOBAL_VAR(opt_log_slow_sp_statements), CMD_LINE(OPT_ARG),
958+ DEFAULT(TRUE));
a9ee80b9
ER
959+static Sys_var_mybool Sys_slow_query_log_timestamp_always(
960+ "slow_query_log_timestamp_always",
b4e1fa2c 961+ "Timestamp is printed for all records of the slow log even if they are same time.",
a9ee80b9 962+ GLOBAL_VAR(opt_slow_query_log_timestamp_always), CMD_LINE(OPT_ARG),
b4e1fa2c 963+ DEFAULT(FALSE));
a9ee80b9
ER
964+const char *slow_query_log_use_global_control_name[]= { "log_slow_filter", "log_slow_rate_limit", "log_slow_verbosity", "long_query_time", "min_examined_row_limit", "all", 0};
965+static bool update_slow_query_log_use_global_control(sys_var */*self*/, THD */*thd*/,
b4e1fa2c
AM
966+ enum_var_type /*type*/)
967+{
a9ee80b9 968+ if(opt_slow_query_log_use_global_control & (ULL(1) << SLOG_UG_ALL))
b4e1fa2c 969+ {
a9ee80b9 970+ opt_slow_query_log_use_global_control=
b4e1fa2c
AM
971+ SLOG_UG_LOG_SLOW_FILTER | SLOG_UG_LOG_SLOW_RATE_LIMIT | SLOG_UG_LOG_SLOW_VERBOSITY |
972+ SLOG_UG_LONG_QUERY_TIME | SLOG_UG_MIN_EXAMINED_ROW_LIMIT;
973+ }
974+ return false;
975+}
976+void init_log_slow_verbosity()
977+{
a9ee80b9 978+ update_slow_query_log_use_global_control(0,0,OPT_GLOBAL);
b4e1fa2c 979+}
a9ee80b9
ER
980+static Sys_var_set Sys_slow_query_log_use_global_control(
981+ "slow_query_log_use_global_control",
b4e1fa2c 982+ "Choose flags, wich always use the global variables. Multiple flags allowed in a comma-separated string. [none, log_slow_filter, log_slow_rate_limit, log_slow_verbosity, long_query_time, min_examined_row_limit, all]",
a9ee80b9
ER
983+ GLOBAL_VAR(opt_slow_query_log_use_global_control), CMD_LINE(REQUIRED_ARG),
984+ slow_query_log_use_global_control_name, DEFAULT(0),
b4e1fa2c 985+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
a9ee80b9
ER
986+ ON_UPDATE(update_slow_query_log_use_global_control));
987+const char *slow_query_log_timestamp_precision_name[]= { "second", "microsecond", 0 };
988+static Sys_var_enum Sys_slow_query_log_timestamp_precision(
989+ "slow_query_log_timestamp_precision",
990+ "Log slow statements executed by stored procedure to the slow log if it is open. [second, microsecond]",
991+ GLOBAL_VAR(opt_slow_query_log_timestamp_precision), CMD_LINE(REQUIRED_ARG),
992+ slow_query_log_timestamp_precision_name, DEFAULT(SLOG_SECOND));
b4e1fa2c
AM
993+
994 /* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
995 static Sys_var_mybool Sys_log_slow(
996 "log_slow_queries",
db82db79
AM
997--- a/sql/sql_profile.cc
998+++ b/sql/sql_profile.cc
b4e1fa2c
AM
999@@ -243,7 +243,8 @@
1000 {
1001 time_usecs= (double) my_getsystime() / 10.0; /* 1 sec was 1e7, now is 1e6 */
1002 #ifdef HAVE_GETRUSAGE
1003- getrusage(RUSAGE_SELF, &rusage);
1004+ if ((profile->get_profiling())->enabled_getrusage())
1005+ getrusage(RUSAGE_SELF, &rusage);
1006 #elif defined(_WIN32)
1007 FILETIME ftDummy;
1008 // NOTE: Get{Process|Thread}Times has a granularity of the clock interval,
1009@@ -251,6 +252,19 @@
1010 // measurable by this function.
1011 GetProcessTimes(GetCurrentProcess(), &ftDummy, &ftDummy, &ftKernel, &ftUser);
1012 #endif
1013+
1014+#ifdef HAVE_CLOCK_GETTIME
1015+ struct timespec tp;
1016+
1017+ if (!(clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
1018+ {
1019+ cpu_time_usecs= tp.tv_sec*1000000000.0 + tp.tv_nsec;
1020+ }
1021+ else
1022+#endif
1023+ {
1024+ cpu_time_usecs= 0;
1025+ }
1026 }
1027
1028
1029@@ -366,7 +380,8 @@
1030 finish_current_query();
1031 }
1032
1033- enabled= ((thd->variables.option_bits & OPTION_PROFILING) != 0);
1034+ enabled= ((thd->variables.option_bits & OPTION_PROFILING) != 0) ||
1035+ ((thd->variables.log_slow_verbosity & (ULL(1) << SLOG_V_PROFILING)) != 0);
1036
1037 if (! enabled) DBUG_VOID_RETURN;
1038
1039@@ -404,7 +419,8 @@
1040 status_change("ending", NULL, NULL, 0);
1041
1042 if ((enabled) && /* ON at start? */
1043- ((thd->variables.option_bits & OPTION_PROFILING) != 0) && /* and ON at end? */
1044+ (((thd->variables.option_bits & OPTION_PROFILING) != 0) ||
1045+ ((thd->variables.log_slow_verbosity & (ULL(1) << SLOG_V_PROFILING)) != 0)) && /* and ON at end? */
1046 (current->query_source != NULL) &&
1047 (! current->entries.is_empty()))
1048 {
1049@@ -505,6 +521,118 @@
1050 DBUG_VOID_RETURN;
1051 }
1052
1053+bool PROFILING::enabled_getrusage()
1054+{
1055+ return ((thd->variables.log_slow_verbosity & (ULL(1) << SLOG_V_PROFILING_USE_GETRUSAGE)) != 0);
1056+}
1057+
1058+/**
1059+ For a given profile entry specified by a name and 2 time measurements,
1060+ print its normalized name (i.e. with all spaces replaced with underscores)
1061+ along with its wall clock and CPU time.
1062+*/
1063+
1064+static void my_b_print_status(IO_CACHE *log_file, const char *status,
1065+ PROF_MEASUREMENT *start, PROF_MEASUREMENT *stop)
1066+{
1067+ DBUG_ENTER("my_b_print_status");
1068+ DBUG_ASSERT(log_file != NULL && status != NULL);
1069+ char query_time_buff[22+7];
1070+ const char *tmp;
1071+
1072+ my_b_printf(log_file, "Profile_");
1073+ for (tmp= status; *tmp; tmp++)
1074+ my_b_write_byte(log_file, *tmp == ' ' ? '_' : *tmp);
1075+
1076+ snprintf(query_time_buff, sizeof(query_time_buff), "%.6f",
1077+ (stop->time_usecs - start->time_usecs) / (1000.0 * 1000));
1078+ my_b_printf(log_file, ": %s ", query_time_buff);
1079+
1080+ my_b_printf(log_file, "Profile_");
1081+ for (tmp= status; *tmp; tmp++)
1082+ my_b_write_byte(log_file, *tmp == ' ' ? '_' : *tmp);
1083+ my_b_printf(log_file, "_cpu: ");
1084+
1085+ snprintf(query_time_buff, sizeof(query_time_buff), "%.6f",
1086+ (stop->cpu_time_usecs - start->cpu_time_usecs) /
1087+ (1000.0 * 1000 * 1000));
1088+ my_b_printf(log_file, "%s ", query_time_buff);
1089+
1090+ DBUG_VOID_RETURN;
1091+}
1092+
1093+/**
1094+ Print output for current query to file
1095+*/
1096+
1097+int PROFILING::print_current(IO_CACHE *log_file)
1098+{
1099+ DBUG_ENTER("PROFILING::print_current");
1100+ ulonglong row_number= 0;
1101+
1102+ QUERY_PROFILE *query;
1103+ /* Get current query */
1104+ if (current == NULL)
1105+ {
1106+ DBUG_RETURN(0);
1107+ }
1108+
1109+ query= current;
1110+
1111+ my_b_printf(log_file, "# ");
1112+
1113+ void *entry_iterator;
1114+ PROF_MEASUREMENT *entry= NULL, *previous= NULL, *first= NULL;
1115+ /* ...and for each query, go through all its state-change steps. */
1116+ for (entry_iterator= query->entries.new_iterator();
1117+ entry_iterator != NULL;
1118+ entry_iterator= query->entries.iterator_next(entry_iterator),
1119+ previous=entry, row_number++)
1120+ {
1121+ entry= query->entries.iterator_value(entry_iterator);
1122+
1123+ /* Skip the first. We count spans of fence, not fence-posts. */
1124+ if (previous == NULL) {first= entry; continue;}
1125+
1126+ if (thd->lex->sql_command == SQLCOM_SHOW_PROFILE)
1127+ {
1128+ /*
1129+ We got here via a SHOW command. That means that we stored
1130+ information about the query we wish to show and that isn't
1131+ in a WHERE clause at a higher level to filter out rows we
1132+ wish to exclude.
1133+
1134+ Because that functionality isn't available in the server yet,
1135+ we must filter here, at the wrong level. Once one can con-
1136+ struct where and having conditions at the SQL layer, then this
1137+ condition should be ripped out.
1138+ */
1139+ if (thd->lex->profile_query_id == 0) /* 0 == show final query */
1140+ {
1141+ if (query != last)
1142+ continue;
1143+ }
1144+ else
1145+ {
1146+ if (thd->lex->profile_query_id != query->profiling_query_id)
1147+ continue;
1148+ }
1149+ }
1150+
1151+ my_b_print_status(log_file, previous->status, previous, entry);
1152+ }
1153+
1154+ my_b_write_byte(log_file, '\n');
1155+ if ((entry != NULL) && (first != NULL))
1156+ {
1157+ my_b_printf(log_file, "# ");
1158+ my_b_print_status(log_file, "total", first, entry);
1159+ my_b_write_byte(log_file, '\n');
1160+ }
1161+
1162+ DBUG_RETURN(0);
1163+}
1164+
1165 /**
1166 Fill the information schema table, "query_profile", as defined in show.cc .
1167 There are two ways to get to this function: Selecting from the information
adf0fb13
AM
1168@@ -600,6 +728,8 @@
1169
1170 #ifdef HAVE_GETRUSAGE
1171
1172+ if (enabled_getrusage())
1173+ {
1174 my_decimal cpu_utime_decimal, cpu_stime_decimal;
1175
1176 double2my_decimal(E_DEC_FATAL_ERROR,
1177@@ -687,6 +817,7 @@
1178 table->field[14]->store((uint32)(entry->rusage.ru_nswap -
1179 previous->rusage.ru_nswap), true);
1180 table->field[14]->set_notnull();
1181+ }
1182 #else
1183 /* TODO: Add swap info for non-BSD systems */
1184 #endif
db82db79
AM
1185--- a/sql/sql_profile.h
1186+++ b/sql/sql_profile.h
b4e1fa2c
AM
1187@@ -164,11 +164,15 @@
1188 */
1189 class PROF_MEASUREMENT
1190 {
1191-private:
1192- friend class QUERY_PROFILE;
1193- friend class PROFILING;
1194-
1195 QUERY_PROFILE *profile;
1196+
1197+ char *allocated_status_memory;
1198+
1199+ void set_label(const char *status_arg, const char *function_arg,
1200+ const char *file_arg, unsigned int line_arg);
1201+ void clean_up();
1202+
1203+public:
1204 char *status;
1205 #ifdef HAVE_GETRUSAGE
1206 struct rusage rusage;
1207@@ -181,12 +185,7 @@
1208 unsigned int line;
1209
1210 double time_usecs;
1211- char *allocated_status_memory;
1212-
1213- void set_label(const char *status_arg, const char *function_arg,
1214- const char *file_arg, unsigned int line_arg);
1215- void clean_up();
1216-
1217+ double cpu_time_usecs;
1218 PROF_MEASUREMENT();
1219 PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg);
1220 PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg,
1221@@ -231,6 +230,11 @@
1222
1223 /* Show this profile. This is called by PROFILING. */
1224 bool show(uint options);
1225+
1226+public:
1227+
1228+ inline PROFILING * get_profiling() { return profiling; };
1229+
1230 };
1231
1232
1233@@ -276,9 +280,11 @@
1234
1235 /* SHOW PROFILES */
1236 bool show_profiles();
1237+ bool enabled_getrusage();
1238
1239 /* ... from INFORMATION_SCHEMA.PROFILING ... */
1240 int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
1241+ int print_current(IO_CACHE *log_file);
1242 };
1243
1244 # endif /* HAVE_PROFILING */
This page took 0.233625 seconds and 4 git commands to generate.