~percona-dev/percona-server/release-5.1.51-12-bug_fix_658274

« back to all changes in this revision

Viewing changes to response-time-distribution.patch

  • Committer: Oleg Tsarev
  • Date: 2010-09-18 13:42:37 UTC
  • mfrom: (108.1.3 percona-server)
  • Revision ID: oleg.tsarev@percona.com-20100918134237-8hntlno9k9eaypob
propogate feature response-time-distribuion (2.0)

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
# Any small change to this file in the main branch
7
7
# should be done or reviewed by the maintainer!
8
8
diff -Nur a/include/mysql_com.h b/include/mysql_com.h
9
 
--- a/include/mysql_com.h       2010-08-10 15:32:19.546992007 +0400
10
 
+++ b/include/mysql_com.h       2010-08-10 15:32:20.088242513 +0400
 
9
--- a/include/mysql_com.h       2010-09-14 20:27:52.000000000 +0000
 
10
+++ b/include/mysql_com.h       2010-09-14 20:31:41.000000000 +0000
11
11
@@ -128,10 +128,11 @@
12
12
 #define REFRESH_FAST           32768   /* Intern flag */
13
13
 
25
25
 #define CLIENT_LONG_PASSWORD   1       /* new more secure passwords */
26
26
 #define CLIENT_FOUND_ROWS      2       /* Found instead of affected rows */
27
27
diff -Nur a/patch_info/response-time-distribution.info b/patch_info/response-time-distribution.info
28
 
--- a/patch_info/response-time-distribution.info        1970-01-01 03:00:00.000000000 +0300
29
 
+++ b/patch_info/response-time-distribution.info        2010-08-10 15:32:20.088242513 +0400
 
28
--- a/patch_info/response-time-distribution.info        1970-01-01 00:00:00.000000000 +0000
 
29
+++ b/patch_info/response-time-distribution.info        2010-09-14 20:31:41.000000000 +0000
30
30
@@ -0,0 +1,9 @@
31
31
+File=response-time-distribution.patch
32
32
+Name=Response time distribution
35
35
+License=GPL
36
36
+Comment=
37
37
+Changelog
38
 
+2010-07-02
39
 
+First version avaliable
 
38
+2010-07-02 first version avaliable
 
39
+2010-09-15 add column 'total'
40
40
diff -Nur a/sql/lex.h b/sql/lex.h
41
 
--- a/sql/lex.h 2010-08-10 15:32:19.566991761 +0400
42
 
+++ b/sql/lex.h 2010-08-10 15:32:20.088242513 +0400
 
41
--- a/sql/lex.h 2010-09-14 20:27:52.000000000 +0000
 
42
+++ b/sql/lex.h 2010-09-14 20:31:41.000000000 +0000
43
43
@@ -415,6 +415,7 @@
44
44
   { "PURGE",           SYM(PURGE)},
45
45
   { "QUARTER",          SYM(QUARTER_SYM)},
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
54
54
@@ -67,7 +67,7 @@
55
55
                        sql_repl.h slave.h rpl_filter.h rpl_injector.h \
56
56
                        log_event.h rpl_record.h \
70
70
                        sql_profile.cc \
71
71
                        sql_prepare.cc sql_error.cc sql_locale.cc \
72
72
diff -Nur a/sql/Makefile.in b/sql/Makefile.in
73
 
--- a/sql/Makefile.in   2010-08-10 15:32:19.566991761 +0400
74
 
+++ b/sql/Makefile.in   2010-08-10 15:32:20.088242513 +0400
 
73
--- a/sql/Makefile.in   2010-09-14 20:27:51.000000000 +0000
 
74
+++ b/sql/Makefile.in   2010-09-14 20:31:41.000000000 +0000
75
75
@@ -122,7 +122,7 @@
76
76
        sql_string.$(OBJEXT) sql_manager.$(OBJEXT) sql_map.$(OBJEXT) \
77
77
        mysqld.$(OBJEXT) password.$(OBJEXT) hash_filo.$(OBJEXT) \
108
108
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repl_failsafe.Po@am__quote@
109
109
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpl_filter.Po@am__quote@
110
110
diff -Nur a/sql/mysqld.cc b/sql/mysqld.cc
111
 
--- a/sql/mysqld.cc     2010-08-10 15:32:19.556992443 +0400
112
 
+++ b/sql/mysqld.cc     2010-08-10 15:32:20.098240993 +0400
 
111
--- a/sql/mysqld.cc     2010-09-14 20:27:52.000000000 +0000
 
112
+++ b/sql/mysqld.cc     2010-09-14 20:32:15.000000000 +0000
113
113
@@ -32,6 +32,8 @@
114
114
 
115
115
 #include "rpl_injector.h"
119
119
 #ifdef HAVE_SYS_PRCTL_H
120
120
 #include <sys/prctl.h>
121
121
 #endif
122
 
@@ -527,6 +529,8 @@
 
122
@@ -527,6 +533,8 @@
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();
136
136
 #ifdef HAVE_REPLICATION
137
137
   end_slave_list();
138
138
 #endif
139
 
@@ -4082,6 +4087,7 @@
 
139
@@ -4082,6 +4096,7 @@
140
140
 
141
141
   init_global_table_stats();
142
142
   init_global_index_stats();
144
144
 
145
145
   /* We have to initialize the storage engines before CSV logging */
146
146
   if (ha_init())
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
170
170
+  },
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},
176
176
    "If set to 1, table names are stored in lowercase on disk and table names "
177
177
    "will be case-insensitive.  Should be set to 2 if you are using a case-"
178
178
diff -Nur a/sql/mysql_priv.h b/sql/mysql_priv.h
179
 
--- a/sql/mysql_priv.h  2010-08-10 15:32:19.566991761 +0400
180
 
+++ b/sql/mysql_priv.h  2010-08-10 15:32:20.098240993 +0400
 
179
--- a/sql/mysql_priv.h  2010-09-14 20:27:52.000000000 +0000
 
180
+++ b/sql/mysql_priv.h  2010-09-14 20:31:41.000000000 +0000
181
181
@@ -2090,6 +2090,8 @@
182
182
 extern my_bool opt_query_cache_strip_comments;
183
183
 extern my_bool opt_use_global_long_query_time;
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
193
 
@@ -0,0 +1,286 @@
 
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
 
193
@@ -0,0 +1,279 @@
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"
200
199
+
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
210
211
+
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"
214
215
+/*
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
218
219
+*/
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
222
 
+
223
 
+
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
 
223
+
 
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
 
227
+
 
228
+#define TIME_STRING_LENGTH     QRT_TIME_STRING_LENGTH
 
229
+#define TIME_STRING_BUFFER_LENGTH      (TIME_STRING_LENGTH + 1 /* '\0' */)
 
230
+
 
231
+#define TOTAL_STRING_LENGTH    QRT_TOTAL_STRING_LENGTH
 
232
+#define TOTAL_STRING_BUFFER_LENGTH     (TOTAL_STRING_LENGTH + 1 /* '\0' */)
226
233
+
227
234
+/*
228
235
+  Calculate length of "log linear"
244
251
+
245
252
+  Last counter always use for time overflow
246
253
+*/
247
 
+#define POSITIVE_POWER_COUNT ((int)(3.32192809 * STRING_POSITIVE_POWER_LENGTH))
248
 
+#define NEGATIVE_POWER_COUNT ((int)(3.32192809 * STRING_NEGATIVE_POWER_LENGTH))
 
254
+#define POSITIVE_POWER_COUNT ((int)(3.32192809 * TIME_STRING_POSITIVE_POWER_LENGTH))
 
255
+#define NEGATIVE_POWER_COUNT ((int)(3.32192809 * TIME_STRING_NEGATIVE_POWER_LENGTH))
249
256
+#define OVERALL_POWER_COUNT (NEGATIVE_POWER_COUNT + 1 + POSITIVE_POWER_COUNT)
250
257
+
 
258
+#define MILLION ((unsigned long)1000 * 1000)
 
259
+
251
260
+namespace query_response_time
252
261
+{
253
262
+
256
265
+public:
257
266
+  utility() : m_base(0)
258
267
+  {
259
 
+    const ulonglong million= 1000 * 1000;
260
 
+    m_max_dec_value= million;
261
 
+    for(int i= 0; STRING_POSITIVE_POWER_LENGTH > i; ++i)
 
268
+    m_max_dec_value= MILLION;
 
269
+    for(int i= 0; TIME_STRING_POSITIVE_POWER_LENGTH > i; ++i)
262
270
+      m_max_dec_value *= 10;
263
271
+    setup(DEFAULT_BASE);
264
272
+  }
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];
319
327
+};
320
328
+
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)
322
330
+{
323
 
+private:
324
 
+  typedef char string_type[STRING_BUFFER_LENGTH];
325
 
+public:
326
 
+  string_collector(utility& u) : m_base(0), m_utility(0)
327
 
+  {
328
 
+    memset((char*)m_nothing,'X',STRING_BUFFER_LENGTH);
329
 
+    m_nothing[STRING_POSITIVE_POWER_LENGTH]= '.';
330
 
+    m_nothing[STRING_LENGTH]= '\0';
331
 
+    setup(u);
332
 
+  }
333
 
+public:
334
 
+  const char* string(uint index) const { return m_bound[ index ]; }
335
 
+public:
336
 
+  void setup(utility& u)
337
 
+  {
338
 
+    if(m_base != u.base())
339
 
+    {
340
 
+      m_utility= &u;
341
 
+      m_base= m_utility->base();
342
 
+      const ulonglong million= 1000 * 1000;
343
 
+      for(int i= 0; OVERALL_POWER_COUNT + 1 > i; ++i)
344
 
+      {
345
 
+       memcpy((char*)m_bound[i],(char*)m_nothing,STRING_BUFFER_LENGTH);
346
 
+      }
347
 
+
348
 
+      for(int i= 0, count= m_utility->bound_count(); i < count; ++i)
349
 
+      {
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)))
353
 
+        {
354
 
+         // string overflow
355
 
+          memcpy(result,STRING_OVERFLOW,sizeof(STRING_OVERFLOW));
356
 
+        }
357
 
+      }
358
 
+      memcpy((char*)(m_bound[m_utility->bound_count()]),TIME_OVERFLOW,sizeof(TIME_OVERFLOW));
359
 
+    }
360
 
+  }
361
 
+private:
362
 
+  ulong       m_base;
363
 
+  utility*    m_utility;
364
 
+  string_type m_bound[OVERALL_POWER_COUNT + 1];
365
 
+  string_type m_nothing;
366
 
+};
367
 
+
 
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)
 
337
+  {
 
338
+    assert(sizeof(STRING_OVERFLOW) <= buffer_size);
 
339
+    memcpy(buffer, STRING_OVERFLOW, sizeof(STRING_OVERFLOW));
 
340
+    return;
 
341
+  }
 
342
+  buffer[result_length]= 0;
 
343
+}
368
344
+class time_collector
369
345
+{
370
346
+public:
371
347
+  time_collector(utility& u) : m_utility(&u)
372
348
+  {
373
349
+  }
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]; }
375
352
+public:
376
353
+  void flush()
377
354
+  {
378
355
+    memset(&m_count,0,sizeof(m_count));
 
356
+    memset(&m_total,0,sizeof(m_total));
379
357
+  }
380
 
+  void collect(ulonglong time)
 
358
+  void collect(uint64 time)
381
359
+  {
382
360
+    int i= 0;
383
361
+    for(int count= m_utility->bound_count(); count > i; ++i)
384
362
+    {
385
363
+      if(m_utility->bound(i) > time)
386
364
+      {
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);
388
367
+       break;
389
368
+      }
390
369
+    }
391
370
+  }
392
371
+private:
393
372
+  utility* m_utility;
394
 
+  ulong    m_base;
395
373
+  uint32   m_count[OVERALL_POWER_COUNT + 1];
 
374
+  uint64   m_total[OVERALL_POWER_COUNT + 1];
396
375
+};
397
376
+
398
377
+class collector
399
378
+{
400
379
+public:
401
 
+  collector() : m_string(m_utility), m_time(m_utility)
 
380
+  collector() : m_time(m_utility)
402
381
+  {
403
382
+    m_utility.setup(DEFAULT_BASE);
404
 
+    m_string.setup(m_utility);
405
383
+    m_time.flush();
406
384
+  }
407
385
+public:
408
386
+  void flush()
409
387
+  {
410
388
+    m_utility.setup(opt_query_response_time_range_base);
411
 
+    m_string.setup(m_utility);
412
389
+    m_time.flush();
413
390
+  }
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)
420
397
+    {
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())
 
401
+      {        
 
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));
 
406
+      }
 
407
+      else
 
408
+      {
 
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));
 
411
+      }
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))
426
416
+      {
427
417
+       DBUG_RETURN(1);
437
427
+  {
438
428
+    return m_utility.bound_count();
439
429
+  }
440
 
+  const char* string(uint index)
 
430
+  ulonglong bound(uint index)
441
431
+  {
442
 
+    return m_string.string(index);
 
432
+    return m_utility.bound(index);
443
433
+  }
444
434
+  ulonglong count(uint index)
445
435
+  {
446
436
+    return m_time.count(index);
447
437
+  }
 
438
+  ulonglong total(uint index)
 
439
+  {
 
440
+    return m_time.total(index);
 
441
+  }
448
442
+private:
449
443
+  utility          m_utility;
450
 
+  string_collector m_string;
451
444
+  time_collector   m_time;
452
445
+};
453
446
+
478
471
+  return query_response_time::g_collector.fill(thd,tables,cond);
479
472
+}
480
473
diff -Nur a/sql/query_response_time.h b/sql/query_response_time.h
481
 
--- a/sql/query_response_time.h 1970-01-01 03:00:00.000000000 +0300
482
 
+++ b/sql/query_response_time.h 2010-08-10 15:32:20.098240993 +0400
483
 
@@ -0,0 +1,63 @@
 
474
--- a/sql/query_response_time.h 1970-01-01 00:00:00.000000000 +0000
 
475
+++ b/sql/query_response_time.h 2010-09-14 20:32:15.000000000 +0000
 
476
@@ -0,0 +1,69 @@
484
477
+#ifndef QUERY_RESPONSE_TIME_H
485
478
+#define QUERY_RESPONSE_TIME_H
486
479
+
489
482
+*/
490
483
+
491
484
+/*
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
494
487
+  Always 2
495
488
+
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
498
491
+*/
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
500
494
+
501
495
+/*
502
496
+  Minimum base for log - ALWAYS 2
503
497
+  Maximum base for log:
504
498
+*/
505
 
+#define QUERY_RESPONSE_TIME_MAXIMUM_BASE 1000
 
499
+#define QRT_MAXIMUM_BASE 1000
506
500
+
507
501
+/*
508
502
+  Filler for whole number (positive power)
509
503
+  Example: for
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:
513
507
+  '   7234'
514
508
+*/
515
 
+#define QUERY_RESPONSE_TIME_POSITIVE_POWER_FILLER " "
 
509
+#define QRT_POSITIVE_POWER_FILLER " "
516
510
+/*
517
511
+  Filler for fractional number. Similiary to whole number
518
512
+*/
519
 
+#define QUERY_RESPONSE_TIME_NEGATIVE_POWER_FILLER "0"
 
513
+#define QRT_NEGATIVE_POWER_FILLER "0"
520
514
+
521
515
+/*
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)
523
517
+*/
524
 
+#define QUERY_RESPONSE_TIME_STRING_OVERFLOW "TOO BIG STRING"
 
518
+#define QRT_STRING_OVERFLOW "TOO BIG STRING"
525
519
+
526
520
+/*
527
521
+  Message if time too big for statistic collecting (very long query)
528
522
+*/
529
 
+#define QUERY_RESPONSE_TIME_TIME_OVERFLOW "TOO LONG QUERY"
530
 
+
531
 
+#define QUERY_RESPONSE_TIME_DEFAULT_BASE 10
532
 
+
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"
 
524
+
 
525
+#define QRT_DEFAULT_BASE 10
 
526
+
 
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) ) )
 
531
+
 
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) ) )
537
536
+
538
537
+extern ST_SCHEMA_TABLE query_response_time_table;
539
538
+
545
544
+
546
545
+#endif // QUERY_RESPONSE_TIME_H
547
546
diff -Nur a/sql/set_var.cc b/sql/set_var.cc
548
 
--- a/sql/set_var.cc    2010-08-10 15:32:19.556992443 +0400
549
 
+++ b/sql/set_var.cc    2010-08-10 15:32:20.098240993 +0400
 
547
--- a/sql/set_var.cc    2010-09-14 20:27:52.000000000 +0000
 
548
+++ b/sql/set_var.cc    2010-09-14 20:31:41.000000000 +0000
550
549
@@ -1004,6 +1004,10 @@
551
550
 static sys_var_use_global_long_query_time sys_use_global_long_query_time;
552
551
 static sys_var_bool_ptr       sys_slow_query_log_microseconds_timestamp(&vars, "slow_query_log_microseconds_timestamp",
559
558
 static sys_var_log_state sys_var_log_slow(&vars, "log_slow_queries",
560
559
                                           &opt_slow_log, QUERY_LOG_SLOW);
561
560
diff -Nur a/sql/sql_parse.cc b/sql/sql_parse.cc
562
 
--- a/sql/sql_parse.cc  2010-08-10 15:32:19.577006165 +0400
563
 
+++ b/sql/sql_parse.cc  2010-08-10 15:32:20.108241429 +0400
 
561
--- a/sql/sql_parse.cc  2010-09-14 20:27:52.000000000 +0000
 
562
+++ b/sql/sql_parse.cc  2010-09-14 20:31:41.000000000 +0000
564
563
@@ -27,6 +27,7 @@
565
564
 #include "sp_cache.h"
566
565
 #include "events.h"
635
634
   {
636
635
     pthread_mutex_lock(&LOCK_global_user_client_stats);
637
636
diff -Nur a/sql/sql_show.cc b/sql/sql_show.cc
638
 
--- a/sql/sql_show.cc   2010-08-10 15:32:19.566991761 +0400
639
 
+++ b/sql/sql_show.cc   2010-08-10 15:32:20.108241429 +0400
 
637
--- a/sql/sql_show.cc   2010-09-14 20:27:52.000000000 +0000
 
638
+++ b/sql/sql_show.cc   2010-09-14 20:32:15.000000000 +0000
640
639
@@ -31,6 +31,7 @@
641
640
 #include "event_data_objects.h"
642
641
 #endif
645
644
 #include "debug_sync.h"
646
645
 
647
646
 #define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
648
 
@@ -7467,6 +7468,13 @@
 
647
@@ -7467,6 +7468,14 @@
649
648
 
650
649
 */
651
650
 
652
651
+ST_FIELD_INFO query_response_time_fields_info[] =
653
652
+  {
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 }
657
657
+  };
658
658
+
659
659
 ST_SCHEMA_TABLE schema_tables[]=
660
660
 {
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 @@
675
675
 %token  PURGE
676
676
 %token  QUARTER_SYM
711
711
         | READ_ONLY_SYM            {}
712
712
         | REBUILD_SYM              {}
713
713
diff -Nur a/sql/table.h b/sql/table.h
714
 
--- a/sql/table.h       2010-08-10 15:32:19.556992443 +0400
715
 
+++ b/sql/table.h       2010-08-10 15:32:20.118244100 +0400
 
714
--- a/sql/table.h       2010-09-14 20:27:52.000000000 +0000
 
715
+++ b/sql/table.h       2010-09-14 20:31:41.000000000 +0000
716
716
@@ -963,6 +963,7 @@
717
717
   SCH_PROFILES,
718
718
   SCH_REFERENTIAL_CONSTRAINTS,