49
49
{ "RANGE", SYM(RANGE_SYM)},
50
50
{ "READ", SYM(READ_SYM)},
51
51
diff -Nur a/sql/Makefile.am b/sql/Makefile.am
52
--- a/sql/Makefile.am 2010-08-10 15:32:19.556992443 +0400
53
+++ b/sql/Makefile.am 2010-08-10 15:32:20.088242513 +0400
52
--- a/sql/Makefile.am 2010-09-14 20:27:51.000000000 +0000
53
+++ b/sql/Makefile.am 2010-09-14 20:31:41.000000000 +0000
55
55
sql_repl.h slave.h rpl_filter.h rpl_injector.h \
56
56
log_event.h rpl_record.h \
119
119
#ifdef HAVE_SYS_PRCTL_H
120
120
#include <sys/prctl.h>
123
123
my_bool opt_query_cache_strip_comments = 0;
124
124
my_bool opt_use_global_long_query_time= 0;
125
125
my_bool opt_slow_query_log_microseconds_timestamp= 0;
126
+ulong opt_query_response_time_range_base = QUERY_RESPONSE_TIME_DEFAULT_BASE;
126
+ulong opt_query_response_time_range_base = QRT_DEFAULT_BASE;
127
127
+my_bool opt_enable_query_response_time_stats= 0;
128
128
my_bool lower_case_file_system= 0;
129
129
my_bool opt_large_pages= 0;
130
130
my_bool opt_myisam_use_mmap= 0;
131
@@ -1382,6 +1386,7 @@
131
@@ -1382,6 +1395,7 @@
132
132
free_global_thread_stats();
133
133
free_global_table_stats();
134
134
free_global_index_stats();
145
145
/* We have to initialize the storage engines before CSV logging */
147
@@ -5895,6 +5901,8 @@
147
@@ -5895,6 +6003,8 @@
148
148
OPT_USE_GLOBAL_LONG_QUERY_TIME,
149
149
OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
150
150
OPT_SLOW_QUERY_LOG_MICROSECONDS_TIMESTAMP,
151
+ OPT_QUERY_RESPONSE_TIME_RANGE_BASE,
152
+ OPT_ENABLE_QUERY_RESPONSE_TIME_STATS,
151
+ OPT_QRT_RANGE_BASE,
152
+ OPT_ENABLE_QRT_STATS,
153
153
OPT_IGNORE_BUILTIN_INNODB,
154
154
OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
155
155
OPT_DEFAULT_CHARACTER_SET_OLD
156
@@ -6964,6 +6972,21 @@
156
@@ -6964,6 +7074,21 @@
157
157
"Use microsecond time's precision in slow query log",
158
158
(uchar**) &opt_slow_query_log_microseconds_timestamp, (uchar**) &opt_slow_query_log_microseconds_timestamp,
159
159
0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
160
+ {"query_response_time_range_base", OPT_QUERY_RESPONSE_TIME_RANGE_BASE,
160
+ {"query_response_time_range_base", OPT_QRT_RANGE_BASE,
161
161
+ "Select base of log for query_response_time ranges. WARNING: variable change affect only after flush",
162
162
+ (uchar**) &opt_query_response_time_range_base, (uchar**) &opt_query_response_time_range_base,
163
163
+ 0, GET_ULONG, REQUIRED_ARG,
164
+ /* def_value */ QUERY_RESPONSE_TIME_DEFAULT_BASE,
164
+ /* def_value */ QRT_DEFAULT_BASE,
165
165
+ /* min_value */ 2,
166
+ /* max_value */ QUERY_RESPONSE_TIME_MAXIMUM_BASE,
166
+ /* max_value */ QRT_MAXIMUM_BASE,
167
167
+ /* sub_size */ 0,
168
168
+ /* block_size */ 1,
169
169
+ /* app_type */ 0
171
+ {"enable_query_response_time_stats", OPT_ENABLE_QUERY_RESPONSE_TIME_STATS,
171
+ {"enable_query_response_time_stats", OPT_ENABLE_QRT_STATS,
172
172
+ "Enable or disable query response time statisics collecting",
173
173
+ (uchar**) &opt_enable_query_response_time_stats, (uchar**) &opt_enable_query_response_time_stats,
174
174
+ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
188
188
extern my_bool opt_old_style_user_limits, trust_function_creators;
189
189
extern uint opt_crash_binlog_innodb;
190
190
diff -Nur a/sql/query_response_time.cc b/sql/query_response_time.cc
191
--- a/sql/query_response_time.cc 1970-01-01 03:00:00.000000000 +0300
192
+++ b/sql/query_response_time.cc 2010-08-10 15:32:20.098240993 +0400
191
--- a/sql/query_response_time.cc 1970-01-01 00:00:00.000000000 +0000
192
+++ b/sql/query_response_time.cc 2010-09-14 20:32:15.000000000 +0000
194
194
+#include "my_global.h"
195
195
+#include "mysql_priv.h"
196
196
+#include "mysql_com.h"
197
197
+#include "rpl_tblmap.h"
198
+#include "my_atomic.h"
199
198
+#include "query_response_time.h"
201
+#define STRING_POSITIVE_POWER_LENGTH QUERY_RESPONSE_TIME_STRING_POSITIVE_POWER_LENGTH
202
+#define STRING_NEGATIVE_POWER_LENGTH 6
200
+#define TIME_STRING_POSITIVE_POWER_LENGTH QRT_TIME_STRING_POSITIVE_POWER_LENGTH
201
+#define TIME_STRING_NEGATIVE_POWER_LENGTH 6
202
+#define TOTAL_STRING_POSITIVE_POWER_LENGTH QRT_TOTAL_STRING_POSITIVE_POWER_LENGTH
203
+#define TOTAL_STRING_NEGATIVE_POWER_LENGTH 6
203
204
+#define MINIMUM_BASE 2
204
+#define MAXIMUM_BASE QUERY_RESPONSE_TIME_MAXIMUM_BASE
205
+#define POSITIVE_POWER_FILLER QUERY_RESPONSE_TIME_POSITIVE_POWER_FILLER
206
+#define NEGATIVE_POWER_FILLER QUERY_RESPONSE_TIME_NEGATIVE_POWER_FILLER
207
+#define STRING_OVERFLOW QUERY_RESPONSE_TIME_STRING_OVERFLOW
208
+#define TIME_OVERFLOW QUERY_RESPONSE_TIME_TIME_OVERFLOW
209
+#define DEFAULT_BASE QUERY_RESPONSE_TIME_DEFAULT_BASE
205
+#define MAXIMUM_BASE QRT_MAXIMUM_BASE
206
+#define POSITIVE_POWER_FILLER QRT_POSITIVE_POWER_FILLER
207
+#define NEGATIVE_POWER_FILLER QRT_NEGATIVE_POWER_FILLER
208
+#define STRING_OVERFLOW QRT_STRING_OVERFLOW
209
+#define TIME_OVERFLOW QRT_TIME_OVERFLOW
210
+#define DEFAULT_BASE QRT_DEFAULT_BASE
211
212
+#define do_xstr(s) do_str(s)
212
213
+#define do_str(s) #s
213
214
+#define do_format(filler,width) "%" filler width "lld"
215
216
+ Format strings for snprintf. Generate from:
216
+ POSITIVE_POWER_FILLER and STRING_POSITIVE_POWER_LENGTH
217
+ NEFATIVE_POWER_FILLER and STRING_NEGATIVE_POWER_LENGTH
217
+ POSITIVE_POWER_FILLER and TIME_STRING_POSITIVE_POWER_LENGTH
218
+ NEFATIVE_POWER_FILLER and TIME_STRING_NEGATIVE_POWER_LENGTH
219
+#define STRING_POSITIVE_POWER_FORMAT do_format(POSITIVE_POWER_FILLER,do_xstr(STRING_POSITIVE_POWER_LENGTH))
220
+#define STRING_NEGATIVE_POWER_FORMAT do_format(NEGATIVE_POWER_FILLER,do_xstr(STRING_NEGATIVE_POWER_LENGTH))
221
+#define STRING_FORMAT STRING_POSITIVE_POWER_FORMAT "." STRING_NEGATIVE_POWER_FORMAT
224
+#define STRING_LENGTH QUERY_RESPONSE_TIME_STRING_LENGTH
225
+#define STRING_BUFFER_LENGTH (STRING_LENGTH + 1 /* '\0' */)
220
+#define TIME_STRING_POSITIVE_POWER_FORMAT do_format(POSITIVE_POWER_FILLER,do_xstr(TIME_STRING_POSITIVE_POWER_LENGTH))
221
+#define TIME_STRING_NEGATIVE_POWER_FORMAT do_format(NEGATIVE_POWER_FILLER,do_xstr(TIME_STRING_NEGATIVE_POWER_LENGTH))
222
+#define TIME_STRING_FORMAT TIME_STRING_POSITIVE_POWER_FORMAT "." TIME_STRING_NEGATIVE_POWER_FORMAT
224
+#define TOTAL_STRING_POSITIVE_POWER_FORMAT do_format(POSITIVE_POWER_FILLER,do_xstr(TOTAL_STRING_POSITIVE_POWER_LENGTH))
225
+#define TOTAL_STRING_NEGATIVE_POWER_FORMAT do_format(NEGATIVE_POWER_FILLER,do_xstr(TOTAL_STRING_NEGATIVE_POWER_LENGTH))
226
+#define TOTAL_STRING_FORMAT TOTAL_STRING_POSITIVE_POWER_FORMAT "." TOTAL_STRING_NEGATIVE_POWER_FORMAT
228
+#define TIME_STRING_LENGTH QRT_TIME_STRING_LENGTH
229
+#define TIME_STRING_BUFFER_LENGTH (TIME_STRING_LENGTH + 1 /* '\0' */)
231
+#define TOTAL_STRING_LENGTH QRT_TOTAL_STRING_LENGTH
232
+#define TOTAL_STRING_BUFFER_LENGTH (TOTAL_STRING_LENGTH + 1 /* '\0' */)
228
235
+ Calculate length of "log linear"
314
322
+ uint m_negative_count;
315
323
+ uint m_positive_count;
316
324
+ uint m_bound_count;
317
+ ulonglong m_max_dec_value; /* for STRING_POSITIVE_POWER_LENGTH=7 is 10000000 */
325
+ ulonglong m_max_dec_value; /* for TIME_STRING_POSITIVE_POWER_LENGTH=7 is 10000000 */
318
326
+ ulonglong m_bound[OVERALL_POWER_COUNT];
321
+class string_collector
329
+void print_time(char* buffer, std::size_t buffer_size, std::size_t string_positive_power_length, const char* format, uint64 value)
324
+ typedef char string_type[STRING_BUFFER_LENGTH];
326
+ string_collector(utility& u) : m_base(0), m_utility(0)
328
+ memset((char*)m_nothing,'X',STRING_BUFFER_LENGTH);
329
+ m_nothing[STRING_POSITIVE_POWER_LENGTH]= '.';
330
+ m_nothing[STRING_LENGTH]= '\0';
334
+ const char* string(uint index) const { return m_bound[ index ]; }
336
+ void setup(utility& u)
338
+ if(m_base != u.base())
341
+ m_base= m_utility->base();
342
+ const ulonglong million= 1000 * 1000;
343
+ for(int i= 0; OVERALL_POWER_COUNT + 1 > i; ++i)
345
+ memcpy((char*)m_bound[i],(char*)m_nothing,STRING_BUFFER_LENGTH);
348
+ for(int i= 0, count= m_utility->bound_count(); i < count; ++i)
350
+ longlong value = (longlong)m_utility->bound(i);
351
+ char* result = (char*)m_bound[i];
352
+ if(0 > snprintf(result,STRING_BUFFER_LENGTH,STRING_FORMAT,(value / million),(value % million)))
355
+ memcpy(result,STRING_OVERFLOW,sizeof(STRING_OVERFLOW));
358
+ memcpy((char*)(m_bound[m_utility->bound_count()]),TIME_OVERFLOW,sizeof(TIME_OVERFLOW));
363
+ utility* m_utility;
364
+ string_type m_bound[OVERALL_POWER_COUNT + 1];
365
+ string_type m_nothing;
331
+ memset(buffer,'X',buffer_size);
332
+ buffer[string_positive_power_length]= '.';
333
+ ulonglong second= (value / MILLION);
334
+ ulonglong microsecond= (value % MILLION);
335
+ std::size_t result_length= snprintf(buffer,buffer_size,format,second,microsecond);
336
+ if(result_length < 0)
338
+ assert(sizeof(STRING_OVERFLOW) <= buffer_size);
339
+ memcpy(buffer, STRING_OVERFLOW, sizeof(STRING_OVERFLOW));
342
+ buffer[result_length]= 0;
368
344
+class time_collector
371
347
+ time_collector(utility& u) : m_utility(&u)
374
+ uint32 count(uint index) { return m_count[index]; }
350
+ uint32 count(uint index) const { return m_count[index]; }
351
+ uint64 total(uint index) const { return m_total[index]; }
378
355
+ memset(&m_count,0,sizeof(m_count));
356
+ memset(&m_total,0,sizeof(m_total));
380
+ void collect(ulonglong time)
358
+ void collect(uint64 time)
383
361
+ for(int count= m_utility->bound_count(); count > i; ++i)
385
363
+ if(m_utility->bound(i) > time)
387
+ my_atomic_add32((int32*)(&(m_count[i])),1);
365
+ __sync_fetch_and_add(&(m_count[i]),(uint32)1);
366
+ __sync_fetch_and_add(&(m_total[i]),time);
393
372
+ utility* m_utility;
395
373
+ uint32 m_count[OVERALL_POWER_COUNT + 1];
374
+ uint64 m_total[OVERALL_POWER_COUNT + 1];
401
+ collector() : m_string(m_utility), m_time(m_utility)
380
+ collector() : m_time(m_utility)
403
382
+ m_utility.setup(DEFAULT_BASE);
404
+ m_string.setup(m_utility);
405
383
+ m_time.flush();
410
388
+ m_utility.setup(opt_query_response_time_range_base);
411
+ m_string.setup(m_utility);
412
389
+ m_time.flush();
414
391
+ int fill(THD* thd, TABLE_LIST *tables, COND *cond)
418
395
+ Field **fields= table->field;
419
396
+ for(int i= 0, count= bound_count() + 1 /* with overflow */; count > i; ++i)
421
+ const char* time= this->string(i);
422
+ const uint32 count= this->count(i);
398
+ char time[TIME_STRING_BUFFER_LENGTH];
399
+ char total[TOTAL_STRING_BUFFER_LENGTH];
400
+ if(i == bound_count())
402
+ assert(sizeof(TIME_OVERFLOW) <= TIME_STRING_BUFFER_LENGTH);
403
+ assert(sizeof(TIME_OVERFLOW) <= TOTAL_STRING_BUFFER_LENGTH);
404
+ memcpy(time,TIME_OVERFLOW,sizeof(TIME_OVERFLOW));
405
+ memcpy(total,TIME_OVERFLOW,sizeof(TIME_OVERFLOW));
409
+ print_time(time,sizeof(time),TIME_STRING_POSITIVE_POWER_LENGTH,TIME_STRING_FORMAT,this->bound(i));
410
+ print_time(total,sizeof(total),TOTAL_STRING_POSITIVE_POWER_LENGTH,TOTAL_STRING_FORMAT,this->total(i));
423
412
+ fields[0]->store(time,strlen(time),system_charset_info);
424
+ fields[1]->store(count);
413
+ fields[1]->store(this->count(i));
414
+ fields[2]->store(total,strlen(total),system_charset_info);
425
415
+ if (schema_table_store_record(thd, table))
427
417
+ DBUG_RETURN(1);
492
+ Maximum string length for (10 ^ (-1 * QUERY_RESPONSE_TIME_STRING_NEGATIVE_POWER_LENGTH)) in text representation.
485
+ Maximum string length for (10 ^ (-1 * QRT_STRING_NEGATIVE_POWER_LENGTH)) in text representation.
493
486
+ Example: for 6 is 0.000001
496
+ Maximum string length for (10 ^ (QUERY_RESPONSE_TIME_STRING_POSITIVE_POWER_LENGTH + 1) - 1) in text representation.
489
+ Maximum string length for (10 ^ (QRT_STRING_POSITIVE_POWER_LENGTH + 1) - 1) in text representation.
497
490
+ Example: for 7 is 9999999.0
499
+#define QUERY_RESPONSE_TIME_STRING_POSITIVE_POWER_LENGTH 7
492
+#define QRT_TIME_STRING_POSITIVE_POWER_LENGTH 7
493
+#define QRT_TOTAL_STRING_POSITIVE_POWER_LENGTH 7
502
496
+ Minimum base for log - ALWAYS 2
503
497
+ Maximum base for log:
505
+#define QUERY_RESPONSE_TIME_MAXIMUM_BASE 1000
499
+#define QRT_MAXIMUM_BASE 1000
508
502
+ Filler for whole number (positive power)
510
+ QUERY_RESPONSE_TIME_POSITIVE_POWER_FILLER ' '
511
+ QUERY_RESPONSE_TIME_POSITIVE_POWER_LENGTH 7
504
+ QRT_POSITIVE_POWER_FILLER ' '
505
+ QRT_POSITIVE_POWER_LENGTH 7
512
506
+ and number 7234 result is:
515
+#define QUERY_RESPONSE_TIME_POSITIVE_POWER_FILLER " "
509
+#define QRT_POSITIVE_POWER_FILLER " "
517
511
+ Filler for fractional number. Similiary to whole number
519
+#define QUERY_RESPONSE_TIME_NEGATIVE_POWER_FILLER "0"
513
+#define QRT_NEGATIVE_POWER_FILLER "0"
522
+ Message if string overflow (string overflow - internal error, this string say about bug in QUERY_RESPONSE_TIME)
516
+ Message if string overflow (string overflow - internal error, this string say about bug in QRT)
524
+#define QUERY_RESPONSE_TIME_STRING_OVERFLOW "TOO BIG STRING"
518
+#define QRT_STRING_OVERFLOW "TOO BIG STRING"
527
521
+ Message if time too big for statistic collecting (very long query)
529
+#define QUERY_RESPONSE_TIME_TIME_OVERFLOW "TOO LONG QUERY"
531
+#define QUERY_RESPONSE_TIME_DEFAULT_BASE 10
533
+#define QUERY_RESPONSE_TIME_STRING_LENGTH \
534
+ max( (QUERY_RESPONSE_TIME_STRING_POSITIVE_POWER_LENGTH + 1 /* '.' */ + 2 /*QUERY_RESPONSE_TIME_STRING_NEGATIVE_POWER_LENGTH*/), \
535
+ max( (sizeof(QUERY_RESPONSE_TIME_TIME_OVERFLOW) - 1), \
536
+ (sizeof(QUERY_RESPONSE_TIME_STRING_OVERFLOW) - 1) ) )
523
+#define QRT_TIME_OVERFLOW "TOO LONG"
525
+#define QRT_DEFAULT_BASE 10
527
+#define QRT_TIME_STRING_LENGTH \
528
+ max( (QRT_TIME_STRING_POSITIVE_POWER_LENGTH + 1 /* '.' */ + 6 /*QRT_TIME_STRING_NEGATIVE_POWER_LENGTH*/), \
529
+ max( (sizeof(QRT_TIME_OVERFLOW) - 1), \
530
+ (sizeof(QRT_STRING_OVERFLOW) - 1) ) )
532
+#define QRT_TOTAL_STRING_LENGTH \
533
+ max( (QRT_TOTAL_STRING_POSITIVE_POWER_LENGTH + 1 /* '.' */ + 6 /*QRT_TOTAL_STRING_NEGATIVE_POWER_LENGTH*/), \
534
+ max( (sizeof(QRT_TIME_OVERFLOW) - 1), \
535
+ (sizeof(QRT_STRING_OVERFLOW) - 1) ) )
538
537
+extern ST_SCHEMA_TABLE query_response_time_table;
645
644
#include "debug_sync.h"
647
646
#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
648
@@ -7467,6 +7468,13 @@
647
@@ -7467,6 +7468,14 @@
652
651
+ST_FIELD_INFO query_response_time_fields_info[] =
654
+ {"time", QUERY_RESPONSE_TIME_STRING_LENGTH, MYSQL_TYPE_STRING, 0, 0, "", SKIP_OPEN_TABLE },
655
+ {"count", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, MY_I_S_UNSIGNED, "", SKIP_OPEN_TABLE },
656
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE }
653
+ {"time", QRT_TIME_STRING_LENGTH, MYSQL_TYPE_STRING, 0, 0, "", SKIP_OPEN_TABLE },
654
+ {"count", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, MY_I_S_UNSIGNED, "", SKIP_OPEN_TABLE },
655
+ {"total", QRT_TIME_STRING_LENGTH, MYSQL_TYPE_STRING, 0, 0, "", SKIP_OPEN_TABLE },
656
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE }
659
659
ST_SCHEMA_TABLE schema_tables[]=
661
661
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
662
@@ -7521,6 +7529,8 @@
662
@@ -7521,6 +7530,8 @@
663
663
1, 9, 0, OPEN_TABLE_ONLY},
664
664
{"ROUTINES", proc_fields_info, create_schema_table,
665
665
fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0},
669
669
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
670
670
{"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
671
671
diff -Nur a/sql/sql_yacc.yy b/sql/sql_yacc.yy
672
--- a/sql/sql_yacc.yy 2010-08-10 15:32:19.566991761 +0400
673
+++ b/sql/sql_yacc.yy 2010-08-10 15:32:20.108241429 +0400
672
--- a/sql/sql_yacc.yy 2010-09-14 20:27:52.000000000 +0000
673
+++ b/sql/sql_yacc.yy 2010-09-14 20:31:41.000000000 +0000
674
674
@@ -1079,6 +1079,7 @@
676
676
%token QUARTER_SYM