~tsarev/percona-server/slow_extended_tests_fixes

102.1.1 by kinoyasu
add header and rule, as the first step of the reordering patch for separate release
1
# name       : userstat.patch
2
# introduced : 11 or before
3
# maintainer : Yasufumi
4
#
5
#!!! notice !!!
6
# Any small change to this file in the main branch
7
# should be done or reviewed by the maintainer!
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
8
diff -ruN a/configure b/configure
9
--- a/configure	2010-08-27 14:28:05.621275596 +0900
10
+++ b/configure	2010-08-27 15:10:33.736074033 +0900
11
@@ -38009,7 +38009,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
12
   realpath rename rint rwlock_init setupterm \
13
   shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \
14
   sighold sigset sigthreadmask port_create sleep \
15
-  snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
16
+  snprintf socket strsep stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
17
   strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \
18
   posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd printstack
19
 do
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
20
diff -ruN a/configure.in b/configure.in
21
--- a/configure.in	2010-08-04 02:24:24.000000000 +0900
22
+++ b/configure.in	2010-08-27 15:10:33.737073307 +0900
23
@@ -2086,7 +2086,7 @@
94 by Oleg Tsarev
fix bug 610525
24
   realpath rename rint rwlock_init setupterm \
25
   shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \
26
   sighold sigset sigthreadmask port_create sleep \
27
-  snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
28
+  snprintf socket strsep stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
29
   strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \
30
   posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd printstack)
31
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
32
diff -ruN a/include/config.h.in b/include/config.h.in
33
--- a/include/config.h.in	2010-08-04 02:28:40.000000000 +0900
34
+++ b/include/config.h.in	2010-08-27 15:10:33.740077919 +0900
35
@@ -802,6 +802,9 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
36
 /* Define to 1 if you have the <stdlib.h> header file. */
37
 #undef HAVE_STDLIB_H
38
 
39
+/* Define to 1 if you have the `strsep' function. */
40
+#undef HAVE_STRSEP
41
+
42
 /* Define to 1 if you have the `stpcpy' function. */
43
 #undef HAVE_STPCPY
44
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
45
diff -ruN a/include/mysql/plugin.h b/include/mysql/plugin.h
46
--- a/include/mysql/plugin.h	2010-08-27 14:38:08.682439958 +0900
47
+++ b/include/mysql/plugin.h	2010-08-27 15:10:33.742003842 +0900
5 by kinoyasu
adjust InnoDB_trx_id: at slow_log, clean patches affected
48
@@ -705,6 +705,9 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
49
 unsigned long thd_log_slow_verbosity(const MYSQL_THD thd);
50
 int thd_opt_slow_log();
51
 #define EXTENDED_SLOWLOG
52
+
53
+#define EXTENDED_FOR_USERSTAT
54
+
55
 /**
56
   Create a temporary file.
57
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
58
diff -ruN a/include/mysql_com.h b/include/mysql_com.h
59
--- a/include/mysql_com.h	2010-08-04 02:24:30.000000000 +0900
60
+++ b/include/mysql_com.h	2010-08-27 15:10:33.743072186 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
61
@@ -29,6 +29,7 @@
62
 
63
 #define SERVER_VERSION_LENGTH 60
64
 #define SQLSTATE_LENGTH 5
65
+#define LIST_PROCESS_HOST_LEN 64
66
 
67
 /*
68
   USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
69
@@ -115,6 +116,12 @@
70
 					   thread */
71
 #define REFRESH_MASTER          128     /* Remove all bin logs in the index
72
 					   and truncate the index */
73
+#define REFRESH_TABLE_STATS     256     /* Refresh table stats hash table */
74
+#define REFRESH_INDEX_STATS     512     /* Refresh index stats hash table */
75
+#define REFRESH_USER_STATS      1024    /* Refresh user stats hash table */
76
+#define REFRESH_SLOW_QUERY_LOG  2048    /* Flush slow query log and rotate*/
77
+#define REFRESH_CLIENT_STATS    4096    /* Refresh client stats hash table */
78
+#define REFRESH_THREAD_STATS    8192    /* Refresh thread stats hash table */
79
 
80
 /* The following can't be set with mysql_refresh() */
81
 #define REFRESH_READ_LOCK	16384	/* Lock tables for read */
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
82
diff -ruN a/patch_info/userstats.info b/patch_info/userstats.info
83
--- /dev/null	1970-01-01 09:00:00.000000000 +0900
84
+++ b/patch_info/userstats.info	2010-08-27 15:10:33.744161257 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
85
@@ -0,0 +1,11 @@
86
+File=userstats.patch
87
+Name=SHOW USER/TABLE/INDEX statistics
88
+Version=V2
89
+Author=Google
90
+License=GPL
91
+Comment=Added INFORMATION_SCHEMA.*_STATISTICS
92
+2008-12-01
93
+YK: fix behavior for prepared statements
94
+
95
+2008-11-26
96
+YK: add switch variable "userstat_running" to control INFORMATION_SCHEMA.*_STATISTICS (default:OFF)
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
97
diff -ruN a/sql/handler.cc b/sql/handler.cc
98
--- a/sql/handler.cc	2010-08-04 02:24:27.000000000 +0900
99
+++ b/sql/handler.cc	2010-08-27 15:10:33.749058856 +0900
9 by kinoyasu
port for 5.1.47-1.0.8
100
@@ -1194,6 +1194,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
101
     if (cookie)
102
       tc_log->unlog(cookie, xid);
103
     DBUG_EXECUTE_IF("crash_commit_after", abort(););
104
+    if (is_real_trans)
105
+      thd->diff_commit_trans++;
106
 end:
107
     if (rw_trans)
108
       start_waiting_global_read_lock(thd);
9 by kinoyasu
port for 5.1.47-1.0.8
109
@@ -1324,6 +1326,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
110
   /* Always cleanup. Even if there nht==0. There may be savepoints. */
111
   if (is_real_trans)
112
     thd->transaction.cleanup();
113
+
114
+  thd->diff_rollback_trans++;
115
 #endif /* USING_TRANSACTIONS */
116
   if (all)
117
     thd->transaction_rollback_request= FALSE;
9 by kinoyasu
port for 5.1.47-1.0.8
118
@@ -1762,6 +1766,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
119
     ha_info->reset(); /* keep it conveniently zero-filled */
120
   }
121
   trans->ha_list= sv->ha_list;
122
+  thd->diff_rollback_trans++;
123
   DBUG_RETURN(error);
124
 }
125
 
9 by kinoyasu
port for 5.1.47-1.0.8
126
@@ -2122,6 +2127,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
127
       dup_ref=ref+ALIGN_SIZE(ref_length);
128
     cached_table_flags= table_flags();
129
   }
130
+  rows_read = rows_changed = 0;
131
+  memset(index_rows_read, 0, sizeof(index_rows_read));
132
   DBUG_RETURN(error);
133
 }
134
 
9 by kinoyasu
port for 5.1.47-1.0.8
135
@@ -3571,6 +3578,111 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
136
   return;
137
 }
138
 
139
+// Updates the global table stats with the TABLE this handler represents.
140
+void handler::update_global_table_stats() {
141
+  if (!opt_userstat_running) {
142
+    rows_read = rows_changed = 0;
143
+    return;
144
+  }
145
+
146
+  if (!rows_read && !rows_changed) return;  // Nothing to update.
147
+  // table_cache_key is db_name + '\0' + table_name + '\0'.
148
+  if (!table->s || !table->s->table_cache_key.str || !table->s->table_name.str) return;
149
+
150
+  TABLE_STATS* table_stats;
151
+  char key[NAME_LEN * 2 + 2];
152
+  // [db] + '.' + [table]
153
+  sprintf(key, "%s.%s", table->s->table_cache_key.str, table->s->table_name.str);
154
+
155
+  pthread_mutex_lock(&LOCK_global_table_stats);
156
+  // Gets the global table stats, creating one if necessary.
157
+  if (!(table_stats = (TABLE_STATS*)hash_search(&global_table_stats,
158
+                                                (uchar*)key,
159
+                                                strlen(key)))) {
160
+    if (!(table_stats = ((TABLE_STATS*)
161
+                         my_malloc(sizeof(TABLE_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
162
+      // Out of memory.
163
+      sql_print_error("Allocating table stats failed.");
164
+      goto end;
165
+    }
166
+    strncpy(table_stats->table, key, sizeof(table_stats->table));
167
+    table_stats->rows_read = 0;
168
+    table_stats->rows_changed = 0;
169
+    table_stats->rows_changed_x_indexes = 0;
170
+    table_stats->engine_type = (int) ht->db_type;
171
+
172
+    if (my_hash_insert(&global_table_stats, (uchar*)table_stats)) {
173
+      // Out of memory.
174
+      sql_print_error("Inserting table stats failed.");
175
+      my_free((char*)table_stats, 0);
176
+      goto end;
177
+    }
178
+  }
179
+  // Updates the global table stats.
180
+  table_stats->rows_read += rows_read;
181
+  table_stats->rows_changed += rows_changed;
182
+  table_stats->rows_changed_x_indexes +=
183
+      rows_changed * (table->s->keys ? table->s->keys : 1);
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
184
+  current_thd->diff_total_read_rows += rows_read;
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
185
+  rows_read = rows_changed = 0;
186
+end:
187
+  pthread_mutex_unlock(&LOCK_global_table_stats);
188
+}
189
+
190
+// Updates the global index stats with this handler's accumulated index reads.
191
+void handler::update_global_index_stats() {
192
+  // table_cache_key is db_name + '\0' + table_name + '\0'.
193
+  if (!table->s || !table->s->table_cache_key.str || !table->s->table_name.str) return;
194
+
195
+  if (!opt_userstat_running) {
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
196
+    for (uint x = 0; x < table->s->keys; x++) {
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
197
+      index_rows_read[x] = 0;
198
+    }
199
+    return;
200
+  }
201
+
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
202
+  for (uint x = 0; x < table->s->keys; x++) {
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
203
+    if (index_rows_read[x]) {
204
+      // Rows were read using this index.
205
+      KEY* key_info = &table->key_info[x];
206
+
207
+      if (!key_info->name) continue;
208
+
209
+      INDEX_STATS* index_stats;
210
+      char key[NAME_LEN * 3 + 3];
211
+      // [db] + '.' + [table] + '.' + [index]
212
+      sprintf(key, "%s.%s.%s",  table->s->table_cache_key.str,
213
+              table->s->table_name.str, key_info->name);
214
+
215
+      pthread_mutex_lock(&LOCK_global_index_stats);
216
+      // Gets the global index stats, creating one if necessary.
217
+      if (!(index_stats = (INDEX_STATS*)hash_search(&global_index_stats,
218
+                                                    (uchar*)key,
219
+                                                    strlen(key)))) {
220
+        if (!(index_stats = ((INDEX_STATS*)
221
+                             my_malloc(sizeof(INDEX_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
222
+          // Out of memory.
223
+          sql_print_error("Allocating index stats failed.");
224
+          goto end;
225
+        }
226
+        strncpy(index_stats->index, key, sizeof(index_stats->index));
227
+        index_stats->rows_read = 0;
228
+
229
+        if (my_hash_insert(&global_index_stats, (uchar*)index_stats)) {
230
+          // Out of memory.
231
+          sql_print_error("Inserting index stats failed.");
232
+          my_free((char*)index_stats, 0);
233
+          goto end;
234
+        }
235
+      }
236
+      // Updates the global index stats.
237
+      index_stats->rows_read += index_rows_read[x];
238
+      index_rows_read[x] = 0;
239
+end:
240
+      pthread_mutex_unlock(&LOCK_global_index_stats);
241
+    }
242
+  }
243
+}
244
 
245
 /****************************************************************************
246
 ** Some general functions that isn't in the handler class
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
247
diff -ruN a/sql/handler.h b/sql/handler.h
248
--- a/sql/handler.h	2010-08-04 02:24:27.000000000 +0900
249
+++ b/sql/handler.h	2010-08-27 15:10:33.753058869 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
250
@@ -30,6 +30,10 @@
251
 
252
 #define USING_TRANSACTIONS
253
 
254
+#if MAX_KEY > 128
255
+#error MAX_KEY is too large.  Values up to 128 are supported.
256
+#endif
257
+
258
 // the following is for checking tables
259
 
260
 #define HA_ADMIN_ALREADY_DONE	  1
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
261
@@ -1121,6 +1125,9 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
262
   bool locked;
263
   bool implicit_emptied;                /* Can be !=0 only if HEAP */
264
   const COND *pushed_cond;
265
+  ulonglong rows_read;
266
+  ulonglong rows_changed;
267
+  ulonglong index_rows_read[MAX_KEY];
268
   /**
269
     next_insert_id is the next value which should be inserted into the
270
     auto_increment column: in a inserting-multi-row statement (like INSERT
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
271
@@ -1158,9 +1165,11 @@
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
272
     ref_length(sizeof(my_off_t)),
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
273
     ft_handler(0), inited(NONE),
274
     locked(FALSE), implicit_emptied(0),
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
275
-    pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
276
+    pushed_cond(0), rows_read(0), rows_changed(0), next_insert_id(0), insert_id_for_cur_row(0),
277
     auto_inc_intervals_count(0)
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
278
-    {}
279
+    {
280
+      memset(index_rows_read, 0, sizeof(index_rows_read));
281
+    }
282
   virtual ~handler(void)
283
   {
284
     DBUG_ASSERT(locked == FALSE);
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
285
@@ -1284,6 +1293,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
286
   {
287
     table= table_arg;
288
     table_share= share;
289
+    rows_read = rows_changed = 0;
290
+    memset(index_rows_read, 0, sizeof(index_rows_read));
291
   }
292
   virtual double scan_time()
293
   { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
294
@@ -1628,6 +1639,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
295
   virtual bool is_crashed() const  { return 0; }
296
   virtual bool auto_repair() const { return 0; }
297
 
298
+  void update_global_table_stats();
299
+  void update_global_index_stats();
300
 
301
 #define CHF_CREATE_FLAG 0
302
 #define CHF_DELETE_FLAG 1
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
303
diff -ruN a/sql/lex.h b/sql/lex.h
304
--- a/sql/lex.h	2010-08-27 14:29:26.009071592 +0900
305
+++ b/sql/lex.h	2010-08-27 15:10:33.755063742 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
306
@@ -106,6 +106,7 @@
307
   { "CHECKSUM",		SYM(CHECKSUM_SYM)},
308
   { "CIPHER",		SYM(CIPHER_SYM)},
309
   { "CLIENT",		SYM(CLIENT_SYM)},
310
+  { "CLIENT_STATISTICS",	SYM(CLIENT_STATS_SYM)},
311
   { "CLOSE",		SYM(CLOSE_SYM)},
312
   { "COALESCE",		SYM(COALESCE)},
313
   { "CODE",             SYM(CODE_SYM)},
314
@@ -245,6 +246,7 @@
315
   { "IN",		SYM(IN_SYM)},
316
   { "INDEX",		SYM(INDEX_SYM)},
317
   { "INDEXES",		SYM(INDEXES)},
318
+  { "INDEX_STATISTICS",	SYM(INDEX_STATS_SYM)},
319
   { "INFILE",		SYM(INFILE)},
320
   { "INITIAL_SIZE",	SYM(INITIAL_SIZE_SYM)},
321
   { "INNER",		SYM(INNER_SYM)},
322
@@ -478,6 +480,7 @@
323
   { "SIGNED",		SYM(SIGNED_SYM)},
324
   { "SIMPLE",		SYM(SIMPLE_SYM)},
325
   { "SLAVE",            SYM(SLAVE)},
326
+  { "SLOW",             SYM(SLOW_SYM)},
327
   { "SNAPSHOT",         SYM(SNAPSHOT_SYM)},
328
   { "SMALLINT",		SYM(SMALLINT)},
329
   { "SOCKET",		SYM(SOCKET_SYM)},
330
@@ -527,12 +530,14 @@
331
   { "TABLES",		SYM(TABLES)},
332
   { "TABLESPACE",	        SYM(TABLESPACE)},
333
   { "TABLE_CHECKSUM",	SYM(TABLE_CHECKSUM_SYM)},
334
+  { "TABLE_STATISTICS",	SYM(TABLE_STATS_SYM)},
335
   { "TEMPORARY",	SYM(TEMPORARY)},
336
   { "TEMPTABLE",	SYM(TEMPTABLE_SYM)},
337
   { "TERMINATED",	SYM(TERMINATED)},
338
   { "TEXT",		SYM(TEXT_SYM)},
339
   { "THAN",             SYM(THAN_SYM)},
340
   { "THEN",		SYM(THEN_SYM)},
341
+  { "THREAD_STATISTICS",	SYM(THREAD_STATS_SYM)},
342
   { "TIME",		SYM(TIME_SYM)},
343
   { "TIMESTAMP",	SYM(TIMESTAMP)},
344
   { "TIMESTAMPADD",     SYM(TIMESTAMP_ADD)},
345
@@ -568,6 +573,7 @@
346
   { "USE",		SYM(USE_SYM)},
347
   { "USER",		SYM(USER)},
348
   { "USER_RESOURCES",	SYM(RESOURCES)},
349
+  { "USER_STATISTICS",	SYM(USER_STATS_SYM)},
350
   { "USE_FRM",		SYM(USE_FRM)},
351
   { "USING",		SYM(USING)},
352
   { "UTC_DATE",         SYM(UTC_DATE_SYM)},
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
353
diff -ruN a/sql/log.cc b/sql/log.cc
354
--- a/sql/log.cc	2010-08-27 14:43:41.986138797 +0900
355
+++ b/sql/log.cc	2010-08-27 15:10:33.761058932 +0900
54.2.6 by Oleg Tsarev
normalize patches
356
@@ -826,6 +826,13 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
357
     mysql_slow_log.reopen_file();
358
 }
359
 
360
+void Log_to_file_event_handler::flush_slow_log()
361
+{
362
+  /* reopen slow log file */
363
+  if (opt_slow_log)
364
+    mysql_slow_log.reopen_file();
365
+}
366
+
367
 /*
368
   Log error with all enabled log event handlers
369
 
54.2.6 by Oleg Tsarev
normalize patches
370
@@ -937,6 +944,21 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
371
   return rc;
372
 }
373
 
374
+bool LOGGER::flush_slow_log(THD *thd)
375
+{
376
+  /*
377
+    Now we lock logger, as nobody should be able to use logging routines while
378
+    log tables are closed
379
+  */
380
+  logger.lock_exclusive();
381
+
382
+  /* reopen log files */
383
+  file_log_handler->flush_slow_log();
384
+
385
+  /* end of log flush */
386
+  logger.unlock();
387
+  return 0;
388
+}
389
 
390
 /*
391
   Log slow query with all enabled log event handlers
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
392
@@ -4491,6 +4513,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
393
                              thd->first_successful_insert_id_in_prev_stmt_for_binlog);
394
           if (e.write(file))
395
             goto err;
396
+          if (file == &log_file)
397
+            thd->binlog_bytes_written += e.data_written;
398
         }
399
         if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
400
         {
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
401
@@ -4502,12 +4526,16 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
402
                              minimum());
403
           if (e.write(file))
404
             goto err;
405
+          if (file == &log_file)
406
+            thd->binlog_bytes_written += e.data_written;
407
         }
408
         if (thd->rand_used)
409
         {
410
           Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
411
           if (e.write(file))
412
             goto err;
413
+          if (file == &log_file)
414
+            thd->binlog_bytes_written += e.data_written;
415
         }
416
         if (thd->user_var_events.elements)
417
         {
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
418
@@ -4523,6 +4551,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
419
                                  user_var_event->charset_number);
420
             if (e.write(file))
421
               goto err;
422
+            if (file == &log_file)
423
+              thd->binlog_bytes_written += e.data_written;
424
           }
425
         }
426
       }
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
427
@@ -4535,6 +4565,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
428
     if (event_info->write(file) || 
429
         DBUG_EVALUATE_IF("injecting_fault_writing", 1, 0))
430
       goto err;
431
+    if (file == &log_file)
432
+      thd->binlog_bytes_written += event_info->data_written;
433
 
434
     if (file == &log_file) // we are writing to the real log (disk)
435
     {
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
436
@@ -4680,7 +4712,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
437
     be reset as a READ_CACHE to be able to read the contents from it.
438
  */
439
 
440
-int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
441
+int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log, bool sync_log)
442
 {
443
   Mutex_sentry sentry(lock_log ? &LOCK_log : NULL);
444
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
445
@@ -4728,6 +4760,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
446
       /* write the first half of the split header */
447
       if (my_b_write(&log_file, header, carry))
448
         return ER_ERROR_ON_WRITE;
449
+      thd->binlog_bytes_written += carry;
450
 
451
       /*
452
         copy fixed second half of header to cache so the correct
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
453
@@ -4796,6 +4829,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
454
     /* Write data to the binary log file */
455
     if (my_b_write(&log_file, cache->read_pos, length))
456
       return ER_ERROR_ON_WRITE;
457
+    thd->binlog_bytes_written += length;
458
     cache->read_pos=cache->read_end;		// Mark buffer used up
459
   } while ((length= my_b_fill(cache)));
460
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
461
@@ -4918,21 +4952,24 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
462
       */
463
       if (qinfo.write(&log_file))
464
         goto err;
465
+      thd->binlog_bytes_written += qinfo.data_written;
466
 
467
       DBUG_EXECUTE_IF("crash_before_writing_xid",
468
                       {
469
-                        if ((write_error= write_cache(cache, false, true)))
470
+                        if ((write_error= write_cache(thd, cache, false, true)))
471
                           DBUG_PRINT("info", ("error writing binlog cache: %d",
472
                                                write_error));
473
                         DBUG_PRINT("info", ("crashing before writing xid"));
474
                         abort();
475
                       });
476
 
477
-      if ((write_error= write_cache(cache, false, false)))
478
+      if ((write_error= write_cache(thd, cache, false, false)))
479
         goto err;
480
 
481
       if (commit_event && commit_event->write(&log_file))
482
         goto err;
483
+      if (commit_event)
484
+        thd->binlog_bytes_written += commit_event->data_written;
485
 
486
       if (incident && write_incident(thd, FALSE))
487
         goto err;
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
488
diff -ruN a/sql/log.h b/sql/log.h
489
--- a/sql/log.h	2010-08-27 14:38:08.690071101 +0900
490
+++ b/sql/log.h	2010-08-27 15:13:33.762976324 +0900
491
@@ -361,7 +361,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
492
   bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
493
 
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
494
   bool write_incident(THD *thd, bool lock);
495
-  int  write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
496
+  int  write_cache(THD *thd, IO_CACHE *cache, bool lock_log, bool flush_and_sync);
497
   void set_write_error(THD *thd);
498
   bool check_write_error(THD *thd);
499
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
500
@@ -499,6 +499,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
501
                            const char *sql_text, uint sql_text_len,
502
                            CHARSET_INFO *client_cs);
503
   void flush();
504
+  void flush_slow_log();
505
   void init_pthread_objects();
506
   MYSQL_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
507
   MYSQL_QUERY_LOG *get_mysql_log() { return &mysql_log; }
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
508
@@ -543,6 +544,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
509
   void init_base();
510
   void init_log_tables();
511
   bool flush_logs(THD *thd);
512
+  bool flush_slow_log(THD *thd);
513
   /* Perform basic logger cleanup. this will leave e.g. error log open. */
514
   void cleanup_base();
515
   /* Free memory. Nothing could be logged after this function is called */
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
516
diff -ruN a/sql/mysql_priv.h b/sql/mysql_priv.h
517
--- a/sql/mysql_priv.h	2010-08-27 14:38:08.699057407 +0900
518
+++ b/sql/mysql_priv.h	2010-08-27 15:10:33.805058568 +0900
519
@@ -1139,7 +1139,17 @@
520
 bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
521
 void init_max_user_conn(void);
522
 void init_update_queries(void);
523
+void init_global_user_stats(void);
524
+void init_global_table_stats(void);
525
+void init_global_index_stats(void);
526
+void init_global_client_stats(void);
527
+void init_global_thread_stats(void);
528
 void free_max_user_conn(void);
529
+void free_global_user_stats(void);
530
+void free_global_table_stats(void);
531
+void free_global_index_stats(void);
532
+void free_global_client_stats(void);
533
+void free_global_thread_stats(void);
534
 pthread_handler_t handle_bootstrap(void *arg);
535
 int mysql_execute_command(THD *thd);
536
 bool do_command(THD *thd);
537
@@ -2014,6 +2024,7 @@
538
 extern ulong max_connect_errors, connect_timeout;
539
 extern ulong slave_net_timeout, slave_trans_retries;
540
 extern uint max_user_connections;
541
+extern ulonglong denied_connections;
542
 extern ulong what_to_log,flush_time;
543
 extern ulong query_buff_size;
544
 extern ulong max_prepared_stmt_count, prepared_stmt_count;
545
@@ -2067,6 +2078,7 @@
546
 extern my_bool opt_slave_compressed_protocol, use_temp_pool;
547
 extern ulong slave_exec_mode_options;
548
 extern my_bool opt_readonly, lower_case_file_system;
549
+extern my_bool opt_userstat_running, opt_thread_statistics;
550
 extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
551
 extern my_bool opt_secure_auth;
552
 extern char* opt_secure_file_priv;
553
@@ -2131,6 +2143,15 @@
554
 extern struct system_variables max_system_variables;
555
 extern struct system_status_var global_status_var;
556
 extern struct rand_struct sql_rand;
557
+extern HASH global_user_stats;
558
+extern HASH global_client_stats;
559
+extern HASH global_thread_stats;
560
+extern pthread_mutex_t LOCK_global_user_client_stats;
561
+extern HASH global_table_stats;
562
+extern pthread_mutex_t LOCK_global_table_stats;
563
+extern HASH global_index_stats;
564
+extern pthread_mutex_t LOCK_global_index_stats;
565
+extern pthread_mutex_t LOCK_stats;
566
 
567
 extern const char *opt_date_time_formats[];
568
 extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
569
diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
570
--- a/sql/mysqld.cc	2010-08-27 14:43:41.996021369 +0900
571
+++ b/sql/mysqld.cc	2010-08-27 15:10:33.772058694 +0900
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
572
@@ -533,6 +533,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
573
 uint    opt_debug_sync_timeout= 0;
574
 #endif /* defined(ENABLED_DEBUG_SYNC) */
575
 my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
576
+my_bool opt_userstat_running= 0, opt_thread_statistics= 0;
577
 /*
578
   True if there is at least one per-hour limit for some user, so we should
579
   check them before each query (and possibly reset counters when hour is
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
580
@@ -581,6 +582,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
581
 ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
582
 ulong max_connections, max_connect_errors;
583
 uint  max_user_connections= 0;
584
+ulonglong denied_connections = 0;
585
 /**
586
   Limit of the total number of prepared statements in the server.
587
   Is necessary to protect the server against out-of-memory attacks.
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
588
@@ -682,6 +684,10 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
589
 	        LOCK_global_system_variables,
590
 		LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
591
                 LOCK_connection_count;
592
+pthread_mutex_t LOCK_stats;
593
+pthread_mutex_t LOCK_global_user_client_stats;
594
+pthread_mutex_t LOCK_global_table_stats;
595
+pthread_mutex_t LOCK_global_index_stats;
596
 /**
597
   The below lock protects access to two global server variables:
598
   max_prepared_stmt_count and prepared_stmt_count. These variables
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
599
@@ -1367,6 +1373,11 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
600
   x_free(opt_secure_file_priv);
601
   bitmap_free(&temp_pool);
602
   free_max_user_conn();
603
+  free_global_user_stats();
604
+  free_global_client_stats();
605
+  free_global_thread_stats();
606
+  free_global_table_stats();
607
+  free_global_index_stats();
608
 #ifdef HAVE_REPLICATION
609
   end_slave_list();
610
 #endif
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
611
@@ -1483,6 +1494,10 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
612
   (void) pthread_cond_destroy(&COND_thread_cache);
613
   (void) pthread_cond_destroy(&COND_flush_thread_cache);
614
   (void) pthread_cond_destroy(&COND_manager);
615
+  (void) pthread_mutex_destroy(&LOCK_stats);
616
+  (void) pthread_mutex_destroy(&LOCK_global_user_client_stats);
617
+  (void) pthread_mutex_destroy(&LOCK_global_table_stats);
618
+  (void) pthread_mutex_destroy(&LOCK_global_index_stats);
619
 }
620
 
621
 #endif /*EMBEDDED_LIBRARY*/
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
622
@@ -3172,6 +3187,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
623
   {"show_binlog_events",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
624
   {"show_binlogs",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
625
   {"show_charsets",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
626
+  {"show_client_statistics",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CLIENT_STATS]), SHOW_LONG_STATUS},
627
   {"show_collations",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
628
   {"show_column_types",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), SHOW_LONG_STATUS},
629
   {"show_contributors",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS},
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
630
@@ -3193,6 +3209,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
631
 #endif
632
   {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
633
   {"show_grants",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
634
+  {"show_index_statistics",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_INDEX_STATS]), SHOW_LONG_STATUS},
635
   {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
636
   {"show_master_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
637
   {"show_new_master",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
638
@@ -3211,9 +3228,12 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
639
   {"show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
640
   {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
641
   {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
642
+  {"show_table_statistics",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATS]), SHOW_LONG_STATUS},
643
   {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
644
   {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
645
+  {"show_thread_statistics",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_THREAD_STATS]), SHOW_LONG_STATUS},
646
   {"show_triggers",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
647
+  {"show_user_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS},
648
   {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
649
   {"show_warnings",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
650
   {"slave_start",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
651
@@ -3652,6 +3672,10 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
652
 #endif
653
   (void) pthread_mutex_init(&LOCK_server_started, MY_MUTEX_INIT_FAST);
654
   (void) pthread_cond_init(&COND_server_started,NULL);
655
+  (void) pthread_mutex_init(&LOCK_stats, MY_MUTEX_INIT_FAST);
656
+  (void) pthread_mutex_init(&LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST);
657
+  (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
658
+  (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
659
   sp_cache_init();
660
 #ifdef HAVE_EVENT_SCHEDULER
661
   Events::init_mutexes();
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
662
@@ -4053,6 +4077,9 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
663
   if (!errmesg[0][0])
664
     unireg_abort(1);
665
 
666
+  init_global_table_stats();
667
+  init_global_index_stats();
668
+
669
   /* We have to initialize the storage engines before CSV logging */
670
   if (ha_init())
671
   {
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
672
@@ -4199,6 +4226,9 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
673
 
674
   init_max_user_conn();
675
   init_update_queries();
676
+  init_global_user_stats();
677
+  init_global_client_stats();
678
+  init_global_thread_stats();
679
   DBUG_RETURN(0);
680
 }
681
 
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
682
@@ -5016,6 +5046,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
683
 
684
     DBUG_PRINT("error",("Too many connections"));
685
     close_connection(thd, ER_CON_COUNT_ERROR, 1);
686
+    statistic_increment(denied_connections, &LOCK_status);
687
     delete thd;
688
     DBUG_VOID_RETURN;
689
   }
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
690
@@ -5800,6 +5831,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
691
   OPT_SLAVE_EXEC_MODE,
692
   OPT_GENERAL_LOG_FILE,
693
   OPT_SLOW_QUERY_LOG_FILE,
694
+  OPT_USERSTAT_RUNNING,
695
+  OPT_THREAD_STATISTICS,
696
   OPT_USE_GLOBAL_LONG_QUERY_TIME,
54.2.6 by Oleg Tsarev
normalize patches
697
   OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
698
   OPT_SLOW_QUERY_LOG_MICROSECONDS_TIMESTAMP,
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
699
@@ -7292,6 +7325,14 @@
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
700
    &max_system_variables.net_wait_timeout, 0, GET_ULONG,
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
701
    REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
702
    0, 1, 0},
703
+  {"userstat_running", OPT_USERSTAT_RUNNING,
704
+   "Control USER_STATISTICS, CLIENT_STATISTICS, THREAD_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS running",
705
+   (uchar**) &opt_userstat_running, (uchar**) &opt_userstat_running,
706
+   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
707
+  {"thread_statistics", OPT_THREAD_STATISTICS,
708
+   "Control TABLE_STATISTICS running, when userstat_running is enabled",
709
+   (uchar**) &opt_thread_statistics, (uchar**) &opt_thread_statistics,
710
+   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
711
   {"binlog-direct-non-transactional-updates", OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
712
    "Causes updates to non-transactional engines using statement format to be "
713
    "written directly to binary log. Before using this option, make sure that "
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
714
diff -ruN a/sql/set_var.cc b/sql/set_var.cc
715
--- a/sql/set_var.cc	2010-08-27 14:43:42.004008722 +0900
716
+++ b/sql/set_var.cc	2010-08-27 15:10:33.809988740 +0900
717
@@ -554,6 +554,10 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
718
 static sys_var_thd_ulong	sys_read_buff_size(&vars, "read_buffer_size",
719
 					   &SV::read_buff_size);
720
 static sys_var_opt_readonly	sys_readonly(&vars, "read_only", &opt_readonly);
721
+static sys_var_bool_ptr		sys_userstat_running(&vars, "userstat_running",
722
+						     &opt_userstat_running);
723
+static sys_var_bool_ptr		sys_thread_statistics(&vars, "thread_statistics",
724
+						      &opt_thread_statistics);
725
 static sys_var_thd_ulong	sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
726
 					       &SV::read_rnd_buff_size);
727
 static sys_var_thd_ulong	sys_div_precincrement(&vars, "div_precision_increment",
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
728
diff -ruN a/sql/sql_base.cc b/sql/sql_base.cc
729
--- a/sql/sql_base.cc	2010-08-04 02:24:34.000000000 +0900
730
+++ b/sql/sql_base.cc	2010-08-27 15:10:33.818058934 +0900
48 by kinoyasu
port for mysql-5.1.48
731
@@ -1382,6 +1382,12 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
732
   DBUG_PRINT("tcache", ("table: '%s'.'%s' 0x%lx", table->s->db.str,
733
                         table->s->table_name.str, (long) table));
734
 
735
+  if(table->file)
736
+  {
737
+    table->file->update_global_table_stats();
738
+    table->file->update_global_index_stats();
739
+  }
740
+
741
   *table_ptr=table->next;
742
   /*
743
     When closing a MERGE parent or child table, detach the children first.
48 by kinoyasu
port for mysql-5.1.48
744
@@ -1922,6 +1928,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
745
   DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",
746
                           table->s->db.str, table->s->table_name.str));
747
 
748
+  table->file->update_global_table_stats();
749
+  table->file->update_global_index_stats();
750
   free_io_cache(table);
751
   closefrm(table, 0);
752
   if (delete_table)
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
753
diff -ruN a/sql/sql_class.cc b/sql/sql_class.cc
754
--- a/sql/sql_class.cc	2010-08-27 14:38:08.741990000 +0900
755
+++ b/sql/sql_class.cc	2010-08-27 15:10:33.825058007 +0900
9 by kinoyasu
port for 5.1.47-1.0.8
756
@@ -704,6 +704,13 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
757
   mysys_var=0;
758
   binlog_evt_union.do_union= FALSE;
759
   enable_slow_log= 0;
760
+  busy_time = 0;
761
+  cpu_time = 0;
762
+  bytes_received = 0;
763
+  bytes_sent = 0;
764
+  binlog_bytes_written = 0;
765
+  updated_row_count = 0;
766
+  sent_row_count_2 = 0;
767
 #ifndef DBUG_OFF
768
   dbug_sentry=THD_SENTRY_MAGIC;
769
 #endif
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
770
@@ -907,6 +914,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
771
   reset_current_stmt_binlog_row_based();
772
   bzero((char *) &status_var, sizeof(status_var));
773
   sql_log_bin_toplevel= options & OPTION_BIN_LOG;
774
+  reset_stats();
775
 
776
 #if defined(ENABLED_DEBUG_SYNC)
777
   /* Initialize the Debug Sync Facility. See debug_sync.cc. */
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
778
@@ -914,6 +922,84 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
779
 #endif /* defined(ENABLED_DEBUG_SYNC) */
780
 }
781
 
782
+// Resets stats in a THD.
783
+void THD::reset_stats(void) {
784
+  current_connect_time = time(NULL);
785
+  last_global_update_time = current_connect_time;
786
+  reset_diff_stats();
787
+}
788
+
789
+// Resets the 'diff' stats, which are used to update global stats.
790
+void THD::reset_diff_stats(void) {
791
+  diff_total_busy_time = 0;
792
+  diff_total_cpu_time = 0;
793
+  diff_total_bytes_received = 0;
794
+  diff_total_bytes_sent = 0;
795
+  diff_total_binlog_bytes_written = 0;
796
+  diff_total_sent_rows = 0;
797
+  diff_total_updated_rows = 0;
798
+  diff_total_read_rows = 0;
799
+  diff_select_commands = 0;
800
+  diff_update_commands = 0;
801
+  diff_other_commands = 0;
802
+  diff_commit_trans = 0;
803
+  diff_rollback_trans = 0;
804
+  diff_denied_connections = 0;
805
+  diff_lost_connections = 0;
806
+  diff_access_denied_errors = 0;
807
+  diff_empty_queries = 0;
808
+}
809
+
810
+// Updates 'diff' stats of a THD.
811
+void THD::update_stats(bool ran_command) {
812
+  if (opt_userstat_running) {
813
+  diff_total_busy_time += busy_time;
814
+  diff_total_cpu_time += cpu_time;
815
+  diff_total_bytes_received += bytes_received;
816
+  diff_total_bytes_sent += bytes_sent;
817
+  diff_total_binlog_bytes_written += binlog_bytes_written;
818
+  diff_total_sent_rows += sent_row_count_2;
819
+  diff_total_updated_rows += updated_row_count;
820
+  // diff_total_read_rows is updated in handler.cc.
821
+
822
+  if (ran_command) {
823
+    // The replication thread has the COM_CONNECT command.
824
+    if ((old_command == COM_QUERY || command == COM_CONNECT) &&
825
+        (lex->sql_command >= 0 && lex->sql_command < SQLCOM_END)) {
826
+      // A SQL query.
827
+      if (lex->sql_command == SQLCOM_SELECT) {
828
+        diff_select_commands++;
829
+        if (!sent_row_count_2)
830
+          diff_empty_queries++;
831
+      } else if (! sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) {
832
+        // 'SHOW ' commands become SQLCOM_SELECT.
833
+        diff_other_commands++;
834
+        // 'SHOW ' commands shouldn't inflate total sent row count.
835
+        diff_total_sent_rows -= sent_row_count_2;
836
+      } else if (is_update_query(lex->sql_command)) {
837
+        diff_update_commands++;
838
+      } else {
839
+        diff_other_commands++;
840
+      }
841
+    }
842
+  }
843
+  // diff_commit_trans is updated in handler.cc.
844
+  // diff_rollback_trans is updated in handler.cc.
845
+  // diff_denied_connections is updated in sql_parse.cc.
846
+  // diff_lost_connections is updated in sql_parse.cc.
847
+  // diff_access_denied_errors is updated in sql_parse.cc.
848
+
849
+  /* reset counters to zero to avoid double-counting since values
850
+     are already store in diff_total_*. */
851
+  }
852
+  busy_time = 0;
853
+  cpu_time = 0;
854
+  bytes_received = 0;
855
+  bytes_sent = 0;
856
+  binlog_bytes_written = 0;
857
+  updated_row_count = 0;
858
+  sent_row_count_2 = 0;
859
+}
860
 
861
 /*
862
   Init THD for query processing.
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
863
@@ -1545,6 +1631,32 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
864
 }
865
 #endif
866
 
867
+char *THD::get_client_host_port(THD *client)
868
+{
869
+  Security_context *client_sctx= client->security_ctx;
870
+  char *client_host= NULL;
871
+
872
+  if (client->peer_port && (client_sctx->host || client_sctx->ip) &&
873
+      security_ctx->host_or_ip[0])
874
+  {
875
+    if ((client_host= (char *) this->alloc(LIST_PROCESS_HOST_LEN+1)))
876
+      my_snprintf((char *) client_host, LIST_PROCESS_HOST_LEN,
877
+                  "%s:%u", client_sctx->host_or_ip, client->peer_port);
878
+  }
879
+  else
880
+    client_host= this->strdup(client_sctx->host_or_ip[0] ?
881
+                              client_sctx->host_or_ip :
882
+                              client_sctx->host ? client_sctx->host : "");
883
+
884
+  return client_host;
885
+}
886
+
887
+const char *get_client_host(THD *client)
888
+{
889
+  return client->security_ctx->host_or_ip[0] ?
890
+      client->security_ctx->host_or_ip :
891
+      client->security_ctx->host ? client->security_ctx->host : "";
892
+}
893
 
894
 struct Item_change_record: public ilink
895
 {
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
896
@@ -1732,6 +1844,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
897
     buffer.set(buff, sizeof(buff), &my_charset_bin);
898
   }
899
   thd->sent_row_count++;
900
+  thd->sent_row_count_2++;
901
   if (thd->is_error())
902
   {
903
     protocol->remove_last_row();
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
904
@@ -1836,6 +1949,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
905
 select_export::~select_export()
906
 {
907
   thd->sent_row_count=row_count;
908
+  thd->sent_row_count_2=row_count;
909
 }
910
 
911
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
912
@@ -2868,6 +2982,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
913
   if (likely(thd != 0))
914
   { /* current_thd==0 when close_connection() calls net_send_error() */
915
     thd->status_var.bytes_sent+= length;
916
+    thd->bytes_sent+= length;
917
   }
918
 }
919
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
920
@@ -2875,6 +2990,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
921
 void thd_increment_bytes_received(ulong length)
922
 {
923
   current_thd->status_var.bytes_received+= length;
924
+  current_thd->bytes_received+= length;
925
 }
926
 
927
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
928
diff -ruN a/sql/sql_class.h b/sql/sql_class.h
929
--- a/sql/sql_class.h	2010-08-27 14:43:42.008006390 +0900
930
+++ b/sql/sql_class.h	2010-08-27 15:10:33.830058443 +0900
931
@@ -1435,6 +1435,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
932
     first byte of the packet in do_command()
933
   */
934
   enum enum_server_command command;
935
+  // Used to save the command, before it is set to COM_SLEEP.
936
+  enum enum_server_command old_command;
937
   uint32     server_id;
938
   uint32     file_id;			// for LOAD DATA INFILE
939
   /* remote (peer) port */
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
940
@@ -1828,6 +1830,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
941
   /* variables.transaction_isolation is reset to this after each commit */
942
   enum_tx_isolation session_tx_isolation;
943
   enum_check_fields count_cuted_fields;
944
+  ha_rows    updated_row_count;
945
+  ha_rows    sent_row_count_2; /* for userstat */
946
 
947
   DYNAMIC_ARRAY user_var_events;        /* For user variables replication */
948
   MEM_ROOT      *user_var_events_alloc; /* Allocate above array elements here */
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
949
@@ -1916,6 +1920,49 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
950
   */
951
   LOG_INFO*  current_linfo;
952
   NET*       slave_net;			// network connection from slave -> m.
953
+
954
+  /*
955
+    Used to update global user stats.  The global user stats are updated
956
+    occasionally with the 'diff' variables.  After the update, the 'diff'
957
+    variables are reset to 0.
958
+   */
959
+  // Time when the current thread connected to MySQL.
960
+  time_t current_connect_time;
961
+  // Last time when THD stats were updated in global_user_stats.
962
+  time_t last_global_update_time;
963
+  // Busy (non-idle) time for just one command.
964
+  double busy_time;
965
+  // Busy time not updated in global_user_stats yet.
966
+  double diff_total_busy_time;
967
+  // Cpu (non-idle) time for just one thread.
968
+  double cpu_time;
969
+  // Cpu time not updated in global_user_stats yet.
970
+  double diff_total_cpu_time;
971
+  /* bytes counting */
972
+  ulonglong bytes_received;
973
+  ulonglong diff_total_bytes_received;
974
+  ulonglong bytes_sent;
975
+  ulonglong diff_total_bytes_sent;
976
+  ulonglong binlog_bytes_written;
977
+  ulonglong diff_total_binlog_bytes_written;
978
+
979
+  // Number of rows not reflected in global_user_stats yet.
980
+  ha_rows diff_total_sent_rows, diff_total_updated_rows, diff_total_read_rows;
981
+  // Number of commands not reflected in global_user_stats yet.
982
+  ulonglong diff_select_commands, diff_update_commands, diff_other_commands;
983
+  // Number of transactions not reflected in global_user_stats yet.
984
+  ulonglong diff_commit_trans, diff_rollback_trans;
985
+  // Number of connection errors not reflected in global_user_stats yet.
986
+  ulonglong diff_denied_connections, diff_lost_connections;
987
+  // Number of db access denied, not reflected in global_user_stats yet.
988
+  ulonglong diff_access_denied_errors;
989
+  // Number of queries that return 0 rows
990
+  ulonglong diff_empty_queries;
991
+
992
+  // Per account query delay in miliseconds. When not 0, sleep this number of
993
+  // milliseconds before every SQL command.
994
+  ulonglong query_delay_millis;
995
+
996
   /* Used by the sys_var class to store temporary values */
997
   union
998
   {
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
999
@@ -1981,6 +2028,11 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1000
     alloc_root. 
1001
   */
1002
   void init_for_queries();
1003
+  void reset_stats(void);
1004
+  void reset_diff_stats(void);
1005
+  // ran_command is true when this is called immediately after a
1006
+  // command has been run.
1007
+  void update_stats(bool ran_command);
1008
   void change_user(void);
1009
   void cleanup(void);
1010
   void cleanup_after_query();
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1011
@@ -2351,9 +2403,15 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1012
     *p_db= strmake(db, db_length);
1013
     *p_db_length= db_length;
1014
     return FALSE;
1015
+
1016
+  // Returns string as 'IP:port' for the client-side of the connnection represented
1017
+  // by 'client' as displayed by SHOW PROCESSLIST. Allocates memory from the heap of
1018
+  // this THD and that is not reclaimed immediately, so use sparingly. May return NULL.
1019
   }
1020
   thd_scheduler scheduler;
1021
 
1022
+  char *get_client_host_port(THD *client);
1023
+
1024
 public:
1025
   inline Internal_error_handler *get_internal_handler()
1026
   { return m_internal_handler; }
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1027
@@ -2438,6 +2496,9 @@
1028
   LEX_STRING invoker_host;
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1029
 };
1030
 
1031
+// Returns string as 'IP' for the client-side of the connection represented by
1032
+// 'client'. Does not allocate memory. May return "".
1033
+const char *get_client_host(THD *client);
1034
 
1035
 /** A short cut for thd->main_da.set_ok_status(). */
1036
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1037
diff -ruN a/sql/sql_connect.cc b/sql/sql_connect.cc
1038
--- a/sql/sql_connect.cc	2010-08-27 14:38:08.750990238 +0900
1039
+++ b/sql/sql_connect.cc	2010-08-27 15:10:33.834058369 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1040
@@ -42,6 +42,24 @@
1041
 extern void win_install_sigabrt_handler();
1042
 #endif
1043
 
1044
+// Increments connection count for user.
1045
+static int increment_connection_count(THD* thd, bool use_lock);
1046
+
1047
+// Uses the THD to update the global stats by user name and client IP
1048
+void update_global_user_stats(THD* thd, bool create_user, time_t now);
1049
+
1050
+HASH global_user_stats;
1051
+HASH global_client_stats;
1052
+HASH global_thread_stats;
1053
+// Protects global_user_stats and global_client_stats
1054
+extern pthread_mutex_t LOCK_global_user_client_stats;
1055
+
1056
+HASH global_table_stats;
1057
+extern pthread_mutex_t LOCK_global_table_stats;
1058
+
1059
+HASH global_index_stats;
1060
+extern pthread_mutex_t LOCK_global_index_stats;
1061
+
1062
 /*
1063
   Get structure for logging connection data for the current user
1064
 */
1065
@@ -99,6 +117,563 @@
1066
 
1067
 }
1068
 
1069
+extern "C" uchar *get_key_user_stats(USER_STATS *user_stats, size_t *length,
1070
+                         my_bool not_used __attribute__((unused)))
1071
+{
1072
+  *length = strlen(user_stats->user);
1073
+  return (uchar*)user_stats->user;
1074
+}
1075
+
1076
+extern "C" uchar *get_key_thread_stats(THREAD_STATS *thread_stats, size_t *length,
1077
+                         my_bool not_used __attribute__((unused)))
1078
+{
1079
+  *length = sizeof(my_thread_id);
1080
+  return (uchar*)&(thread_stats->id);
1081
+}
1082
+
1083
+void free_user_stats(USER_STATS* user_stats)
1084
+{
1085
+  my_free((char*)user_stats, MYF(0));
1086
+}
1087
+
1088
+void free_thread_stats(THREAD_STATS* thread_stats)
1089
+{
1090
+  my_free((char*)thread_stats, MYF(0));
1091
+}
1092
+
1093
+void init_user_stats(USER_STATS *user_stats,
1094
+                     const char *user,
1095
+                     const char *priv_user,
1096
+                     uint total_connections,
1097
+                     uint concurrent_connections,
1098
+                     time_t connected_time,
1099
+                     double busy_time,
1100
+                     double cpu_time,
1101
+                     ulonglong bytes_received,
1102
+                     ulonglong bytes_sent,
1103
+                     ulonglong binlog_bytes_written,
1104
+                     ha_rows rows_fetched,
1105
+                     ha_rows rows_updated,
1106
+                     ha_rows rows_read,
1107
+                     ulonglong select_commands,
1108
+                     ulonglong update_commands,
1109
+                     ulonglong other_commands,
1110
+                     ulonglong commit_trans,
1111
+                     ulonglong rollback_trans,
1112
+                     ulonglong denied_connections,
1113
+                     ulonglong lost_connections,
1114
+                     ulonglong access_denied_errors,
1115
+                     ulonglong empty_queries)
1116
+{
1117
+  DBUG_ENTER("init_user_stats");
1118
+  DBUG_PRINT("info",
1119
+             ("Add user_stats entry for user %s - priv_user %s",
1120
+              user, priv_user));
1121
+  strncpy(user_stats->user, user, sizeof(user_stats->user));
1122
+  strncpy(user_stats->priv_user, priv_user, sizeof(user_stats->priv_user));
1123
+
1124
+  user_stats->total_connections = total_connections;
1125
+  user_stats->concurrent_connections = concurrent_connections;
1126
+  user_stats->connected_time = connected_time;
1127
+  user_stats->busy_time = busy_time;
1128
+  user_stats->cpu_time = cpu_time;
1129
+  user_stats->bytes_received = bytes_received;
1130
+  user_stats->bytes_sent = bytes_sent;
1131
+  user_stats->binlog_bytes_written = binlog_bytes_written;
1132
+  user_stats->rows_fetched = rows_fetched;
1133
+  user_stats->rows_updated = rows_updated;
1134
+  user_stats->rows_read = rows_read;
1135
+  user_stats->select_commands = select_commands;
1136
+  user_stats->update_commands = update_commands;
1137
+  user_stats->other_commands = other_commands;
1138
+  user_stats->commit_trans = commit_trans;
1139
+  user_stats->rollback_trans = rollback_trans;
1140
+  user_stats->denied_connections = denied_connections;
1141
+  user_stats->lost_connections = lost_connections;
1142
+  user_stats->access_denied_errors = access_denied_errors;
1143
+  user_stats->empty_queries = empty_queries;
1144
+  DBUG_VOID_RETURN;
1145
+}
1146
+
1147
+void init_thread_stats(THREAD_STATS *thread_stats,
1148
+                     my_thread_id id,
1149
+                     uint total_connections,
1150
+                     uint concurrent_connections,
1151
+                     time_t connected_time,
1152
+                     double busy_time,
1153
+                     double cpu_time,
1154
+                     ulonglong bytes_received,
1155
+                     ulonglong bytes_sent,
1156
+                     ulonglong binlog_bytes_written,
1157
+                     ha_rows rows_fetched,
1158
+                     ha_rows rows_updated,
1159
+                     ha_rows rows_read,
1160
+                     ulonglong select_commands,
1161
+                     ulonglong update_commands,
1162
+                     ulonglong other_commands,
1163
+                     ulonglong commit_trans,
1164
+                     ulonglong rollback_trans,
1165
+                     ulonglong denied_connections,
1166
+                     ulonglong lost_connections,
1167
+                     ulonglong access_denied_errors,
1168
+                     ulonglong empty_queries)
1169
+{
1170
+  DBUG_ENTER("init_thread_stats");
1171
+  DBUG_PRINT("info",
1172
+             ("Add thread_stats entry for thread %lu",
1173
+              id));
1174
+  thread_stats->id = id;
1175
+
1176
+  thread_stats->total_connections = total_connections;
1177
+  thread_stats->concurrent_connections = concurrent_connections;
1178
+  thread_stats->connected_time = connected_time;
1179
+  thread_stats->busy_time = busy_time;
1180
+  thread_stats->cpu_time = cpu_time;
1181
+  thread_stats->bytes_received = bytes_received;
1182
+  thread_stats->bytes_sent = bytes_sent;
1183
+  thread_stats->binlog_bytes_written = binlog_bytes_written;
1184
+  thread_stats->rows_fetched = rows_fetched;
1185
+  thread_stats->rows_updated = rows_updated;
1186
+  thread_stats->rows_read = rows_read;
1187
+  thread_stats->select_commands = select_commands;
1188
+  thread_stats->update_commands = update_commands;
1189
+  thread_stats->other_commands = other_commands;
1190
+  thread_stats->commit_trans = commit_trans;
1191
+  thread_stats->rollback_trans = rollback_trans;
1192
+  thread_stats->denied_connections = denied_connections;
1193
+  thread_stats->lost_connections = lost_connections;
1194
+  thread_stats->access_denied_errors = access_denied_errors;
1195
+  thread_stats->empty_queries = empty_queries;
1196
+  DBUG_VOID_RETURN;
1197
+}
1198
+
1199
+void add_user_stats(USER_STATS *user_stats,
1200
+                    uint total_connections,
1201
+                    uint concurrent_connections,
1202
+                    time_t connected_time,
1203
+                    double busy_time,
1204
+                    double cpu_time,
1205
+                    ulonglong bytes_received,
1206
+                    ulonglong bytes_sent,
1207
+                    ulonglong binlog_bytes_written,
1208
+                    ha_rows rows_fetched,
1209
+                    ha_rows rows_updated,
1210
+                    ha_rows rows_read,
1211
+                    ulonglong select_commands,
1212
+                    ulonglong update_commands,
1213
+                    ulonglong other_commands,
1214
+                    ulonglong commit_trans,
1215
+                    ulonglong rollback_trans,
1216
+                    ulonglong denied_connections,
1217
+                    ulonglong lost_connections,
1218
+                    ulonglong access_denied_errors,
1219
+                    ulonglong empty_queries)
1220
+{
1221
+  user_stats->total_connections += total_connections;
1222
+  user_stats->concurrent_connections += concurrent_connections;
1223
+  user_stats->connected_time += connected_time;
1224
+  user_stats->busy_time += busy_time;
1225
+  user_stats->cpu_time += cpu_time;
1226
+  user_stats->bytes_received += bytes_received;
1227
+  user_stats->bytes_sent += bytes_sent;
1228
+  user_stats->binlog_bytes_written += binlog_bytes_written;
1229
+  user_stats->rows_fetched += rows_fetched;
1230
+  user_stats->rows_updated += rows_updated;
1231
+  user_stats->rows_read += rows_read;
1232
+  user_stats->select_commands += select_commands;
1233
+  user_stats->update_commands += update_commands;
1234
+  user_stats->other_commands += other_commands;
1235
+  user_stats->commit_trans += commit_trans;
1236
+  user_stats->rollback_trans += rollback_trans;
1237
+  user_stats->denied_connections += denied_connections;
1238
+  user_stats->lost_connections += lost_connections;
1239
+  user_stats->access_denied_errors += access_denied_errors;
1240
+  user_stats->empty_queries += empty_queries;
1241
+}
1242
+
1243
+void add_thread_stats(THREAD_STATS *thread_stats,
1244
+                    uint total_connections,
1245
+                    uint concurrent_connections,
1246
+                    time_t connected_time,
1247
+                    double busy_time,
1248
+                    double cpu_time,
1249
+                    ulonglong bytes_received,
1250
+                    ulonglong bytes_sent,
1251
+                    ulonglong binlog_bytes_written,
1252
+                    ha_rows rows_fetched,
1253
+                    ha_rows rows_updated,
1254
+                    ha_rows rows_read,
1255
+                    ulonglong select_commands,
1256
+                    ulonglong update_commands,
1257
+                    ulonglong other_commands,
1258
+                    ulonglong commit_trans,
1259
+                    ulonglong rollback_trans,
1260
+                    ulonglong denied_connections,
1261
+                    ulonglong lost_connections,
1262
+                    ulonglong access_denied_errors,
1263
+                    ulonglong empty_queries)
1264
+{
1265
+  thread_stats->total_connections += total_connections;
1266
+  thread_stats->concurrent_connections += concurrent_connections;
1267
+  thread_stats->connected_time += connected_time;
1268
+  thread_stats->busy_time += busy_time;
1269
+  thread_stats->cpu_time += cpu_time;
1270
+  thread_stats->bytes_received += bytes_received;
1271
+  thread_stats->bytes_sent += bytes_sent;
1272
+  thread_stats->binlog_bytes_written += binlog_bytes_written;
1273
+  thread_stats->rows_fetched += rows_fetched;
1274
+  thread_stats->rows_updated += rows_updated;
1275
+  thread_stats->rows_read += rows_read;
1276
+  thread_stats->select_commands += select_commands;
1277
+  thread_stats->update_commands += update_commands;
1278
+  thread_stats->other_commands += other_commands;
1279
+  thread_stats->commit_trans += commit_trans;
1280
+  thread_stats->rollback_trans += rollback_trans;
1281
+  thread_stats->denied_connections += denied_connections;
1282
+  thread_stats->lost_connections += lost_connections;
1283
+  thread_stats->access_denied_errors += access_denied_errors;
1284
+  thread_stats->empty_queries += empty_queries;
1285
+}
1286
+
1287
+void init_global_user_stats(void)
1288
+{
1289
+  if (hash_init(&global_user_stats, system_charset_info, max_connections,
1290
+                0, 0, (hash_get_key)get_key_user_stats,
1291
+                (hash_free_key)free_user_stats, 0)) {
1292
+    sql_print_error("Initializing global_user_stats failed.");
1293
+    exit(1);
1294
+  }
1295
+}
1296
+
1297
+void init_global_client_stats(void)
1298
+{
1299
+  if (hash_init(&global_client_stats, system_charset_info, max_connections,
1300
+                0, 0, (hash_get_key)get_key_user_stats,
1301
+                (hash_free_key)free_user_stats, 0)) {
1302
+    sql_print_error("Initializing global_client_stats failed.");
1303
+    exit(1);
1304
+  }
1305
+}
1306
+
1307
+void init_global_thread_stats(void)
1308
+{
1309
+  if (hash_init(&global_thread_stats, &my_charset_bin, max_connections,
1310
+                0, 0, (hash_get_key)get_key_thread_stats,
1311
+                (hash_free_key)free_thread_stats, 0)) {
1312
+    sql_print_error("Initializing global_client_stats failed.");
1313
+    exit(1);
1314
+  }
1315
+}
1316
+
1317
+extern "C" uchar *get_key_table_stats(TABLE_STATS *table_stats, size_t *length,
1318
+                                     my_bool not_used __attribute__((unused)))
1319
+{
1320
+  *length = strlen(table_stats->table);
1321
+  return (uchar*)table_stats->table;
1322
+}
1323
+
1324
+extern "C" void free_table_stats(TABLE_STATS* table_stats)
1325
+{
1326
+  my_free((char*)table_stats, MYF(0));
1327
+}
1328
+
1329
+void init_global_table_stats(void)
1330
+{
1331
+  if (hash_init(&global_table_stats, system_charset_info, max_connections,
1332
+                0, 0, (hash_get_key)get_key_table_stats,
1333
+                (hash_free_key)free_table_stats, 0)) {
1334
+    sql_print_error("Initializing global_table_stats failed.");
1335
+    exit(1);
1336
+  }
1337
+}
1338
+
1339
+extern "C" uchar *get_key_index_stats(INDEX_STATS *index_stats, size_t *length,
1340
+                                     my_bool not_used __attribute__((unused)))
1341
+{
1342
+  *length = strlen(index_stats->index);
1343
+  return (uchar*)index_stats->index;
1344
+}
1345
+
1346
+extern "C" void free_index_stats(INDEX_STATS* index_stats)
1347
+{
1348
+  my_free((char*)index_stats, MYF(0));
1349
+}
1350
+
1351
+void init_global_index_stats(void)
1352
+{
1353
+  if (hash_init(&global_index_stats, system_charset_info, max_connections,
1354
+                0, 0, (hash_get_key)get_key_index_stats,
1355
+                (hash_free_key)free_index_stats, 0)) {
1356
+    sql_print_error("Initializing global_index_stats failed.");
1357
+    exit(1);
1358
+  }
1359
+}
1360
+
1361
+void free_global_user_stats(void)
1362
+{
1363
+  hash_free(&global_user_stats);
1364
+}
1365
+
1366
+void free_global_thread_stats(void)
1367
+{
1368
+  hash_free(&global_thread_stats);
1369
+}
1370
+
1371
+void free_global_table_stats(void)
1372
+{
1373
+  hash_free(&global_table_stats);
1374
+}
1375
+
1376
+void free_global_index_stats(void)
1377
+{
1378
+  hash_free(&global_index_stats);
1379
+}
1380
+
1381
+void free_global_client_stats(void)
1382
+{
1383
+  hash_free(&global_client_stats);
1384
+}
1385
+
1386
+// 'mysql_system_user' is used for when the user is not defined for a THD.
1387
+static char mysql_system_user[] = "#mysql_system#";
1388
+
1389
+// Returns 'user' if it's not NULL.  Returns 'mysql_system_user' otherwise.
1390
+static char* get_valid_user_string(char* user) {
1391
+  return user ? user : mysql_system_user;
1392
+}
1393
+
1394
+// Increments the global stats connection count for an entry from
1395
+// global_client_stats or global_user_stats. Returns 0 on success
1396
+// and 1 on error.
1397
+static int increment_count_by_name(const char *name, const char *role_name,
1398
+                                   HASH *users_or_clients, THD *thd)
1399
+{
1400
+  USER_STATS* user_stats;
1401
+
1402
+  if (!(user_stats = (USER_STATS*)hash_search(users_or_clients, (uchar*) name,
1403
+                                              strlen(name))))
1404
+  {
1405
+    // First connection for this user or client
1406
+    if (!(user_stats = ((USER_STATS*)
1407
+                        my_malloc(sizeof(USER_STATS), MYF(MY_WME | MY_ZEROFILL)))))
1408
+    {
1409
+      return 1; // Out of memory
1410
+    }
1411
+
1412
+    init_user_stats(user_stats, name, role_name,
1413
+                    0, 0,      // connections
1414
+                    0, 0, 0,   // time
1415
+                    0, 0, 0,   // bytes sent, received and written
1416
+                    0, 0, 0,   // rows fetched, updated and read
1417
+                    0, 0, 0,   // select, update and other commands
1418
+                    0, 0,      // commit and rollback trans
1419
+                    thd->diff_denied_connections,
1420
+                    0,         // lost connections
1421
+                    0,         // access denied errors
1422
+                    0);        // empty queries
1423
+
1424
+    if (my_hash_insert(users_or_clients, (uchar*)user_stats))
1425
+    {
1426
+      my_free((char*)user_stats, 0);
1427
+      return 1; // Out of memory
1428
+    }
1429
+  }
1430
+  user_stats->total_connections++;
1431
+  return 0;
1432
+}
1433
+
1434
+static int increment_count_by_id(my_thread_id id,
1435
+                                 HASH *users_or_clients, THD *thd)
1436
+{
1437
+  THREAD_STATS* thread_stats;
1438
+
1439
+  if (!(thread_stats = (THREAD_STATS*)hash_search(users_or_clients, (uchar*) &id,
1440
+                                              sizeof(my_thread_id))))
1441
+  {
1442
+    // First connection for this user or client
1443
+    if (!(thread_stats = ((THREAD_STATS*)
1444
+                        my_malloc(sizeof(THREAD_STATS), MYF(MY_WME | MY_ZEROFILL)))))
1445
+    {
1446
+      return 1; // Out of memory
1447
+    }
1448
+
1449
+    init_thread_stats(thread_stats, id,
1450
+                    0, 0,      // connections
1451
+                    0, 0, 0,   // time
1452
+                    0, 0, 0,   // bytes sent, received and written
1453
+                    0, 0, 0,   // rows fetched, updated and read
1454
+                    0, 0, 0,   // select, update and other commands
1455
+                    0, 0,      // commit and rollback trans
1456
+                    thd->diff_denied_connections,
1457
+                    0,         // lost connections
1458
+                    0,         // access denied errors
1459
+                    0);        // empty queries
1460
+
1461
+    if (my_hash_insert(users_or_clients, (uchar*)thread_stats))
1462
+    {
1463
+      my_free((char*)thread_stats, 0);
1464
+      return 1; // Out of memory
1465
+    }
1466
+  }
1467
+  thread_stats->total_connections++;
1468
+  return 0;
1469
+}
1470
+
1471
+// Increments the global user and client stats connection count.  If 'use_lock'
1472
+// is true, LOCK_global_user_client_stats will be locked/unlocked.  Returns
1473
+// 0 on success, 1 on error.
1474
+static int increment_connection_count(THD* thd, bool use_lock)
1475
+{
1476
+  char* user_string = get_valid_user_string(thd->main_security_ctx.user);
1477
+  const char* client_string = get_client_host(thd);
1478
+  int return_value = 0;
1479
+
1480
+  if (!opt_userstat_running)
1481
+    return return_value;
1482
+
1483
+  if (use_lock) pthread_mutex_lock(&LOCK_global_user_client_stats);
1484
+
1485
+  if (increment_count_by_name(user_string, user_string,
1486
+                              &global_user_stats, thd))
1487
+  {
1488
+    return_value = 1;
1489
+    goto end;
1490
+  }
1491
+  if (increment_count_by_name(client_string,
1492
+                              user_string,
1493
+                              &global_client_stats, thd))
1494
+  {
1495
+    return_value = 1;
1496
+    goto end;
1497
+  }
1498
+  if (opt_thread_statistics) {
1499
+    if (increment_count_by_id(thd->thread_id, &global_thread_stats, thd))
1500
+    {
1501
+      return_value = 1;
1502
+      goto end;
1503
+    }
1504
+  }
1505
+
1506
+end:
1507
+  if (use_lock) pthread_mutex_unlock(&LOCK_global_user_client_stats);
1508
+  return return_value;
1509
+}
1510
+
1511
+// Used to update the global user and client stats.
1512
+static void update_global_user_stats_with_user(THD* thd,
1513
+                                               USER_STATS* user_stats,
1514
+                                               time_t now)
1515
+{
1516
+  user_stats->connected_time += now - thd->last_global_update_time;
1517
+//  thd->last_global_update_time = now;
1518
+  user_stats->busy_time += thd->diff_total_busy_time;
1519
+  user_stats->cpu_time += thd->diff_total_cpu_time;
1520
+  user_stats->bytes_received += thd->diff_total_bytes_received;
1521
+  user_stats->bytes_sent += thd->diff_total_bytes_sent;
1522
+  user_stats->binlog_bytes_written += thd->diff_total_binlog_bytes_written;
1523
+  user_stats->rows_fetched += thd->diff_total_sent_rows;
1524
+  user_stats->rows_updated += thd->diff_total_updated_rows;
1525
+  user_stats->rows_read += thd->diff_total_read_rows;
1526
+  user_stats->select_commands += thd->diff_select_commands;
1527
+  user_stats->update_commands += thd->diff_update_commands;
1528
+  user_stats->other_commands += thd->diff_other_commands;
1529
+  user_stats->commit_trans += thd->diff_commit_trans;
1530
+  user_stats->rollback_trans += thd->diff_rollback_trans;
1531
+  user_stats->denied_connections += thd->diff_denied_connections;
1532
+  user_stats->lost_connections += thd->diff_lost_connections;
1533
+  user_stats->access_denied_errors += thd->diff_access_denied_errors;
1534
+  user_stats->empty_queries += thd->diff_empty_queries;
1535
+}
1536
+
1537
+static void update_global_thread_stats_with_thread(THD* thd,
1538
+                                               THREAD_STATS* thread_stats,
1539
+                                               time_t now)
1540
+{
1541
+  thread_stats->connected_time += now - thd->last_global_update_time;
1542
+//  thd->last_global_update_time = now;
1543
+  thread_stats->busy_time += thd->diff_total_busy_time;
1544
+  thread_stats->cpu_time += thd->diff_total_cpu_time;
1545
+  thread_stats->bytes_received += thd->diff_total_bytes_received;
1546
+  thread_stats->bytes_sent += thd->diff_total_bytes_sent;
1547
+  thread_stats->binlog_bytes_written += thd->diff_total_binlog_bytes_written;
1548
+  thread_stats->rows_fetched += thd->diff_total_sent_rows;
1549
+  thread_stats->rows_updated += thd->diff_total_updated_rows;
1550
+  thread_stats->rows_read += thd->diff_total_read_rows;
1551
+  thread_stats->select_commands += thd->diff_select_commands;
1552
+  thread_stats->update_commands += thd->diff_update_commands;
1553
+  thread_stats->other_commands += thd->diff_other_commands;
1554
+  thread_stats->commit_trans += thd->diff_commit_trans;
1555
+  thread_stats->rollback_trans += thd->diff_rollback_trans;
1556
+  thread_stats->denied_connections += thd->diff_denied_connections;
1557
+  thread_stats->lost_connections += thd->diff_lost_connections;
1558
+  thread_stats->access_denied_errors += thd->diff_access_denied_errors;
1559
+  thread_stats->empty_queries += thd->diff_empty_queries;
1560
+}
1561
+
1562
+// Updates the global stats of a user or client
1563
+void update_global_user_stats(THD* thd, bool create_user, time_t now)
1564
+{
1565
+  if (opt_userstat_running) {
1566
+  char* user_string = get_valid_user_string(thd->main_security_ctx.user);
1567
+  const char* client_string = get_client_host(thd);
1568
+
1569
+  USER_STATS* user_stats;
1570
+  THREAD_STATS* thread_stats;
1571
+  pthread_mutex_lock(&LOCK_global_user_client_stats);
1572
+
1573
+  // Update by user name
1574
+  if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
1575
+                                             (uchar*)user_string,
1576
+                                             strlen(user_string)))) {
1577
+    // Found user.
1578
+    update_global_user_stats_with_user(thd, user_stats, now);
1579
+  } else {
1580
+    // Create the entry
1581
+    if (create_user) {
1582
+      increment_count_by_name(user_string, user_string,
1583
+                              &global_user_stats, thd);
1584
+    }
1585
+  }
1586
+
1587
+  // Update by client IP
1588
+  if ((user_stats = (USER_STATS*)hash_search(&global_client_stats,
1589
+                                             (uchar*)client_string,
1590
+                                             strlen(client_string)))) {
1591
+    // Found by client IP
1592
+    update_global_user_stats_with_user(thd, user_stats, now);
1593
+  } else {
1594
+    // Create the entry
1595
+    if (create_user) {
1596
+      increment_count_by_name(client_string,
1597
+                              user_string,
1598
+                              &global_client_stats, thd);
1599
+    }
1600
+  }
1601
+
1602
+  if (opt_thread_statistics) {
1603
+    // Update by thread ID
1604
+    if ((thread_stats = (THREAD_STATS*)hash_search(&global_thread_stats,
1605
+                                             (uchar*) &(thd->thread_id),
1606
+                                             sizeof(my_thread_id)))) {
1607
+      // Found by thread ID
1608
+      update_global_thread_stats_with_thread(thd, thread_stats, now);
1609
+    } else {
1610
+      // Create the entry
1611
+      if (create_user) {
1612
+        increment_count_by_id(thd->thread_id,
1613
+                              &global_thread_stats, thd);
1614
+      }
1615
+    }
1616
+  }
1617
+
1618
+  thd->last_global_update_time = now;
1619
+  thd->reset_diff_stats();
1620
+
1621
+  pthread_mutex_unlock(&LOCK_global_user_client_stats);
1622
+  } else {
1623
+  thd->reset_diff_stats();
1624
+  }
1625
+}
1626
 
1627
 /*
1628
   check if user has already too many connections
1629
@@ -154,7 +729,10 @@
1630
 
1631
 end:
1632
   if (error)
1633
+  {
1634
     uc->connections--; // no need for decrease_user_connections() here
1635
+    statistic_increment(denied_connections, &LOCK_status);
1636
+  }
1637
   (void) pthread_mutex_unlock(&LOCK_user_conn);
1638
   DBUG_RETURN(error);
1639
 }
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
1640
@@ -490,6 +1068,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1641
     general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
1642
     DBUG_RETURN(1);
1643
   }
1644
+  thd->diff_access_denied_errors++;
1645
   my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
1646
            thd->main_security_ctx.user,
1647
            thd->main_security_ctx.host_or_ip,
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
1648
@@ -971,11 +1550,20 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1649
       my_sleep(1000);				/* must wait after eof() */
1650
 #endif
1651
     statistic_increment(aborted_connects,&LOCK_status);
1652
+    thd->diff_denied_connections++;
1653
     DBUG_RETURN(1);
1654
   }
1655
   /* Connect completed, set read/write timeouts back to default */
1656
   my_net_set_read_timeout(net, thd->variables.net_read_timeout);
1657
   my_net_set_write_timeout(net, thd->variables.net_write_timeout);
1658
+
1659
+  thd->reset_stats();
1660
+  // Updates global user connection stats.
1661
+  if (increment_connection_count(thd, true)) {
1662
+    net_send_error(thd, ER_OUTOFMEMORY);  // Out of memory
1663
+    DBUG_RETURN(1);
1664
+  }
1665
+
1666
   DBUG_RETURN(0);
1667
 }
1668
 
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
1669
@@ -997,6 +1585,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1670
   if (thd->killed || (net->error && net->vio != 0))
1671
   {
1672
     statistic_increment(aborted_threads,&LOCK_status);
1673
+    thd->diff_lost_connections++;
1674
   }
1675
 
1676
   if (net->error && net->vio != 0)
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
1677
@@ -1123,10 +1712,14 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1678
   for (;;)
1679
   {
1680
     NET *net= &thd->net;
1681
+    bool create_user= TRUE;
1682
 
1683
     lex_start(thd);
1684
     if (login_connection(thd))
1685
+    {
1686
+      create_user= FALSE;
1687
       goto end_thread;
1688
+    }
1689
 
1690
     prepare_new_connection_state(thd);
1691
 
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
1692
@@ -1149,6 +1742,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1693
    
1694
 end_thread:
1695
     close_connection(thd, 0, 1);
1696
+    thd->update_stats(false);
1697
+    update_global_user_stats(thd, create_user, time(NULL));
1698
     if (thread_scheduler.end_thread(thd,1))
1699
       return 0;                                 // Probably no-threads
1700
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1701
diff -ruN a/sql/sql_delete.cc b/sql/sql_delete.cc
1702
--- a/sql/sql_delete.cc	2010-08-04 02:24:34.000000000 +0900
1703
+++ b/sql/sql_delete.cc	2010-08-27 15:10:33.837058490 +0900
1704
@@ -452,6 +452,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1705
     my_ok(thd, (ha_rows) thd->row_count_func);
1706
     DBUG_PRINT("info",("%ld records deleted",(long) deleted));
1707
   }
1708
+  thd->updated_row_count += deleted;
1709
   DBUG_RETURN(error >= 0 || thd->is_error());
1710
 }
1711
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1712
@@ -1059,6 +1060,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1713
     thd->row_count_func= deleted;
1714
     ::my_ok(thd, (ha_rows) thd->row_count_func);
1715
   }
1716
+  thd->updated_row_count += deleted;
1717
   return 0;
1718
 }
1719
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1720
diff -ruN a/sql/sql_insert.cc b/sql/sql_insert.cc
1721
--- a/sql/sql_insert.cc	2010-08-04 02:24:19.000000000 +0900
1722
+++ b/sql/sql_insert.cc	2010-08-27 15:10:33.841059138 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1723
@@ -981,6 +981,7 @@
1724
     thd->row_count_func= info.copied + info.deleted + updated;
1725
     ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
1726
   }
1727
+  thd->updated_row_count += thd->row_count_func;
1728
   thd->abort_on_warning= 0;
1729
   DBUG_RETURN(FALSE);
1730
 
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1731
@@ -3311,6 +3312,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1732
      thd->first_successful_insert_id_in_prev_stmt :
1733
      (info.copied ? autoinc_value_of_last_inserted_row : 0));
1734
   ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
1735
+  thd->updated_row_count += thd->row_count_func;
1736
   DBUG_RETURN(0);
1737
 }
1738
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1739
diff -ruN a/sql/sql_lex.h b/sql/sql_lex.h
1740
--- a/sql/sql_lex.h	2010-08-27 14:29:26.030989835 +0900
1741
+++ b/sql/sql_lex.h	2010-08-27 15:10:33.844058293 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1742
@@ -124,6 +124,9 @@
1743
     When a command is added here, be sure it's also added in mysqld.cc
1744
     in "struct show_var_st status_vars[]= {" ...
1745
   */
1746
+  // TODO(mcallaghan): update status_vars in mysqld to export these
1747
+  SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS,
1748
+  SQLCOM_SHOW_CLIENT_STATS, SQLCOM_SHOW_THREAD_STATS,
1749
   /* This should be the last !!! */
1750
   SQLCOM_END
1751
 };
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1752
diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
1753
--- a/sql/sql_parse.cc	2010-08-27 14:38:08.757059579 +0900
1754
+++ b/sql/sql_parse.cc	2010-08-27 15:15:30.420996146 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1755
@@ -46,6 +46,9 @@
1756
 static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
1757
 static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
1758
 
1759
+// Uses the THD to update the global stats by user name and client IP
1760
+void update_global_user_stats(THD* thd, bool create_user, time_t now);
1761
+
1762
 const char *any_db="*any*";	// Special symbol for check_access
1763
 
1764
 const LEX_STRING command_name[]={
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1765
@@ -824,6 +827,12 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1766
   */
1767
   thd->clear_error();				// Clear error message
1768
   thd->main_da.reset_diagnostics_area();
1769
+  thd->updated_row_count=0;
1770
+  thd->busy_time=0;
1771
+  thd->cpu_time=0;
1772
+  thd->bytes_received=0;
1773
+  thd->bytes_sent=0;
1774
+  thd->binlog_bytes_written=0;
1775
 
1776
   net_new_transaction(net);
1777
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1778
@@ -993,6 +1002,9 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1779
   DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
1780
 
1781
   thd->command=command;
1782
+  // To increment the corrent command counter for user stats, 'command' must
1783
+  // be saved because it is set to COM_SLEEP at the end of this function.
1784
+  thd->old_command = command;
1785
   /*
1786
     Commands which always take a long time are logged into
1787
     the slow log only if opt_log_slow_admin_statements is set.
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1788
@@ -1864,6 +1876,13 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1789
     thd->profiling.discard_current_query();
1790
 #endif
1791
     break;
1792
+  case SCH_USER_STATS:
1793
+  case SCH_CLIENT_STATS:
1794
+  case SCH_THREAD_STATS:
1795
+    if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
1796
+      DBUG_RETURN(1);
1797
+  case SCH_TABLE_STATS:
1798
+  case SCH_INDEX_STATS:
1799
   case SCH_OPEN_TABLES:
1800
   case SCH_VARIABLES:
1801
   case SCH_STATUS:
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1802
@@ -2020,6 +2039,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1803
                        thd->security_ctx->priv_host)) &&
1804
         check_global_access(thd, SUPER_ACL))
1805
     {
1806
+      thd->diff_access_denied_errors++;
1807
       my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
1808
       DBUG_RETURN(TRUE);
1809
     }
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1810
@@ -5331,6 +5351,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1811
       if (!no_errors)
1812
       {
1813
         const char *db_name= db ? db : thd->db;
1814
+        thd->diff_access_denied_errors++;
1815
         my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
1816
                  sctx->priv_user, sctx->priv_host, db_name);
1817
       }
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1818
@@ -5363,12 +5384,15 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1819
   {						// We can never grant this
1820
     DBUG_PRINT("error",("No possible access"));
1821
     if (!no_errors)
1822
+    {
1823
+      thd->diff_access_denied_errors++;
1824
       my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
1825
                sctx->priv_user,
1826
                sctx->priv_host,
1827
                (thd->password ?
1828
                 ER(ER_YES) :
1829
                 ER(ER_NO)));                    /* purecov: tested */
1830
+    }
1831
     DBUG_RETURN(TRUE);				/* purecov: tested */
1832
   }
1833
 
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1834
@@ -5394,11 +5418,15 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1835
 
1836
   DBUG_PRINT("error",("Access denied"));
1837
   if (!no_errors)
1838
+  {
1839
+    // increment needs !no_errors condition, otherwise double counting.
1840
+    thd->diff_access_denied_errors++;
1841
     my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
1842
              sctx->priv_user, sctx->priv_host,
1843
              (db ? db : (thd->db ?
1844
                          thd->db :
1845
                          "unknown")));          /* purecov: tested */
1846
+  }
1847
   DBUG_RETURN(TRUE);				/* purecov: tested */
1848
 }
1849
 
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1850
@@ -5427,6 +5455,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1851
 
1852
     if (!thd->col_access && check_grant_db(thd, dst_db_name))
1853
     {
1854
+      thd->diff_access_denied_errors++;
1855
       my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
1856
                thd->security_ctx->priv_user,
1857
                thd->security_ctx->priv_host,
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1858
@@ -5508,9 +5537,12 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1859
         (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
1860
     {
1861
       if (!no_errors)
1862
+      {
1863
+        thd->diff_access_denied_errors++;
1864
         my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
1865
                  sctx->priv_user, sctx->priv_host,
1866
                  INFORMATION_SCHEMA_NAME.str);
1867
+      }
1868
       return TRUE;
1869
     }
1870
     /*
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1871
@@ -5673,6 +5705,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1872
   if ((thd->security_ctx->master_access & want_access))
1873
     return 0;
1874
   get_privilege_desc(command, sizeof(command), want_access);
1875
+  thd->diff_access_denied_errors++;
1876
   my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
1877
   return 1;
1878
 #else
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1879
@@ -6054,6 +6087,34 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1880
   lex_start(thd);
1881
   mysql_reset_thd_for_next_command(thd);
1882
 
1883
+  int start_time_error = 0;
1884
+  int end_time_error = 0;
1885
+  struct timeval start_time, end_time;
1886
+  double start_usecs = 0;
1887
+  double end_usecs = 0;
1888
+  /* cpu time */
1889
+  int cputime_error = 0;
1890
+  struct timespec tp;
1891
+  double start_cpu_nsecs = 0;
1892
+  double end_cpu_nsecs = 0;
1893
+
1894
+  if (opt_userstat_running) {
1895
+#ifdef HAVE_CLOCK_GETTIME
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1896
+    /* get start cputime */
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1897
+    if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
1898
+      start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
1899
+#else
1900
+#warning : HAVE_CLOCK_GETTIME is disabled.
1901
+#warning : Most systems require librt library to use the function clock_gettime().
1902
+#warning : Did you set environment when ./configure ?  (e.g. "export LIBS=-lrt" for sh)
1903
+#endif
1904
+
1905
+    // Gets the start time, in order to measure how long this command takes.
1906
+    if (!(start_time_error = gettimeofday(&start_time, NULL))) {
1907
+      start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
1908
+    }
1909
+  }
1910
+
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
1911
   if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1912
   {
1913
     LEX *lex= thd->lex;
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1914
@@ -6134,6 +6195,43 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1915
     *found_semicolon= NULL;
1916
   }
1917
 
1918
+  if (opt_userstat_running) {
1919
+    // Gets the end time.
1920
+    if (!(end_time_error = gettimeofday(&end_time, NULL))) {
1921
+      end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
1922
+    }
1923
+
1924
+    // Calculates the difference between the end and start times.
1925
+    if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
1926
+      thd->busy_time = (end_usecs - start_usecs) / 1000000;
1927
+      // In case there are bad values, 2629743 is the #seconds in a month.
1928
+      if (thd->busy_time > 2629743) {
1929
+        thd->busy_time = 0;
1930
+      }
1931
+    } else {
1932
+      // end time went back in time, or gettimeofday() failed.
1933
+      thd->busy_time = 0;
1934
+    }
1935
+
1936
+#ifdef HAVE_CLOCK_GETTIME
1937
+    /* get end cputime */
1938
+    if (!cputime_error &&
1939
+        !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
1940
+      end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
1941
+#endif
1942
+    if (start_cpu_nsecs && !cputime_error) {
1943
+      thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
1944
+      // In case there are bad values, 2629743 is the #seconds in a month.
1945
+      if (thd->cpu_time > 2629743) {
1946
+        thd->cpu_time = 0;
1947
+      }
1948
+    } else
1949
+      thd->cpu_time = 0;
1950
+  }
1951
+  // Updates THD stats and the global user stats.
1952
+  thd->update_stats(true);
1953
+  update_global_user_stats(thd, true, time(NULL));
1954
+
1955
   DBUG_VOID_RETURN;
1956
 }
1957
 
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1958
@@ -6999,6 +7097,13 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1959
     if (flush_error_log())
1960
       result=1;
1961
   }
1962
+  if (((options & (REFRESH_SLOW_QUERY_LOG | REFRESH_LOG)) ==
1963
+       REFRESH_SLOW_QUERY_LOG))
1964
+  {
1965
+    /* We are only flushing slow query log */
1966
+    logger.flush_slow_log(thd);
1967
+  }
1968
+
1969
 #ifdef HAVE_QUERY_CACHE
1970
   if (options & REFRESH_QUERY_CACHE_FREE)
1971
   {
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
1972
@@ -7099,6 +7204,40 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
1973
 #endif
1974
  if (options & REFRESH_USER_RESOURCES)
1975
    reset_mqh((LEX_USER *) NULL, 0);             /* purecov: inspected */
1976
+  if (options & REFRESH_TABLE_STATS)
1977
+  {
1978
+    pthread_mutex_lock(&LOCK_global_table_stats);
1979
+    free_global_table_stats();
1980
+    init_global_table_stats();
1981
+    pthread_mutex_unlock(&LOCK_global_table_stats);
1982
+  }
1983
+  if (options & REFRESH_INDEX_STATS)
1984
+  {
1985
+    pthread_mutex_lock(&LOCK_global_index_stats);
1986
+    free_global_index_stats();
1987
+    init_global_index_stats();
1988
+    pthread_mutex_unlock(&LOCK_global_index_stats);
1989
+  }
1990
+  if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS | REFRESH_THREAD_STATS))
1991
+  {
1992
+    pthread_mutex_lock(&LOCK_global_user_client_stats);
1993
+    if (options & REFRESH_USER_STATS)
1994
+    {
1995
+      free_global_user_stats();
1996
+      init_global_user_stats();
1997
+    }
1998
+    if (options & REFRESH_CLIENT_STATS)
1999
+    {
2000
+      free_global_client_stats();
2001
+      init_global_client_stats();
2002
+    }
2003
+    if (options & REFRESH_THREAD_STATS)
2004
+    {
2005
+      free_global_thread_stats();
2006
+      init_global_thread_stats();
2007
+    }
2008
+    pthread_mutex_unlock(&LOCK_global_user_client_stats);
2009
+  }
2010
  *write_to_binlog= tmp_write_to_binlog;
2011
  /*
2012
    If the query was killed then this function must fail.
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2013
diff -ruN a/sql/sql_prepare.cc b/sql/sql_prepare.cc
2014
--- a/sql/sql_prepare.cc	2010-08-27 14:29:26.043058814 +0900
2015
+++ b/sql/sql_prepare.cc	2010-08-27 15:10:33.858058832 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2016
@@ -96,6 +96,9 @@
2017
 #include <mysql_com.h>
2018
 #endif
2019
 
2020
+// Uses the THD to update the global stats by user name and client IP
2021
+void update_global_user_stats(THD* thd, bool create_user, time_t now);
2022
+
2023
 /**
2024
   A result class used to send cursor rows using the binary protocol.
2025
 */
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2026
@@ -2103,8 +2106,36 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2027
   /* First of all clear possible warnings from the previous command */
2028
   mysql_reset_thd_for_next_command(thd);
2029
 
2030
+  int start_time_error = 0;
2031
+  int end_time_error = 0;
2032
+  struct timeval start_time, end_time;
2033
+  double start_usecs = 0;
2034
+  double end_usecs = 0;
2035
+  /* cpu time */
2036
+  int cputime_error = 0;
2037
+  struct timespec tp;
2038
+  double start_cpu_nsecs = 0;
2039
+  double end_cpu_nsecs = 0;
2040
+
2041
+  if (opt_userstat_running) {
2042
+#ifdef HAVE_CLOCK_GETTIME
2043
+    /* get start cputime */
2044
+    if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
2045
+      start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
2046
+#else
2047
+#warning : HAVE_CLOCK_GETTIME is disabled.
2048
+#warning : Most systems require librt library to use the function clock_gettime().
2049
+#warning : Did you set environment when ./configure ?  (e.g. "export LIBS=-lrt" for sh)
2050
+#endif
2051
+
2052
+    // Gets the start time, in order to measure how long this command takes.
2053
+    if (!(start_time_error = gettimeofday(&start_time, NULL))) {
2054
+      start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
2055
+    }
2056
+  }
2057
+
2058
   if (! (stmt= new Prepared_statement(thd)))
2059
-    DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */
2060
+    goto end; /* out of memory: error is set in Sql_alloc */
2061
 
2062
   if (thd->stmt_map.insert(thd, stmt))
2063
   {
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2064
@@ -2112,7 +2143,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2065
       The error is set in the insert. The statement itself
2066
       will be also deleted there (this is how the hash works).
2067
     */
2068
-    DBUG_VOID_RETURN;
2069
+    goto end;
2070
   }
2071
 
2072
   /* Reset warnings from previous command */
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2073
@@ -2139,6 +2170,44 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2074
   thd->protocol= save_protocol;
2075
 
2076
   /* check_prepared_statemnt sends the metadata packet in case of success */
2077
+end:
2078
+  if (opt_userstat_running) {
2079
+    // Gets the end time.
2080
+    if (!(end_time_error = gettimeofday(&end_time, NULL))) {
2081
+      end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
2082
+    }
2083
+
2084
+    // Calculates the difference between the end and start times.
2085
+    if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
2086
+      thd->busy_time = (end_usecs - start_usecs) / 1000000;
2087
+      // In case there are bad values, 2629743 is the #seconds in a month.
2088
+      if (thd->busy_time > 2629743) {
2089
+        thd->busy_time = 0;
2090
+      }
2091
+    } else {
2092
+      // end time went back in time, or gettimeofday() failed.
2093
+      thd->busy_time = 0;
2094
+    }
2095
+
2096
+#ifdef HAVE_CLOCK_GETTIME
2097
+    /* get end cputime */
2098
+    if (!cputime_error &&
2099
+        !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
2100
+      end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
2101
+#endif
2102
+    if (start_cpu_nsecs && !cputime_error) {
2103
+      thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
2104
+      // In case there are bad values, 2629743 is the #seconds in a month.
2105
+      if (thd->cpu_time > 2629743) {
2106
+        thd->cpu_time = 0;
2107
+      }
2108
+    } else
2109
+      thd->cpu_time = 0;
2110
+  }
2111
+  // Updates THD stats and the global user stats.
2112
+  thd->update_stats(true);
2113
+  update_global_user_stats(thd, true, time(NULL));
2114
+
2115
   DBUG_VOID_RETURN;
2116
 }
2117
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2118
@@ -2485,12 +2554,36 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2119
   /* First of all clear possible warnings from the previous command */
2120
   mysql_reset_thd_for_next_command(thd);
2121
 
2122
+  int start_time_error = 0;
2123
+  int end_time_error = 0;
2124
+  struct timeval start_time, end_time;
2125
+  double start_usecs = 0;
2126
+  double end_usecs = 0;
2127
+  /* cpu time */
2128
+  int cputime_error = 0;
2129
+  struct timespec tp;
2130
+  double start_cpu_nsecs = 0;
2131
+  double end_cpu_nsecs = 0;
2132
+
2133
+  if (opt_userstat_running) {
2134
+#ifdef HAVE_CLOCK_GETTIME
2135
+    /* get start cputime */
2136
+    if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
2137
+      start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
2138
+#endif
2139
+
2140
+    // Gets the start time, in order to measure how long this command takes.
2141
+    if (!(start_time_error = gettimeofday(&start_time, NULL))) {
2142
+      start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
2143
+    }
2144
+  }
2145
+
2146
   if (!(stmt= find_prepared_statement(thd, stmt_id)))
2147
   {
2148
     char llbuf[22];
2149
     my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
2150
              llstr(stmt_id, llbuf), "mysqld_stmt_execute");
2151
-    DBUG_VOID_RETURN;
2152
+    goto end;
2153
   }
2154
 
2155
 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2156
@@ -2511,6 +2604,44 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2157
   /* Close connection socket; for use with client testing (Bug#43560). */
2158
   DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_close(thd->net.vio););
2159
 
2160
+end:
2161
+  if (opt_userstat_running) {
2162
+    // Gets the end time.
2163
+    if (!(end_time_error = gettimeofday(&end_time, NULL))) {
2164
+      end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
2165
+    }
2166
+
2167
+    // Calculates the difference between the end and start times.
2168
+    if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
2169
+      thd->busy_time = (end_usecs - start_usecs) / 1000000;
2170
+      // In case there are bad values, 2629743 is the #seconds in a month.
2171
+      if (thd->busy_time > 2629743) {
2172
+        thd->busy_time = 0;
2173
+      }
2174
+    } else {
2175
+      // end time went back in time, or gettimeofday() failed.
2176
+      thd->busy_time = 0;
2177
+    }
2178
+
2179
+#ifdef HAVE_CLOCK_GETTIME
2180
+    /* get end cputime */
2181
+    if (!cputime_error &&
2182
+        !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
2183
+      end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
2184
+#endif
2185
+    if (start_cpu_nsecs && !cputime_error) {
2186
+      thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
2187
+      // In case there are bad values, 2629743 is the #seconds in a month.
2188
+      if (thd->cpu_time > 2629743) {
2189
+        thd->cpu_time = 0;
2190
+      }
2191
+    } else
2192
+      thd->cpu_time = 0;
2193
+  }
2194
+  // Updates THD stats and the global user stats.
2195
+  thd->update_stats(true);
2196
+  update_global_user_stats(thd, true, time(NULL));
2197
+
2198
   DBUG_VOID_RETURN;
2199
 
2200
 }
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2201
@@ -2584,20 +2715,45 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2202
 
2203
   /* First of all clear possible warnings from the previous command */
2204
   mysql_reset_thd_for_next_command(thd);
2205
+
2206
+  int start_time_error = 0;
2207
+  int end_time_error = 0;
2208
+  struct timeval start_time, end_time;
2209
+  double start_usecs = 0;
2210
+  double end_usecs = 0;
2211
+  /* cpu time */
2212
+  int cputime_error = 0;
2213
+  struct timespec tp;
2214
+  double start_cpu_nsecs = 0;
2215
+  double end_cpu_nsecs = 0;
2216
+
2217
+  if (opt_userstat_running) {
2218
+#ifdef HAVE_CLOCK_GETTIME
2219
+    /* get start cputime */
2220
+    if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
2221
+      start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
2222
+#endif
2223
+
2224
+    // Gets the start time, in order to measure how long this command takes.
2225
+    if (!(start_time_error = gettimeofday(&start_time, NULL))) {
2226
+      start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
2227
+    }
2228
+  }
2229
+
2230
   status_var_increment(thd->status_var.com_stmt_fetch);
2231
   if (!(stmt= find_prepared_statement(thd, stmt_id)))
2232
   {
2233
     char llbuf[22];
2234
     my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
2235
              llstr(stmt_id, llbuf), "mysqld_stmt_fetch");
2236
-    DBUG_VOID_RETURN;
2237
+    goto end;
2238
   }
2239
 
2240
   cursor= stmt->cursor;
2241
   if (!cursor)
2242
   {
2243
     my_error(ER_STMT_HAS_NO_OPEN_CURSOR, MYF(0), stmt_id);
2244
-    DBUG_VOID_RETURN;
2245
+    goto end;
2246
   }
2247
 
2248
   thd->stmt_arena= stmt;
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2249
@@ -2621,6 +2777,44 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2250
   thd->restore_backup_statement(stmt, &stmt_backup);
2251
   thd->stmt_arena= thd;
2252
 
2253
+end:
2254
+  if (opt_userstat_running) {
2255
+    // Gets the end time.
2256
+    if (!(end_time_error = gettimeofday(&end_time, NULL))) {
2257
+      end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
2258
+    }
2259
+
2260
+    // Calculates the difference between the end and start times.
2261
+    if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
2262
+      thd->busy_time = (end_usecs - start_usecs) / 1000000;
2263
+      // In case there are bad values, 2629743 is the #seconds in a month.
2264
+      if (thd->busy_time > 2629743) {
2265
+        thd->busy_time = 0;
2266
+      }
2267
+    } else {
2268
+      // end time went back in time, or gettimeofday() failed.
2269
+      thd->busy_time = 0;
2270
+    }
2271
+
2272
+#ifdef HAVE_CLOCK_GETTIME
2273
+    /* get end cputime */
2274
+    if (!cputime_error &&
2275
+        !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
2276
+      end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
2277
+#endif
2278
+    if (start_cpu_nsecs && !cputime_error) {
2279
+      thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
2280
+      // In case there are bad values, 2629743 is the #seconds in a month.
2281
+      if (thd->cpu_time > 2629743) {
2282
+        thd->cpu_time = 0;
2283
+      }
2284
+    } else
2285
+      thd->cpu_time = 0;
2286
+  }
2287
+  // Updates THD stats and the global user stats.
2288
+  thd->update_stats(true);
2289
+  update_global_user_stats(thd, true, time(NULL));
2290
+
2291
   DBUG_VOID_RETURN;
2292
 }
2293
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2294
@@ -2651,13 +2845,37 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2295
   /* First of all clear possible warnings from the previous command */
2296
   mysql_reset_thd_for_next_command(thd);
2297
 
2298
+  int start_time_error = 0;
2299
+  int end_time_error = 0;
2300
+  struct timeval start_time, end_time;
2301
+  double start_usecs = 0;
2302
+  double end_usecs = 0;
2303
+  /* cpu time */
2304
+  int cputime_error = 0;
2305
+  struct timespec tp;
2306
+  double start_cpu_nsecs = 0;
2307
+  double end_cpu_nsecs = 0;
2308
+
2309
+  if (opt_userstat_running) {
2310
+#ifdef HAVE_CLOCK_GETTIME
2311
+    /* get start cputime */
2312
+    if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
2313
+      start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
2314
+#endif
2315
+
2316
+    // Gets the start time, in order to measure how long this command takes.
2317
+    if (!(start_time_error = gettimeofday(&start_time, NULL))) {
2318
+      start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
2319
+    }
2320
+  }
2321
+
2322
   status_var_increment(thd->status_var.com_stmt_reset);
2323
   if (!(stmt= find_prepared_statement(thd, stmt_id)))
2324
   {
2325
     char llbuf[22];
2326
     my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
2327
              llstr(stmt_id, llbuf), "mysqld_stmt_reset");
2328
-    DBUG_VOID_RETURN;
2329
+    goto end;
2330
   }
2331
 
2332
   stmt->close_cursor();
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2333
@@ -2674,6 +2892,44 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2334
 
2335
   my_ok(thd);
2336
 
2337
+end:
2338
+  if (opt_userstat_running) {
2339
+    // Gets the end time.
2340
+    if (!(end_time_error = gettimeofday(&end_time, NULL))) {
2341
+      end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
2342
+    }
2343
+
2344
+    // Calculates the difference between the end and start times.
2345
+    if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
2346
+      thd->busy_time = (end_usecs - start_usecs) / 1000000;
2347
+      // In case there are bad values, 2629743 is the #seconds in a month.
2348
+      if (thd->busy_time > 2629743) {
2349
+        thd->busy_time = 0;
2350
+      }
2351
+    } else {
2352
+      // end time went back in time, or gettimeofday() failed.
2353
+      thd->busy_time = 0;
2354
+    }
2355
+
2356
+#ifdef HAVE_CLOCK_GETTIME
2357
+    /* get end cputime */
2358
+    if (!cputime_error &&
2359
+        !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
2360
+      end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
2361
+#endif
2362
+    if (start_cpu_nsecs && !cputime_error) {
2363
+      thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
2364
+      // In case there are bad values, 2629743 is the #seconds in a month.
2365
+      if (thd->cpu_time > 2629743) {
2366
+        thd->cpu_time = 0;
2367
+      }
2368
+    } else
2369
+      thd->cpu_time = 0;
2370
+  }
2371
+  // Updates THD stats and the global user stats.
2372
+  thd->update_stats(true);
2373
+  update_global_user_stats(thd, true, time(NULL));
2374
+
2375
   DBUG_VOID_RETURN;
2376
 }
2377
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2378
diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
2379
--- a/sql/sql_show.cc	2010-08-27 14:48:13.050141329 +0900
2380
+++ b/sql/sql_show.cc	2010-08-27 15:10:33.866059533 +0900
48 by kinoyasu
port for mysql-5.1.48
2381
@@ -84,6 +84,40 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2382
 
2383
 static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table);
2384
 
2385
+/*
2386
+ * Solaris 10 does not have strsep(). 
2387
+ * 
2388
+ * based on getToken from http://www.winehq.org/pipermail/wine-patches/2001-November/001322.html
2389
+ *
2390
+ */
2391
+
2392
+#ifndef HAVE_STRSEP
2393
+static char* strsep(char** str, const char* delims)
2394
+{
2395
+  char *token;
2396
+
2397
+  if (*str == NULL) {
2398
+    /* No more tokens */
2399
+    return NULL;
2400
+  }
2401
+
2402
+  token = *str;
2403
+  while (**str != '\0') {
2404
+    if (strchr(delims, **str) != NULL) {
2405
+      **str = '\0';
2406
+      (*str)++;
2407
+      return token;
2408
+    }
2409
+    (*str)++;
2410
+  }
2411
+
2412
+  /* There is not another token */
2413
+  *str = NULL;
2414
+
2415
+  return token;
2416
+}
2417
+#endif
2418
+
2419
 /***************************************************************************
2420
 ** List all table types supported
2421
 ***************************************************************************/
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2422
@@ -832,6 +866,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2423
 		sctx->master_access);
2424
   if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname))
2425
   {
2426
+    thd->diff_access_denied_errors++;
2427
     my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
2428
              sctx->priv_user, sctx->host_or_ip, dbname);
2429
     general_log_print(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2430
@@ -2386,6 +2421,279 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2431
   DBUG_RETURN(res);
2432
 }
2433
 
2434
+/*
2435
+   Write result to network for SHOW USER_STATISTICS
2436
+
2437
+   SYNOPSIS
2438
+     send_user_stats
2439
+       all_user_stats - values to return
2440
+       table - I_S table
2441
+
2442
+   RETURN
2443
+     0 - OK
2444
+     1 - error
2445
+ */
2446
+int send_user_stats(THD* thd, HASH *all_user_stats, TABLE *table)
2447
+{
2448
+  DBUG_ENTER("send_user_stats");
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
2449
+  for (uint i = 0; i < all_user_stats->records; ++i) {
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2450
+    restore_record(table, s->default_values);
2451
+    USER_STATS *user_stats = (USER_STATS*)hash_element(all_user_stats, i);
2452
+      table->field[0]->store(user_stats->user, strlen(user_stats->user), system_charset_info);
2453
+      table->field[1]->store((longlong)user_stats->total_connections);
2454
+      table->field[2]->store((longlong)user_stats->concurrent_connections);
2455
+      table->field[3]->store((longlong)user_stats->connected_time);
2456
+      table->field[4]->store((longlong)user_stats->busy_time);
2457
+      table->field[5]->store((longlong)user_stats->cpu_time);
2458
+      table->field[6]->store((longlong)user_stats->bytes_received);
2459
+      table->field[7]->store((longlong)user_stats->bytes_sent);
2460
+      table->field[8]->store((longlong)user_stats->binlog_bytes_written);
2461
+      table->field[9]->store((longlong)user_stats->rows_fetched);
2462
+      table->field[10]->store((longlong)user_stats->rows_updated);
2463
+      table->field[11]->store((longlong)user_stats->rows_read);
2464
+      table->field[12]->store((longlong)user_stats->select_commands);
2465
+      table->field[13]->store((longlong)user_stats->update_commands);
2466
+      table->field[14]->store((longlong)user_stats->other_commands);
2467
+      table->field[15]->store((longlong)user_stats->commit_trans);
2468
+      table->field[16]->store((longlong)user_stats->rollback_trans);
2469
+      table->field[17]->store((longlong)user_stats->denied_connections);
2470
+      table->field[18]->store((longlong)user_stats->lost_connections);
2471
+      table->field[19]->store((longlong)user_stats->access_denied_errors);
2472
+      table->field[20]->store((longlong)user_stats->empty_queries);
2473
+      if (schema_table_store_record(thd, table))
2474
+      {
2475
+	      DBUG_PRINT("error", ("store record error"));
2476
+	      DBUG_RETURN(1);
2477
+      }
2478
+  }
2479
+  DBUG_RETURN(0);
2480
+}
2481
+
2482
+int send_thread_stats(THD* thd, HASH *all_thread_stats, TABLE *table)
2483
+{
2484
+  DBUG_ENTER("send_thread_stats");
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
2485
+  for (uint i = 0; i < all_thread_stats->records; ++i) {
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2486
+    restore_record(table, s->default_values);
2487
+    THREAD_STATS *user_stats = (THREAD_STATS*)hash_element(all_thread_stats, i);
2488
+      table->field[0]->store((longlong)user_stats->id);
2489
+      table->field[1]->store((longlong)user_stats->total_connections);
2490
+      table->field[2]->store((longlong)user_stats->concurrent_connections);
2491
+      table->field[3]->store((longlong)user_stats->connected_time);
2492
+      table->field[4]->store((longlong)user_stats->busy_time);
2493
+      table->field[5]->store((longlong)user_stats->cpu_time);
2494
+      table->field[6]->store((longlong)user_stats->bytes_received);
2495
+      table->field[7]->store((longlong)user_stats->bytes_sent);
2496
+      table->field[8]->store((longlong)user_stats->binlog_bytes_written);
2497
+      table->field[9]->store((longlong)user_stats->rows_fetched);
2498
+      table->field[10]->store((longlong)user_stats->rows_updated);
2499
+      table->field[11]->store((longlong)user_stats->rows_read);
2500
+      table->field[12]->store((longlong)user_stats->select_commands);
2501
+      table->field[13]->store((longlong)user_stats->update_commands);
2502
+      table->field[14]->store((longlong)user_stats->other_commands);
2503
+      table->field[15]->store((longlong)user_stats->commit_trans);
2504
+      table->field[16]->store((longlong)user_stats->rollback_trans);
2505
+      table->field[17]->store((longlong)user_stats->denied_connections);
2506
+      table->field[18]->store((longlong)user_stats->lost_connections);
2507
+      table->field[19]->store((longlong)user_stats->access_denied_errors);
2508
+      table->field[20]->store((longlong)user_stats->empty_queries);
2509
+      if (schema_table_store_record(thd, table))
2510
+      {
2511
+              DBUG_PRINT("error", ("store record error"));
2512
+              DBUG_RETURN(1);
2513
+      }
2514
+  }
2515
+  DBUG_RETURN(0);
2516
+}
2517
+
2518
+/*
2519
+   Process SHOW USER_STATISTICS
2520
+
2521
+   SYNOPSIS
2522
+     mysqld_show_user_stats
2523
+       thd - current thread
2524
+       wild - limit results to the entry for this user
2525
+       with_roles - when true, display role for mapped users
2526
+
2527
+   RETURN
2528
+     0 - OK
2529
+     1 - error
2530
+ */
2531
+
2532
+
2533
+int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond)
2534
+{
2535
+  TABLE *table= tables->table;
2536
+  DBUG_ENTER("fill_schema_user_stats");
2537
+
2538
+  if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
2539
+          DBUG_RETURN(1);
2540
+
2541
+  // Iterates through all the global stats and sends them to the client.
2542
+  // Pattern matching on the client IP is supported.
2543
+
2544
+  pthread_mutex_lock(&LOCK_global_user_client_stats);
2545
+  int result= send_user_stats(thd, &global_user_stats, table);
2546
+  pthread_mutex_unlock(&LOCK_global_user_client_stats);
2547
+  if (result)
2548
+    goto err;
2549
+
2550
+  DBUG_PRINT("exit", ("fill_schema_user_stats result is 0"));
2551
+  DBUG_RETURN(0);
2552
+
2553
+ err:
2554
+  DBUG_PRINT("exit", ("fill_schema_user_stats result is 1"));
2555
+  DBUG_RETURN(1);
2556
+}
2557
+
2558
+/*
2559
+   Process SHOW CLIENT_STATISTICS
2560
+
2561
+   SYNOPSIS
2562
+     mysqld_show_client_stats
2563
+       thd - current thread
2564
+       wild - limit results to the entry for this client
2565
+
2566
+   RETURN
2567
+     0 - OK
2568
+     1 - error
2569
+ */
2570
+
2571
+
2572
+int fill_schema_client_stats(THD* thd, TABLE_LIST* tables, COND* cond)
2573
+{
2574
+  TABLE *table= tables->table;
2575
+  DBUG_ENTER("fill_schema_client_stats");
2576
+
2577
+  if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
2578
+          DBUG_RETURN(1);
2579
+
2580
+  // Iterates through all the global stats and sends them to the client.
2581
+  // Pattern matching on the client IP is supported.
2582
+
2583
+  pthread_mutex_lock(&LOCK_global_user_client_stats);
2584
+  int result= send_user_stats(thd, &global_client_stats, table);
2585
+  pthread_mutex_unlock(&LOCK_global_user_client_stats);
2586
+  if (result)
2587
+    goto err;
2588
+
2589
+  DBUG_PRINT("exit", ("mysqld_show_client_stats result is 0"));
2590
+  DBUG_RETURN(0);
2591
+
2592
+ err:
2593
+  DBUG_PRINT("exit", ("mysqld_show_client_stats result is 1"));
2594
+  DBUG_RETURN(1);
2595
+}
2596
+
2597
+int fill_schema_thread_stats(THD* thd, TABLE_LIST* tables, COND* cond)
2598
+{
2599
+  TABLE *table= tables->table;
2600
+  DBUG_ENTER("fill_schema_thread_stats");
2601
+
2602
+  if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
2603
+          DBUG_RETURN(1);
2604
+
2605
+  // Iterates through all the global stats and sends them to the client.
2606
+  // Pattern matching on the client IP is supported.
2607
+
2608
+  pthread_mutex_lock(&LOCK_global_user_client_stats);
2609
+  int result= send_thread_stats(thd, &global_thread_stats, table);
2610
+  pthread_mutex_unlock(&LOCK_global_user_client_stats);
2611
+  if (result)
2612
+    goto err;
2613
+
2614
+  DBUG_PRINT("exit", ("mysqld_show_thread_stats result is 0"));
2615
+  DBUG_RETURN(0);
2616
+
2617
+ err:
2618
+  DBUG_PRINT("exit", ("mysqld_show_thread_stats result is 1"));
2619
+  DBUG_RETURN(1);
2620
+}
2621
+
2622
+// Sends the global table stats back to the client.
2623
+int fill_schema_table_stats(THD* thd, TABLE_LIST* tables, COND* cond)
2624
+{
2625
+  TABLE *table= tables->table;
2626
+  DBUG_ENTER("fill_schema_table_stats");
2627
+  char *table_full_name, *table_schema;
2628
+
2629
+  pthread_mutex_lock(&LOCK_global_table_stats);
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
2630
+  for (uint i = 0; i < global_table_stats.records; ++i) {
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2631
+    restore_record(table, s->default_values);
2632
+    TABLE_STATS *table_stats = 
2633
+      (TABLE_STATS*)hash_element(&global_table_stats, i);
2634
+
2635
+    table_full_name= thd->strdup(table_stats->table);
2636
+    table_schema= strsep(&table_full_name, ".");
2637
+
2638
+    TABLE_LIST tmp_table;
2639
+    bzero((char*) &tmp_table,sizeof(tmp_table));
2640
+    tmp_table.table_name= table_full_name;
2641
+    tmp_table.db= table_schema;
2642
+    tmp_table.grant.privilege= 0;
2643
+    if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
2644
+                      &tmp_table.grant.privilege, 0, 0,
2645
+                      is_schema_db(table_schema)) ||
2646
+         check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
2647
+        continue;
2648
+
2649
+    table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
2650
+    table->field[1]->store(table_full_name, strlen(table_full_name), system_charset_info);
2651
+    table->field[2]->store((longlong)table_stats->rows_read, TRUE);
2652
+    table->field[3]->store((longlong)table_stats->rows_changed, TRUE);
2653
+    table->field[4]->store((longlong)table_stats->rows_changed_x_indexes, TRUE);
2654
+
2655
+    if (schema_table_store_record(thd, table))
2656
+    {
2657
+      VOID(pthread_mutex_unlock(&LOCK_global_table_stats));
2658
+      DBUG_RETURN(1);
2659
+    }
2660
+  }
2661
+  pthread_mutex_unlock(&LOCK_global_table_stats);
2662
+  DBUG_RETURN(0);
2663
+}
2664
+
2665
+// Sends the global index stats back to the client.
2666
+int fill_schema_index_stats(THD* thd, TABLE_LIST* tables, COND* cond)
2667
+{
2668
+  TABLE *table= tables->table;
2669
+  DBUG_ENTER("fill_schema_index_stats");
2670
+  char *index_full_name, *table_schema, *table_name;
2671
+
2672
+  pthread_mutex_lock(&LOCK_global_index_stats);
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
2673
+  for (uint i = 0; i < global_index_stats.records; ++i) {
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2674
+    restore_record(table, s->default_values);
2675
+    INDEX_STATS *index_stats =
2676
+      (INDEX_STATS*)hash_element(&global_index_stats, i);
2677
+
2678
+    index_full_name= thd->strdup(index_stats->index);
2679
+    table_schema= strsep(&index_full_name, ".");
2680
+    table_name= strsep(&index_full_name, ".");
2681
+
2682
+    TABLE_LIST tmp_table;
2683
+    bzero((char*) &tmp_table,sizeof(tmp_table));
2684
+    tmp_table.table_name= table_name;
2685
+    tmp_table.db= table_schema;
2686
+    tmp_table.grant.privilege= 0;
2687
+    if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
2688
+                      &tmp_table.grant.privilege, 0, 0,
2689
+                      is_schema_db(table_schema)) ||
2690
+         check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
2691
+        continue;
2692
+
2693
+    table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
2694
+    table->field[1]->store(table_name, strlen(table_name), system_charset_info);
2695
+    table->field[2]->store(index_full_name, strlen(index_full_name), system_charset_info);
2696
+    table->field[3]->store((longlong)index_stats->rows_read, TRUE);
2697
+
2698
+    if (schema_table_store_record(thd, table))
2699
+    { 
2700
+      VOID(pthread_mutex_unlock(&LOCK_global_index_stats));
2701
+      DBUG_RETURN(1);
2702
+    }
2703
+  }
2704
+  pthread_mutex_unlock(&LOCK_global_index_stats);
2705
+  DBUG_RETURN(0);
2706
+}
2707
 
2708
 /* collect status for all running threads */
2709
 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2710
@@ -6688,6 +6996,104 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2711
 };
2712
 
2713
 
2714
+ST_FIELD_INFO user_stats_fields_info[]=
2715
+{
2716
+  {"USER", USERNAME_LENGTH, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
2717
+  {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections", SKIP_OPEN_TABLE},
2718
+  {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections", SKIP_OPEN_TABLE},
2719
+  {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time", SKIP_OPEN_TABLE},
2720
+  {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time", SKIP_OPEN_TABLE},
2721
+  {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time", SKIP_OPEN_TABLE},
2722
+  {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received", SKIP_OPEN_TABLE},
2723
+  {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent", SKIP_OPEN_TABLE},
2724
+  {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written", SKIP_OPEN_TABLE},
2725
+  {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched", SKIP_OPEN_TABLE},
2726
+  {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated", SKIP_OPEN_TABLE},
2727
+  {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read", SKIP_OPEN_TABLE},
2728
+  {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands", SKIP_OPEN_TABLE},
2729
+  {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands", SKIP_OPEN_TABLE},
2730
+  {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands", SKIP_OPEN_TABLE},
2731
+  {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions", SKIP_OPEN_TABLE},
2732
+  {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions", SKIP_OPEN_TABLE},
2733
+  {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections", SKIP_OPEN_TABLE},
2734
+  {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections", SKIP_OPEN_TABLE},
2735
+  {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied", SKIP_OPEN_TABLE},
2736
+  {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries", SKIP_OPEN_TABLE},
2737
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
2738
+};
2739
+
2740
+ST_FIELD_INFO client_stats_fields_info[]=
2741
+{
2742
+  {"CLIENT", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Client", SKIP_OPEN_TABLE},
2743
+  {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections", SKIP_OPEN_TABLE},
2744
+  {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections", SKIP_OPEN_TABLE},
2745
+  {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time", SKIP_OPEN_TABLE},
2746
+  {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time", SKIP_OPEN_TABLE},
2747
+  {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time", SKIP_OPEN_TABLE},
2748
+  {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received", SKIP_OPEN_TABLE},
2749
+  {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent", SKIP_OPEN_TABLE},
2750
+  {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written", SKIP_OPEN_TABLE},
2751
+  {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched", SKIP_OPEN_TABLE},
2752
+  {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated", SKIP_OPEN_TABLE},
2753
+  {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read", SKIP_OPEN_TABLE},
2754
+  {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands", SKIP_OPEN_TABLE},
2755
+  {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands", SKIP_OPEN_TABLE},
2756
+  {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands", SKIP_OPEN_TABLE},
2757
+  {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions", SKIP_OPEN_TABLE},
2758
+  {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions", SKIP_OPEN_TABLE},
2759
+  {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections", SKIP_OPEN_TABLE},
2760
+  {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections", SKIP_OPEN_TABLE},
2761
+  {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied", SKIP_OPEN_TABLE},
2762
+  {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries", SKIP_OPEN_TABLE},
2763
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
2764
+};
2765
+
2766
+ST_FIELD_INFO thread_stats_fields_info[]=
2767
+{
2768
+  {"THREAD_ID", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Thread_id", SKIP_OPEN_TABLE},
2769
+  {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections", SKIP_OPEN_TABLE},
2770
+  {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections", SKIP_OPEN_TABLE},
2771
+  {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time", SKIP_OPEN_TABLE},
2772
+  {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time", SKIP_OPEN_TABLE},
2773
+  {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time", SKIP_OPEN_TABLE},
2774
+  {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received", SKIP_OPEN_TABLE},
2775
+  {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent", SKIP_OPEN_TABLE},
2776
+  {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written", SKIP_OPEN_TABLE},
2777
+  {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched", SKIP_OPEN_TABLE},
2778
+  {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated", SKIP_OPEN_TABLE},
2779
+  {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read", SKIP_OPEN_TABLE},
2780
+  {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands", SKIP_OPEN_TABLE},
2781
+  {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands", SKIP_OPEN_TABLE},
2782
+  {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands", SKIP_OPEN_TABLE},
2783
+  {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions", SKIP_OPEN_TABLE},
2784
+  {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions", SKIP_OPEN_TABLE},
2785
+  {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections", SKIP_OPEN_TABLE},
2786
+  {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections", SKIP_OPEN_TABLE},
2787
+  {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied", SKIP_OPEN_TABLE},
2788
+  {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries", SKIP_OPEN_TABLE},
2789
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
2790
+};
2791
+
2792
+ST_FIELD_INFO table_stats_fields_info[]=
2793
+{
2794
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema", SKIP_OPEN_TABLE},
2795
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name", SKIP_OPEN_TABLE},
2796
+  {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read", SKIP_OPEN_TABLE},
2797
+  {"ROWS_CHANGED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed", SKIP_OPEN_TABLE},
2798
+  {"ROWS_CHANGED_X_INDEXES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed_x_#indexes", SKIP_OPEN_TABLE},
2799
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
2800
+};
2801
+
2802
+ST_FIELD_INFO index_stats_fields_info[]=
2803
+{
2804
+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema", SKIP_OPEN_TABLE},
2805
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name", SKIP_OPEN_TABLE},
2806
+  {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name", SKIP_OPEN_TABLE},
2807
+  {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read", SKIP_OPEN_TABLE},
2808
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
2809
+};
2810
+
2811
+
2812
 ST_FIELD_INFO processlist_fields_info[]=
2813
 {
2814
   {"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2815
@@ -6823,6 +7229,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2816
 {
2817
   {"CHARACTER_SETS", charsets_fields_info, create_schema_table, 
2818
    fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
2819
+  {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table, 
2820
+    fill_schema_client_stats, make_old_format, 0, -1, -1, 0, 0},
2821
   {"COLLATIONS", collation_fields_info, create_schema_table, 
2822
    fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
2823
   {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2824
@@ -6832,6 +7240,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2825
    OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
2826
   {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
2827
    fill_schema_column_privileges, 0, 0, -1, -1, 0, 0},
2828
+  {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table,
2829
+   fill_schema_index_stats, make_old_format, 0, -1, -1, 0, 0},
2830
   {"ENGINES", engines_fields_info, create_schema_table,
2831
    fill_schema_engines, make_old_format, 0, -1, -1, 0, 0},
2832
 #ifdef HAVE_EVENT_SCHEDULER
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2833
@@ -6888,11 +7298,17 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2834
    get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
2835
   {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
2836
    fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
2837
+  {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
2838
+    fill_schema_table_stats, make_old_format, 0, -1, -1, 0, 0},
2839
+  {"THREAD_STATISTICS", thread_stats_fields_info, create_schema_table,
2840
+    fill_schema_thread_stats, make_old_format, 0, -1, -1, 0, 0},
2841
   {"TRIGGERS", triggers_fields_info, create_schema_table,
2842
    get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
2843
    OPEN_TABLE_ONLY},
2844
   {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, 
2845
    fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
2846
+  {"USER_STATISTICS", user_stats_fields_info, create_schema_table, 
2847
+    fill_schema_user_stats, make_old_format, 0, -1, -1, 0, 0},
2848
   {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
2849
    make_old_format, 0, 0, -1, 1, 0},
2850
   {"VIEWS", view_fields_info, create_schema_table, 
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2851
diff -ruN a/sql/sql_update.cc b/sql/sql_update.cc
2852
--- a/sql/sql_update.cc	2010-08-04 02:24:35.000000000 +0900
2853
+++ b/sql/sql_update.cc	2010-08-27 15:10:33.880988383 +0900
2854
@@ -843,6 +843,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2855
     thd->row_count_func=
2856
       (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
2857
     my_ok(thd, (ulong) thd->row_count_func, id, buff);
2858
+    thd->updated_row_count += thd->row_count_func;
2859
     DBUG_PRINT("info",("%ld records updated", (long) updated));
2860
   }
2861
   thd->count_cuted_fields= CHECK_FIELD_IGNORE;		/* calc cuted fields */
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
2862
@@ -2145,5 +2146,6 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2863
   thd->row_count_func=
2864
     (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
2865
   ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
2866
+  thd->updated_row_count += thd->row_count_func;
2867
   DBUG_RETURN(FALSE);
2868
 }
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
2869
diff -ruN a/sql/sql_yacc.yy b/sql/sql_yacc.yy
2870
--- a/sql/sql_yacc.yy	2010-08-27 14:29:26.060990130 +0900
2871
+++ b/sql/sql_yacc.yy	2010-08-27 15:10:33.890987529 +0900
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
2872
@@ -757,6 +757,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2873
 %token  CHECK_SYM                     /* SQL-2003-R */
2874
 %token  CIPHER_SYM
2875
 %token  CLIENT_SYM
2876
+%token  CLIENT_STATS_SYM
2877
 %token  CLOSE_SYM                     /* SQL-2003-R */
2878
 %token  COALESCE                      /* SQL-2003-N */
2879
 %token  CODE_SYM
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
2880
@@ -903,6 +904,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2881
 %token  IMPORT
2882
 %token  INDEXES
2883
 %token  INDEX_SYM
2884
+%token  INDEX_STATS_SYM
2885
 %token  INFILE
2886
 %token  INITIAL_SIZE_SYM
2887
 %token  INNER_SYM                     /* SQL-2003-R */
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
2888
@@ -1144,6 +1146,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2889
 %token  SIGNED_SYM
2890
 %token  SIMPLE_SYM                    /* SQL-2003-N */
2891
 %token  SLAVE
2892
+%token  SLOW_SYM
2893
 %token  SMALLINT                      /* SQL-2003-R */
2894
 %token  SNAPSHOT_SYM
2895
 %token  SOCKET_SYM
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
2896
@@ -1189,6 +1192,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2897
 %token  TABLESPACE
2898
 %token  TABLE_REF_PRIORITY
2899
 %token  TABLE_SYM                     /* SQL-2003-R */
2900
+%token  TABLE_STATS_SYM
2901
 %token  TABLE_CHECKSUM_SYM
2902
 %token  TEMPORARY                     /* SQL-2003-N */
2903
 %token  TEMPTABLE_SYM
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
2904
@@ -1197,6 +1201,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2905
 %token  TEXT_SYM
2906
 %token  THAN_SYM
2907
 %token  THEN_SYM                      /* SQL-2003-R */
2908
+%token  THREAD_STATS_SYM
2909
 %token  TIMESTAMP                     /* SQL-2003-R */
2910
 %token  TIMESTAMP_ADD
2911
 %token  TIMESTAMP_DIFF
77 by kinoyasu
port and adjust the part of the patches to 5.1.49: But query_cache_with_comments.patch, response-time-distribution.patch, mysql_remove_eol_carret.patch, log_connection_error.patch, status_wait_query_cache_mutex.patch and sql_no_fcache.patch were not ported yet. Please port them.
2912
@@ -1234,6 +1239,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2913
 %token  UPGRADE_SYM
2914
 %token  USAGE                         /* SQL-2003-N */
2915
 %token  USER                          /* SQL-2003-R */
2916
+%token  USER_STATS_SYM
2917
 %token  USE_FRM
2918
 %token  USE_SYM
2919
 %token  USING                         /* SQL-2003-R */
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
2920
@@ -10346,6 +10352,41 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2921
           {
2922
             Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
2923
           }
2924
+        | CLIENT_STATS_SYM wild_and_where 
2925
+          {
2926
+           LEX *lex= Lex;
2927
+           Lex->sql_command = SQLCOM_SELECT;
2928
+           if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS))
2929
+             MYSQL_YYABORT;
2930
+          }
2931
+        | USER_STATS_SYM wild_and_where 
2932
+          {
2933
+           LEX *lex= Lex;
2934
+           lex->sql_command = SQLCOM_SELECT;
2935
+           if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
2936
+             MYSQL_YYABORT;
2937
+          }
2938
+        | THREAD_STATS_SYM wild_and_where
2939
+          {
2940
+           LEX *lex= Lex;
2941
+           Lex->sql_command = SQLCOM_SELECT;
2942
+           if (prepare_schema_table(YYTHD, lex, 0, SCH_THREAD_STATS))
2943
+             MYSQL_YYABORT;
2944
+          }
2945
+        | TABLE_STATS_SYM wild_and_where
2946
+          {
2947
+           LEX *lex= Lex;
2948
+           lex->sql_command= SQLCOM_SELECT;
2949
+           if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
2950
+             MYSQL_YYABORT;
2951
+          }
2952
+        | INDEX_STATS_SYM wild_and_where
2953
+          {
2954
+           LEX *lex= Lex;
2955
+           lex->sql_command= SQLCOM_SELECT;
2956
+           if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
2957
+             MYSQL_YYABORT;
2958
+          }
2959
         | CREATE PROCEDURE sp_name
2960
           {
2961
             LEX *lex= Lex;
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
2962
@@ -10554,6 +10595,18 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2963
           { Lex->type|= REFRESH_STATUS; }
2964
         | SLAVE
2965
           { Lex->type|= REFRESH_SLAVE; }
2966
+        | SLOW_SYM QUERY_SYM LOGS_SYM
2967
+          { Lex->type |= REFRESH_SLOW_QUERY_LOG; }
2968
+        | CLIENT_STATS_SYM
2969
+          { Lex->type|= REFRESH_CLIENT_STATS; }
2970
+        | USER_STATS_SYM
2971
+          { Lex->type|= REFRESH_USER_STATS; }
2972
+        | THREAD_STATS_SYM
2973
+          { Lex->type|= REFRESH_THREAD_STATS; }
2974
+        | TABLE_STATS_SYM
2975
+          { Lex->type|= REFRESH_TABLE_STATS; }
2976
+        | INDEX_STATS_SYM
2977
+          { Lex->type|= REFRESH_INDEX_STATS; }
2978
         | MASTER_SYM
2979
           { Lex->type|= REFRESH_MASTER; }
2980
         | DES_KEY_FILE
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
2981
@@ -11671,6 +11724,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2982
         | CHAIN_SYM                {}
2983
         | CHANGED                  {}
2984
         | CIPHER_SYM               {}
2985
+        | CLIENT_STATS_SYM         {}
2986
         | CLIENT_SYM               {}
2987
         | COALESCE                 {}
2988
         | CODE_SYM                 {}
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
2989
@@ -11732,6 +11786,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2990
         | HOSTS_SYM                {}
2991
         | HOUR_SYM                 {}
2992
         | IDENTIFIED_SYM           {}
2993
+        | INDEX_STATS_SYM          {}
2994
         | INVOKER_SYM              {}
2995
         | IMPORT                   {}
2996
         | INDEXES                  {}
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
2997
@@ -11856,6 +11911,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
2998
         | SIMPLE_SYM               {}
2999
         | SHARE_SYM                {}
3000
         | SHUTDOWN                 {}
3001
+        | SLOW_SYM                 {}
3002
         | SNAPSHOT_SYM             {}
3003
         | SOUNDS_SYM               {}
3004
         | SOURCE_SYM               {}
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
3005
@@ -11875,6 +11931,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3006
         | SUSPEND_SYM              {}
3007
         | SWAPS_SYM                {}
3008
         | SWITCHES_SYM             {}
3009
+        | TABLE_STATS_SYM          {}
3010
         | TABLES                   {}
3011
         | TABLE_CHECKSUM_SYM       {}
3012
         | TABLESPACE               {}
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
3013
@@ -11882,6 +11939,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3014
         | TEMPTABLE_SYM            {}
3015
         | TEXT_SYM                 {}
3016
         | THAN_SYM                 {}
3017
+        | THREAD_STATS_SYM         {}
3018
         | TRANSACTION_SYM          {}
3019
         | TRIGGERS_SYM             {}
3020
         | TIMESTAMP                {}
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
3021
@@ -11899,6 +11957,7 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3022
         | UNKNOWN_SYM              {}
3023
         | UNTIL_SYM                {}
3024
         | USER                     {}
3025
+        | USER_STATS_SYM           {}
3026
         | USE_FRM                  {}
3027
         | VARIABLES                {}
3028
         | VIEW_SYM                 {}
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
3029
diff -ruN a/sql/structs.h b/sql/structs.h
3030
--- a/sql/structs.h	2010-08-04 02:24:35.000000000 +0900
3031
+++ b/sql/structs.h	2010-08-27 15:10:33.904059058 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3032
@@ -237,6 +237,171 @@
3033
   USER_RESOURCES user_resources;
3034
 } USER_CONN;
3035
 
3036
+typedef struct st_user_stats {
3037
+  char user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
3038
+  // Account name the user is mapped to when this is a user from mapped_user.
3039
+  // Otherwise, the same value as user.
3040
+  char priv_user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
3041
+  uint total_connections;
3042
+  uint concurrent_connections;
3043
+  time_t connected_time;  // in seconds
3044
+  double busy_time;       // in seconds
3045
+  double cpu_time;        // in seconds
3046
+  ulonglong bytes_received;
3047
+  ulonglong bytes_sent;
3048
+  ulonglong binlog_bytes_written;
3049
+  ha_rows rows_fetched, rows_updated, rows_read;
3050
+  ulonglong select_commands, update_commands, other_commands;
3051
+  ulonglong commit_trans, rollback_trans;
3052
+  ulonglong denied_connections, lost_connections;
3053
+  ulonglong access_denied_errors;
3054
+  ulonglong empty_queries;
3055
+} USER_STATS;
3056
+
3057
+/* Lookup function for hash tables with USER_STATS entries */
3058
+extern "C" uchar *get_key_user_stats(USER_STATS *user_stats, size_t *length,
3059
+                                my_bool not_used __attribute__((unused)));
3060
+
3061
+/* Free all memory for a hash table with USER_STATS entries */
3062
+extern void free_user_stats(USER_STATS* user_stats);
3063
+
3064
+/* Intialize an instance of USER_STATS */
3065
+extern void
3066
+init_user_stats(USER_STATS *user_stats,
3067
+                const char *user,
3068
+                const char *priv_user,
3069
+                uint total_connections,
3070
+                uint concurrent_connections,
3071
+                time_t connected_time,
3072
+                double busy_time,
3073
+                double cpu_time,
3074
+                ulonglong bytes_received,
3075
+                ulonglong bytes_sent,
3076
+                ulonglong binlog_bytes_written,
3077
+                ha_rows rows_fetched,
3078
+                ha_rows rows_updated,
3079
+                ha_rows rows_read,
3080
+                ulonglong select_commands,
3081
+                ulonglong update_commands,
3082
+                ulonglong other_commands,
3083
+                ulonglong commit_trans,
3084
+                ulonglong rollback_trans,
3085
+                ulonglong denied_connections,
3086
+                ulonglong lost_connections,
3087
+                ulonglong access_denied_errors,
3088
+                ulonglong empty_queries);
3089
+
3090
+/* Increment values of an instance of USER_STATS */
3091
+extern void
3092
+add_user_stats(USER_STATS *user_stats,
3093
+               uint total_connections,
3094
+               uint concurrent_connections,
3095
+               time_t connected_time,
3096
+               double busy_time,
3097
+               double cpu_time,
3098
+               ulonglong bytes_received,
3099
+               ulonglong bytes_sent,
3100
+               ulonglong binlog_bytes_written,
3101
+               ha_rows rows_fetched,
3102
+               ha_rows rows_updated,
3103
+               ha_rows rows_read,
3104
+               ulonglong select_commands,
3105
+               ulonglong update_commands,
3106
+               ulonglong other_commands,
3107
+               ulonglong commit_trans,
3108
+               ulonglong rollback_trans,
3109
+               ulonglong denied_connections,
3110
+               ulonglong lost_connections,
3111
+               ulonglong access_denied_errors,
3112
+               ulonglong empty_queries);
3113
+
3114
+typedef struct st_thread_stats {
3115
+  my_thread_id id;
3116
+  uint total_connections;
3117
+  uint concurrent_connections;
3118
+  time_t connected_time;  // in seconds
3119
+  double busy_time;       // in seconds
3120
+  double cpu_time;        // in seconds
3121
+  ulonglong bytes_received;
3122
+  ulonglong bytes_sent;
3123
+  ulonglong binlog_bytes_written;
3124
+  ha_rows rows_fetched, rows_updated, rows_read;
3125
+  ulonglong select_commands, update_commands, other_commands;
3126
+  ulonglong commit_trans, rollback_trans;
3127
+  ulonglong denied_connections, lost_connections;
3128
+  ulonglong access_denied_errors;
3129
+  ulonglong empty_queries;
3130
+} THREAD_STATS;
3131
+
3132
+/* Lookup function for hash tables with THREAD_STATS entries */
3133
+extern "C" uchar *get_key_thread_stats(THREAD_STATS *thread_stats, size_t *length,
3134
+                                my_bool not_used __attribute__((unused)));
3135
+
3136
+/* Free all memory for a hash table with THREAD_STATS entries */
3137
+extern void free_thread_stats(THREAD_STATS* thread_stats);
3138
+
3139
+/* Intialize an instance of THREAD_STATS */
3140
+extern void
3141
+init_thread_stats(THREAD_STATS *thread_stats,
3142
+                my_thread_id id,
3143
+                uint total_connections,
3144
+                uint concurrent_connections,
3145
+                time_t connected_time,
3146
+                double busy_time,
3147
+                double cpu_time,
3148
+                ulonglong bytes_received,
3149
+                ulonglong bytes_sent,
3150
+                ulonglong binlog_bytes_written,
3151
+                ha_rows rows_fetched,
3152
+                ha_rows rows_updated,
3153
+                ha_rows rows_read,
3154
+                ulonglong select_commands,
3155
+                ulonglong update_commands,
3156
+                ulonglong other_commands,
3157
+                ulonglong commit_trans,
3158
+                ulonglong rollback_trans,
3159
+                ulonglong denied_connections,
3160
+                ulonglong lost_connections,
3161
+                ulonglong access_denied_errors,
3162
+                ulonglong empty_queries);
3163
+
3164
+/* Increment values of an instance of THREAD_STATS */
3165
+extern void
3166
+add_thread_stats(THREAD_STATS *thread_stats,
3167
+               uint total_connections,
3168
+               uint concurrent_connections,
3169
+               time_t connected_time,
3170
+               double busy_time,
3171
+               double cpu_time,
3172
+               ulonglong bytes_received,
3173
+               ulonglong bytes_sent,
3174
+               ulonglong binlog_bytes_written,
3175
+               ha_rows rows_fetched,
3176
+               ha_rows rows_updated,
3177
+               ha_rows rows_read,
3178
+               ulonglong select_commands,
3179
+               ulonglong update_commands,
3180
+               ulonglong other_commands,
3181
+               ulonglong commit_trans,
3182
+               ulonglong rollback_trans,
3183
+               ulonglong denied_connections,
3184
+               ulonglong lost_connections,
3185
+               ulonglong access_denied_errors,
3186
+               ulonglong empty_queries);
3187
+
3188
+typedef struct st_table_stats {
3189
+  char table[NAME_LEN * 2 + 2];  // [db] + '.' + [table] + '\0'
3190
+  ulonglong rows_read, rows_changed;
3191
+  ulonglong rows_changed_x_indexes;
3192
+  /* Stores enum db_type, but forward declarations cannot be done */
3193
+  int engine_type;
3194
+} TABLE_STATS;
3195
+
3196
+typedef struct st_index_stats {
3197
+  char index[NAME_LEN * 3 + 3];  // [db] + '.' + [table] + '.' + [index] + '\0'
3198
+  ulonglong rows_read;
3199
+} INDEX_STATS;
3200
+
3201
 	/* Bits in form->update */
3202
 #define REG_MAKE_DUPP		1	/* Make a copy of record when read */
3203
 #define REG_NEW_RECORD		2	/* Write a new record if not found */
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
3204
diff -ruN a/sql/table.h b/sql/table.h
3205
--- a/sql/table.h	2010-08-04 02:24:19.000000000 +0900
3206
+++ b/sql/table.h	2010-08-27 15:10:33.906987259 +0900
3207
@@ -943,10 +943,12 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3208
 enum enum_schema_tables
3209
 {
3210
   SCH_CHARSETS= 0,
3211
+  SCH_CLIENT_STATS,
3212
   SCH_COLLATIONS,
3213
   SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
3214
   SCH_COLUMNS,
3215
   SCH_COLUMN_PRIVILEGES,
3216
+  SCH_INDEX_STATS,
3217
   SCH_ENGINES,
3218
   SCH_EVENTS,
3219
   SCH_FILES,
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
3220
@@ -970,8 +972,11 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3221
   SCH_TABLE_CONSTRAINTS,
3222
   SCH_TABLE_NAMES,
3223
   SCH_TABLE_PRIVILEGES,
3224
+  SCH_TABLE_STATS,
3225
+  SCH_THREAD_STATS,
3226
   SCH_TRIGGERS,
3227
   SCH_USER_PRIVILEGES,
3228
+  SCH_USER_STATS,
3229
   SCH_VARIABLES,
3230
   SCH_VIEWS
3231
 };
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
3232
diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
3233
--- a/storage/innobase/handler/ha_innodb.cc	2010-08-04 02:24:20.000000000 +0900
3234
+++ b/storage/innobase/handler/ha_innodb.cc	2010-08-27 15:10:33.913058592 +0900
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
3235
@@ -4055,6 +4055,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3236
 
3237
 	error = row_insert_for_mysql((byte*) record, prebuilt);
3238
 
3239
+	if (error == DB_SUCCESS) rows_changed++;
3240
+
3241
 	/* Handle duplicate key errors */
3242
 	if (auto_inc_used) {
3243
 		ulint		err;
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
3244
@@ -4392,6 +4394,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3245
 		}
3246
 	}
3247
 
3248
+	if (error == DB_SUCCESS) rows_changed++;
3249
+
3250
 	innodb_srv_conc_exit_innodb(trx);
3251
 
3252
 	error = convert_error_code_to_mysql(error, user_thd);
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
3253
@@ -4444,6 +4448,8 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3254
 
3255
 	error = row_update_for_mysql((byte*) record, prebuilt);
3256
 
3257
+	if (error == DB_SUCCESS) rows_changed++;
3258
+
3259
 	innodb_srv_conc_exit_innodb(trx);
3260
 
3261
 	error = convert_error_code_to_mysql(error, user_thd);
127 by kinoyasu
port maintainer-Yasufumi patches for 5.1.51
3262
@@ -4923,6 +4929,9 @@
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3263
 	if (ret == DB_SUCCESS) {
3264
 		error = 0;
3265
 		table->status = 0;
3266
+		rows_read++;
3267
+		if (active_index >= 0 && active_index < MAX_KEY)
3268
+			index_rows_read[active_index]++;
3269
 
3270
 	} else if (ret == DB_RECORD_NOT_FOUND) {
3271
 		error = HA_ERR_END_OF_FILE;
106 by kinoyasu
Port Yasufumi maintaining patches to 5.1.50:
3272
diff -ruN a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
3273
--- a/storage/myisam/ha_myisam.cc	2010-08-04 02:24:27.000000000 +0900
3274
+++ b/storage/myisam/ha_myisam.cc	2010-08-27 15:10:33.921058182 +0900
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3275
@@ -761,6 +761,7 @@
3276
 
3277
 int ha_myisam::write_row(uchar *buf)
3278
 {
3279
+  int error;
3280
   ha_statistic_increment(&SSV::ha_write_count);
3281
 
3282
   /* If we have a timestamp column, update it to the current time */
3283
@@ -773,11 +774,12 @@
3284
   */
3285
   if (table->next_number_field && buf == table->record[0])
3286
   {
3287
-    int error;
3288
     if ((error= update_auto_increment()))
3289
       return error;
3290
   }
3291
-  return mi_write(file,buf);
3292
+  error=mi_write(file,buf);
3293
+  if (!error) rows_changed++;
3294
+  return error;
3295
 }
3296
 
3297
 int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
3298
@@ -1638,16 +1640,22 @@
3299
 
3300
 int ha_myisam::update_row(const uchar *old_data, uchar *new_data)
3301
 {
3302
+  int error;
3303
   ha_statistic_increment(&SSV::ha_update_count);
3304
   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
3305
     table->timestamp_field->set_time();
3306
-  return mi_update(file,old_data,new_data);
3307
+  error=mi_update(file,old_data,new_data);
3308
+  if (!error) rows_changed++;
3309
+  return error;
3310
 }
3311
 
3312
 int ha_myisam::delete_row(const uchar *buf)
3313
 {
3314
+  int error;
3315
   ha_statistic_increment(&SSV::ha_delete_count);
3316
-  return mi_delete(file,buf);
3317
+  error=mi_delete(file,buf);
3318
+  if (!error) rows_changed++;
3319
+  return error;
3320
 }
3321
 
3322
 int ha_myisam::index_read_map(uchar *buf, const uchar *key,
3323
@@ -1658,6 +1666,13 @@
3324
   ha_statistic_increment(&SSV::ha_read_key_count);
3325
   int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
3326
   table->status=error ? STATUS_NOT_FOUND: 0;
3327
+  if (!error) {
3328
+    rows_read++;
3329
+
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
3330
+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3331
+    if (inx >= 0 && inx < MAX_KEY)
3332
+      index_rows_read[inx]++;
3333
+  }
3334
   return error;
3335
 }
3336
 
3337
@@ -1668,6 +1683,13 @@
3338
   ha_statistic_increment(&SSV::ha_read_key_count);
3339
   int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
3340
   table->status=error ? STATUS_NOT_FOUND: 0;
3341
+  if (!error) {
3342
+    rows_read++;
3343
+
3344
+    int inx = index;
3345
+    if (inx >= 0 && inx < MAX_KEY)
3346
+      index_rows_read[inx]++;
3347
+  }
3348
   return error;
3349
 }
3350
 
3351
@@ -1680,6 +1702,13 @@
3352
   int error=mi_rkey(file, buf, active_index, key, keypart_map,
3353
                     HA_READ_PREFIX_LAST);
3354
   table->status=error ? STATUS_NOT_FOUND: 0;
3355
+  if (!error) {
3356
+    rows_read++;
3357
+
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
3358
+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3359
+    if (inx >= 0 && inx < MAX_KEY)
3360
+      index_rows_read[inx]++;
3361
+  }
3362
   DBUG_RETURN(error);
3363
 }
3364
 
3365
@@ -1689,6 +1718,13 @@
3366
   ha_statistic_increment(&SSV::ha_read_next_count);
3367
   int error=mi_rnext(file,buf,active_index);
3368
   table->status=error ? STATUS_NOT_FOUND: 0;
3369
+  if (!error) {
3370
+    rows_read++;
3371
+
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
3372
+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3373
+    if (inx >= 0 && inx < MAX_KEY)
3374
+      index_rows_read[inx]++;
3375
+  }
3376
   return error;
3377
 }
3378
 
3379
@@ -1698,6 +1734,13 @@
3380
   ha_statistic_increment(&SSV::ha_read_prev_count);
3381
   int error=mi_rprev(file,buf, active_index);
3382
   table->status=error ? STATUS_NOT_FOUND: 0;
3383
+  if (!error) {
3384
+    rows_read++;
3385
+
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
3386
+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3387
+    if (inx >= 0 && inx < MAX_KEY)
3388
+      index_rows_read[inx]++;
3389
+  }
3390
   return error;
3391
 }
3392
 
3393
@@ -1707,6 +1750,13 @@
3394
   ha_statistic_increment(&SSV::ha_read_first_count);
3395
   int error=mi_rfirst(file, buf, active_index);
3396
   table->status=error ? STATUS_NOT_FOUND: 0;
3397
+  if (!error) {
3398
+    rows_read++;
3399
+
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
3400
+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3401
+    if (inx >= 0 && inx < MAX_KEY)
3402
+      index_rows_read[inx]++;
3403
+  }
3404
   return error;
3405
 }
3406
 
3407
@@ -1716,6 +1766,13 @@
3408
   ha_statistic_increment(&SSV::ha_read_last_count);
3409
   int error=mi_rlast(file, buf, active_index);
3410
   table->status=error ? STATUS_NOT_FOUND: 0;
3411
+  if (!error) {
3412
+    rows_read++;
3413
+
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
3414
+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3415
+    if (inx >= 0 && inx < MAX_KEY)
3416
+      index_rows_read[inx]++;
3417
+  }
3418
   return error;
3419
 }
3420
 
3421
@@ -1731,6 +1788,13 @@
3422
     error= mi_rnext_same(file,buf);
3423
   } while (error == HA_ERR_RECORD_DELETED);
3424
   table->status=error ? STATUS_NOT_FOUND: 0;
3425
+  if (!error) {
3426
+    rows_read++;
3427
+
83.2.3 by kinoyasu
adjust not to cause warnings with -Wall
3428
+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
1 by kinoyasu
merge, reorder and port patches based on mysql 5.1.46 innodb 1.0.7
3429
+    if (inx >= 0 && inx < MAX_KEY)
3430
+      index_rows_read[inx]++;
3431
+  }
3432
   return error;
3433
 }
3434
 
3435
@@ -1747,6 +1811,7 @@
3436
   ha_statistic_increment(&SSV::ha_read_rnd_next_count);
3437
   int error=mi_scan(file, buf);
3438
   table->status=error ? STATUS_NOT_FOUND: 0;
3439
+  if (!error) rows_read++;
3440
   return error;
3441
 }
3442
 
3443
@@ -1760,6 +1825,7 @@
3444
   ha_statistic_increment(&SSV::ha_read_rnd_count);
3445
   int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
3446
   table->status=error ? STATUS_NOT_FOUND: 0;
3447
+  if (!error) rows_read++;
3448
   return error;
3449
 }
3450