1 diff -r 592f6c3641ba BUILD/Makefile.in
2 --- a/BUILD/Makefile.in Wed Jul 29 13:33:34 2009 -0700
3 +++ b/BUILD/Makefile.in Wed Jul 29 13:34:11 2009 -0700
6 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
11 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
12 diff -r 592f6c3641ba Docs/Makefile.in
13 --- a/Docs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
14 +++ b/Docs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
17 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
22 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
23 diff -r 592f6c3641ba Makefile.in
24 --- a/Makefile.in Wed Jul 29 13:33:34 2009 -0700
25 +++ b/Makefile.in Wed Jul 29 13:34:11 2009 -0700
28 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
33 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
34 diff -r 592f6c3641ba SSL/Makefile.in
35 --- a/SSL/Makefile.in Wed Jul 29 13:33:34 2009 -0700
36 +++ b/SSL/Makefile.in Wed Jul 29 13:34:11 2009 -0700
39 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
44 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
45 diff -r 592f6c3641ba client/Makefile.in
46 --- a/client/Makefile.in Wed Jul 29 13:33:34 2009 -0700
47 +++ b/client/Makefile.in Wed Jul 29 13:34:11 2009 -0700
50 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
55 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
56 diff -r 592f6c3641ba cmd-line-utils/Makefile.in
57 --- a/cmd-line-utils/Makefile.in Wed Jul 29 13:33:34 2009 -0700
58 +++ b/cmd-line-utils/Makefile.in Wed Jul 29 13:34:11 2009 -0700
61 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
66 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
67 diff -r 592f6c3641ba cmd-line-utils/libedit/Makefile.in
68 --- a/cmd-line-utils/libedit/Makefile.in Wed Jul 29 13:33:34 2009 -0700
69 +++ b/cmd-line-utils/libedit/Makefile.in Wed Jul 29 13:34:11 2009 -0700
72 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
77 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
78 diff -r 592f6c3641ba cmd-line-utils/readline/Makefile.in
79 --- a/cmd-line-utils/readline/Makefile.in Wed Jul 29 13:33:34 2009 -0700
80 +++ b/cmd-line-utils/readline/Makefile.in Wed Jul 29 13:34:11 2009 -0700
83 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
88 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
89 diff -r 592f6c3641ba configure
90 diff -r 592f6c3641ba configure.in
91 --- a/configure.in Wed Jul 29 13:33:34 2009 -0700
92 +++ b/configure.in Wed Jul 29 13:34:11 2009 -0700
93 @@ -2136,7 +2136,18 @@
94 # We also disable for SCO for the time being, the headers for the
95 # thread library we use conflicts with other headers.
97 - *) AC_CHECK_FUNCS(clock_gettime)
99 + # most systems require the program be linked with librt library to use
100 + # the function clock_gettime
101 + my_save_LIBS="$LIBS"
103 + AC_CHECK_LIB(rt,clock_gettime)
105 + LIBS="$my_save_LIBS"
108 + LIBS="$LIBS $LIBRT"
109 + AC_CHECK_FUNCS(clock_gettime)
113 @@ -2772,7 +2783,7 @@
114 AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe])
117 -CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS"
118 +CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT"
120 AC_SUBST(CLIENT_LIBS)
121 AC_SUBST(NON_THREADED_LIBS)
122 diff -r 592f6c3641ba dbug/Makefile.in
123 --- a/dbug/Makefile.in Wed Jul 29 13:33:34 2009 -0700
124 +++ b/dbug/Makefile.in Wed Jul 29 13:34:11 2009 -0700
127 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
132 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
133 diff -r 592f6c3641ba extra/Makefile.in
134 --- a/extra/Makefile.in Wed Jul 29 13:33:34 2009 -0700
135 +++ b/extra/Makefile.in Wed Jul 29 13:34:11 2009 -0700
138 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
143 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
144 diff -r 592f6c3641ba extra/yassl/Makefile.in
145 --- a/extra/yassl/Makefile.in Wed Jul 29 13:33:34 2009 -0700
146 +++ b/extra/yassl/Makefile.in Wed Jul 29 13:34:11 2009 -0700
149 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
154 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
155 diff -r 592f6c3641ba extra/yassl/src/Makefile.in
156 --- a/extra/yassl/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
157 +++ b/extra/yassl/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
160 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
165 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
166 diff -r 592f6c3641ba extra/yassl/taocrypt/Makefile.in
167 --- a/extra/yassl/taocrypt/Makefile.in Wed Jul 29 13:33:34 2009 -0700
168 +++ b/extra/yassl/taocrypt/Makefile.in Wed Jul 29 13:34:11 2009 -0700
171 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
176 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
177 diff -r 592f6c3641ba extra/yassl/taocrypt/benchmark/Makefile.in
178 --- a/extra/yassl/taocrypt/benchmark/Makefile.in Wed Jul 29 13:33:34 2009 -0700
179 +++ b/extra/yassl/taocrypt/benchmark/Makefile.in Wed Jul 29 13:34:11 2009 -0700
182 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
187 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
188 diff -r 592f6c3641ba extra/yassl/taocrypt/src/Makefile.in
189 --- a/extra/yassl/taocrypt/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
190 +++ b/extra/yassl/taocrypt/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
193 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
198 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
199 diff -r 592f6c3641ba extra/yassl/taocrypt/test/Makefile.in
200 --- a/extra/yassl/taocrypt/test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
201 +++ b/extra/yassl/taocrypt/test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
204 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
209 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
210 diff -r 592f6c3641ba extra/yassl/testsuite/Makefile.in
211 --- a/extra/yassl/testsuite/Makefile.in Wed Jul 29 13:33:34 2009 -0700
212 +++ b/extra/yassl/testsuite/Makefile.in Wed Jul 29 13:34:11 2009 -0700
215 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
220 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
221 diff -r 592f6c3641ba heap/Makefile.in
222 --- a/heap/Makefile.in Wed Jul 29 13:33:34 2009 -0700
223 +++ b/heap/Makefile.in Wed Jul 29 13:34:11 2009 -0700
226 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
231 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
232 diff -r 592f6c3641ba include/Makefile.in
233 --- a/include/Makefile.in Wed Jul 29 13:33:34 2009 -0700
234 +++ b/include/Makefile.in Wed Jul 29 13:34:11 2009 -0700
237 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
242 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
243 diff -r 592f6c3641ba include/mysql_com.h
244 --- a/include/mysql_com.h Wed Jul 29 13:33:34 2009 -0700
245 +++ b/include/mysql_com.h Wed Jul 29 13:34:11 2009 -0700
247 #define USERNAME_LENGTH 16
248 #define SERVER_VERSION_LENGTH 60
249 #define SQLSTATE_LENGTH 5
250 +#define LIST_PROCESS_HOST_LEN 64
253 USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
256 #define REFRESH_MASTER 128 /* Remove all bin logs in the index
257 and truncate the index */
258 +#define REFRESH_TABLE_STATS 256 /* Refresh table stats hash table */
259 +#define REFRESH_INDEX_STATS 512 /* Refresh index stats hash table */
260 +#define REFRESH_USER_STATS 1024 /* Refresh user stats hash table */
261 +#define REFRESH_SLOW_QUERY_LOG 4096 /* Flush slow query log and rotate*/
262 +#define REFRESH_CLIENT_STATS 8192 /* Refresh client stats hash table */
264 /* The following can't be set with mysql_refresh() */
265 #define REFRESH_READ_LOCK 16384 /* Lock tables for read */
266 diff -r 592f6c3641ba libmysql/Makefile.in
267 --- a/libmysql/Makefile.in Wed Jul 29 13:33:34 2009 -0700
268 +++ b/libmysql/Makefile.in Wed Jul 29 13:34:11 2009 -0700
271 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
276 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
277 diff -r 592f6c3641ba libmysql_r/Makefile.in
278 --- a/libmysql_r/Makefile.in Wed Jul 29 13:33:34 2009 -0700
279 +++ b/libmysql_r/Makefile.in Wed Jul 29 13:34:11 2009 -0700
282 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
285 LIBS = @LIBS@ @ZLIB_LIBS@ @openssl_libs@
287 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
288 diff -r 592f6c3641ba libmysqld/Makefile.in
289 --- a/libmysqld/Makefile.in Wed Jul 29 13:33:34 2009 -0700
290 +++ b/libmysqld/Makefile.in Wed Jul 29 13:34:11 2009 -0700
293 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
298 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
299 diff -r 592f6c3641ba libmysqld/examples/Makefile.in
300 --- a/libmysqld/examples/Makefile.in Wed Jul 29 13:33:34 2009 -0700
301 +++ b/libmysqld/examples/Makefile.in Wed Jul 29 13:34:11 2009 -0700
304 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
307 LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs)
309 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
310 diff -r 592f6c3641ba man/Makefile.in
311 --- a/man/Makefile.in Wed Jul 29 13:33:34 2009 -0700
312 +++ b/man/Makefile.in Wed Jul 29 13:34:11 2009 -0700
315 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
320 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
321 diff -r 592f6c3641ba myisam/Makefile.in
322 --- a/myisam/Makefile.in Wed Jul 29 13:33:34 2009 -0700
323 +++ b/myisam/Makefile.in Wed Jul 29 13:34:11 2009 -0700
326 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
331 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
332 diff -r 592f6c3641ba myisammrg/Makefile.in
333 --- a/myisammrg/Makefile.in Wed Jul 29 13:33:34 2009 -0700
334 +++ b/myisammrg/Makefile.in Wed Jul 29 13:34:11 2009 -0700
337 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
342 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
343 diff -r 592f6c3641ba mysql-test/Makefile.in
344 --- a/mysql-test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
345 +++ b/mysql-test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
348 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
353 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
354 diff -r 592f6c3641ba mysql-test/ndb/Makefile.in
355 --- a/mysql-test/ndb/Makefile.in Wed Jul 29 13:33:34 2009 -0700
356 +++ b/mysql-test/ndb/Makefile.in Wed Jul 29 13:34:11 2009 -0700
359 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
364 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
365 diff -r 592f6c3641ba mysql-test/r/information_schema.result
366 --- a/mysql-test/r/information_schema.result Wed Jul 29 13:33:34 2009 -0700
367 +++ b/mysql-test/r/information_schema.result Wed Jul 29 13:34:11 2009 -0700
374 COLLATION_CHARACTER_SET_APPLICABILITY
394 TABLE_CONSTRAINTS TABLE_CONSTRAINTS
395 TABLE_PRIVILEGES TABLE_PRIVILEGES
396 +TABLE_STATISTICS TABLE_STATISTICS
398 tables_priv tables_priv
402 TABLE_CONSTRAINTS TABLE_CONSTRAINTS
403 TABLE_PRIVILEGES TABLE_PRIVILEGES
404 +TABLE_STATISTICS TABLE_STATISTICS
406 tables_priv tables_priv
410 TABLE_CONSTRAINTS TABLE_CONSTRAINTS
411 TABLE_PRIVILEGES TABLE_PRIVILEGES
412 +TABLE_STATISTICS TABLE_STATISTICS
414 tables_priv tables_priv
416 @@ -594,12 +601,13 @@
417 where table_schema='information_schema' limit 2;
418 TABLE_NAME TABLE_TYPE ENGINE
419 CHARACTER_SETS SYSTEM VIEW MEMORY
420 -COLLATIONS SYSTEM VIEW MEMORY
421 +CLIENT_STATISTICS SYSTEM VIEW MEMORY
422 show tables from information_schema like "T%";
423 Tables_in_information_schema (T%)
429 create database information_schema;
430 ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
433 TABLE_CONSTRAINTS SYSTEM VIEW
434 TABLE_PRIVILEGES SYSTEM VIEW
435 +TABLE_STATISTICS SYSTEM VIEW
437 create table t1(a int);
438 ERROR 42S02: Unknown table 't1' in information_schema
445 select table_name from tables where table_name='user';
448 CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
449 CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
454 drop table t_crashme;
455 select table_schema,table_name, column_name from
456 @@ -790,18 +800,20 @@
457 TABLE_NAME COLUMN_NAME PRIVILEGES
458 COLUMNS TABLE_NAME select
459 COLUMN_PRIVILEGES TABLE_NAME select
460 +INDEX_STATISTICS TABLE_NAME select
461 KEY_COLUMN_USAGE TABLE_NAME select
462 STATISTICS TABLE_NAME select
463 TABLES TABLE_NAME select
464 TABLE_CONSTRAINTS TABLE_NAME select
465 TABLE_PRIVILEGES TABLE_NAME select
466 +TABLE_STATISTICS TABLE_NAME select
467 VIEWS TABLE_NAME select
468 delete from mysql.user where user='mysqltest_4';
469 delete from mysql.db where user='mysqltest_4';
471 SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
472 table_schema count(*)
473 -information_schema 17
474 +information_schema 21
476 create table t1 (i int, j int);
477 create trigger trg1 before insert on t1 for each row
478 @@ -1187,10 +1199,12 @@
480 table_name column_name
481 CHARACTER_SETS CHARACTER_SET_NAME
482 +CLIENT_STATISTICS CLIENT
483 COLLATIONS COLLATION_NAME
484 COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
486 COLUMN_PRIVILEGES TABLE_SCHEMA
487 +INDEX_STATISTICS TABLE_SCHEMA
488 KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
490 ROUTINES ROUTINE_SCHEMA
491 @@ -1200,8 +1214,10 @@
493 TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
494 TABLE_PRIVILEGES TABLE_SCHEMA
495 +TABLE_STATISTICS TABLE_SCHEMA
496 TRIGGERS TRIGGER_SCHEMA
497 USER_PRIVILEGES GRANTEE
498 +USER_STATISTICS USER
500 SELECT t.table_name, c1.column_name
501 FROM information_schema.tables t
502 @@ -1219,10 +1235,12 @@
504 table_name column_name
505 CHARACTER_SETS CHARACTER_SET_NAME
506 +CLIENT_STATISTICS CLIENT
507 COLLATIONS COLLATION_NAME
508 COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
510 COLUMN_PRIVILEGES TABLE_SCHEMA
511 +INDEX_STATISTICS TABLE_SCHEMA
512 KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
514 ROUTINES ROUTINE_SCHEMA
515 @@ -1232,8 +1250,10 @@
517 TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
518 TABLE_PRIVILEGES TABLE_SCHEMA
519 +TABLE_STATISTICS TABLE_SCHEMA
520 TRIGGERS TRIGGER_SCHEMA
521 USER_PRIVILEGES GRANTEE
522 +USER_STATISTICS USER
524 SELECT MAX(table_name) FROM information_schema.tables;
526 @@ -1302,10 +1322,12 @@
527 group by t.table_name order by num1, t.table_name;
528 table_name group_concat(t.table_schema, '.', t.table_name) num1
529 CHARACTER_SETS information_schema.CHARACTER_SETS 1
530 +CLIENT_STATISTICS information_schema.CLIENT_STATISTICS 1
531 COLLATIONS information_schema.COLLATIONS 1
532 COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 1
533 COLUMNS information_schema.COLUMNS 1
534 COLUMN_PRIVILEGES information_schema.COLUMN_PRIVILEGES 1
535 +INDEX_STATISTICS information_schema.INDEX_STATISTICS 1
536 KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1
537 PROFILING information_schema.PROFILING 1
538 ROUTINES information_schema.ROUTINES 1
539 @@ -1315,8 +1337,10 @@
540 TABLES information_schema.TABLES 1
541 TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1
542 TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
543 +TABLE_STATISTICS information_schema.TABLE_STATISTICS 1
544 TRIGGERS information_schema.TRIGGERS 1
545 USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
546 +USER_STATISTICS information_schema.USER_STATISTICS 1
547 VIEWS information_schema.VIEWS 1
548 create table t1(f1 int);
549 create view v1 as select f1+1 as a from t1;
550 diff -r 592f6c3641ba mysql-test/r/information_schema_db.result
551 --- a/mysql-test/r/information_schema_db.result Wed Jul 29 13:33:34 2009 -0700
552 +++ b/mysql-test/r/information_schema_db.result Wed Jul 29 13:34:11 2009 -0700
555 Tables_in_information_schema
559 COLLATION_CHARACTER_SET_APPLICABILITY
575 show tables from INFORMATION_SCHEMA like 'T%';
576 Tables_in_information_schema (T%)
582 create database `inf%`;
583 create database mbase;
584 diff -r 592f6c3641ba mysql-test/r/mysqlshow.result
585 --- a/mysql-test/r/mysqlshow.result Wed Jul 29 13:33:34 2009 -0700
586 +++ b/mysql-test/r/mysqlshow.result Wed Jul 29 13:34:11 2009 -0700
589 +---------------------------------------+
591 +| CLIENT_STATISTICS |
593 | COLLATION_CHARACTER_SET_APPLICABILITY |
595 | COLUMN_PRIVILEGES |
596 +| INDEX_STATISTICS |
602 | TABLE_CONSTRAINTS |
604 +| TABLE_STATISTICS |
609 +---------------------------------------+
610 Database: INFORMATION_SCHEMA
611 @@ -102,10 +106,12 @@
613 +---------------------------------------+
615 +| CLIENT_STATISTICS |
617 | COLLATION_CHARACTER_SET_APPLICABILITY |
619 | COLUMN_PRIVILEGES |
620 +| INDEX_STATISTICS |
626 | TABLE_CONSTRAINTS |
628 +| TABLE_STATISTICS |
633 +---------------------------------------+
634 Wildcard: inf_rmation_schema
635 diff -r 592f6c3641ba mysys/Makefile.in
636 --- a/mysys/Makefile.in Wed Jul 29 13:33:34 2009 -0700
637 +++ b/mysys/Makefile.in Wed Jul 29 13:34:11 2009 -0700
640 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
645 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
646 diff -r 592f6c3641ba ndb/Makefile.in
647 --- a/ndb/Makefile.in Wed Jul 29 13:33:34 2009 -0700
648 +++ b/ndb/Makefile.in Wed Jul 29 13:34:11 2009 -0700
651 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
656 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
657 diff -r 592f6c3641ba ndb/docs/Makefile.in
658 --- a/ndb/docs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
659 +++ b/ndb/docs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
662 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
667 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
668 diff -r 592f6c3641ba ndb/include/Makefile.in
669 --- a/ndb/include/Makefile.in Wed Jul 29 13:33:34 2009 -0700
670 +++ b/ndb/include/Makefile.in Wed Jul 29 13:34:11 2009 -0700
673 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
678 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
679 diff -r 592f6c3641ba ndb/src/Makefile.in
680 --- a/ndb/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
681 +++ b/ndb/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
684 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
689 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
690 diff -r 592f6c3641ba ndb/src/common/Makefile.in
691 --- a/ndb/src/common/Makefile.in Wed Jul 29 13:33:34 2009 -0700
692 +++ b/ndb/src/common/Makefile.in Wed Jul 29 13:34:11 2009 -0700
695 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
700 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
701 diff -r 592f6c3641ba ndb/src/common/debugger/Makefile.in
702 --- a/ndb/src/common/debugger/Makefile.in Wed Jul 29 13:33:34 2009 -0700
703 +++ b/ndb/src/common/debugger/Makefile.in Wed Jul 29 13:34:11 2009 -0700
706 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
711 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
712 diff -r 592f6c3641ba ndb/src/common/debugger/signaldata/Makefile.in
713 --- a/ndb/src/common/debugger/signaldata/Makefile.in Wed Jul 29 13:33:34 2009 -0700
714 +++ b/ndb/src/common/debugger/signaldata/Makefile.in Wed Jul 29 13:34:11 2009 -0700
717 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
722 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
723 diff -r 592f6c3641ba ndb/src/common/logger/Makefile.in
724 --- a/ndb/src/common/logger/Makefile.in Wed Jul 29 13:33:34 2009 -0700
725 +++ b/ndb/src/common/logger/Makefile.in Wed Jul 29 13:34:11 2009 -0700
728 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
733 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
734 diff -r 592f6c3641ba ndb/src/common/mgmcommon/Makefile.in
735 --- a/ndb/src/common/mgmcommon/Makefile.in Wed Jul 29 13:33:34 2009 -0700
736 +++ b/ndb/src/common/mgmcommon/Makefile.in Wed Jul 29 13:34:11 2009 -0700
739 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
744 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
745 diff -r 592f6c3641ba ndb/src/common/portlib/Makefile.in
746 --- a/ndb/src/common/portlib/Makefile.in Wed Jul 29 13:33:34 2009 -0700
747 +++ b/ndb/src/common/portlib/Makefile.in Wed Jul 29 13:34:11 2009 -0700
750 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
755 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
756 diff -r 592f6c3641ba ndb/src/common/transporter/Makefile.in
757 --- a/ndb/src/common/transporter/Makefile.in Wed Jul 29 13:33:34 2009 -0700
758 +++ b/ndb/src/common/transporter/Makefile.in Wed Jul 29 13:34:11 2009 -0700
761 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
766 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
767 diff -r 592f6c3641ba ndb/src/common/util/Makefile.in
768 --- a/ndb/src/common/util/Makefile.in Wed Jul 29 13:33:34 2009 -0700
769 +++ b/ndb/src/common/util/Makefile.in Wed Jul 29 13:34:11 2009 -0700
772 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
777 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
778 diff -r 592f6c3641ba ndb/src/cw/Makefile.in
779 --- a/ndb/src/cw/Makefile.in Wed Jul 29 13:33:34 2009 -0700
780 +++ b/ndb/src/cw/Makefile.in Wed Jul 29 13:34:11 2009 -0700
783 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
788 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
789 diff -r 592f6c3641ba ndb/src/cw/cpcd/Makefile.in
790 --- a/ndb/src/cw/cpcd/Makefile.in Wed Jul 29 13:33:34 2009 -0700
791 +++ b/ndb/src/cw/cpcd/Makefile.in Wed Jul 29 13:34:11 2009 -0700
794 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
799 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
800 diff -r 592f6c3641ba ndb/src/kernel/Makefile.in
801 --- a/ndb/src/kernel/Makefile.in Wed Jul 29 13:33:34 2009 -0700
802 +++ b/ndb/src/kernel/Makefile.in Wed Jul 29 13:34:11 2009 -0700
805 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
810 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
811 diff -r 592f6c3641ba ndb/src/kernel/blocks/Makefile.in
812 --- a/ndb/src/kernel/blocks/Makefile.in Wed Jul 29 13:33:34 2009 -0700
813 +++ b/ndb/src/kernel/blocks/Makefile.in Wed Jul 29 13:34:11 2009 -0700
816 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
821 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
822 diff -r 592f6c3641ba ndb/src/kernel/blocks/backup/Makefile.in
823 --- a/ndb/src/kernel/blocks/backup/Makefile.in Wed Jul 29 13:33:34 2009 -0700
824 +++ b/ndb/src/kernel/blocks/backup/Makefile.in Wed Jul 29 13:34:11 2009 -0700
827 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
832 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
833 diff -r 592f6c3641ba ndb/src/kernel/blocks/cmvmi/Makefile.in
834 --- a/ndb/src/kernel/blocks/cmvmi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
835 +++ b/ndb/src/kernel/blocks/cmvmi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
838 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
843 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
844 diff -r 592f6c3641ba ndb/src/kernel/blocks/dbacc/Makefile.in
845 --- a/ndb/src/kernel/blocks/dbacc/Makefile.in Wed Jul 29 13:33:34 2009 -0700
846 +++ b/ndb/src/kernel/blocks/dbacc/Makefile.in Wed Jul 29 13:34:11 2009 -0700
849 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
854 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
855 diff -r 592f6c3641ba ndb/src/kernel/blocks/dbdict/Makefile.in
856 --- a/ndb/src/kernel/blocks/dbdict/Makefile.in Wed Jul 29 13:33:34 2009 -0700
857 +++ b/ndb/src/kernel/blocks/dbdict/Makefile.in Wed Jul 29 13:34:11 2009 -0700
860 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
865 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
866 diff -r 592f6c3641ba ndb/src/kernel/blocks/dbdih/Makefile.in
867 --- a/ndb/src/kernel/blocks/dbdih/Makefile.in Wed Jul 29 13:33:34 2009 -0700
868 +++ b/ndb/src/kernel/blocks/dbdih/Makefile.in Wed Jul 29 13:34:11 2009 -0700
871 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
876 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
877 diff -r 592f6c3641ba ndb/src/kernel/blocks/dblqh/Makefile.in
878 --- a/ndb/src/kernel/blocks/dblqh/Makefile.in Wed Jul 29 13:33:34 2009 -0700
879 +++ b/ndb/src/kernel/blocks/dblqh/Makefile.in Wed Jul 29 13:34:11 2009 -0700
882 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
887 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
888 diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtc/Makefile.in
889 --- a/ndb/src/kernel/blocks/dbtc/Makefile.in Wed Jul 29 13:33:34 2009 -0700
890 +++ b/ndb/src/kernel/blocks/dbtc/Makefile.in Wed Jul 29 13:34:11 2009 -0700
893 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
898 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
899 diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtup/Makefile.in
900 --- a/ndb/src/kernel/blocks/dbtup/Makefile.in Wed Jul 29 13:33:34 2009 -0700
901 +++ b/ndb/src/kernel/blocks/dbtup/Makefile.in Wed Jul 29 13:34:11 2009 -0700
904 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
909 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
910 diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtux/Makefile.in
911 --- a/ndb/src/kernel/blocks/dbtux/Makefile.in Wed Jul 29 13:33:34 2009 -0700
912 +++ b/ndb/src/kernel/blocks/dbtux/Makefile.in Wed Jul 29 13:34:11 2009 -0700
915 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
920 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
921 diff -r 592f6c3641ba ndb/src/kernel/blocks/dbutil/Makefile.in
922 --- a/ndb/src/kernel/blocks/dbutil/Makefile.in Wed Jul 29 13:33:34 2009 -0700
923 +++ b/ndb/src/kernel/blocks/dbutil/Makefile.in Wed Jul 29 13:34:11 2009 -0700
926 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
931 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
932 diff -r 592f6c3641ba ndb/src/kernel/blocks/ndbcntr/Makefile.in
933 --- a/ndb/src/kernel/blocks/ndbcntr/Makefile.in Wed Jul 29 13:33:34 2009 -0700
934 +++ b/ndb/src/kernel/blocks/ndbcntr/Makefile.in Wed Jul 29 13:34:11 2009 -0700
937 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
942 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
943 diff -r 592f6c3641ba ndb/src/kernel/blocks/ndbfs/Makefile.in
944 --- a/ndb/src/kernel/blocks/ndbfs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
945 +++ b/ndb/src/kernel/blocks/ndbfs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
948 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
953 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
954 diff -r 592f6c3641ba ndb/src/kernel/blocks/qmgr/Makefile.in
955 --- a/ndb/src/kernel/blocks/qmgr/Makefile.in Wed Jul 29 13:33:34 2009 -0700
956 +++ b/ndb/src/kernel/blocks/qmgr/Makefile.in Wed Jul 29 13:34:11 2009 -0700
959 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
964 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
965 diff -r 592f6c3641ba ndb/src/kernel/blocks/suma/Makefile.in
966 --- a/ndb/src/kernel/blocks/suma/Makefile.in Wed Jul 29 13:33:34 2009 -0700
967 +++ b/ndb/src/kernel/blocks/suma/Makefile.in Wed Jul 29 13:34:11 2009 -0700
970 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
975 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
976 diff -r 592f6c3641ba ndb/src/kernel/blocks/trix/Makefile.in
977 --- a/ndb/src/kernel/blocks/trix/Makefile.in Wed Jul 29 13:33:34 2009 -0700
978 +++ b/ndb/src/kernel/blocks/trix/Makefile.in Wed Jul 29 13:34:11 2009 -0700
981 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
986 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
987 diff -r 592f6c3641ba ndb/src/kernel/error/Makefile.in
988 --- a/ndb/src/kernel/error/Makefile.in Wed Jul 29 13:33:34 2009 -0700
989 +++ b/ndb/src/kernel/error/Makefile.in Wed Jul 29 13:34:11 2009 -0700
992 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
997 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
998 diff -r 592f6c3641ba ndb/src/kernel/vm/Makefile.in
999 --- a/ndb/src/kernel/vm/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1000 +++ b/ndb/src/kernel/vm/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1003 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1008 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1009 diff -r 592f6c3641ba ndb/src/mgmapi/Makefile.in
1010 --- a/ndb/src/mgmapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1011 +++ b/ndb/src/mgmapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1014 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1019 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1020 diff -r 592f6c3641ba ndb/src/mgmclient/Makefile.in
1021 --- a/ndb/src/mgmclient/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1022 +++ b/ndb/src/mgmclient/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1025 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1030 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1031 diff -r 592f6c3641ba ndb/src/mgmsrv/Makefile.in
1032 --- a/ndb/src/mgmsrv/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1033 +++ b/ndb/src/mgmsrv/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1036 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1041 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1042 diff -r 592f6c3641ba ndb/src/ndbapi/Makefile.in
1043 --- a/ndb/src/ndbapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1044 +++ b/ndb/src/ndbapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1047 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1052 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1053 diff -r 592f6c3641ba ndb/test/Makefile.in
1054 --- a/ndb/test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1055 +++ b/ndb/test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1058 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1063 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1064 diff -r 592f6c3641ba ndb/test/ndbapi/Makefile.in
1065 --- a/ndb/test/ndbapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1066 +++ b/ndb/test/ndbapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1069 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1074 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1075 diff -r 592f6c3641ba ndb/test/ndbapi/bank/Makefile.in
1076 --- a/ndb/test/ndbapi/bank/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1077 +++ b/ndb/test/ndbapi/bank/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1080 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1085 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1086 diff -r 592f6c3641ba ndb/test/run-test/Makefile.in
1087 --- a/ndb/test/run-test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1088 +++ b/ndb/test/run-test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1091 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1096 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1097 diff -r 592f6c3641ba ndb/test/src/Makefile.in
1098 --- a/ndb/test/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1099 +++ b/ndb/test/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1102 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1107 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1108 diff -r 592f6c3641ba ndb/test/tools/Makefile.in
1109 --- a/ndb/test/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1110 +++ b/ndb/test/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1113 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1118 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1119 diff -r 592f6c3641ba ndb/tools/Makefile.in
1120 --- a/ndb/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1121 +++ b/ndb/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1124 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1129 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1130 diff -r 592f6c3641ba netware/Makefile.in
1131 --- a/netware/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1132 +++ b/netware/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1135 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1140 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1141 diff -r 592f6c3641ba os2/Makefile.in
1142 --- a/os2/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1143 +++ b/os2/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1146 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1151 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1152 diff -r 592f6c3641ba os2/include/Makefile.in
1153 --- a/os2/include/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1154 +++ b/os2/include/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1157 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1162 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1163 diff -r 592f6c3641ba os2/include/sys/Makefile.in
1164 --- a/os2/include/sys/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1165 +++ b/os2/include/sys/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1168 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1173 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1174 diff -r 592f6c3641ba patch_info/userstats.info
1175 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1176 +++ b/patch_info/userstats.info Wed Jul 29 13:34:11 2009 -0700
1178 +File=userstatsv2.patch
1179 +Name=SHOW USER/TABLE/INDEX statistics
1183 +Comment=Added INFORMATION_SCHEMA.*_STATISTICS
1185 +YK: fix behavior for prepared statements
1188 +YK: add switch variable "userstat_running" to control INFORMATION_SCHEMA.*_STATISTICS (default:OFF)
1191 +YK: fixed "Row_sent: 0" problem at microslow_innodb.patch
1192 diff -r 592f6c3641ba pstack/Makefile.in
1193 --- a/pstack/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1194 +++ b/pstack/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1197 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1202 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1203 diff -r 592f6c3641ba pstack/aout/Makefile.in
1204 --- a/pstack/aout/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1205 +++ b/pstack/aout/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1208 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1213 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1214 diff -r 592f6c3641ba regex/Makefile.in
1215 --- a/regex/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1216 +++ b/regex/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1219 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1224 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1225 diff -r 592f6c3641ba scripts/Makefile.in
1226 --- a/scripts/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1227 +++ b/scripts/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1230 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1235 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1236 diff -r 592f6c3641ba server-tools/Makefile.in
1237 --- a/server-tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1238 +++ b/server-tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1241 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1246 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1247 diff -r 592f6c3641ba server-tools/instance-manager/Makefile.in
1248 --- a/server-tools/instance-manager/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1249 +++ b/server-tools/instance-manager/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1252 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1257 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1258 diff -r 592f6c3641ba sql/Makefile.in
1259 --- a/sql/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1260 +++ b/sql/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1263 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1268 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1269 diff -r 592f6c3641ba sql/ha_innodb.cc
1270 --- a/sql/ha_innodb.cc Wed Jul 29 13:33:34 2009 -0700
1271 +++ b/sql/ha_innodb.cc Wed Jul 29 13:34:11 2009 -0700
1272 @@ -3341,6 +3341,8 @@
1274 error = row_insert_for_mysql((byte*) record, prebuilt);
1276 + if (error == DB_SUCCESS) rows_changed++;
1278 if (error == DB_SUCCESS && auto_inc_used) {
1280 /* Fetch the value that was set in the autoincrement field */
1281 @@ -3613,6 +3615,8 @@
1285 + if (error == DB_SUCCESS) rows_changed++;
1287 innodb_srv_conc_exit_innodb(prebuilt->trx);
1289 error = convert_error_code_to_mysql(error, user_thd);
1290 @@ -3661,6 +3665,8 @@
1292 error = row_update_for_mysql((byte*) record, prebuilt);
1294 + if (error == DB_SUCCESS) rows_changed++;
1296 innodb_srv_conc_exit_innodb(prebuilt->trx);
1298 error = convert_error_code_to_mysql(error, user_thd);
1299 @@ -4092,6 +4098,9 @@
1300 if (ret == DB_SUCCESS) {
1304 + if (active_index >= 0 && active_index < MAX_KEY)
1305 + index_rows_read[active_index]++;
1307 } else if (ret == DB_RECORD_NOT_FOUND) {
1308 error = HA_ERR_END_OF_FILE;
1309 diff -r 592f6c3641ba sql/ha_myisam.cc
1310 --- a/sql/ha_myisam.cc Wed Jul 29 13:33:34 2009 -0700
1311 +++ b/sql/ha_myisam.cc Wed Jul 29 13:34:11 2009 -0700
1313 if ((error= update_auto_increment()))
1316 - return mi_write(file,buf);
1317 + int error=mi_write(file,buf);
1318 + if (!error) rows_changed++;
1322 int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
1323 @@ -1521,13 +1523,17 @@
1324 statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status);
1325 if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1326 table->timestamp_field->set_time();
1327 - return mi_update(file,old_data,new_data);
1328 + int error=mi_update(file,old_data,new_data);
1329 + if (!error) rows_changed++;
1333 int ha_myisam::delete_row(const byte * buf)
1335 statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status);
1336 - return mi_delete(file,buf);
1337 + int error=mi_delete(file,buf);
1338 + if (!error) rows_changed++;
1342 int ha_myisam::index_read(byte * buf, const byte * key,
1343 @@ -1538,6 +1544,13 @@
1345 int error=mi_rkey(file,buf,active_index, key, key_len, find_flag);
1346 table->status=error ? STATUS_NOT_FOUND: 0;
1350 + int inx = (active_index == -1) ? file->lastinx : active_index;
1351 + if (inx >= 0 && inx < MAX_KEY)
1352 + index_rows_read[inx]++;
1357 @@ -1548,6 +1561,13 @@
1359 int error=mi_rkey(file,buf,index, key, key_len, find_flag);
1360 table->status=error ? STATUS_NOT_FOUND: 0;
1365 + if (inx >= 0 && inx < MAX_KEY)
1366 + index_rows_read[inx]++;
1371 @@ -1558,6 +1578,13 @@
1373 int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
1374 table->status=error ? STATUS_NOT_FOUND: 0;
1378 + int inx = (active_index == -1) ? file->lastinx : active_index;
1379 + if (inx >= 0 && inx < MAX_KEY)
1380 + index_rows_read[inx]++;
1385 @@ -1568,6 +1595,13 @@
1387 int error=mi_rnext(file,buf,active_index);
1388 table->status=error ? STATUS_NOT_FOUND: 0;
1392 + int inx = (active_index == -1) ? file->lastinx : active_index;
1393 + if (inx >= 0 && inx < MAX_KEY)
1394 + index_rows_read[inx]++;
1399 @@ -1578,6 +1612,13 @@
1401 int error=mi_rprev(file,buf, active_index);
1402 table->status=error ? STATUS_NOT_FOUND: 0;
1406 + int inx = (active_index == -1) ? file->lastinx : active_index;
1407 + if (inx >= 0 && inx < MAX_KEY)
1408 + index_rows_read[inx]++;
1413 @@ -1588,6 +1629,13 @@
1415 int error=mi_rfirst(file, buf, active_index);
1416 table->status=error ? STATUS_NOT_FOUND: 0;
1420 + int inx = (active_index == -1) ? file->lastinx : active_index;
1421 + if (inx >= 0 && inx < MAX_KEY)
1422 + index_rows_read[inx]++;
1427 @@ -1598,6 +1646,13 @@
1429 int error=mi_rlast(file, buf, active_index);
1430 table->status=error ? STATUS_NOT_FOUND: 0;
1434 + int inx = (active_index == -1) ? file->lastinx : active_index;
1435 + if (inx >= 0 && inx < MAX_KEY)
1436 + index_rows_read[inx]++;
1441 @@ -1614,6 +1669,13 @@
1442 error= mi_rnext_same(file,buf);
1443 } while (error == HA_ERR_RECORD_DELETED);
1444 table->status=error ? STATUS_NOT_FOUND: 0;
1448 + int inx = (active_index == -1) ? file->lastinx : active_index;
1449 + if (inx >= 0 && inx < MAX_KEY)
1450 + index_rows_read[inx]++;
1455 @@ -1631,6 +1693,7 @@
1457 int error=mi_scan(file, buf);
1458 table->status=error ? STATUS_NOT_FOUND: 0;
1459 + if (!error) rows_read++;
1463 @@ -1645,6 +1708,7 @@
1465 int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
1466 table->status=error ? STATUS_NOT_FOUND: 0;
1467 + if (!error) rows_read++;
1471 diff -r 592f6c3641ba sql/handler.cc
1472 --- a/sql/handler.cc Wed Jul 29 13:33:34 2009 -0700
1473 +++ b/sql/handler.cc Wed Jul 29 13:34:11 2009 -0700
1476 tc_log->unlog(cookie, xid);
1477 DBUG_EXECUTE_IF("crash_commit_after", abort(););
1478 + if (is_real_trans)
1479 + thd->diff_commit_trans++;
1482 start_waiting_global_read_lock(thd);
1484 thd->transaction.cleanup();
1487 + thd->diff_rollback_trans++;
1488 #endif /* USING_TRANSACTIONS */
1491 @@ -1223,6 +1226,7 @@
1492 statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status);
1493 *ht=0; // keep it conveniently zero-filled
1495 + thd->diff_rollback_trans++;
1499 @@ -1453,6 +1457,8 @@
1501 dupp_ref=ref+ALIGN_SIZE(ref_length);
1503 + rows_read = rows_changed = 0;
1504 + memset(index_rows_read, 0, sizeof(index_rows_read));
1508 @@ -2287,6 +2293,111 @@
1512 +// Updates the global table stats with the TABLE this handler represents.
1513 +void handler::update_global_table_stats() {
1514 + if (!opt_userstat_running) {
1515 + rows_read = rows_changed = 0;
1519 + if (!rows_read && !rows_changed) return; // Nothing to update.
1520 + // table_cache_key is db_name + '\0' + table_name + '\0'.
1521 + if (!table->s || !table->s->table_cache_key || !table->s->table_name) return;
1523 + TABLE_STATS* table_stats;
1524 + char key[NAME_LEN * 2 + 2];
1525 + // [db] + '.' + [table]
1526 + sprintf(key, "%s.%s", table->s->table_cache_key, table->s->table_name);
1528 + pthread_mutex_lock(&LOCK_global_table_stats);
1529 + // Gets the global table stats, creating one if necessary.
1530 + if (!(table_stats = (TABLE_STATS*)hash_search(&global_table_stats,
1533 + if (!(table_stats = ((TABLE_STATS*)
1534 + my_malloc(sizeof(TABLE_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
1536 + sql_print_error("Allocating table stats failed.");
1539 + strncpy(table_stats->table, key, sizeof(table_stats->table));
1540 + table_stats->rows_read = 0;
1541 + table_stats->rows_changed = 0;
1542 + table_stats->rows_changed_x_indexes = 0;
1543 + table_stats->engine_type = (int) ht->db_type;
1545 + if (my_hash_insert(&global_table_stats, (byte*)table_stats)) {
1547 + sql_print_error("Inserting table stats failed.");
1548 + my_free((char*)table_stats, 0);
1552 + // Updates the global table stats.
1553 + table_stats->rows_read += rows_read;
1554 + table_stats->rows_changed += rows_changed;
1555 + table_stats->rows_changed_x_indexes +=
1556 + rows_changed * (table->s->keys ? table->s->keys : 1);
1557 + current_thd->diff_total_read_rows += rows_read;
1558 + rows_read = rows_changed = 0;
1560 + pthread_mutex_unlock(&LOCK_global_table_stats);
1563 +// Updates the global index stats with this handler's accumulated index reads.
1564 +void handler::update_global_index_stats() {
1565 + // table_cache_key is db_name + '\0' + table_name + '\0'.
1566 + if (!table->s || !table->s->table_cache_key || !table->s->table_name) return;
1568 + if (!opt_userstat_running) {
1569 + for (int x = 0; x < table->s->keys; x++) {
1570 + index_rows_read[x] = 0;
1575 + for (int x = 0; x < table->s->keys; x++) {
1576 + if (index_rows_read[x]) {
1577 + // Rows were read using this index.
1578 + KEY* key_info = &table->key_info[x];
1580 + if (!key_info->name) continue;
1582 + INDEX_STATS* index_stats;
1583 + char key[NAME_LEN * 3 + 3];
1584 + // [db] + '.' + [table] + '.' + [index]
1585 + sprintf(key, "%s.%s.%s", table->s->table_cache_key,
1586 + table->s->table_name, key_info->name);
1588 + pthread_mutex_lock(&LOCK_global_index_stats);
1589 + // Gets the global index stats, creating one if necessary.
1590 + if (!(index_stats = (INDEX_STATS*)hash_search(&global_index_stats,
1593 + if (!(index_stats = ((INDEX_STATS*)
1594 + my_malloc(sizeof(INDEX_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
1596 + sql_print_error("Allocating index stats failed.");
1599 + strncpy(index_stats->index, key, sizeof(index_stats->index));
1600 + index_stats->rows_read = 0;
1602 + if (my_hash_insert(&global_index_stats, (byte*)index_stats)) {
1604 + sql_print_error("Inserting index stats failed.");
1605 + my_free((char*)index_stats, 0);
1609 + // Updates the global index stats.
1610 + index_stats->rows_read += index_rows_read[x];
1611 + index_rows_read[x] = 0;
1613 + pthread_mutex_unlock(&LOCK_global_index_stats);
1618 /****************************************************************************
1619 ** Some general functions that isn't in the handler class
1620 diff -r 592f6c3641ba sql/handler.h
1621 --- a/sql/handler.h Wed Jul 29 13:33:34 2009 -0700
1622 +++ b/sql/handler.h Wed Jul 29 13:34:11 2009 -0700
1624 #define USING_TRANSACTIONS
1628 +#error MAX_KEY is too large. Values up to 128 are supported.
1631 // the following is for checking tables
1633 #define HA_ADMIN_ALREADY_DONE 1
1635 bool auto_increment_column_changed;
1636 bool implicit_emptied; /* Can be !=0 only if HEAP */
1637 const COND *pushed_cond;
1638 + ulonglong rows_read;
1639 + ulonglong rows_changed;
1640 + ulonglong index_rows_read[MAX_KEY];
1642 handler(const handlerton *ht_arg, TABLE *table_arg) :table(table_arg),
1644 @@ -615,8 +622,10 @@
1645 ref_length(sizeof(my_off_t)), block_size(0),
1646 raid_type(0), ft_handler(0), inited(NONE),
1647 locked(FALSE), implicit_emptied(0),
1650 + pushed_cond(NULL), rows_read(0), rows_changed(0)
1652 + memset(index_rows_read, 0, sizeof(index_rows_read));
1654 virtual ~handler(void) { DBUG_ASSERT(locked == FALSE); /* TODO: DBUG_ASSERT(inited == NONE); */ }
1655 virtual handler *clone(MEM_ROOT *mem_root);
1656 int ha_open(const char *name, int mode, int test_if_locked);
1657 @@ -625,7 +634,11 @@
1658 virtual void print_error(int error, myf errflag);
1659 virtual bool get_error_message(int error, String *buf);
1660 uint get_dup_key(int error);
1661 - void change_table_ptr(TABLE *table_arg) { table=table_arg; }
1662 + void change_table_ptr(TABLE *table_arg) {
1664 + rows_read = rows_changed = 0;
1665 + memset(index_rows_read, 0, sizeof(index_rows_read));
1667 virtual double scan_time()
1668 { return ulonglong2double(data_file_length) / IO_SIZE + 2; }
1669 virtual double read_time(uint index, uint ranges, ha_rows rows)
1671 virtual bool is_crashed() const { return 0; }
1672 virtual bool auto_repair() const { return 0; }
1674 + void update_global_table_stats();
1675 + void update_global_index_stats();
1678 default rename_table() and delete_table() rename/delete files with a
1679 given name and extensions from bas_ext()
1680 diff -r 592f6c3641ba sql/lex.h
1681 --- a/sql/lex.h Wed Jul 29 13:33:34 2009 -0700
1682 +++ b/sql/lex.h Wed Jul 29 13:34:11 2009 -0700
1684 { "CHECKSUM", SYM(CHECKSUM_SYM)},
1685 { "CIPHER", SYM(CIPHER_SYM)},
1686 { "CLIENT", SYM(CLIENT_SYM)},
1687 + { "CLIENT_STATISTICS", SYM(CLIENT_STATS_SYM)},
1688 { "CLOSE", SYM(CLOSE_SYM)},
1689 { "CODE", SYM(CODE_SYM)},
1690 { "COLLATE", SYM(COLLATE_SYM)},
1692 { "IN", SYM(IN_SYM)},
1693 { "INDEX", SYM(INDEX_SYM)},
1694 { "INDEXES", SYM(INDEXES)},
1695 + { "INDEX_STATISTICS", SYM(INDEX_STATS_SYM)},
1696 { "INFILE", SYM(INFILE)},
1697 { "INNER", SYM(INNER_SYM)},
1698 { "INNOBASE", SYM(INNOBASE_SYM)},
1700 { "SIGNED", SYM(SIGNED_SYM)},
1701 { "SIMPLE", SYM(SIMPLE_SYM)},
1702 { "SLAVE", SYM(SLAVE)},
1703 + { "SLOW", SYM(SLOW_SYM)},
1704 { "SNAPSHOT", SYM(SNAPSHOT_SYM)},
1705 { "SMALLINT", SYM(SMALLINT)},
1706 { "SOME", SYM(ANY_SYM)},
1708 { "TABLE", SYM(TABLE_SYM)},
1709 { "TABLES", SYM(TABLES)},
1710 { "TABLESPACE", SYM(TABLESPACE)},
1711 + { "TABLE_STATISTICS", SYM(TABLE_STATS_SYM)},
1712 { "TEMPORARY", SYM(TEMPORARY)},
1713 { "TEMPTABLE", SYM(TEMPTABLE_SYM)},
1714 { "TERMINATED", SYM(TERMINATED)},
1716 { "USE", SYM(USE_SYM)},
1717 { "USER", SYM(USER)},
1718 { "USER_RESOURCES", SYM(RESOURCES)},
1719 + { "USER_STATISTICS", SYM(USER_STATS_SYM)},
1720 { "USE_FRM", SYM(USE_FRM)},
1721 { "USING", SYM(USING)},
1722 { "UTC_DATE", SYM(UTC_DATE_SYM)},
1723 diff -r 592f6c3641ba sql/log.cc
1724 --- a/sql/log.cc Wed Jul 29 13:33:34 2009 -0700
1725 +++ b/sql/log.cc Wed Jul 29 13:34:11 2009 -0700
1726 @@ -1958,18 +1958,24 @@
1727 thd->current_insert_id);
1730 + if (file == &log_file)
1731 + thd->binlog_bytes_written += e.data_written;
1733 if (thd->insert_id_used)
1735 Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id);
1738 + if (file == &log_file)
1739 + thd->binlog_bytes_written += e.data_written;
1743 Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
1746 + if (file == &log_file)
1747 + thd->binlog_bytes_written += e.data_written;
1749 if (thd->user_var_events.elements)
1751 @@ -1985,6 +1991,8 @@
1752 user_var_event->charset_number);
1755 + if (file == &log_file)
1756 + thd->binlog_bytes_written += e.data_written;
1760 @@ -1995,6 +2003,8 @@
1762 if (event_info->write(file))
1764 + if (file == &log_file)
1765 + thd->binlog_bytes_written += event_info->data_written;
1767 if (file == &log_file) // we are writing to the real log (disk)
1769 @@ -2117,6 +2127,7 @@
1771 if (qinfo.write(&log_file))
1773 + thd->binlog_bytes_written += qinfo.data_written;
1775 /* Read from the file used to cache the queries .*/
1776 if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
1777 @@ -2163,6 +2174,7 @@
1778 /* write the first half of the split header */
1779 if (my_b_write(&log_file, header, carry))
1781 + thd->binlog_bytes_written += carry;
1784 copy fixed second half of header to cache so the correct
1785 @@ -2231,6 +2243,8 @@
1786 /* Write data to the binary log file */
1787 if (my_b_write(&log_file, cache->read_pos, length))
1789 + thd->binlog_bytes_written += length;
1791 cache->read_pos=cache->read_end; // Mark buffer used up
1792 DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;);
1793 } while ((length=my_b_fill(cache)));
1794 @@ -2239,6 +2253,8 @@
1796 if (commit_event->write(&log_file))
1798 + thd->binlog_bytes_written += commit_event->data_written;
1803 diff -r 592f6c3641ba sql/mysql_priv.h
1804 --- a/sql/mysql_priv.h Wed Jul 29 13:33:34 2009 -0700
1805 +++ b/sql/mysql_priv.h Wed Jul 29 13:34:11 2009 -0700
1806 @@ -837,7 +837,15 @@
1807 bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
1808 void init_max_user_conn(void);
1809 void init_update_queries(void);
1810 +void init_global_user_stats(void);
1811 +void init_global_table_stats(void);
1812 +void init_global_index_stats(void);
1813 +void init_global_client_stats(void);
1814 void free_max_user_conn(void);
1815 +void free_global_user_stats(void);
1816 +void free_global_table_stats(void);
1817 +void free_global_index_stats(void);
1818 +void free_global_client_stats(void);
1819 pthread_handler_t handle_one_connection(void *arg);
1820 pthread_handler_t handle_bootstrap(void *arg);
1821 void end_thread(THD *thd,bool put_in_cache);
1822 @@ -1416,6 +1424,7 @@
1823 extern ulong max_connections,max_connect_errors, connect_timeout;
1824 extern ulong slave_net_timeout, slave_trans_retries;
1825 extern uint max_user_connections;
1826 +extern ulonglong denied_connections;
1827 extern ulong what_to_log,flush_time;
1828 extern ulong query_buff_size, thread_stack;
1829 extern ulong max_prepared_stmt_count, prepared_stmt_count;
1830 @@ -1446,6 +1455,7 @@
1831 extern my_bool opt_safe_show_db, opt_local_infile;
1832 extern my_bool opt_slave_compressed_protocol, use_temp_pool;
1833 extern my_bool opt_readonly, lower_case_file_system;
1834 +extern my_bool opt_userstat_running;
1835 extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
1836 extern my_bool opt_secure_auth;
1837 extern char* opt_secure_file_priv;
1838 @@ -1493,6 +1503,14 @@
1839 extern struct system_variables max_system_variables;
1840 extern struct system_status_var global_status_var;
1841 extern struct rand_struct sql_rand;
1842 +extern HASH global_user_stats;
1843 +extern HASH global_client_stats;
1844 +extern pthread_mutex_t LOCK_global_user_client_stats;
1845 +extern HASH global_table_stats;
1846 +extern pthread_mutex_t LOCK_global_table_stats;
1847 +extern HASH global_index_stats;
1848 +extern pthread_mutex_t LOCK_global_index_stats;
1849 +extern pthread_mutex_t LOCK_stats;
1851 extern const char *opt_date_time_formats[];
1852 extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
1853 diff -r 592f6c3641ba sql/mysqld.cc
1854 --- a/sql/mysqld.cc Wed Jul 29 13:33:34 2009 -0700
1855 +++ b/sql/mysqld.cc Wed Jul 29 13:34:11 2009 -0700
1857 uint opt_large_page_size= 0;
1858 my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
1859 char* opt_slow_logname= 0;
1860 +my_bool opt_userstat_running= 0;
1862 True if there is at least one per-hour limit for some user, so we should
1863 check them before each query (and possibly reset counters when hour is
1865 ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
1866 ulong max_connections, max_connect_errors;
1867 uint max_user_connections= 0;
1868 +ulonglong denied_connections = 0;
1870 Limit of the total number of prepared statements in the server.
1871 Is necessary to protect the server against out-of-memory attacks.
1872 @@ -555,6 +557,10 @@
1873 LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
1874 LOCK_global_system_variables,
1875 LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
1876 +pthread_mutex_t LOCK_stats;
1877 +pthread_mutex_t LOCK_global_user_client_stats;
1878 +pthread_mutex_t LOCK_global_table_stats;
1879 +pthread_mutex_t LOCK_global_index_stats;
1881 The below lock protects access to two global server variables:
1882 max_prepared_stmt_count and prepared_stmt_count. These variables
1883 @@ -1196,6 +1202,10 @@
1884 x_free(opt_secure_file_priv);
1885 bitmap_free(&temp_pool);
1886 free_max_user_conn();
1887 + free_global_user_stats();
1888 + free_global_client_stats();
1889 + free_global_table_stats();
1890 + free_global_index_stats();
1891 #ifdef HAVE_REPLICATION
1893 free_list(&replicate_do_db);
1894 @@ -1310,6 +1320,10 @@
1895 (void) pthread_cond_destroy(&COND_thread_cache);
1896 (void) pthread_cond_destroy(&COND_flush_thread_cache);
1897 (void) pthread_cond_destroy(&COND_manager);
1898 + (void) pthread_mutex_destroy(&LOCK_stats);
1899 + (void) pthread_mutex_destroy(&LOCK_global_user_client_stats);
1900 + (void) pthread_mutex_destroy(&LOCK_global_table_stats);
1901 + (void) pthread_mutex_destroy(&LOCK_global_index_stats);
1904 #endif /*EMBEDDED_LIBRARY*/
1905 @@ -3157,6 +3171,10 @@
1906 (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
1907 (void) pthread_cond_init(&COND_rpl_status, NULL);
1909 + (void) pthread_mutex_init(&LOCK_stats, MY_MUTEX_INIT_FAST);
1910 + (void) pthread_mutex_init(&LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST);
1911 + (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
1912 + (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
1914 /* Parameter for threads created for connections */
1915 (void) pthread_attr_init(&connection_attrib);
1916 @@ -3428,6 +3446,10 @@
1917 sql_print_error("Out of memory");
1921 + init_global_table_stats();
1922 + init_global_index_stats();
1926 sql_print_error("Can't init databases");
1927 @@ -3510,6 +3532,8 @@
1929 init_max_user_conn();
1930 init_update_queries();
1931 + init_global_user_stats();
1932 + init_global_client_stats();
1936 @@ -4236,6 +4260,7 @@
1938 DBUG_PRINT("error",("Too many connections"));
1939 close_connection(thd, ER_CON_COUNT_ERROR, 1);
1940 + statistic_increment(denied_connections, &LOCK_status);
1944 @@ -5056,6 +5081,7 @@
1945 OPT_PROFILING_USE_GETRUSAGE,
1947 OPT_SLOW_QUERY_LOG_FILE,
1948 + OPT_USERSTAT_RUNNING,
1949 OPT_USE_GLOBAL_LONG_QUERY_TIME,
1950 OPT_INNODB_ROLLBACK_ON_TIMEOUT,
1951 OPT_SECURE_FILE_PRIV,
1952 @@ -6523,6 +6549,10 @@
1953 (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
1954 REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
1956 + {"userstat_running", OPT_USERSTAT_RUNNING,
1957 + "Control USER_STATISTICS, CLIENT_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS running",
1958 + (gptr*) &opt_userstat_running, (gptr*) &opt_userstat_running,
1959 + 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
1960 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1963 diff -r 592f6c3641ba sql/set_var.cc
1964 --- a/sql/set_var.cc Wed Jul 29 13:33:34 2009 -0700
1965 +++ b/sql/set_var.cc Wed Jul 29 13:34:11 2009 -0700
1967 sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
1968 &SV::read_buff_size);
1969 sys_var_bool_ptr sys_readonly("read_only", &opt_readonly);
1970 +sys_var_bool_ptr sys_userstat_running("userstat_running", &opt_userstat_running);
1971 sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size",
1972 &SV::read_rnd_buff_size);
1973 sys_var_thd_ulong sys_div_precincrement("div_precision_increment",
1975 &sys_trans_alloc_block_size,
1976 &sys_trans_prealloc_size,
1978 + &sys_userstat_running,
1980 #ifdef HAVE_BERKELEY_DB
1982 @@ -1190,6 +1192,7 @@
1983 {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS},
1984 {sys_updatable_views_with_limit.name,
1985 (char*) &sys_updatable_views_with_limit,SHOW_SYS},
1986 + {sys_userstat_running.name, (char*) &sys_userstat_running, SHOW_SYS},
1987 {sys_use_global_long_query_time.name, (char*) &sys_use_global_long_query_time, SHOW_SYS},
1988 {sys_version.name, (char*) &sys_version, SHOW_SYS},
1989 #ifdef HAVE_BERKELEY_DB
1990 diff -r 592f6c3641ba sql/share/Makefile.in
1991 --- a/sql/share/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1992 +++ b/sql/share/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1995 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
2000 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
2001 diff -r 592f6c3641ba sql/sql_base.cc
2002 --- a/sql/sql_base.cc Wed Jul 29 13:33:34 2009 -0700
2003 +++ b/sql/sql_base.cc Wed Jul 29 13:34:11 2009 -0700
2004 @@ -624,6 +624,12 @@
2005 DBUG_ENTER("close_thread_table");
2006 DBUG_ASSERT(table->key_read == 0);
2007 DBUG_ASSERT(!table->file || table->file->inited == handler::NONE);
2011 + table->file->update_global_table_stats();
2012 + table->file->update_global_index_stats();
2015 *table_ptr=table->next;
2016 if (table->needs_reopen_or_name_lock() ||
2019 DBUG_ENTER("close_temporary");
2020 char path[FN_REFLEN];
2022 + table->file->update_global_table_stats();
2023 + table->file->update_global_index_stats();
2024 db_type table_type=table->s->db_type;
2025 strmov(path,table->s->path);
2026 free_io_cache(table);
2027 diff -r 592f6c3641ba sql/sql_class.cc
2028 --- a/sql/sql_class.cc Wed Jul 29 13:33:34 2009 -0700
2029 +++ b/sql/sql_class.cc Wed Jul 29 13:34:11 2009 -0700
2030 @@ -239,6 +239,13 @@
2031 bzero(ha_data, sizeof(ha_data));
2033 binlog_evt_union.do_union= FALSE;
2036 + bytes_received = 0;
2038 + binlog_bytes_written = 0;
2039 + updated_row_count = 0;
2040 + sent_row_count_2 = 0;
2042 dbug_sentry=THD_SENTRY_MAGIC;
2044 @@ -378,6 +385,88 @@
2045 total_warn_count= 0;
2047 bzero((char *) &status_var, sizeof(status_var));
2051 +// Resets stats in a THD.
2052 +void THD::reset_stats(void) {
2053 + current_connect_time = time(NULL);
2054 + last_global_update_time = current_connect_time;
2055 + reset_diff_stats();
2058 +// Resets the 'diff' stats, which are used to update global stats.
2059 +void THD::reset_diff_stats(void) {
2060 + diff_total_busy_time = 0;
2061 + diff_total_cpu_time = 0;
2062 + diff_total_bytes_received = 0;
2063 + diff_total_bytes_sent = 0;
2064 + diff_total_binlog_bytes_written = 0;
2065 + diff_total_sent_rows = 0;
2066 + diff_total_updated_rows = 0;
2067 + diff_total_read_rows = 0;
2068 + diff_select_commands = 0;
2069 + diff_update_commands = 0;
2070 + diff_other_commands = 0;
2071 + diff_commit_trans = 0;
2072 + diff_rollback_trans = 0;
2073 + diff_denied_connections = 0;
2074 + diff_lost_connections = 0;
2075 + diff_access_denied_errors = 0;
2076 + diff_empty_queries = 0;
2079 +// Updates 'diff' stats of a THD.
2080 +void THD::update_stats(bool ran_command) {
2081 + if (opt_userstat_running) {
2082 + diff_total_busy_time += busy_time;
2083 + diff_total_cpu_time += cpu_time;
2084 + diff_total_bytes_received += bytes_received;
2085 + diff_total_bytes_sent += bytes_sent;
2086 + diff_total_binlog_bytes_written += binlog_bytes_written;
2087 + diff_total_sent_rows += sent_row_count_2;
2088 + diff_total_updated_rows += updated_row_count;
2089 + // diff_total_read_rows is updated in handler.cc.
2091 + if (ran_command) {
2092 + // The replication thread has the COM_CONNECT command.
2093 + if ((old_command == COM_QUERY || command == COM_CONNECT) &&
2094 + (lex->sql_command >= 0 && lex->sql_command < SQLCOM_END)) {
2096 + if (lex->sql_command == SQLCOM_SELECT) {
2097 + if (lex->orig_sql_command == SQLCOM_END) {
2098 + diff_select_commands++;
2099 + if (!sent_row_count_2)
2100 + diff_empty_queries++;
2102 + // 'SHOW ' commands become SQLCOM_SELECT.
2103 + diff_other_commands++;
2104 + // 'SHOW ' commands shouldn't inflate total sent row count.
2105 + diff_total_sent_rows -= sent_row_count_2;
2107 + } else if (is_update_query(lex->sql_command)) {
2108 + diff_update_commands++;
2110 + diff_other_commands++;
2114 + // diff_commit_trans is updated in handler.cc.
2115 + // diff_rollback_trans is updated in handler.cc.
2116 + // diff_denied_connections is updated in sql_parse.cc.
2117 + // diff_lost_connections is updated in sql_parse.cc.
2118 + // diff_access_denied_errors is updated in sql_parse.cc.
2120 + /* reset counters to zero to avoid double-counting since values
2121 + are already store in diff_total_*. */
2125 + bytes_received = 0;
2127 + binlog_bytes_written = 0;
2128 + updated_row_count = 0;
2129 + sent_row_count_2 = 0;
2133 @@ -907,6 +996,33 @@
2137 +char *THD::get_client_host_port(THD *client)
2139 + Security_context *client_sctx= client->security_ctx;
2140 + char *client_host= NULL;
2142 + if (client->peer_port && (client_sctx->host || client_sctx->ip) &&
2143 + security_ctx->host_or_ip[0])
2145 + if ((client_host= this->alloc(LIST_PROCESS_HOST_LEN+1)))
2146 + my_snprintf((char *) client_host, LIST_PROCESS_HOST_LEN,
2147 + "%s:%u", client_sctx->host_or_ip, client->peer_port);
2150 + client_host= this->strdup(client_sctx->host_or_ip[0] ?
2151 + client_sctx->host_or_ip :
2152 + client_sctx->host ? client_sctx->host : "");
2154 + return client_host;
2157 +const char *get_client_host(THD *client)
2159 + return client->security_ctx->host_or_ip[0] ?
2160 + client->security_ctx->host_or_ip :
2161 + client->security_ctx->host ? client->security_ctx->host : "";
2165 struct Item_change_record: public ilink
2167 @@ -1082,6 +1198,7 @@
2168 buffer.set(buff, sizeof(buff), &my_charset_bin);
2170 thd->sent_row_count++;
2171 + thd->sent_row_count_2++;
2174 if (!thd->net.report_error)
2175 @@ -1174,6 +1291,7 @@
2176 select_export::~select_export()
2178 thd->sent_row_count=row_count;
2179 + thd->sent_row_count_2=row_count;
2183 @@ -2108,6 +2226,7 @@
2184 if (likely(thd != 0))
2185 { /* current_thd==0 when close_connection() calls net_send_error() */
2186 thd->status_var.bytes_sent+= length;
2187 + thd->bytes_sent+= length;
2191 @@ -2115,6 +2234,7 @@
2192 void thd_increment_bytes_received(ulong length)
2194 current_thd->status_var.bytes_received+= length;
2195 + current_thd->bytes_received+= length;
2199 diff -r 592f6c3641ba sql/sql_class.h
2200 --- a/sql/sql_class.h Wed Jul 29 13:33:34 2009 -0700
2201 +++ b/sql/sql_class.h Wed Jul 29 13:34:11 2009 -0700
2202 @@ -1302,6 +1302,8 @@
2203 first byte of the packet in do_command()
2205 enum enum_server_command command;
2206 + // Used to save the command, before it is set to COM_SLEEP.
2207 + enum enum_server_command old_command;
2209 uint32 file_id; // for LOAD DATA INFILE
2211 @@ -1498,6 +1500,8 @@
2212 /* variables.transaction_isolation is reset to this after each commit */
2213 enum_tx_isolation session_tx_isolation;
2214 enum_check_fields count_cuted_fields;
2215 + ha_rows updated_row_count;
2216 + ha_rows sent_row_count_2; /* for userstat */
2218 DYNAMIC_ARRAY user_var_events; /* For user variables replication */
2219 MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
2220 @@ -1607,6 +1611,49 @@
2222 LOG_INFO* current_linfo;
2223 NET* slave_net; // network connection from slave -> m.
2226 + Used to update global user stats. The global user stats are updated
2227 + occasionally with the 'diff' variables. After the update, the 'diff'
2228 + variables are reset to 0.
2230 + // Time when the current thread connected to MySQL.
2231 + time_t current_connect_time;
2232 + // Last time when THD stats were updated in global_user_stats.
2233 + time_t last_global_update_time;
2234 + // Busy (non-idle) time for just one command.
2236 + // Busy time not updated in global_user_stats yet.
2237 + double diff_total_busy_time;
2238 + // Cpu (non-idle) time for just one thread.
2240 + // Cpu time not updated in global_user_stats yet.
2241 + double diff_total_cpu_time;
2242 + /* bytes counting */
2243 + ulonglong bytes_received;
2244 + ulonglong diff_total_bytes_received;
2245 + ulonglong bytes_sent;
2246 + ulonglong diff_total_bytes_sent;
2247 + ulonglong binlog_bytes_written;
2248 + ulonglong diff_total_binlog_bytes_written;
2250 + // Number of rows not reflected in global_user_stats yet.
2251 + ha_rows diff_total_sent_rows, diff_total_updated_rows, diff_total_read_rows;
2252 + // Number of commands not reflected in global_user_stats yet.
2253 + ulonglong diff_select_commands, diff_update_commands, diff_other_commands;
2254 + // Number of transactions not reflected in global_user_stats yet.
2255 + ulonglong diff_commit_trans, diff_rollback_trans;
2256 + // Number of connection errors not reflected in global_user_stats yet.
2257 + ulonglong diff_denied_connections, diff_lost_connections;
2258 + // Number of db access denied, not reflected in global_user_stats yet.
2259 + ulonglong diff_access_denied_errors;
2260 + // Number of queries that return 0 rows
2261 + ulonglong diff_empty_queries;
2263 + // Per account query delay in miliseconds. When not 0, sleep this number of
2264 + // milliseconds before every SQL command.
2265 + ulonglong query_delay_millis;
2267 /* Used by the sys_var class to store temporary values */
2270 @@ -1662,6 +1709,11 @@
2273 void init_for_queries();
2274 + void reset_stats(void);
2275 + void reset_diff_stats(void);
2276 + // ran_command is true when this is called immediately after a
2277 + // command has been run.
2278 + void update_stats(bool ran_command);
2279 void change_user(void);
2281 void cleanup_after_query();
2282 @@ -1891,8 +1943,14 @@
2284 *p_db_length= db_length;
2287 + // Returns string as 'IP:port' for the client-side of the connnection represented
2288 + // by 'client' as displayed by SHOW PROCESSLIST. Allocates memory from the heap of
2289 + // this THD and that is not reclaimed immediately, so use sparingly. May return NULL.
2292 + char *get_client_host_port(THD *client);
2296 Add an internal error handler to the thread execution context.
2297 @@ -1935,6 +1993,10 @@
2298 MEM_ROOT main_mem_root;
2301 +// Returns string as 'IP' for the client-side of the connection represented by
2302 +// 'client'. Does not allocate memory. May return "".
2303 +const char *get_client_host(THD *client);
2306 #define tmp_disable_binlog(A) \
2307 {ulonglong tmp_disable_binlog__save_options= (A)->options; \
2308 diff -r 592f6c3641ba sql/sql_delete.cc
2309 --- a/sql/sql_delete.cc Wed Jul 29 13:33:34 2009 -0700
2310 +++ b/sql/sql_delete.cc Wed Jul 29 13:34:11 2009 -0700
2312 send_ok(thd,deleted);
2313 DBUG_PRINT("info",("%ld records deleted",(long) deleted));
2315 + thd->updated_row_count += deleted;
2316 DBUG_RETURN(error >= 0 || thd->net.report_error);
2320 thd->row_count_func= deleted;
2321 ::send_ok(thd, deleted);
2323 + thd->updated_row_count += deleted;
2327 diff -r 592f6c3641ba sql/sql_insert.cc
2328 --- a/sql/sql_insert.cc Wed Jul 29 13:33:34 2009 -0700
2329 +++ b/sql/sql_insert.cc Wed Jul 29 13:34:11 2009 -0700
2331 thd->row_count_func= info.copied + info.deleted + updated;
2332 ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
2334 + thd->updated_row_count += thd->row_count_func;
2335 thd->abort_on_warning= 0;
2338 @@ -3094,6 +3095,7 @@
2339 autoinc_value_of_first_inserted_row : thd->insert_id_used ?
2340 thd->last_insert_id : 0;
2341 ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
2342 + thd->updated_row_count += thd->row_count_func;
2346 diff -r 592f6c3641ba sql/sql_lex.h
2347 --- a/sql/sql_lex.h Wed Jul 29 13:33:34 2009 -0700
2348 +++ b/sql/sql_lex.h Wed Jul 29 13:34:11 2009 -0700
2350 When a command is added here, be sure it's also added in mysqld.cc
2351 in "struct show_var_st status_vars[]= {" ...
2353 + // TODO(mcallaghan): update status_vars in mysqld to export these
2354 + SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS,
2355 + SQLCOM_SHOW_CLIENT_STATS,
2356 /* This should be the last !!! */
2359 diff -r 592f6c3641ba sql/sql_parse.cc
2360 --- a/sql/sql_parse.cc Wed Jul 29 13:33:34 2009 -0700
2361 +++ b/sql/sql_parse.cc Wed Jul 29 13:34:11 2009 -0700
2363 const char *table_name);
2364 static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
2366 +// Increments connection count for user.
2367 +static int increment_connection_count(THD* thd, bool use_lock);
2369 +// Uses the THD to update the global stats by user name and client IP
2370 +void update_global_user_stats(THD* thd, bool create_user, time_t now);
2372 const char *any_db="*any*"; // Special symbol for check_access
2374 const char *command_name[]={
2375 @@ -146,6 +152,17 @@
2376 static bool do_command(THD *thd);
2377 #endif // EMBEDDED_LIBRARY
2379 +HASH global_user_stats;
2380 +HASH global_client_stats;
2381 +// Protects global_user_stats and global_client_stats
2382 +extern pthread_mutex_t LOCK_global_user_client_stats;
2384 +HASH global_table_stats;
2385 +extern pthread_mutex_t LOCK_global_table_stats;
2387 +HASH global_index_stats;
2388 +extern pthread_mutex_t LOCK_global_index_stats;
2391 extern void win_install_sigabrt_handler(void);
2394 mysql_log.write(thd,COM_CONNECT,"%s",ER(ER_NOT_SUPPORTED_AUTH_MODE));
2397 + thd->diff_access_denied_errors++;
2398 net_printf_error(thd, ER_ACCESS_DENIED_ERROR,
2399 thd->main_security_ctx.user,
2400 thd->main_security_ctx.host_or_ip,
2401 @@ -536,12 +554,190 @@
2402 void init_max_user_conn(void)
2404 #ifndef NO_EMBEDDED_ACCESS_CHECKS
2405 - (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
2407 - (hash_get_key) get_key_conn, (hash_free_key) free_user,
2411 + if (hash_init(&hash_user_connections,system_charset_info,max_connections,
2413 + (hash_get_key) get_key_conn, (hash_free_key) free_user,
2415 + sql_print_error("Initializing hash_user_connections failed.");
2421 +byte *get_key_user_stats(USER_STATS *user_stats, uint *length,
2422 + my_bool not_used __attribute__((unused)))
2424 + *length = strlen(user_stats->user);
2425 + return (byte*)user_stats->user;
2428 +void free_user_stats(USER_STATS* user_stats)
2430 + my_free((char*)user_stats, MYF(0));
2433 +void init_user_stats(USER_STATS *user_stats,
2435 + const char *priv_user,
2436 + uint total_connections,
2437 + uint concurrent_connections,
2438 + time_t connected_time,
2441 + ulonglong bytes_received,
2442 + ulonglong bytes_sent,
2443 + ulonglong binlog_bytes_written,
2444 + ha_rows rows_fetched,
2445 + ha_rows rows_updated,
2446 + ha_rows rows_read,
2447 + ulonglong select_commands,
2448 + ulonglong update_commands,
2449 + ulonglong other_commands,
2450 + ulonglong commit_trans,
2451 + ulonglong rollback_trans,
2452 + ulonglong denied_connections,
2453 + ulonglong lost_connections,
2454 + ulonglong access_denied_errors,
2455 + ulonglong empty_queries)
2457 + DBUG_ENTER("init_user_stats");
2458 + DBUG_PRINT("info",
2459 + ("Add user_stats entry for user %s - priv_user %s",
2460 + user, priv_user));
2461 + strncpy(user_stats->user, user, sizeof(user_stats->user));
2462 + strncpy(user_stats->priv_user, priv_user, sizeof(user_stats->priv_user));
2464 + user_stats->total_connections = total_connections;
2465 + user_stats->concurrent_connections = concurrent_connections;
2466 + user_stats->connected_time = connected_time;
2467 + user_stats->busy_time = busy_time;
2468 + user_stats->cpu_time = cpu_time;
2469 + user_stats->bytes_received = bytes_received;
2470 + user_stats->bytes_sent = bytes_sent;
2471 + user_stats->binlog_bytes_written = binlog_bytes_written;
2472 + user_stats->rows_fetched = rows_fetched;
2473 + user_stats->rows_updated = rows_updated;
2474 + user_stats->rows_read = rows_read;
2475 + user_stats->select_commands = select_commands;
2476 + user_stats->update_commands = update_commands;
2477 + user_stats->other_commands = other_commands;
2478 + user_stats->commit_trans = commit_trans;
2479 + user_stats->rollback_trans = rollback_trans;
2480 + user_stats->denied_connections = denied_connections;
2481 + user_stats->lost_connections = lost_connections;
2482 + user_stats->access_denied_errors = access_denied_errors;
2483 + user_stats->empty_queries = empty_queries;
2487 +void add_user_stats(USER_STATS *user_stats,
2488 + uint total_connections,
2489 + uint concurrent_connections,
2490 + time_t connected_time,
2493 + ulonglong bytes_received,
2494 + ulonglong bytes_sent,
2495 + ulonglong binlog_bytes_written,
2496 + ha_rows rows_fetched,
2497 + ha_rows rows_updated,
2498 + ha_rows rows_read,
2499 + ulonglong select_commands,
2500 + ulonglong update_commands,
2501 + ulonglong other_commands,
2502 + ulonglong commit_trans,
2503 + ulonglong rollback_trans,
2504 + ulonglong denied_connections,
2505 + ulonglong lost_connections,
2506 + ulonglong access_denied_errors,
2507 + ulonglong empty_queries)
2509 + user_stats->total_connections += total_connections;
2510 + user_stats->concurrent_connections += concurrent_connections;
2511 + user_stats->connected_time += connected_time;
2512 + user_stats->busy_time += busy_time;
2513 + user_stats->cpu_time += cpu_time;
2514 + user_stats->bytes_received += bytes_received;
2515 + user_stats->bytes_sent += bytes_sent;
2516 + user_stats->binlog_bytes_written += binlog_bytes_written;
2517 + user_stats->rows_fetched += rows_fetched;
2518 + user_stats->rows_updated += rows_updated;
2519 + user_stats->rows_read += rows_read;
2520 + user_stats->select_commands += select_commands;
2521 + user_stats->update_commands += update_commands;
2522 + user_stats->other_commands += other_commands;
2523 + user_stats->commit_trans += commit_trans;
2524 + user_stats->rollback_trans += rollback_trans;
2525 + user_stats->denied_connections += denied_connections;
2526 + user_stats->lost_connections += lost_connections;
2527 + user_stats->access_denied_errors += access_denied_errors;
2528 + user_stats->empty_queries += empty_queries;
2531 +void init_global_user_stats(void)
2533 + if (hash_init(&global_user_stats, system_charset_info, max_connections,
2534 + 0, 0, (hash_get_key)get_key_user_stats,
2535 + (hash_free_key)free_user_stats, 0)) {
2536 + sql_print_error("Initializing global_user_stats failed.");
2541 +void init_global_client_stats(void)
2543 + if (hash_init(&global_client_stats, system_charset_info, max_connections,
2544 + 0, 0, (hash_get_key)get_key_user_stats,
2545 + (hash_free_key)free_user_stats, 0)) {
2546 + sql_print_error("Initializing global_client_stats failed.");
2551 +extern "C" byte *get_key_table_stats(TABLE_STATS *table_stats, uint *length,
2552 + my_bool not_used __attribute__((unused)))
2554 + *length = strlen(table_stats->table);
2555 + return (byte*)table_stats->table;
2558 +extern "C" void free_table_stats(TABLE_STATS* table_stats)
2560 + my_free((char*)table_stats, MYF(0));
2563 +void init_global_table_stats(void)
2565 + if (hash_init(&global_table_stats, system_charset_info, max_connections,
2566 + 0, 0, (hash_get_key)get_key_table_stats,
2567 + (hash_free_key)free_table_stats, 0)) {
2568 + sql_print_error("Initializing global_table_stats failed.");
2573 +extern "C" byte *get_key_index_stats(INDEX_STATS *index_stats, uint *length,
2574 + my_bool not_used __attribute__((unused)))
2576 + *length = strlen(index_stats->index);
2577 + return (byte*)index_stats->index;
2580 +extern "C" void free_index_stats(INDEX_STATS* index_stats)
2582 + my_free((char*)index_stats, MYF(0));
2585 +void init_global_index_stats(void)
2587 + if (hash_init(&global_index_stats, system_charset_info, max_connections,
2588 + 0, 0, (hash_get_key)get_key_index_stats,
2589 + (hash_free_key)free_index_stats, 0)) {
2590 + sql_print_error("Initializing global_index_stats failed.");
2598 @@ -599,7 +795,10 @@
2603 + statistic_increment(denied_connections, &LOCK_status);
2604 uc->connections--; // no need for decrease_user_connections() here
2606 (void) pthread_mutex_unlock(&LOCK_user_conn);
2609 @@ -646,6 +845,25 @@
2610 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
2613 +void free_global_user_stats(void)
2615 + hash_free(&global_user_stats);
2618 +void free_global_table_stats(void)
2620 + hash_free(&global_table_stats);
2623 +void free_global_index_stats(void)
2625 + hash_free(&global_index_stats);
2628 +void free_global_client_stats(void)
2630 + hash_free(&global_client_stats);
2635 @@ -698,6 +916,214 @@
2636 return uc_update_queries[command] != 0;
2639 +// 'mysql_system_user' is used for when the user is not defined for a THD.
2640 +static char mysql_system_user[] = "#mysql_system#";
2642 +// Returns 'user' if it's not NULL. Returns 'mysql_system_user' otherwise.
2643 +static char* get_valid_user_string(char* user) {
2644 + return user ? user : mysql_system_user;
2647 +// Increments the global stats connection count for an entry from
2648 +// global_client_stats or global_user_stats. Returns 0 on success
2650 +static int increment_count_by_name(const char *name, const char *role_name,
2651 + HASH *users_or_clients, THD *thd)
2653 + USER_STATS* user_stats;
2655 + if (!(user_stats = (USER_STATS*)hash_search(users_or_clients, name,
2658 + // First connection for this user or client
2659 + if (!(user_stats = ((USER_STATS*)
2660 + my_malloc(sizeof(USER_STATS), MYF(MY_WME | MY_ZEROFILL)))))
2662 + return 1; // Out of memory
2665 + init_user_stats(user_stats, name, role_name,
2666 + 0, 0, // connections
2668 + 0, 0, 0, // bytes sent, received and written
2669 + 0, 0, 0, // rows fetched, updated and read
2670 + 0, 0, 0, // select, update and other commands
2671 + 0, 0, // commit and rollback trans
2672 + thd->diff_denied_connections,
2673 + 0, // lost connections
2674 + 0, // access denied errors
2675 + 0); // empty queries
2677 + if (my_hash_insert(users_or_clients, (byte*)user_stats))
2679 + my_free((char*)user_stats, 0);
2680 + return 1; // Out of memory
2683 + user_stats->total_connections++;
2687 +// Increments the global user and client stats connection count. If 'use_lock'
2688 +// is true, LOCK_global_user_client_stats will be locked/unlocked. Returns
2689 +// 0 on success, 1 on error.
2690 +static int increment_connection_count(THD* thd, bool use_lock)
2692 + char* user_string = get_valid_user_string(thd->main_security_ctx.user);
2693 + const char* client_string = get_client_host(thd);
2694 + int return_value = 0;
2696 + if (!opt_userstat_running)
2697 + return return_value;
2699 + if (use_lock) pthread_mutex_lock(&LOCK_global_user_client_stats);
2701 + if (increment_count_by_name(user_string, user_string,
2702 + &global_user_stats, thd))
2707 + if (increment_count_by_name(client_string,
2709 + &global_client_stats, thd))
2716 + if (use_lock) pthread_mutex_unlock(&LOCK_global_user_client_stats);
2717 + return return_value;
2720 +// Used to update the global user and client stats.
2721 +static void update_global_user_stats_with_user(THD* thd,
2722 + USER_STATS* user_stats,
2725 + user_stats->connected_time += now - thd->last_global_update_time;
2726 + thd->last_global_update_time = now;
2727 + user_stats->busy_time += thd->diff_total_busy_time;
2728 + user_stats->cpu_time += thd->diff_total_cpu_time;
2729 + user_stats->bytes_received += thd->diff_total_bytes_received;
2730 + user_stats->bytes_sent += thd->diff_total_bytes_sent;
2731 + user_stats->binlog_bytes_written += thd->diff_total_binlog_bytes_written;
2732 + user_stats->rows_fetched += thd->diff_total_sent_rows;
2733 + user_stats->rows_updated += thd->diff_total_updated_rows;
2734 + user_stats->rows_read += thd->diff_total_read_rows;
2735 + user_stats->select_commands += thd->diff_select_commands;
2736 + user_stats->update_commands += thd->diff_update_commands;
2737 + user_stats->other_commands += thd->diff_other_commands;
2738 + user_stats->commit_trans += thd->diff_commit_trans;
2739 + user_stats->rollback_trans += thd->diff_rollback_trans;
2740 + user_stats->denied_connections += thd->diff_denied_connections;
2741 + user_stats->lost_connections += thd->diff_lost_connections;
2742 + user_stats->access_denied_errors += thd->diff_access_denied_errors;
2743 + user_stats->empty_queries += thd->diff_empty_queries;
2746 +// Updates the global stats of a user or client
2747 +void update_global_user_stats(THD* thd, bool create_user, time_t now)
2749 + if (opt_userstat_running) {
2750 + char* user_string = get_valid_user_string(thd->main_security_ctx.user);
2751 + const char* client_string = get_client_host(thd);
2753 + USER_STATS* user_stats;
2754 + pthread_mutex_lock(&LOCK_global_user_client_stats);
2756 + // Update by user name
2757 + if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
2758 + (byte*)user_string,
2759 + strlen(user_string)))) {
2761 + update_global_user_stats_with_user(thd, user_stats, now);
2763 + // Create the entry
2764 + if (create_user) {
2765 + increment_count_by_name(user_string, user_string,
2766 + &global_user_stats, thd);
2770 + // Update by client IP
2771 + if ((user_stats = (USER_STATS*)hash_search(&global_client_stats,
2772 + (byte*)client_string,
2773 + strlen(client_string)))) {
2774 + // Found by client IP
2775 + update_global_user_stats_with_user(thd, user_stats, now);
2777 + // Create the entry
2778 + if (create_user) {
2779 + increment_count_by_name(client_string,
2781 + &global_client_stats, thd);
2784 + thd->reset_diff_stats();
2786 + pthread_mutex_unlock(&LOCK_global_user_client_stats);
2788 + thd->reset_diff_stats();
2792 +// Determines the concurrent number of connections of current threads.
2793 +static void set_connections_stats()
2795 + USER_STATS* user_stats;
2797 + pthread_mutex_lock(&LOCK_global_user_client_stats);
2798 + pthread_mutex_lock(&LOCK_thread_count);
2800 + // Resets all concurrent connections to 0.
2801 + for (int i = 0; i < global_user_stats.records; ++i) {
2802 + user_stats = (USER_STATS*)hash_element(&global_user_stats, i);
2803 + user_stats->concurrent_connections = 0;
2805 + for (int i = 0; i < global_client_stats.records; ++i) {
2806 + user_stats = (USER_STATS*)hash_element(&global_client_stats, i);
2807 + user_stats->concurrent_connections = 0;
2810 + I_List_iterator<THD> it(threads);
2812 + time_t now = time(NULL);
2813 + // Iterates through the current threads.
2814 + while ((thd = it++)) {
2815 + char* user_string = get_valid_user_string(thd->main_security_ctx.user);
2816 + if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
2817 + (byte*)user_string,
2818 + strlen(user_string)))) {
2820 + user_stats->concurrent_connections++;
2821 + update_global_user_stats_with_user(thd, user_stats, now);
2823 + // The user name should exist.
2824 + if (user_string == mysql_system_user) {
2825 + // Only create the user if it is the mysql_system_user
2826 + increment_count_by_name(user_string, user_string,
2827 + &global_user_stats, thd);
2831 + const char* client_string = get_client_host(thd);
2832 + if ((user_stats = (USER_STATS*)hash_search(&global_client_stats,
2833 + (byte*)client_string,
2834 + strlen(client_string)))) {
2836 + user_stats->concurrent_connections++;
2837 + update_global_user_stats_with_user(thd, user_stats, now);
2839 + // Do nothing, unlike what is done for global_user_stats
2841 + thd->reset_diff_stats();
2843 + pthread_mutex_unlock(&LOCK_thread_count);
2844 + pthread_mutex_unlock(&LOCK_global_user_client_stats);
2848 Reset per-hour user resource limits when it has been more than
2849 an hour since they were last checked
2850 @@ -1184,6 +1610,8 @@
2851 my_net_set_read_timeout(net, connect_timeout);
2852 my_net_set_write_timeout(net, connect_timeout);
2854 + bool create_user = true;
2856 if ((error=check_connection(thd)))
2857 { // Wrong permissions
2859 @@ -1193,8 +1621,22 @@
2860 my_sleep(1000); /* must wait after eof() */
2862 statistic_increment(aborted_connects,&LOCK_status);
2863 + thd->diff_denied_connections++;
2864 + if (error == -2) {
2865 + // Do not create statistics for a user who does not exist, or failed
2866 + // to authenticate.
2867 + create_user = false;
2872 + thd->reset_stats();
2873 + // Updates global user connection stats.
2874 + if (increment_connection_count(thd, true)) {
2875 + net_send_error(thd, ER_OUTOFMEMORY); // Out of memory
2880 netware_reg_user(sctx->ip, sctx->user, "MySQL");
2882 @@ -1251,6 +1693,7 @@
2883 (net->vio && net->error && net->report_error))
2885 statistic_increment(aborted_threads, &LOCK_status);
2886 + thd->diff_lost_connections++;
2889 if (net->error && net->vio != 0 && net->report_error)
2890 @@ -1270,6 +1713,8 @@
2893 close_connection(thd, 0, 1);
2894 + thd->update_stats(false);
2895 + update_global_user_stats(thd, create_user, time(NULL));
2898 If end_thread returns, we are either running with --one-thread
2899 @@ -1601,6 +2046,13 @@
2901 thd->clear_error(); // Clear error message
2903 + thd->updated_row_count=0;
2906 + thd->bytes_received=0;
2907 + thd->bytes_sent=0;
2908 + thd->binlog_bytes_written=0;
2910 net_new_transaction(net);
2912 packet_length= my_net_read(net);
2913 @@ -1759,6 +2211,9 @@
2916 thd->command=command;
2917 + // To increment the corrent command counter for user stats, 'command' must
2918 + // be saved because it is set to COM_SLEEP at the end of this function.
2919 + thd->old_command = command;
2921 Commands which always take a long time are logged into
2922 the slow log only if opt_log_slow_admin_statements is set.
2923 @@ -4539,6 +4994,15 @@
2924 if (check_global_access(thd,RELOAD_ACL))
2927 + if(lex->type & REFRESH_SLOW_QUERY_LOG) {
2928 + /* We are only flushing slow query log */
2929 + mysql_slow_log.new_file(1);
2937 reload_acl_and_cache() will tell us if we are allowed to write to the
2939 @@ -4847,6 +5311,7 @@
2941 if (check_global_access(thd, SUPER_ACL))
2943 + thd->diff_access_denied_errors++;
2944 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
2945 goto create_sp_error;
2947 @@ -5691,6 +6156,7 @@
2950 const char *db_name= db ? db : thd->db;
2951 + thd->diff_access_denied_errors++;
2952 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
2953 sctx->priv_user, sctx->priv_host, db_name);
2955 @@ -5726,6 +6192,7 @@
2956 { // We can never grant this
2957 DBUG_PRINT("error",("No possible access"));
2959 + thd->diff_access_denied_errors++;
2960 my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
2963 @@ -5758,11 +6225,15 @@
2965 DBUG_PRINT("error",("Access denied"));
2968 + // increment needs !no_errors condition, otherwise double counting.
2969 + thd->diff_access_denied_errors++;
2970 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
2971 sctx->priv_user, sctx->priv_host,
2972 (db ? db : (thd->db ?
2974 "unknown"))); /* purecov: tested */
2976 DBUG_RETURN(TRUE); /* purecov: tested */
2977 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
2979 @@ -5796,6 +6267,7 @@
2980 if ((thd->security_ctx->master_access & want_access))
2982 get_privilege_desc(command, sizeof(command), want_access);
2983 + thd->diff_access_denied_errors++;
2984 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
2986 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
2987 @@ -5828,6 +6300,7 @@
2989 if (!thd->col_access && check_grant_db(thd, dst_db_name))
2991 + thd->diff_access_denied_errors++;
2992 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
2993 thd->security_ctx->priv_user,
2994 thd->security_ctx->priv_host,
2995 @@ -5859,6 +6332,12 @@
2996 check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE);
3000 + case SCH_USER_STATS:
3001 + case SCH_CLIENT_STATS:
3002 + return check_global_access(thd, SUPER_ACL | PROCESS_ACL);
3003 + case SCH_TABLE_STATS:
3004 + case SCH_INDEX_STATS:
3005 case SCH_OPEN_TABLES:
3008 @@ -5912,8 +6391,8 @@
3009 #ifndef NO_EMBEDDED_ACCESS_CHECKS
3010 TABLE_LIST *org_tables= tables;
3012 + Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
3013 TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
3014 - Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
3016 The check that first_not_own_table is not reached is for the case when
3017 the given table list refers to the list for prelocking (contains tables
3018 @@ -5930,9 +6409,12 @@
3019 (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
3023 + thd->diff_access_denied_errors++;
3024 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
3025 sctx->priv_user, sctx->priv_host,
3026 INFORMATION_SCHEMA_NAME.str);
3031 @@ -6442,6 +6924,30 @@
3033 mysql_reset_thd_for_next_command(thd);
3035 + int start_time_error = 0;
3036 + int end_time_error = 0;
3037 + struct timeval start_time, end_time;
3038 + double start_usecs = 0;
3039 + double end_usecs = 0;
3041 + int cputime_error = 0;
3042 + struct timespec tp;
3043 + double start_cpu_nsecs = 0;
3044 + double end_cpu_nsecs = 0;
3046 + if (opt_userstat_running) {
3047 +#ifdef HAVE_CLOCK_GETTIME
3048 + /* get start cputime */
3049 + if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3050 + start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3053 + // Gets the start time, in order to measure how long this command takes.
3054 + if (!(start_time_error = gettimeofday(&start_time, NULL))) {
3055 + start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
3059 if (query_cache_send_result_to_client(thd, (char*) inBuf, length) <= 0)
3062 @@ -6520,6 +7026,43 @@
3063 *found_semicolon= NULL;
3066 + if (opt_userstat_running) {
3067 + // Gets the end time.
3068 + if (!(end_time_error = gettimeofday(&end_time, NULL))) {
3069 + end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
3072 + // Calculates the difference between the end and start times.
3073 + if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
3074 + thd->busy_time = (end_usecs - start_usecs) / 1000000;
3075 + // In case there are bad values, 2629743 is the #seconds in a month.
3076 + if (thd->busy_time > 2629743) {
3077 + thd->busy_time = 0;
3080 + // end time went back in time, or gettimeofday() failed.
3081 + thd->busy_time = 0;
3084 +#ifdef HAVE_CLOCK_GETTIME
3085 + /* get end cputime */
3086 + if (!cputime_error &&
3087 + !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3088 + end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3090 + if (start_cpu_nsecs && !cputime_error) {
3091 + thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
3092 + // In case there are bad values, 2629743 is the #seconds in a month.
3093 + if (thd->cpu_time > 2629743) {
3094 + thd->cpu_time = 0;
3097 + thd->cpu_time = 0;
3099 + // Updates THD stats and the global user stats.
3100 + thd->update_stats(true);
3101 + update_global_user_stats(thd, true, time(NULL));
3106 @@ -7531,8 +8074,35 @@
3107 pthread_mutex_unlock(&LOCK_active_mi);
3110 - if (options & REFRESH_USER_RESOURCES)
3111 - reset_mqh((LEX_USER *) NULL);
3112 + if (options & REFRESH_TABLE_STATS)
3114 + pthread_mutex_lock(&LOCK_global_table_stats);
3115 + free_global_table_stats();
3116 + init_global_table_stats();
3117 + pthread_mutex_unlock(&LOCK_global_table_stats);
3119 + if (options & REFRESH_INDEX_STATS)
3121 + pthread_mutex_lock(&LOCK_global_index_stats);
3122 + free_global_index_stats();
3123 + init_global_index_stats();
3124 + pthread_mutex_unlock(&LOCK_global_index_stats);
3126 + if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS))
3128 + pthread_mutex_lock(&LOCK_global_user_client_stats);
3129 + if (options & REFRESH_USER_STATS)
3131 + free_global_user_stats();
3132 + init_global_user_stats();
3134 + if (options & REFRESH_CLIENT_STATS)
3136 + free_global_client_stats();
3137 + init_global_client_stats();
3139 + pthread_mutex_unlock(&LOCK_global_user_client_stats);
3141 *write_to_binlog= tmp_write_to_binlog;
3144 diff -r 592f6c3641ba sql/sql_prepare.cc
3145 --- a/sql/sql_prepare.cc Wed Jul 29 13:33:34 2009 -0700
3146 +++ b/sql/sql_prepare.cc Wed Jul 29 13:34:11 2009 -0700
3148 #include <mysql_com.h>
3151 +// Uses the THD to update the global stats by user name and client IP
3152 +void update_global_user_stats(THD* thd, bool create_user, time_t now);
3154 /* A result class used to send cursor rows using the binary protocol. */
3156 class Select_fetch_protocol_prep: public select_send
3157 @@ -1910,8 +1913,32 @@
3158 /* First of all clear possible warnings from the previous command */
3159 mysql_reset_thd_for_next_command(thd);
3161 + int start_time_error = 0;
3162 + int end_time_error = 0;
3163 + struct timeval start_time, end_time;
3164 + double start_usecs = 0;
3165 + double end_usecs = 0;
3167 + int cputime_error = 0;
3168 + struct timespec tp;
3169 + double start_cpu_nsecs = 0;
3170 + double end_cpu_nsecs = 0;
3172 + if (opt_userstat_running) {
3173 +#ifdef HAVE_CLOCK_GETTIME
3174 + /* get start cputime */
3175 + if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3176 + start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3179 + // Gets the start time, in order to measure how long this command takes.
3180 + if (!(start_time_error = gettimeofday(&start_time, NULL))) {
3181 + start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
3185 if (! (stmt= new Prepared_statement(thd, &thd->protocol_prep)))
3186 - DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */
3187 + goto end; /* out of memory: error is set in Sql_alloc */
3189 if (thd->stmt_map.insert(thd, stmt))
3191 @@ -1919,7 +1946,7 @@
3192 The error is set in the insert. The statement itself
3193 will be also deleted there (this is how the hash works).
3199 /* Reset warnings from previous command */
3200 @@ -1941,6 +1968,44 @@
3201 thd->stmt_map.erase(stmt);
3203 /* check_prepared_statemnt sends the metadata packet in case of success */
3205 + if (opt_userstat_running) {
3206 + // Gets the end time.
3207 + if (!(end_time_error = gettimeofday(&end_time, NULL))) {
3208 + end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
3211 + // Calculates the difference between the end and start times.
3212 + if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
3213 + thd->busy_time = (end_usecs - start_usecs) / 1000000;
3214 + // In case there are bad values, 2629743 is the #seconds in a month.
3215 + if (thd->busy_time > 2629743) {
3216 + thd->busy_time = 0;
3219 + // end time went back in time, or gettimeofday() failed.
3220 + thd->busy_time = 0;
3223 +#ifdef HAVE_CLOCK_GETTIME
3224 + /* get end cputime */
3225 + if (!cputime_error &&
3226 + !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3227 + end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3229 + if (start_cpu_nsecs && !cputime_error) {
3230 + thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
3231 + // In case there are bad values, 2629743 is the #seconds in a month.
3232 + if (thd->cpu_time > 2629743) {
3233 + thd->cpu_time = 0;
3236 + thd->cpu_time = 0;
3238 + // Updates THD stats and the global user stats.
3239 + thd->update_stats(true);
3240 + update_global_user_stats(thd, true, time(NULL));
3245 @@ -2281,8 +2346,32 @@
3246 /* First of all clear possible warnings from the previous command */
3247 mysql_reset_thd_for_next_command(thd);
3249 + int start_time_error = 0;
3250 + int end_time_error = 0;
3251 + struct timeval start_time, end_time;
3252 + double start_usecs = 0;
3253 + double end_usecs = 0;
3255 + int cputime_error = 0;
3256 + struct timespec tp;
3257 + double start_cpu_nsecs = 0;
3258 + double end_cpu_nsecs = 0;
3260 + if (opt_userstat_running) {
3261 +#ifdef HAVE_CLOCK_GETTIME
3262 + /* get start cputime */
3263 + if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3264 + start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3267 + // Gets the start time, in order to measure how long this command takes.
3268 + if (!(start_time_error = gettimeofday(&start_time, NULL))) {
3269 + start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
3273 if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
3277 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
3278 thd->profiling.set_query_source(stmt->query, stmt->query_length);
3279 @@ -2325,11 +2414,50 @@
3280 test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
3281 if (!(specialflag & SPECIAL_NO_PRIOR))
3282 my_pthread_setprio(pthread_self(), WAIT_PRIOR);
3286 set_params_data_err:
3287 my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_execute");
3288 reset_stmt_params(stmt);
3291 + if (opt_userstat_running) {
3292 + // Gets the end time.
3293 + if (!(end_time_error = gettimeofday(&end_time, NULL))) {
3294 + end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
3297 + // Calculates the difference between the end and start times.
3298 + if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
3299 + thd->busy_time = (end_usecs - start_usecs) / 1000000;
3300 + // In case there are bad values, 2629743 is the #seconds in a month.
3301 + if (thd->busy_time > 2629743) {
3302 + thd->busy_time = 0;
3305 + // end time went back in time, or gettimeofday() failed.
3306 + thd->busy_time = 0;
3309 +#ifdef HAVE_CLOCK_GETTIME
3310 + /* get end cputime */
3311 + if (!cputime_error &&
3312 + !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3313 + end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3315 + if (start_cpu_nsecs && !cputime_error) {
3316 + thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
3317 + // In case there are bad values, 2629743 is the #seconds in a month.
3318 + if (thd->cpu_time > 2629743) {
3319 + thd->cpu_time = 0;
3322 + thd->cpu_time = 0;
3324 + // Updates THD stats and the global user stats.
3325 + thd->update_stats(true);
3326 + update_global_user_stats(thd, true, time(NULL));
3331 @@ -2423,6 +2551,31 @@
3333 /* First of all clear possible warnings from the previous command */
3334 mysql_reset_thd_for_next_command(thd);
3336 + int start_time_error = 0;
3337 + int end_time_error = 0;
3338 + struct timeval start_time, end_time;
3339 + double start_usecs = 0;
3340 + double end_usecs = 0;
3342 + int cputime_error = 0;
3343 + struct timespec tp;
3344 + double start_cpu_nsecs = 0;
3345 + double end_cpu_nsecs = 0;
3347 + if (opt_userstat_running) {
3348 +#ifdef HAVE_CLOCK_GETTIME
3349 + /* get start cputime */
3350 + if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3351 + start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3354 + // Gets the start time, in order to measure how long this command takes.
3355 + if (!(start_time_error = gettimeofday(&start_time, NULL))) {
3356 + start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
3360 statistic_increment(thd->status_var.com_stmt_fetch, &LOCK_status);
3361 if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_fetch")))
3363 @@ -2455,6 +2608,43 @@
3364 thd->restore_backup_statement(stmt, &stmt_backup);
3365 thd->stmt_arena= thd;
3367 + if (opt_userstat_running) {
3368 + // Gets the end time.
3369 + if (!(end_time_error = gettimeofday(&end_time, NULL))) {
3370 + end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
3373 + // Calculates the difference between the end and start times.
3374 + if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
3375 + thd->busy_time = (end_usecs - start_usecs) / 1000000;
3376 + // In case there are bad values, 2629743 is the #seconds in a month.
3377 + if (thd->busy_time > 2629743) {
3378 + thd->busy_time = 0;
3381 + // end time went back in time, or gettimeofday() failed.
3382 + thd->busy_time = 0;
3385 +#ifdef HAVE_CLOCK_GETTIME
3386 + /* get end cputime */
3387 + if (!cputime_error &&
3388 + !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3389 + end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3391 + if (start_cpu_nsecs && !cputime_error) {
3392 + thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
3393 + // In case there are bad values, 2629743 is the #seconds in a month.
3394 + if (thd->cpu_time > 2629743) {
3395 + thd->cpu_time = 0;
3398 + thd->cpu_time = 0;
3400 + // Updates THD stats and the global user stats.
3401 + thd->update_stats(true);
3402 + update_global_user_stats(thd, true, time(NULL));
3407 @@ -2487,6 +2677,30 @@
3408 /* First of all clear possible warnings from the previous command */
3409 mysql_reset_thd_for_next_command(thd);
3411 + int start_time_error = 0;
3412 + int end_time_error = 0;
3413 + struct timeval start_time, end_time;
3414 + double start_usecs = 0;
3415 + double end_usecs = 0;
3417 + int cputime_error = 0;
3418 + struct timespec tp;
3419 + double start_cpu_nsecs = 0;
3420 + double end_cpu_nsecs = 0;
3422 + if (opt_userstat_running) {
3423 +#ifdef HAVE_CLOCK_GETTIME
3424 + /* get start cputime */
3425 + if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3426 + start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3429 + // Gets the start time, in order to measure how long this command takes.
3430 + if (!(start_time_error = gettimeofday(&start_time, NULL))) {
3431 + start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
3435 statistic_increment(thd->status_var.com_stmt_reset, &LOCK_status);
3436 if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
3438 @@ -2503,6 +2717,43 @@
3442 + if (opt_userstat_running) {
3443 + // Gets the end time.
3444 + if (!(end_time_error = gettimeofday(&end_time, NULL))) {
3445 + end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
3448 + // Calculates the difference between the end and start times.
3449 + if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
3450 + thd->busy_time = (end_usecs - start_usecs) / 1000000;
3451 + // In case there are bad values, 2629743 is the #seconds in a month.
3452 + if (thd->busy_time > 2629743) {
3453 + thd->busy_time = 0;
3456 + // end time went back in time, or gettimeofday() failed.
3457 + thd->busy_time = 0;
3460 +#ifdef HAVE_CLOCK_GETTIME
3461 + /* get end cputime */
3462 + if (!cputime_error &&
3463 + !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3464 + end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3466 + if (start_cpu_nsecs && !cputime_error) {
3467 + thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
3468 + // In case there are bad values, 2629743 is the #seconds in a month.
3469 + if (thd->cpu_time > 2629743) {
3470 + thd->cpu_time = 0;
3473 + thd->cpu_time = 0;
3475 + // Updates THD stats and the global user stats.
3476 + thd->update_stats(true);
3477 + update_global_user_stats(thd, true, time(NULL));
3482 diff -r 592f6c3641ba sql/sql_show.cc
3483 --- a/sql/sql_show.cc Wed Jul 29 13:33:34 2009 -0700
3484 +++ b/sql/sql_show.cc Wed Jul 29 13:34:11 2009 -0700
3486 sctx->master_access);
3487 if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
3489 + thd->diff_access_denied_errors++;
3490 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
3491 sctx->priv_user, sctx->host_or_ip, dbname);
3492 mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
3493 @@ -1890,6 +1891,300 @@
3498 + Aggregate values for mapped_user entries by their role.
3501 + aggregate_user_stats
3502 + all_user_stats - input to aggregate
3503 + agg_user_stats - returns aggregated values
3510 +aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats)
3512 + DBUG_ENTER("aggregate_user_stats");
3513 + if (hash_init(agg_user_stats, system_charset_info,
3514 + max(all_user_stats->records, 1),
3515 + 0, 0, (hash_get_key)get_key_user_stats,
3516 + (hash_free_key)free_user_stats, 0))
3518 + sql_print_error("Malloc in aggregate_user_stats failed");
3522 + for (int i = 0; i < all_user_stats->records; ++i) {
3523 + USER_STATS *user = (USER_STATS*)hash_element(all_user_stats, i);
3524 + USER_STATS *agg_user;
3525 + if (!(agg_user = (USER_STATS*)hash_search(agg_user_stats,
3526 + (byte*)user->priv_user,
3527 + strlen(user->priv_user))))
3529 + // First entry for this role.
3531 + (USER_STATS*) my_malloc(sizeof(USER_STATS), MYF(MY_WME | MY_ZEROFILL))))
3533 + sql_print_error("Malloc in aggregate_user_stats failed");
3537 + init_user_stats(agg_user, user->priv_user, user->priv_user,
3538 + user->total_connections, user->concurrent_connections,
3539 + user->connected_time, user->busy_time, user->cpu_time,
3540 + user->bytes_received, user->bytes_sent,
3541 + user->binlog_bytes_written,
3542 + user->rows_fetched, user->rows_updated, user->rows_read,
3543 + user->select_commands, user->update_commands,
3544 + user->other_commands,
3545 + user->commit_trans, user->rollback_trans,
3546 + user->denied_connections, user->lost_connections,
3547 + user->access_denied_errors, user->empty_queries);
3549 + if (my_hash_insert(agg_user_stats, (byte*)agg_user))
3552 + my_free((char*)agg_user, 0);
3553 + sql_print_error("Malloc in aggregate_user_stats failed");
3559 + // Aggregate with existing values for this role.
3560 + add_user_stats(agg_user,
3561 + user->total_connections, user->concurrent_connections,
3562 + user->connected_time, user->busy_time, user->cpu_time,
3563 + user->bytes_received, user->bytes_sent,
3564 + user->binlog_bytes_written,
3565 + user->rows_fetched, user->rows_updated, user->rows_read,
3566 + user->select_commands, user->update_commands,
3567 + user->other_commands,
3568 + user->commit_trans, user->rollback_trans,
3569 + user->denied_connections, user->lost_connections,
3570 + user->access_denied_errors, user->empty_queries);
3573 + DBUG_PRINT("exit", ("aggregated %d input into %d output entries",
3574 + all_user_stats->records, agg_user_stats->records));
3579 + Write result to network for SHOW USER_STATISTICS
3583 + all_user_stats - values to return
3590 +int send_user_stats(THD* thd, HASH *all_user_stats, TABLE *table)
3592 + DBUG_ENTER("send_user_stats");
3593 + for (int i = 0; i < all_user_stats->records; ++i) {
3594 + restore_record(table, s->default_values);
3595 + USER_STATS *user_stats = (USER_STATS*)hash_element(all_user_stats, i);
3596 + table->field[0]->store(user_stats->user, strlen(user_stats->user), system_charset_info);
3597 + table->field[1]->store((longlong)user_stats->total_connections);
3598 + table->field[2]->store((longlong)user_stats->concurrent_connections);
3599 + table->field[3]->store((longlong)user_stats->connected_time);
3600 + table->field[4]->store((longlong)user_stats->busy_time);
3601 + table->field[5]->store((longlong)user_stats->cpu_time);
3602 + table->field[6]->store((longlong)user_stats->bytes_received);
3603 + table->field[7]->store((longlong)user_stats->bytes_sent);
3604 + table->field[8]->store((longlong)user_stats->binlog_bytes_written);
3605 + table->field[9]->store((longlong)user_stats->rows_fetched);
3606 + table->field[10]->store((longlong)user_stats->rows_updated);
3607 + table->field[11]->store((longlong)user_stats->rows_read);
3608 + table->field[12]->store((longlong)user_stats->select_commands);
3609 + table->field[13]->store((longlong)user_stats->update_commands);
3610 + table->field[14]->store((longlong)user_stats->other_commands);
3611 + table->field[15]->store((longlong)user_stats->commit_trans);
3612 + table->field[16]->store((longlong)user_stats->rollback_trans);
3613 + table->field[17]->store((longlong)user_stats->denied_connections);
3614 + table->field[18]->store((longlong)user_stats->lost_connections);
3615 + table->field[19]->store((longlong)user_stats->access_denied_errors);
3616 + table->field[20]->store((longlong)user_stats->empty_queries);
3617 + if (schema_table_store_record(thd, table))
3619 + DBUG_PRINT("error", ("store record error"));
3627 + Process SHOW USER_STATISTICS
3630 + mysqld_show_user_stats
3631 + thd - current thread
3632 + wild - limit results to the entry for this user
3633 + with_roles - when true, display role for mapped users
3641 +int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond)
3643 + TABLE *table= tables->table;
3644 + DBUG_ENTER("fill_schema_user_stats");
3646 + if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
3649 + // Iterates through all the global stats and sends them to the client.
3650 + // Pattern matching on the client IP is supported.
3652 + pthread_mutex_lock(&LOCK_global_user_client_stats);
3653 + int result= send_user_stats(thd, &global_user_stats, table);
3654 + pthread_mutex_unlock(&LOCK_global_user_client_stats);
3658 + DBUG_PRINT("exit", ("fill_schema_user_stats result is 0"));
3662 + DBUG_PRINT("exit", ("fill_schema_user_stats result is 1"));
3667 + Process SHOW CLIENT_STATISTICS
3670 + mysqld_show_client_stats
3671 + thd - current thread
3672 + wild - limit results to the entry for this client
3680 +int fill_schema_client_stats(THD* thd, TABLE_LIST* tables, COND* cond)
3682 + TABLE *table= tables->table;
3683 + DBUG_ENTER("fill_schema_client_stats");
3685 + if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
3688 + // Iterates through all the global stats and sends them to the client.
3689 + // Pattern matching on the client IP is supported.
3691 + pthread_mutex_lock(&LOCK_global_user_client_stats);
3692 + int result= send_user_stats(thd, &global_client_stats, table);
3693 + pthread_mutex_unlock(&LOCK_global_user_client_stats);
3697 + DBUG_PRINT("exit", ("mysqld_show_client_stats result is 0"));
3701 + DBUG_PRINT("exit", ("mysqld_show_client_stats result is 1"));
3706 +// Sends the global table stats back to the client.
3707 +int fill_schema_table_stats(THD* thd, TABLE_LIST* tables, COND* cond)
3709 + TABLE *table= tables->table;
3710 + DBUG_ENTER("fill_schema_table_stats");
3711 + char *table_full_name, *table_schema;
3713 + pthread_mutex_lock(&LOCK_global_table_stats);
3714 + for (int i = 0; i < global_table_stats.records; ++i) {
3715 + restore_record(table, s->default_values);
3716 + TABLE_STATS *table_stats =
3717 + (TABLE_STATS*)hash_element(&global_table_stats, i);
3719 + table_full_name= thd->strdup(table_stats->table);
3720 + table_schema= strsep(&table_full_name, ".");
3722 + TABLE_LIST tmp_table;
3723 + bzero((char*) &tmp_table,sizeof(tmp_table));
3724 + tmp_table.table_name= table_full_name;
3725 + tmp_table.db= table_schema;
3726 + tmp_table.grant.privilege= 0;
3727 + if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
3728 + &tmp_table.grant.privilege, 0, 0,
3729 + is_schema_db(table_schema)) ||
3730 + grant_option && check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
3733 + table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
3734 + table->field[1]->store(table_full_name, strlen(table_full_name), system_charset_info);
3735 + table->field[2]->store((longlong)table_stats->rows_read, TRUE);
3736 + table->field[3]->store((longlong)table_stats->rows_changed, TRUE);
3737 + table->field[4]->store((longlong)table_stats->rows_changed_x_indexes, TRUE);
3739 + if (schema_table_store_record(thd, table))
3741 + VOID(pthread_mutex_unlock(&LOCK_global_table_stats));
3745 + pthread_mutex_unlock(&LOCK_global_table_stats);
3749 +// Sends the global index stats back to the client.
3750 +int fill_schema_index_stats(THD* thd, TABLE_LIST* tables, COND* cond)
3752 + TABLE *table= tables->table;
3753 + DBUG_ENTER("fill_schema_index_stats");
3754 + char *index_full_name, *table_schema, *table_name;
3756 + pthread_mutex_lock(&LOCK_global_index_stats);
3757 + for (int i = 0; i < global_index_stats.records; ++i) {
3758 + restore_record(table, s->default_values);
3759 + INDEX_STATS *index_stats =
3760 + (INDEX_STATS*)hash_element(&global_index_stats, i);
3762 + index_full_name= thd->strdup(index_stats->index);
3763 + table_schema= strsep(&index_full_name, ".");
3764 + table_name= strsep(&index_full_name, ".");
3766 + TABLE_LIST tmp_table;
3767 + bzero((char*) &tmp_table,sizeof(tmp_table));
3768 + tmp_table.table_name= table_name;
3769 + tmp_table.db= table_schema;
3770 + tmp_table.grant.privilege= 0;
3771 + if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
3772 + &tmp_table.grant.privilege, 0, 0,
3773 + is_schema_db(table_schema)) ||
3774 + grant_option && check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
3777 + table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
3778 + table->field[1]->store(table_name, strlen(table_name), system_charset_info);
3779 + table->field[2]->store(index_full_name, strlen(index_full_name), system_charset_info);
3780 + table->field[3]->store((longlong)index_stats->rows_read, TRUE);
3782 + if (schema_table_store_record(thd, table))
3784 + VOID(pthread_mutex_unlock(&LOCK_global_index_stats));
3788 + pthread_mutex_unlock(&LOCK_global_index_stats);
3792 /* collect status for all running threads */
3794 @@ -4500,6 +4795,77 @@
3795 {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
3798 +ST_FIELD_INFO user_stats_fields_info[]=
3800 + {"USER", USERNAME_LENGTH, MYSQL_TYPE_STRING, 0, 0, "User"},
3801 + {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections"},
3802 + {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections"},
3803 + {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time"},
3804 + {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time"},
3805 + {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time"},
3806 + {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received"},
3807 + {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent"},
3808 + {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written"},
3809 + {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched"},
3810 + {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated"},
3811 + {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read"},
3812 + {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands"},
3813 + {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands"},
3814 + {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands"},
3815 + {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions"},
3816 + {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions"},
3817 + {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections"},
3818 + {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections"},
3819 + {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied"},
3820 + {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries"},
3821 + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
3824 +ST_FIELD_INFO client_stats_fields_info[]=
3826 + {"CLIENT", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Client"},
3827 + {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections"},
3828 + {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections"},
3829 + {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time"},
3830 + {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time"},
3831 + {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time"},
3832 + {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received"},
3833 + {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent"},
3834 + {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written"},
3835 + {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched"},
3836 + {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated"},
3837 + {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read"},
3838 + {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands"},
3839 + {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands"},
3840 + {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands"},
3841 + {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions"},
3842 + {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions"},
3843 + {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections"},
3844 + {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections"},
3845 + {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied"},
3846 + {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries"},
3847 + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
3851 +ST_FIELD_INFO table_stats_fields_info[]=
3853 + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema"},
3854 + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name"},
3855 + {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read"},
3856 + {"ROWS_CHANGED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed"},
3857 + {"ROWS_CHANGED_X_INDEXES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed_x_#indexes"},
3858 + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
3861 +ST_FIELD_INFO index_stats_fields_info[]=
3863 + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema"},
3864 + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name"},
3865 + {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name"},
3866 + {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read"},
3867 + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
3871 Description of ST_FIELD_INFO in table.h
3872 @@ -4509,6 +4875,8 @@
3874 {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
3875 fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0},
3876 + {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table,
3877 + fill_schema_client_stats, make_old_format, 0, -1, -1, 0},
3878 {"COLLATIONS", collation_fields_info, create_schema_table,
3879 fill_schema_collation, make_old_format, 0, -1, -1, 0},
3880 {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
3881 @@ -4517,6 +4885,8 @@
3882 get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0},
3883 {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
3884 fill_schema_column_privileges, 0, 0, -1, -1, 0},
3885 + {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table,
3886 + fill_schema_index_stats, make_old_format, 0, -1, -1, 0},
3887 {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
3888 get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
3889 {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
3890 @@ -4542,10 +4912,14 @@
3891 get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
3892 {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
3893 fill_schema_table_privileges, 0, 0, -1, -1, 0},
3894 + {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
3895 + fill_schema_table_stats, make_old_format, 0, -1, -1, 0},
3896 {"TRIGGERS", triggers_fields_info, create_schema_table,
3897 get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
3898 {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
3899 fill_schema_user_privileges, 0, 0, -1, -1, 0},
3900 + {"USER_STATISTICS", user_stats_fields_info, create_schema_table,
3901 + fill_schema_user_stats, make_old_format, 0, -1, -1, 0},
3902 {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
3903 make_old_format, 0, -1, -1, 1},
3904 {"VIEWS", view_fields_info, create_schema_table,
3905 diff -r 592f6c3641ba sql/sql_update.cc
3906 --- a/sql/sql_update.cc Wed Jul 29 13:33:34 2009 -0700
3907 +++ b/sql/sql_update.cc Wed Jul 29 13:34:11 2009 -0700
3909 (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
3910 send_ok(thd, (ulong) thd->row_count_func,
3911 thd->insert_id_used ? thd->last_insert_id : 0L,buff);
3912 - DBUG_PRINT("info",("%ld records updated", (long) updated));
3913 + thd->updated_row_count += thd->row_count_func;
3914 + DBUG_PRINT("info",("%d records updated",updated));
3916 thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
3917 thd->abort_on_warning= 0;
3918 @@ -1832,5 +1833,6 @@
3919 (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
3920 ::send_ok(thd, (ulong) thd->row_count_func,
3921 thd->insert_id_used ? thd->last_insert_id : 0L,buff);
3922 + thd->updated_row_count += thd->row_count_func;
3925 diff -r 592f6c3641ba sql/sql_yacc.yy
3926 --- a/sql/sql_yacc.yy Wed Jul 29 13:33:34 2009 -0700
3927 +++ b/sql/sql_yacc.yy Wed Jul 29 13:34:11 2009 -0700
3932 +%token CLIENT_STATS_SYM
3940 +%token INDEX_STATS_SYM
3956 +%token TABLE_STATS_SYM
3958 %token TEMPTABLE_SYM
3964 +%token USER_STATS_SYM
3968 @@ -8255,6 +8260,38 @@
3970 Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
3972 + | CLIENT_STATS_SYM wild_and_where
3975 + Lex->sql_command = SQLCOM_SELECT;
3976 + lex->orig_sql_command= SQLCOM_SHOW_CLIENT_STATS;
3977 + if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS))
3980 + | USER_STATS_SYM wild_and_where
3983 + lex->sql_command = SQLCOM_SELECT;
3984 + lex->orig_sql_command= SQLCOM_SHOW_USER_STATS;
3985 + if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
3988 + | TABLE_STATS_SYM wild_and_where
3991 + lex->sql_command= SQLCOM_SELECT;
3992 + lex->orig_sql_command= SQLCOM_SHOW_TABLE_STATS;
3993 + if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
3996 + | INDEX_STATS_SYM wild_and_where
3999 + lex->sql_command= SQLCOM_SELECT;
4000 + lex->orig_sql_command= SQLCOM_SHOW_INDEX_STATS;
4001 + if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
4004 | CREATE PROCEDURE sp_name
4007 @@ -8459,9 +8496,14 @@
4008 | LOGS_SYM { Lex->type|= REFRESH_LOG; }
4009 | STATUS_SYM { Lex->type|= REFRESH_STATUS; }
4010 | SLAVE { Lex->type|= REFRESH_SLAVE; }
4011 + | SLOW_SYM QUERY_SYM LOGS_SYM { Lex->type |= REFRESH_SLOW_QUERY_LOG; }
4012 | MASTER_SYM { Lex->type|= REFRESH_MASTER; }
4013 | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; }
4014 - | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; };
4015 + | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; }
4016 + | CLIENT_STATS_SYM { Lex->type|= REFRESH_CLIENT_STATS; }
4017 + | USER_STATS_SYM { Lex->type|= REFRESH_USER_STATS; }
4018 + | TABLE_STATS_SYM { Lex->type|= REFRESH_TABLE_STATS; }
4019 + | INDEX_STATS_SYM { Lex->type|= REFRESH_INDEX_STATS; };
4023 @@ -9450,6 +9492,7 @@
4027 + | CLIENT_STATS_SYM {}
4031 @@ -9502,6 +9545,7 @@
4035 + | INDEX_STATS_SYM {}
4039 @@ -9611,6 +9655,7 @@
4047 @@ -9627,6 +9672,7 @@
4051 + | TABLE_STATS_SYM {}
4055 @@ -9647,6 +9693,7 @@
4059 + | USER_STATS_SYM {}
4063 diff -r 592f6c3641ba sql/structs.h
4064 --- a/sql/structs.h Wed Jul 29 13:33:34 2009 -0700
4065 +++ b/sql/structs.h Wed Jul 29 13:34:11 2009 -0700
4066 @@ -273,6 +273,98 @@
4070 +typedef struct st_user_stats {
4071 + char user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
4072 + // Account name the user is mapped to when this is a user from mapped_user.
4073 + // Otherwise, the same value as user.
4074 + char priv_user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
4075 + uint total_connections;
4076 + uint concurrent_connections;
4077 + time_t connected_time; // in seconds
4078 + double busy_time; // in seconds
4079 + double cpu_time; // in seconds
4080 + ulonglong bytes_received;
4081 + ulonglong bytes_sent;
4082 + ulonglong binlog_bytes_written;
4083 + ha_rows rows_fetched, rows_updated, rows_read;
4084 + ulonglong select_commands, update_commands, other_commands;
4085 + ulonglong commit_trans, rollback_trans;
4086 + ulonglong denied_connections, lost_connections;
4087 + ulonglong access_denied_errors;
4088 + ulonglong empty_queries;
4091 +/* Lookup function for hash tables with USER_STATS entries */
4092 +extern byte *get_key_user_stats(USER_STATS *user_stats, uint *length,
4093 + my_bool not_used __attribute__((unused)));
4095 +/* Free all memory for a hash table with USER_STATS entries */
4096 +extern void free_user_stats(USER_STATS* user_stats);
4098 +/* Intialize an instance of USER_STATS */
4100 +init_user_stats(USER_STATS *user_stats,
4102 + const char *priv_user,
4103 + uint total_connections,
4104 + uint concurrent_connections,
4105 + time_t connected_time,
4108 + ulonglong bytes_received,
4109 + ulonglong bytes_sent,
4110 + ulonglong binlog_bytes_written,
4111 + ha_rows rows_fetched,
4112 + ha_rows rows_updated,
4113 + ha_rows rows_read,
4114 + ulonglong select_commands,
4115 + ulonglong update_commands,
4116 + ulonglong other_commands,
4117 + ulonglong commit_trans,
4118 + ulonglong rollback_trans,
4119 + ulonglong denied_connections,
4120 + ulonglong lost_connections,
4121 + ulonglong access_denied_errors,
4122 + ulonglong empty_queries);
4124 +/* Increment values of an instance of USER_STATS */
4126 +add_user_stats(USER_STATS *user_stats,
4127 + uint total_connections,
4128 + uint concurrent_connections,
4129 + time_t connected_time,
4132 + ulonglong bytes_received,
4133 + ulonglong bytes_sent,
4134 + ulonglong binlog_bytes_written,
4135 + ha_rows rows_fetched,
4136 + ha_rows rows_updated,
4137 + ha_rows rows_read,
4138 + ulonglong select_commands,
4139 + ulonglong update_commands,
4140 + ulonglong other_commands,
4141 + ulonglong commit_trans,
4142 + ulonglong rollback_trans,
4143 + ulonglong denied_connections,
4144 + ulonglong lost_connections,
4145 + ulonglong access_denied_errors,
4146 + ulonglong empty_queries);
4148 +typedef struct st_table_stats {
4149 + char table[NAME_LEN * 2 + 2]; // [db] + '.' + [table] + '\0'
4150 + ulonglong rows_read, rows_changed;
4151 + ulonglong rows_changed_x_indexes;
4152 + /* Stores enum db_type, but forward declarations cannot be done */
4156 +typedef struct st_index_stats {
4157 + char index[NAME_LEN * 3 + 3]; // [db] + '.' + [table] + '.' + [index] + '\0'
4158 + ulonglong rows_read;
4162 /* Bits in form->update */
4163 #define REG_MAKE_DUPP 1 /* Make a copy of record when read */
4164 #define REG_NEW_RECORD 2 /* Write a new record if not found */
4165 diff -r 592f6c3641ba sql/table.h
4166 --- a/sql/table.h Wed Jul 29 13:33:34 2009 -0700
4167 +++ b/sql/table.h Wed Jul 29 13:34:11 2009 -0700
4168 @@ -371,10 +371,12 @@
4169 enum enum_schema_tables
4174 SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
4176 SCH_COLUMN_PRIVILEGES,
4178 SCH_KEY_COLUMN_USAGE,
4181 @@ -387,8 +389,10 @@
4182 SCH_TABLE_CONSTRAINTS,
4184 SCH_TABLE_PRIVILEGES,
4187 SCH_USER_PRIVILEGES,
4192 diff -r 592f6c3641ba strings/Makefile.in
4193 --- a/strings/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4194 +++ b/strings/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4197 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4202 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4203 diff -r 592f6c3641ba support-files/MacOSX/Makefile.in
4204 --- a/support-files/MacOSX/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4205 +++ b/support-files/MacOSX/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4208 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4213 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4214 diff -r 592f6c3641ba support-files/Makefile.in
4215 --- a/support-files/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4216 +++ b/support-files/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4219 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4224 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4225 diff -r 592f6c3641ba support-files/RHEL4-SElinux/Makefile.in
4226 --- a/support-files/RHEL4-SElinux/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4227 +++ b/support-files/RHEL4-SElinux/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4230 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4235 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4236 diff -r 592f6c3641ba tests/Makefile.in
4237 --- a/tests/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4238 +++ b/tests/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4241 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4244 LIBS = @CLIENT_LIBS@
4246 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4247 diff -r 592f6c3641ba tools/Makefile.in
4248 --- a/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4249 +++ b/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4252 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4257 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4258 diff -r 592f6c3641ba vio/Makefile.in
4259 --- a/vio/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4260 +++ b/vio/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4263 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4268 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4269 diff -r 592f6c3641ba win/Makefile.in
4270 --- a/win/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4271 +++ b/win/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4274 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4279 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4280 diff -r 592f6c3641ba zlib/Makefile.in
4281 --- a/zlib/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4282 +++ b/zlib/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4285 LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4288 LIBS = $(NON_THREADED_LIBS)
4290 LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@