Gentoo Archives: gentoo-commits

From: "Robin H. Johnson" <robbat2@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/mysql-extras:master commit in: /
Date: Sun, 01 Apr 2012 17:59:31
Message-Id: 1333303146.43bb20efca6cc827d8b20ed4a54ba88cdfb2b09c.robbat2@gentoo
1 commit: 43bb20efca6cc827d8b20ed4a54ba88cdfb2b09c
2 Author: Robin H. Johnson <robbat2 <AT> orbis-terrarum <DOT> net>
3 AuthorDate: Sun Apr 1 17:59:06 2012 +0000
4 Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
5 CommitDate: Sun Apr 1 17:59:06 2012 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=43bb20ef
7
8 Forward-port a Percona patch.
9
10 ---
11 00000_index.txt | 7 +-
12 10030_all_userstatv2-percona-5.0.96.patch | 4378 +++++++++++++++++++++++++++++
13 2 files changed, 4384 insertions(+), 1 deletions(-)
14
15 diff --git a/00000_index.txt b/00000_index.txt
16 index 163c5a2..d5cd020 100644
17 --- a/00000_index.txt
18 +++ b/00000_index.txt
19 @@ -883,10 +883,15 @@
20 @@ Percona 5.0.91-b22-20100522: SHOW USER/TABLE/INDEX statistics
21
22 @patch 10030_all_userstatv2-percona-5.0.92.patch
23 -@ver 5.00.92.00 to 5.00.99.99
24 +@ver 5.00.92.00 to 5.00.95.99
25 @pn mysql
26 @@ Percona 5.0.92: SHOW USER/TABLE/INDEX statistics
27
28 +@patch 10030_all_userstatv2-percona-5.0.96.patch
29 +@ver 5.00.96.00 to 5.00.99.99
30 +@pn mysql
31 +@@ Percona 5.0.96: SHOW USER/TABLE/INDEX statistics (Gentoo forward-port)
32 +
33 @patch 10040_all_microsec_process-percona-5.0.75-b12.patch
34 @ver 5.00.75.00 to 5.00.76.99
35 @pn mysql-community
36
37 diff --git a/10030_all_userstatv2-percona-5.0.96.patch b/10030_all_userstatv2-percona-5.0.96.patch
38 new file mode 100644
39 index 0000000..79ba002
40 --- /dev/null
41 +++ b/10030_all_userstatv2-percona-5.0.96.patch
42 @@ -0,0 +1,4378 @@
43 +Forward ported from 10030_all_userstatv2-percona-5.0.92.patch by robbat2@gentoo
44 +
45 +diff -r 592f6c3641ba BUILD/Makefile.in
46 +--- a/BUILD/Makefile.in Wed Jul 29 13:33:34 2009 -0700
47 ++++ b/BUILD/Makefile.in Wed Jul 29 13:34:11 2009 -0700
48 +@@ -146,6 +146,7 @@
49 + LIBDL = @LIBDL@
50 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
51 + LIBOBJS = @LIBOBJS@
52 ++LIBRT = @LIBRT@
53 + LIBS = @LIBS@
54 + LIBTOOL = @LIBTOOL@
55 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
56 +diff -r 592f6c3641ba Docs/Makefile.in
57 +--- a/Docs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
58 ++++ b/Docs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
59 +@@ -144,6 +144,7 @@
60 + LIBDL = @LIBDL@
61 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
62 + LIBOBJS = @LIBOBJS@
63 ++LIBRT = @LIBRT@
64 + LIBS = @LIBS@
65 + LIBTOOL = @LIBTOOL@
66 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
67 +diff -r 592f6c3641ba Makefile.in
68 +--- a/Makefile.in Wed Jul 29 13:33:34 2009 -0700
69 ++++ b/Makefile.in Wed Jul 29 13:34:11 2009 -0700
70 +@@ -171,6 +171,7 @@
71 + LIBDL = @LIBDL@
72 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
73 + LIBOBJS = @LIBOBJS@
74 ++LIBRT = @LIBRT@
75 + LIBS = @LIBS@
76 + LIBTOOL = @LIBTOOL@
77 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
78 +diff -r 592f6c3641ba SSL/Makefile.in
79 +--- a/SSL/Makefile.in Wed Jul 29 13:33:34 2009 -0700
80 ++++ b/SSL/Makefile.in Wed Jul 29 13:34:11 2009 -0700
81 +@@ -144,6 +144,7 @@
82 + LIBDL = @LIBDL@
83 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
84 + LIBOBJS = @LIBOBJS@
85 ++LIBRT = @LIBRT@
86 + LIBS = @LIBS@
87 + LIBTOOL = @LIBTOOL@
88 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
89 +diff -r 592f6c3641ba client/Makefile.in
90 +--- a/client/Makefile.in Wed Jul 29 13:33:34 2009 -0700
91 ++++ b/client/Makefile.in Wed Jul 29 13:34:11 2009 -0700
92 +@@ -247,6 +247,7 @@
93 + LIBDL = @LIBDL@
94 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
95 + LIBOBJS = @LIBOBJS@
96 ++LIBRT = @LIBRT@
97 + LIBS = @CLIENT_LIBS@
98 + LIBTOOL = @LIBTOOL@
99 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
100 +diff -r 592f6c3641ba cmd-line-utils/Makefile.in
101 +--- a/cmd-line-utils/Makefile.in Wed Jul 29 13:33:34 2009 -0700
102 ++++ b/cmd-line-utils/Makefile.in Wed Jul 29 13:34:11 2009 -0700
103 +@@ -157,6 +157,7 @@
104 + LIBDL = @LIBDL@
105 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
106 + LIBOBJS = @LIBOBJS@
107 ++LIBRT = @LIBRT@
108 + LIBS = @LIBS@
109 + LIBTOOL = @LIBTOOL@
110 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
111 +diff -r 592f6c3641ba cmd-line-utils/libedit/Makefile.in
112 +--- a/cmd-line-utils/libedit/Makefile.in Wed Jul 29 13:33:34 2009 -0700
113 ++++ b/cmd-line-utils/libedit/Makefile.in Wed Jul 29 13:34:11 2009 -0700
114 +@@ -166,6 +166,7 @@
115 + LIBDL = @LIBDL@
116 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
117 + LIBOBJS = @LIBOBJS@
118 ++LIBRT = @LIBRT@
119 + LIBS = @LIBS@
120 + LIBTOOL = @LIBTOOL@
121 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
122 +diff -r 592f6c3641ba cmd-line-utils/readline/Makefile.in
123 +--- a/cmd-line-utils/readline/Makefile.in Wed Jul 29 13:33:34 2009 -0700
124 ++++ b/cmd-line-utils/readline/Makefile.in Wed Jul 29 13:34:11 2009 -0700
125 +@@ -173,6 +173,7 @@
126 + LIBDL = @LIBDL@
127 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
128 + LIBOBJS = @LIBOBJS@
129 ++LIBRT = @LIBRT@
130 + LIBS = @LIBS@
131 + LIBTOOL = @LIBTOOL@
132 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
133 +diff -r 592f6c3641ba configure
134 +--- a/configure Wed Jul 29 13:33:34 2009 -0700
135 ++++ b/configure Wed Jul 29 13:34:11 2009 -0700
136 +@@ -35347,7 +35347,91 @@
137 + # We also disable for SCO for the time being, the headers for the
138 + # thread library we use conflicts with other headers.
139 + ;;
140 +- *)
141 ++*)
142 ++ # most systems require the program be linked with librt library to use
143 ++ # the function clock_gettime
144 ++ my_save_LIBS="$LIBS"
145 ++ LIBS=""
146 ++
147 ++echo "$as_me:$LINENO: checking for clock_gettime in -lrt" >&5
148 ++echo $ECHO_N "checking for clock_gettime in -lrt... $ECHO_C" >&6
149 ++if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then
150 ++ echo $ECHO_N "(cached) $ECHO_C" >&6
151 ++else
152 ++ ac_check_lib_save_LIBS=$LIBS
153 ++LIBS="-lrt $LIBS"
154 ++cat >conftest.$ac_ext <<_ACEOF
155 ++/* confdefs.h. */
156 ++_ACEOF
157 ++cat confdefs.h >>conftest.$ac_ext
158 ++cat >>conftest.$ac_ext <<_ACEOF
159 ++/* end confdefs.h. */
160 ++
161 ++/* Override any gcc2 internal prototype to avoid an error. */
162 ++#ifdef __cplusplus
163 ++extern "C"
164 ++#endif
165 ++/* We use char because int might match the return type of a gcc2
166 ++ builtin and then its argument prototype would still apply. */
167 ++char clock_gettime ();
168 ++int
169 ++main ()
170 ++{
171 ++clock_gettime ();
172 ++ ;
173 ++ return 0;
174 ++}
175 ++_ACEOF
176 ++rm -f conftest.$ac_objext conftest$ac_exeext
177 ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
178 ++ (eval $ac_link) 2>conftest.er1
179 ++ ac_status=$?
180 ++ grep -v '^ *+' conftest.er1 >conftest.err
181 ++ rm -f conftest.er1
182 ++ cat conftest.err >&5
183 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
184 ++ (exit $ac_status); } &&
185 ++ { ac_try='test -z "$ac_c_werror_flag"
186 ++ || test ! -s conftest.err'
187 ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
188 ++ (eval $ac_try) 2>&5
189 ++ ac_status=$?
190 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
191 ++ (exit $ac_status); }; } &&
192 ++ { ac_try='test -s conftest$ac_exeext'
193 ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
194 ++ (eval $ac_try) 2>&5
195 ++ ac_status=$?
196 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
197 ++ (exit $ac_status); }; }; then
198 ++ ac_cv_lib_rt_clock_gettime=yes
199 ++else
200 ++ echo "$as_me: failed program was:" >&5
201 ++sed 's/^/| /' conftest.$ac_ext >&5
202 ++
203 ++ac_cv_lib_rt_clock_gettime=no
204 ++fi
205 ++rm -f conftest.err conftest.$ac_objext \
206 ++ conftest$ac_exeext conftest.$ac_ext
207 ++LIBS=$ac_check_lib_save_LIBS
208 ++fi
209 ++echo "$as_me:$LINENO: result: $ac_cv_lib_rt_clock_gettime" >&5
210 ++echo "${ECHO_T}$ac_cv_lib_rt_clock_gettime" >&6
211 ++if test $ac_cv_lib_rt_clock_gettime = yes; then
212 ++ cat >>confdefs.h <<_ACEOF
213 ++#define HAVE_LIBRT 1
214 ++_ACEOF
215 ++
216 ++ LIBS="-lrt $LIBS"
217 ++
218 ++fi
219 ++
220 ++ LIBRT=$LIBS
221 ++ LIBS="$my_save_LIBS"
222 ++
223 ++
224 ++ LIBS="$LIBS $LIBRT"
225 ++
226 + for ac_func in clock_gettime
227 + do
228 + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
229 +@@ -38791,7 +38875,7 @@
230 +
231 + fi
232 +
233 +-CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS"
234 ++CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT"
235 +
236 +
237 +
238 +diff -r 592f6c3641ba configure.in
239 +--- a/configure.in Wed Jul 29 13:33:34 2009 -0700
240 ++++ b/configure.in Wed Jul 29 13:34:11 2009 -0700
241 +@@ -2136,7 +2136,18 @@
242 + # We also disable for SCO for the time being, the headers for the
243 + # thread library we use conflicts with other headers.
244 + ;;
245 +- *) AC_CHECK_FUNCS(clock_gettime)
246 ++*)
247 ++ # most systems require the program be linked with librt library to use
248 ++ # the function clock_gettime
249 ++ my_save_LIBS="$LIBS"
250 ++ LIBS=""
251 ++ AC_CHECK_LIB(rt,clock_gettime)
252 ++ LIBRT=$LIBS
253 ++ LIBS="$my_save_LIBS"
254 ++ AC_SUBST(LIBRT)
255 ++
256 ++ LIBS="$LIBS $LIBRT"
257 ++ AC_CHECK_FUNCS(clock_gettime)
258 + ;;
259 + esac
260 +
261 +@@ -2772,7 +2783,7 @@
262 + AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe])
263 + fi
264 +
265 +-CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS"
266 ++CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT"
267 +
268 + AC_SUBST(CLIENT_LIBS)
269 + AC_SUBST(NON_THREADED_LIBS)
270 +diff -r 592f6c3641ba dbug/Makefile.in
271 +--- a/dbug/Makefile.in Wed Jul 29 13:33:34 2009 -0700
272 ++++ b/dbug/Makefile.in Wed Jul 29 13:34:11 2009 -0700
273 +@@ -192,6 +192,7 @@
274 + LIBDL = @LIBDL@
275 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
276 + LIBOBJS = @LIBOBJS@
277 ++LIBRT = @LIBRT@
278 + LIBS = @LIBS@
279 + LIBTOOL = @LIBTOOL@
280 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
281 +diff -r 592f6c3641ba extra/Makefile.in
282 +--- a/extra/Makefile.in Wed Jul 29 13:33:34 2009 -0700
283 ++++ b/extra/Makefile.in Wed Jul 29 13:34:11 2009 -0700
284 +@@ -240,6 +240,7 @@
285 + LIBDL = @LIBDL@
286 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
287 + LIBOBJS = @LIBOBJS@
288 ++LIBRT = @LIBRT@
289 + LIBS = @LIBS@
290 + LIBTOOL = @LIBTOOL@
291 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
292 +diff -r 592f6c3641ba extra/yassl/Makefile.in
293 +--- a/extra/yassl/Makefile.in Wed Jul 29 13:33:34 2009 -0700
294 ++++ b/extra/yassl/Makefile.in Wed Jul 29 13:34:11 2009 -0700
295 +@@ -142,6 +142,7 @@
296 + LIBDL = @LIBDL@
297 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
298 + LIBOBJS = @LIBOBJS@
299 ++LIBRT = @LIBRT@
300 + LIBS = @LIBS@
301 + LIBTOOL = @LIBTOOL@
302 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
303 +diff -r 592f6c3641ba extra/yassl/src/Makefile.in
304 +--- a/extra/yassl/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
305 ++++ b/extra/yassl/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
306 +@@ -151,6 +151,7 @@
307 + LIBDL = @LIBDL@
308 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
309 + LIBOBJS = @LIBOBJS@
310 ++LIBRT = @LIBRT@
311 + LIBS = @LIBS@
312 + LIBTOOL = @LIBTOOL@
313 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
314 +diff -r 592f6c3641ba extra/yassl/taocrypt/Makefile.in
315 +--- a/extra/yassl/taocrypt/Makefile.in Wed Jul 29 13:33:34 2009 -0700
316 ++++ b/extra/yassl/taocrypt/Makefile.in Wed Jul 29 13:34:11 2009 -0700
317 +@@ -142,6 +142,7 @@
318 + LIBDL = @LIBDL@
319 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
320 + LIBOBJS = @LIBOBJS@
321 ++LIBRT = @LIBRT@
322 + LIBS = @LIBS@
323 + LIBTOOL = @LIBTOOL@
324 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
325 +diff -r 592f6c3641ba extra/yassl/taocrypt/benchmark/Makefile.in
326 +--- a/extra/yassl/taocrypt/benchmark/Makefile.in Wed Jul 29 13:33:34 2009 -0700
327 ++++ b/extra/yassl/taocrypt/benchmark/Makefile.in Wed Jul 29 13:34:11 2009 -0700
328 +@@ -153,6 +153,7 @@
329 + LIBDL = @LIBDL@
330 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
331 + LIBOBJS = @LIBOBJS@
332 ++LIBRT = @LIBRT@
333 + LIBS = @LIBS@
334 + LIBTOOL = @LIBTOOL@
335 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
336 +diff -r 592f6c3641ba extra/yassl/taocrypt/src/Makefile.in
337 +--- a/extra/yassl/taocrypt/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
338 ++++ b/extra/yassl/taocrypt/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
339 +@@ -164,6 +164,7 @@
340 + LIBDL = @LIBDL@
341 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
342 + LIBOBJS = @LIBOBJS@
343 ++LIBRT = @LIBRT@
344 + LIBS = @LIBS@
345 + LIBTOOL = @LIBTOOL@
346 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
347 +diff -r 592f6c3641ba extra/yassl/taocrypt/test/Makefile.in
348 +--- a/extra/yassl/taocrypt/test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
349 ++++ b/extra/yassl/taocrypt/test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
350 +@@ -153,6 +153,7 @@
351 + LIBDL = @LIBDL@
352 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
353 + LIBOBJS = @LIBOBJS@
354 ++LIBRT = @LIBRT@
355 + LIBS = @LIBS@
356 + LIBTOOL = @LIBTOOL@
357 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
358 +diff -r 592f6c3641ba extra/yassl/testsuite/Makefile.in
359 +--- a/extra/yassl/testsuite/Makefile.in Wed Jul 29 13:33:34 2009 -0700
360 ++++ b/extra/yassl/testsuite/Makefile.in Wed Jul 29 13:34:11 2009 -0700
361 +@@ -156,6 +156,7 @@
362 + LIBDL = @LIBDL@
363 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
364 + LIBOBJS = @LIBOBJS@
365 ++LIBRT = @LIBRT@
366 + LIBS = @LIBS@
367 + LIBTOOL = @LIBTOOL@
368 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
369 +diff -r 592f6c3641ba heap/Makefile.in
370 +--- a/heap/Makefile.in Wed Jul 29 13:33:34 2009 -0700
371 ++++ b/heap/Makefile.in Wed Jul 29 13:34:11 2009 -0700
372 +@@ -202,6 +202,7 @@
373 + LIBDL = @LIBDL@
374 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
375 + LIBOBJS = @LIBOBJS@
376 ++LIBRT = @LIBRT@
377 + LIBS = @LIBS@
378 + LIBTOOL = @LIBTOOL@
379 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
380 +diff -r 592f6c3641ba include/Makefile.in
381 +--- a/include/Makefile.in Wed Jul 29 13:33:34 2009 -0700
382 ++++ b/include/Makefile.in Wed Jul 29 13:34:11 2009 -0700
383 +@@ -160,6 +160,7 @@
384 + LIBDL = @LIBDL@
385 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
386 + LIBOBJS = @LIBOBJS@
387 ++LIBRT = @LIBRT@
388 + LIBS = @LIBS@
389 + LIBTOOL = @LIBTOOL@
390 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
391 +diff -r 592f6c3641ba include/mysql_com.h
392 +--- a/include/mysql_com.h Wed Jul 29 13:33:34 2009 -0700
393 ++++ b/include/mysql_com.h Wed Jul 29 13:34:11 2009 -0700
394 +@@ -25,6 +25,7 @@
395 + #define USERNAME_LENGTH 16
396 + #define SERVER_VERSION_LENGTH 60
397 + #define SQLSTATE_LENGTH 5
398 ++#define LIST_PROCESS_HOST_LEN 64
399 +
400 + /*
401 + USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
402 +@@ -106,6 +107,11 @@
403 + thread */
404 + #define REFRESH_MASTER 128 /* Remove all bin logs in the index
405 + and truncate the index */
406 ++#define REFRESH_TABLE_STATS 256 /* Refresh table stats hash table */
407 ++#define REFRESH_INDEX_STATS 512 /* Refresh index stats hash table */
408 ++#define REFRESH_USER_STATS 1024 /* Refresh user stats hash table */
409 ++#define REFRESH_SLOW_QUERY_LOG 4096 /* Flush slow query log and rotate*/
410 ++#define REFRESH_CLIENT_STATS 8192 /* Refresh client stats hash table */
411 +
412 + /* The following can't be set with mysql_refresh() */
413 + #define REFRESH_READ_LOCK 16384 /* Lock tables for read */
414 +diff -r 592f6c3641ba libmysql/Makefile.in
415 +--- a/libmysql/Makefile.in Wed Jul 29 13:33:34 2009 -0700
416 ++++ b/libmysql/Makefile.in Wed Jul 29 13:34:11 2009 -0700
417 +@@ -224,6 +224,7 @@
418 + LIBDL = @LIBDL@
419 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
420 + LIBOBJS = @LIBOBJS@
421 ++LIBRT = @LIBRT@
422 + LIBS = @CLIENT_LIBS@
423 + LIBTOOL = @LIBTOOL@
424 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
425 +diff -r 592f6c3641ba libmysql_r/Makefile.in
426 +--- a/libmysql_r/Makefile.in Wed Jul 29 13:33:34 2009 -0700
427 ++++ b/libmysql_r/Makefile.in Wed Jul 29 13:34:11 2009 -0700
428 +@@ -221,6 +221,7 @@
429 + LIBDL = @LIBDL@
430 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
431 + LIBOBJS = @LIBOBJS@
432 ++LIBRT = @LIBRT@
433 + LIBS = @LIBS@ @ZLIB_LIBS@ @openssl_libs@
434 + LIBTOOL = @LIBTOOL@
435 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
436 +diff -r 592f6c3641ba libmysqld/Makefile.in
437 +--- a/libmysqld/Makefile.in Wed Jul 29 13:33:34 2009 -0700
438 ++++ b/libmysqld/Makefile.in Wed Jul 29 13:34:11 2009 -0700
439 +@@ -246,6 +246,7 @@
440 + LIBDL = @LIBDL@
441 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
442 + LIBOBJS = @LIBOBJS@
443 ++LIBRT = @LIBRT@
444 + LIBS = @LIBS@
445 + LIBTOOL = @LIBTOOL@
446 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
447 +diff -r 592f6c3641ba libmysqld/examples/Makefile.in
448 +--- a/libmysqld/examples/Makefile.in Wed Jul 29 13:33:34 2009 -0700
449 ++++ b/libmysqld/examples/Makefile.in Wed Jul 29 13:34:11 2009 -0700
450 +@@ -192,6 +192,7 @@
451 + LIBDL = @LIBDL@
452 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
453 + LIBOBJS = @LIBOBJS@
454 ++LIBRT = @LIBRT@
455 + LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs)
456 + LIBTOOL = @LIBTOOL@
457 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
458 +diff -r 592f6c3641ba man/Makefile.in
459 +--- a/man/Makefile.in Wed Jul 29 13:33:34 2009 -0700
460 ++++ b/man/Makefile.in Wed Jul 29 13:34:11 2009 -0700
461 +@@ -151,6 +151,7 @@
462 + LIBDL = @LIBDL@
463 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
464 + LIBOBJS = @LIBOBJS@
465 ++LIBRT = @LIBRT@
466 + LIBS = @LIBS@
467 + LIBTOOL = @LIBTOOL@
468 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
469 +diff -r 592f6c3641ba myisam/Makefile.in
470 +--- a/myisam/Makefile.in Wed Jul 29 13:33:34 2009 -0700
471 ++++ b/myisam/Makefile.in Wed Jul 29 13:34:11 2009 -0700
472 +@@ -235,6 +235,7 @@
473 + LIBDL = @LIBDL@
474 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
475 + LIBOBJS = @LIBOBJS@
476 ++LIBRT = @LIBRT@
477 + LIBS = @LIBS@
478 + LIBTOOL = @LIBTOOL@
479 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
480 +diff -r 592f6c3641ba myisammrg/Makefile.in
481 +--- a/myisammrg/Makefile.in Wed Jul 29 13:33:34 2009 -0700
482 ++++ b/myisammrg/Makefile.in Wed Jul 29 13:34:11 2009 -0700
483 +@@ -183,6 +183,7 @@
484 + LIBDL = @LIBDL@
485 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
486 + LIBOBJS = @LIBOBJS@
487 ++LIBRT = @LIBRT@
488 + LIBS = @LIBS@
489 + LIBTOOL = @LIBTOOL@
490 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
491 +diff -r 592f6c3641ba mysql-test/Makefile.in
492 +--- a/mysql-test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
493 ++++ b/mysql-test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
494 +@@ -161,6 +161,7 @@
495 + LIBDL = @LIBDL@
496 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
497 + LIBOBJS = @LIBOBJS@
498 ++LIBRT = @LIBRT@
499 + LIBS = @LIBS@
500 + LIBTOOL = @LIBTOOL@
501 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
502 +diff -r 592f6c3641ba mysql-test/ndb/Makefile.in
503 +--- a/mysql-test/ndb/Makefile.in Wed Jul 29 13:33:34 2009 -0700
504 ++++ b/mysql-test/ndb/Makefile.in Wed Jul 29 13:34:11 2009 -0700
505 +@@ -147,6 +147,7 @@
506 + LIBDL = @LIBDL@
507 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
508 + LIBOBJS = @LIBOBJS@
509 ++LIBRT = @LIBRT@
510 + LIBS = @LIBS@
511 + LIBTOOL = @LIBTOOL@
512 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
513 +diff -r 592f6c3641ba mysql-test/r/information_schema.result
514 +--- a/mysql-test/r/information_schema.result Wed Jul 29 13:33:34 2009 -0700
515 ++++ b/mysql-test/r/information_schema.result Wed Jul 29 13:34:11 2009 -0700
516 +@@ -37,10 +37,12 @@
517 + select * from v1;
518 + c
519 + CHARACTER_SETS
520 ++CLIENT_STATISTICS
521 + COLLATIONS
522 + COLLATION_CHARACTER_SET_APPLICABILITY
523 + COLUMNS
524 + COLUMN_PRIVILEGES
525 ++INDEX_STATISTICS
526 + KEY_COLUMN_USAGE
527 + PROFILING
528 + ROUTINES
529 +@@ -50,8 +52,10 @@
530 + TABLES
531 + TABLE_CONSTRAINTS
532 + TABLE_PRIVILEGES
533 ++TABLE_STATISTICS
534 + TRIGGERS
535 + USER_PRIVILEGES
536 ++USER_STATISTICS
537 + VIEWS
538 + columns_priv
539 + db
540 +@@ -83,6 +87,7 @@
541 + TABLES TABLES
542 + TABLE_CONSTRAINTS TABLE_CONSTRAINTS
543 + TABLE_PRIVILEGES TABLE_PRIVILEGES
544 ++TABLE_STATISTICS TABLE_STATISTICS
545 + TRIGGERS TRIGGERS
546 + tables_priv tables_priv
547 + time_zone time_zone
548 +@@ -102,6 +107,7 @@
549 + TABLES TABLES
550 + TABLE_CONSTRAINTS TABLE_CONSTRAINTS
551 + TABLE_PRIVILEGES TABLE_PRIVILEGES
552 ++TABLE_STATISTICS TABLE_STATISTICS
553 + TRIGGERS TRIGGERS
554 + tables_priv tables_priv
555 + time_zone time_zone
556 +@@ -121,6 +127,7 @@
557 + TABLES TABLES
558 + TABLE_CONSTRAINTS TABLE_CONSTRAINTS
559 + TABLE_PRIVILEGES TABLE_PRIVILEGES
560 ++TABLE_STATISTICS TABLE_STATISTICS
561 + TRIGGERS TRIGGERS
562 + tables_priv tables_priv
563 + time_zone time_zone
564 +@@ -594,12 +601,13 @@
565 + where table_schema='information_schema' limit 2;
566 + TABLE_NAME TABLE_TYPE ENGINE
567 + CHARACTER_SETS SYSTEM VIEW MEMORY
568 +-COLLATIONS SYSTEM VIEW MEMORY
569 ++CLIENT_STATISTICS SYSTEM VIEW MEMORY
570 + show tables from information_schema like "T%";
571 + Tables_in_information_schema (T%)
572 + TABLES
573 + TABLE_CONSTRAINTS
574 + TABLE_PRIVILEGES
575 ++TABLE_STATISTICS
576 + TRIGGERS
577 + create database information_schema;
578 + ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
579 +@@ -609,6 +617,7 @@
580 + TABLES SYSTEM VIEW
581 + TABLE_CONSTRAINTS SYSTEM VIEW
582 + TABLE_PRIVILEGES SYSTEM VIEW
583 ++TABLE_STATISTICS SYSTEM VIEW
584 + TRIGGERS SYSTEM VIEW
585 + create table t1(a int);
586 + ERROR 42S02: Unknown table 't1' in information_schema
587 +@@ -621,6 +630,7 @@
588 + TABLES
589 + TABLE_CONSTRAINTS
590 + TABLE_PRIVILEGES
591 ++TABLE_STATISTICS
592 + TRIGGERS
593 + select table_name from tables where table_name='user';
594 + table_name
595 +@@ -730,7 +740,7 @@
596 + CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
597 + CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
598 + count(*)
599 +-102
600 ++106
601 + drop view a2, a1;
602 + drop table t_crashme;
603 + select table_schema,table_name, column_name from
604 +@@ -790,18 +800,20 @@
605 + TABLE_NAME COLUMN_NAME PRIVILEGES
606 + COLUMNS TABLE_NAME select
607 + COLUMN_PRIVILEGES TABLE_NAME select
608 ++INDEX_STATISTICS TABLE_NAME select
609 + KEY_COLUMN_USAGE TABLE_NAME select
610 + STATISTICS TABLE_NAME select
611 + TABLES TABLE_NAME select
612 + TABLE_CONSTRAINTS TABLE_NAME select
613 + TABLE_PRIVILEGES TABLE_NAME select
614 ++TABLE_STATISTICS TABLE_NAME select
615 + VIEWS TABLE_NAME select
616 + delete from mysql.user where user='mysqltest_4';
617 + delete from mysql.db where user='mysqltest_4';
618 + flush privileges;
619 + SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
620 + table_schema count(*)
621 +-information_schema 17
622 ++information_schema 21
623 + mysql 17
624 + create table t1 (i int, j int);
625 + create trigger trg1 before insert on t1 for each row
626 +@@ -1187,10 +1199,12 @@
627 + );
628 + table_name column_name
629 + CHARACTER_SETS CHARACTER_SET_NAME
630 ++CLIENT_STATISTICS CLIENT
631 + COLLATIONS COLLATION_NAME
632 + COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
633 + COLUMNS TABLE_SCHEMA
634 + COLUMN_PRIVILEGES TABLE_SCHEMA
635 ++INDEX_STATISTICS TABLE_SCHEMA
636 + KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
637 + PROFILING QUERY_ID
638 + ROUTINES ROUTINE_SCHEMA
639 +@@ -1200,8 +1214,10 @@
640 + TABLES TABLE_SCHEMA
641 + TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
642 + TABLE_PRIVILEGES TABLE_SCHEMA
643 ++TABLE_STATISTICS TABLE_SCHEMA
644 + TRIGGERS TRIGGER_SCHEMA
645 + USER_PRIVILEGES GRANTEE
646 ++USER_STATISTICS USER
647 + VIEWS TABLE_SCHEMA
648 + SELECT t.table_name, c1.column_name
649 + FROM information_schema.tables t
650 +@@ -1219,10 +1235,12 @@
651 + );
652 + table_name column_name
653 + CHARACTER_SETS CHARACTER_SET_NAME
654 ++CLIENT_STATISTICS CLIENT
655 + COLLATIONS COLLATION_NAME
656 + COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
657 + COLUMNS TABLE_SCHEMA
658 + COLUMN_PRIVILEGES TABLE_SCHEMA
659 ++INDEX_STATISTICS TABLE_SCHEMA
660 + KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
661 + PROFILING QUERY_ID
662 + ROUTINES ROUTINE_SCHEMA
663 +@@ -1232,8 +1250,10 @@
664 + TABLES TABLE_SCHEMA
665 + TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
666 + TABLE_PRIVILEGES TABLE_SCHEMA
667 ++TABLE_STATISTICS TABLE_SCHEMA
668 + TRIGGERS TRIGGER_SCHEMA
669 + USER_PRIVILEGES GRANTEE
670 ++USER_STATISTICS USER
671 + VIEWS TABLE_SCHEMA
672 + SELECT MAX(table_name) FROM information_schema.tables;
673 + MAX(table_name)
674 +@@ -1302,10 +1322,12 @@
675 + group by t.table_name order by num1, t.table_name;
676 + table_name group_concat(t.table_schema, '.', t.table_name) num1
677 + CHARACTER_SETS information_schema.CHARACTER_SETS 1
678 ++CLIENT_STATISTICS information_schema.CLIENT_STATISTICS 1
679 + COLLATIONS information_schema.COLLATIONS 1
680 + COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 1
681 + COLUMNS information_schema.COLUMNS 1
682 + COLUMN_PRIVILEGES information_schema.COLUMN_PRIVILEGES 1
683 ++INDEX_STATISTICS information_schema.INDEX_STATISTICS 1
684 + KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1
685 + PROFILING information_schema.PROFILING 1
686 + ROUTINES information_schema.ROUTINES 1
687 +@@ -1315,8 +1337,10 @@
688 + TABLES information_schema.TABLES 1
689 + TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1
690 + TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
691 ++TABLE_STATISTICS information_schema.TABLE_STATISTICS 1
692 + TRIGGERS information_schema.TRIGGERS 1
693 + USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
694 ++USER_STATISTICS information_schema.USER_STATISTICS 1
695 + VIEWS information_schema.VIEWS 1
696 + create table t1(f1 int);
697 + create view v1 as select f1+1 as a from t1;
698 +diff -r 592f6c3641ba mysql-test/r/information_schema_db.result
699 +--- a/mysql-test/r/information_schema_db.result Wed Jul 29 13:33:34 2009 -0700
700 ++++ b/mysql-test/r/information_schema_db.result Wed Jul 29 13:34:11 2009 -0700
701 +@@ -6,10 +6,12 @@
702 + show tables;
703 + Tables_in_information_schema
704 + CHARACTER_SETS
705 ++CLIENT_STATISTICS
706 + COLLATIONS
707 + COLLATION_CHARACTER_SET_APPLICABILITY
708 + COLUMNS
709 + COLUMN_PRIVILEGES
710 ++INDEX_STATISTICS
711 + KEY_COLUMN_USAGE
712 + PROFILING
713 + ROUTINES
714 +@@ -19,14 +21,17 @@
715 + TABLES
716 + TABLE_CONSTRAINTS
717 + TABLE_PRIVILEGES
718 ++TABLE_STATISTICS
719 + TRIGGERS
720 + USER_PRIVILEGES
721 ++USER_STATISTICS
722 + VIEWS
723 + show tables from INFORMATION_SCHEMA like 'T%';
724 + Tables_in_information_schema (T%)
725 + TABLES
726 + TABLE_CONSTRAINTS
727 + TABLE_PRIVILEGES
728 ++TABLE_STATISTICS
729 + TRIGGERS
730 + create database `inf%`;
731 + create database mbase;
732 +diff -r 592f6c3641ba mysql-test/r/mysqlshow.result
733 +--- a/mysql-test/r/mysqlshow.result Wed Jul 29 13:33:34 2009 -0700
734 ++++ b/mysql-test/r/mysqlshow.result Wed Jul 29 13:34:11 2009 -0700
735 +@@ -80,10 +80,12 @@
736 + | Tables |
737 + +---------------------------------------+
738 + | CHARACTER_SETS |
739 ++| CLIENT_STATISTICS |
740 + | COLLATIONS |
741 + | COLLATION_CHARACTER_SET_APPLICABILITY |
742 + | COLUMNS |
743 + | COLUMN_PRIVILEGES |
744 ++| INDEX_STATISTICS |
745 + | KEY_COLUMN_USAGE |
746 + | PROFILING |
747 + | ROUTINES |
748 +@@ -93,8 +95,10 @@
749 + | TABLES |
750 + | TABLE_CONSTRAINTS |
751 + | TABLE_PRIVILEGES |
752 ++| TABLE_STATISTICS |
753 + | TRIGGERS |
754 + | USER_PRIVILEGES |
755 ++| USER_STATISTICS |
756 + | VIEWS |
757 + +---------------------------------------+
758 + Database: INFORMATION_SCHEMA
759 +@@ -102,10 +106,12 @@
760 + | Tables |
761 + +---------------------------------------+
762 + | CHARACTER_SETS |
763 ++| CLIENT_STATISTICS |
764 + | COLLATIONS |
765 + | COLLATION_CHARACTER_SET_APPLICABILITY |
766 + | COLUMNS |
767 + | COLUMN_PRIVILEGES |
768 ++| INDEX_STATISTICS |
769 + | KEY_COLUMN_USAGE |
770 + | PROFILING |
771 + | ROUTINES |
772 +@@ -115,8 +121,10 @@
773 + | TABLES |
774 + | TABLE_CONSTRAINTS |
775 + | TABLE_PRIVILEGES |
776 ++| TABLE_STATISTICS |
777 + | TRIGGERS |
778 + | USER_PRIVILEGES |
779 ++| USER_STATISTICS |
780 + | VIEWS |
781 + +---------------------------------------+
782 + Wildcard: inf_rmation_schema
783 +diff -r 592f6c3641ba mysys/Makefile.in
784 +--- a/mysys/Makefile.in Wed Jul 29 13:33:34 2009 -0700
785 ++++ b/mysys/Makefile.in Wed Jul 29 13:34:11 2009 -0700
786 +@@ -228,6 +228,7 @@
787 + LIBDL = @LIBDL@
788 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
789 + LIBOBJS = @LIBOBJS@
790 ++LIBRT = @LIBRT@
791 + LIBS = @LIBS@
792 + LIBTOOL = @LIBTOOL@
793 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
794 +diff -r 592f6c3641ba ndb/Makefile.in
795 +--- a/ndb/Makefile.in Wed Jul 29 13:33:34 2009 -0700
796 ++++ b/ndb/Makefile.in Wed Jul 29 13:34:11 2009 -0700
797 +@@ -171,6 +171,7 @@
798 + LIBDL = @LIBDL@
799 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
800 + LIBOBJS = @LIBOBJS@
801 ++LIBRT = @LIBRT@
802 + LIBS = @LIBS@
803 + LIBTOOL = @LIBTOOL@
804 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
805 +diff -r 592f6c3641ba ndb/docs/Makefile.in
806 +--- a/ndb/docs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
807 ++++ b/ndb/docs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
808 +@@ -149,6 +149,7 @@
809 + LIBDL = @LIBDL@
810 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
811 + LIBOBJS = @LIBOBJS@
812 ++LIBRT = @LIBRT@
813 + LIBS = @LIBS@
814 + LIBTOOL = @LIBTOOL@
815 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
816 +diff -r 592f6c3641ba ndb/include/Makefile.in
817 +--- a/ndb/include/Makefile.in Wed Jul 29 13:33:34 2009 -0700
818 ++++ b/ndb/include/Makefile.in Wed Jul 29 13:34:11 2009 -0700
819 +@@ -179,6 +179,7 @@
820 + LIBDL = @LIBDL@
821 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
822 + LIBOBJS = @LIBOBJS@
823 ++LIBRT = @LIBRT@
824 + LIBS = @LIBS@
825 + LIBTOOL = @LIBTOOL@
826 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
827 +diff -r 592f6c3641ba ndb/src/Makefile.in
828 +--- a/ndb/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
829 ++++ b/ndb/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
830 +@@ -204,6 +204,7 @@
831 + LIBDL = @LIBDL@
832 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
833 + LIBOBJS = @LIBOBJS@
834 ++LIBRT = @LIBRT@
835 + LIBS = @LIBS@
836 + LIBTOOL = @LIBTOOL@
837 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
838 +diff -r 592f6c3641ba ndb/src/common/Makefile.in
839 +--- a/ndb/src/common/Makefile.in Wed Jul 29 13:33:34 2009 -0700
840 ++++ b/ndb/src/common/Makefile.in Wed Jul 29 13:34:11 2009 -0700
841 +@@ -174,6 +174,7 @@
842 + LIBDL = @LIBDL@
843 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
844 + LIBOBJS = @LIBOBJS@
845 ++LIBRT = @LIBRT@
846 + LIBS = @LIBS@
847 + LIBTOOL = @LIBTOOL@
848 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
849 +diff -r 592f6c3641ba ndb/src/common/debugger/Makefile.in
850 +--- a/ndb/src/common/debugger/Makefile.in Wed Jul 29 13:33:34 2009 -0700
851 ++++ b/ndb/src/common/debugger/Makefile.in Wed Jul 29 13:34:11 2009 -0700
852 +@@ -206,6 +206,7 @@
853 + LIBDL = @LIBDL@
854 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
855 + LIBOBJS = @LIBOBJS@
856 ++LIBRT = @LIBRT@
857 + LIBS = @LIBS@
858 + LIBTOOL = @LIBTOOL@
859 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
860 +diff -r 592f6c3641ba ndb/src/common/debugger/signaldata/Makefile.in
861 +--- a/ndb/src/common/debugger/signaldata/Makefile.in Wed Jul 29 13:33:34 2009 -0700
862 ++++ b/ndb/src/common/debugger/signaldata/Makefile.in Wed Jul 29 13:34:11 2009 -0700
863 +@@ -211,6 +211,7 @@
864 + LIBDL = @LIBDL@
865 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
866 + LIBOBJS = @LIBOBJS@
867 ++LIBRT = @LIBRT@
868 + LIBS = @LIBS@
869 + LIBTOOL = @LIBTOOL@
870 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
871 +diff -r 592f6c3641ba ndb/src/common/logger/Makefile.in
872 +--- a/ndb/src/common/logger/Makefile.in Wed Jul 29 13:33:34 2009 -0700
873 ++++ b/ndb/src/common/logger/Makefile.in Wed Jul 29 13:34:11 2009 -0700
874 +@@ -197,6 +197,7 @@
875 + LIBDL = @LIBDL@
876 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
877 + LIBOBJS = @LIBOBJS@
878 ++LIBRT = @LIBRT@
879 + LIBS = @LIBS@
880 + LIBTOOL = @LIBTOOL@
881 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
882 +diff -r 592f6c3641ba ndb/src/common/mgmcommon/Makefile.in
883 +--- a/ndb/src/common/mgmcommon/Makefile.in Wed Jul 29 13:33:34 2009 -0700
884 ++++ b/ndb/src/common/mgmcommon/Makefile.in Wed Jul 29 13:34:11 2009 -0700
885 +@@ -211,6 +211,7 @@
886 + LIBDL = @LIBDL@
887 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
888 + LIBOBJS = @LIBOBJS@
889 ++LIBRT = @LIBRT@
890 + LIBS = @LIBS@
891 + LIBTOOL = @LIBTOOL@
892 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
893 +diff -r 592f6c3641ba ndb/src/common/portlib/Makefile.in
894 +--- a/ndb/src/common/portlib/Makefile.in Wed Jul 29 13:33:34 2009 -0700
895 ++++ b/ndb/src/common/portlib/Makefile.in Wed Jul 29 13:34:11 2009 -0700
896 +@@ -222,6 +222,7 @@
897 + LIBDL = @LIBDL@
898 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
899 + LIBOBJS = @LIBOBJS@
900 ++LIBRT = @LIBRT@
901 + LIBS = @LIBS@
902 + LIBTOOL = @LIBTOOL@
903 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
904 +diff -r 592f6c3641ba ndb/src/common/transporter/Makefile.in
905 +--- a/ndb/src/common/transporter/Makefile.in Wed Jul 29 13:33:34 2009 -0700
906 ++++ b/ndb/src/common/transporter/Makefile.in Wed Jul 29 13:34:11 2009 -0700
907 +@@ -197,6 +197,7 @@
908 + LIBDL = @LIBDL@
909 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
910 + LIBOBJS = @LIBOBJS@
911 ++LIBRT = @LIBRT@
912 + LIBS = @LIBS@
913 + LIBTOOL = @LIBTOOL@
914 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
915 +diff -r 592f6c3641ba ndb/src/common/util/Makefile.in
916 +--- a/ndb/src/common/util/Makefile.in Wed Jul 29 13:33:34 2009 -0700
917 ++++ b/ndb/src/common/util/Makefile.in Wed Jul 29 13:34:11 2009 -0700
918 +@@ -217,6 +217,7 @@
919 + LIBDL = @LIBDL@
920 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
921 + LIBOBJS = @LIBOBJS@
922 ++LIBRT = @LIBRT@
923 + LIBS = @LIBS@
924 + LIBTOOL = @LIBTOOL@
925 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
926 +diff -r 592f6c3641ba ndb/src/cw/Makefile.in
927 +--- a/ndb/src/cw/Makefile.in Wed Jul 29 13:33:34 2009 -0700
928 ++++ b/ndb/src/cw/Makefile.in Wed Jul 29 13:34:11 2009 -0700
929 +@@ -156,6 +156,7 @@
930 + LIBDL = @LIBDL@
931 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
932 + LIBOBJS = @LIBOBJS@
933 ++LIBRT = @LIBRT@
934 + LIBS = @LIBS@
935 + LIBTOOL = @LIBTOOL@
936 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
937 +diff -r 592f6c3641ba ndb/src/cw/cpcd/Makefile.in
938 +--- a/ndb/src/cw/cpcd/Makefile.in Wed Jul 29 13:33:34 2009 -0700
939 ++++ b/ndb/src/cw/cpcd/Makefile.in Wed Jul 29 13:34:11 2009 -0700
940 +@@ -207,6 +207,7 @@
941 + LIBDL = @LIBDL@
942 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
943 + LIBOBJS = @LIBOBJS@
944 ++LIBRT = @LIBRT@
945 + LIBS = @LIBS@
946 + LIBTOOL = @LIBTOOL@
947 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
948 +diff -r 592f6c3641ba ndb/src/kernel/Makefile.in
949 +--- a/ndb/src/kernel/Makefile.in Wed Jul 29 13:33:34 2009 -0700
950 ++++ b/ndb/src/kernel/Makefile.in Wed Jul 29 13:34:11 2009 -0700
951 +@@ -227,6 +227,7 @@
952 + LIBDL = @LIBDL@
953 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
954 + LIBOBJS = @LIBOBJS@
955 ++LIBRT = @LIBRT@
956 + LIBS = @LIBS@
957 + LIBTOOL = @LIBTOOL@
958 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
959 +diff -r 592f6c3641ba ndb/src/kernel/blocks/Makefile.in
960 +--- a/ndb/src/kernel/blocks/Makefile.in Wed Jul 29 13:33:34 2009 -0700
961 ++++ b/ndb/src/kernel/blocks/Makefile.in Wed Jul 29 13:34:11 2009 -0700
962 +@@ -156,6 +156,7 @@
963 + LIBDL = @LIBDL@
964 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
965 + LIBOBJS = @LIBOBJS@
966 ++LIBRT = @LIBRT@
967 + LIBS = @LIBS@
968 + LIBTOOL = @LIBTOOL@
969 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
970 +diff -r 592f6c3641ba ndb/src/kernel/blocks/backup/Makefile.in
971 +--- a/ndb/src/kernel/blocks/backup/Makefile.in Wed Jul 29 13:33:34 2009 -0700
972 ++++ b/ndb/src/kernel/blocks/backup/Makefile.in Wed Jul 29 13:34:11 2009 -0700
973 +@@ -196,6 +196,7 @@
974 + LIBDL = @LIBDL@
975 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
976 + LIBOBJS = @LIBOBJS@
977 ++LIBRT = @LIBRT@
978 + LIBS = @LIBS@
979 + LIBTOOL = @LIBTOOL@
980 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
981 +diff -r 592f6c3641ba ndb/src/kernel/blocks/cmvmi/Makefile.in
982 +--- a/ndb/src/kernel/blocks/cmvmi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
983 ++++ b/ndb/src/kernel/blocks/cmvmi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
984 +@@ -196,6 +196,7 @@
985 + LIBDL = @LIBDL@
986 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
987 + LIBOBJS = @LIBOBJS@
988 ++LIBRT = @LIBRT@
989 + LIBS = @LIBS@
990 + LIBTOOL = @LIBTOOL@
991 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
992 +diff -r 592f6c3641ba ndb/src/kernel/blocks/dbacc/Makefile.in
993 +--- a/ndb/src/kernel/blocks/dbacc/Makefile.in Wed Jul 29 13:33:34 2009 -0700
994 ++++ b/ndb/src/kernel/blocks/dbacc/Makefile.in Wed Jul 29 13:34:11 2009 -0700
995 +@@ -196,6 +196,7 @@
996 + LIBDL = @LIBDL@
997 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
998 + LIBOBJS = @LIBOBJS@
999 ++LIBRT = @LIBRT@
1000 + LIBS = @LIBS@
1001 + LIBTOOL = @LIBTOOL@
1002 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1003 +diff -r 592f6c3641ba ndb/src/kernel/blocks/dbdict/Makefile.in
1004 +--- a/ndb/src/kernel/blocks/dbdict/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1005 ++++ b/ndb/src/kernel/blocks/dbdict/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1006 +@@ -206,6 +206,7 @@
1007 + LIBDL = @LIBDL@
1008 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1009 + LIBOBJS = @LIBOBJS@
1010 ++LIBRT = @LIBRT@
1011 + LIBS = @LIBS@
1012 + LIBTOOL = @LIBTOOL@
1013 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1014 +diff -r 592f6c3641ba ndb/src/kernel/blocks/dbdih/Makefile.in
1015 +--- a/ndb/src/kernel/blocks/dbdih/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1016 ++++ b/ndb/src/kernel/blocks/dbdih/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1017 +@@ -203,6 +203,7 @@
1018 + LIBDL = @LIBDL@
1019 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1020 + LIBOBJS = @LIBOBJS@
1021 ++LIBRT = @LIBRT@
1022 + LIBS = @LIBS@
1023 + LIBTOOL = @LIBTOOL@
1024 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1025 +diff -r 592f6c3641ba ndb/src/kernel/blocks/dblqh/Makefile.in
1026 +--- a/ndb/src/kernel/blocks/dblqh/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1027 ++++ b/ndb/src/kernel/blocks/dblqh/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1028 +@@ -204,6 +204,7 @@
1029 + LIBDL = @LIBDL@
1030 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1031 + LIBOBJS = @LIBOBJS@
1032 ++LIBRT = @LIBRT@
1033 + LIBS = @LIBS@
1034 + LIBTOOL = @LIBTOOL@
1035 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1036 +diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtc/Makefile.in
1037 +--- a/ndb/src/kernel/blocks/dbtc/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1038 ++++ b/ndb/src/kernel/blocks/dbtc/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1039 +@@ -196,6 +196,7 @@
1040 + LIBDL = @LIBDL@
1041 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1042 + LIBOBJS = @LIBOBJS@
1043 ++LIBRT = @LIBRT@
1044 + LIBS = @LIBS@
1045 + LIBTOOL = @LIBTOOL@
1046 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1047 +diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtup/Makefile.in
1048 +--- a/ndb/src/kernel/blocks/dbtup/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1049 ++++ b/ndb/src/kernel/blocks/dbtup/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1050 +@@ -204,6 +204,7 @@
1051 + LIBDL = @LIBDL@
1052 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1053 + LIBOBJS = @LIBOBJS@
1054 ++LIBRT = @LIBRT@
1055 + LIBS = @LIBS@
1056 + LIBTOOL = @LIBTOOL@
1057 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1058 +diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtux/Makefile.in
1059 +--- a/ndb/src/kernel/blocks/dbtux/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1060 ++++ b/ndb/src/kernel/blocks/dbtux/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1061 +@@ -199,6 +199,7 @@
1062 + LIBDL = @LIBDL@
1063 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1064 + LIBOBJS = @LIBOBJS@
1065 ++LIBRT = @LIBRT@
1066 + LIBS = @LIBS@
1067 + LIBTOOL = @LIBTOOL@
1068 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1069 +diff -r 592f6c3641ba ndb/src/kernel/blocks/dbutil/Makefile.in
1070 +--- a/ndb/src/kernel/blocks/dbutil/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1071 ++++ b/ndb/src/kernel/blocks/dbutil/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1072 +@@ -196,6 +196,7 @@
1073 + LIBDL = @LIBDL@
1074 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1075 + LIBOBJS = @LIBOBJS@
1076 ++LIBRT = @LIBRT@
1077 + LIBS = @LIBS@
1078 + LIBTOOL = @LIBTOOL@
1079 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1080 +diff -r 592f6c3641ba ndb/src/kernel/blocks/ndbcntr/Makefile.in
1081 +--- a/ndb/src/kernel/blocks/ndbcntr/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1082 ++++ b/ndb/src/kernel/blocks/ndbcntr/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1083 +@@ -197,6 +197,7 @@
1084 + LIBDL = @LIBDL@
1085 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1086 + LIBOBJS = @LIBOBJS@
1087 ++LIBRT = @LIBRT@
1088 + LIBS = @LIBS@
1089 + LIBTOOL = @LIBTOOL@
1090 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1091 +diff -r 592f6c3641ba ndb/src/kernel/blocks/ndbfs/Makefile.in
1092 +--- a/ndb/src/kernel/blocks/ndbfs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1093 ++++ b/ndb/src/kernel/blocks/ndbfs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1094 +@@ -197,6 +197,7 @@
1095 + LIBDL = @LIBDL@
1096 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1097 + LIBOBJS = @LIBOBJS@
1098 ++LIBRT = @LIBRT@
1099 + LIBS = @LIBS@
1100 + LIBTOOL = @LIBTOOL@
1101 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1102 +diff -r 592f6c3641ba ndb/src/kernel/blocks/qmgr/Makefile.in
1103 +--- a/ndb/src/kernel/blocks/qmgr/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1104 ++++ b/ndb/src/kernel/blocks/qmgr/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1105 +@@ -196,6 +196,7 @@
1106 + LIBDL = @LIBDL@
1107 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1108 + LIBOBJS = @LIBOBJS@
1109 ++LIBRT = @LIBRT@
1110 + LIBS = @LIBS@
1111 + LIBTOOL = @LIBTOOL@
1112 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1113 +diff -r 592f6c3641ba ndb/src/kernel/blocks/suma/Makefile.in
1114 +--- a/ndb/src/kernel/blocks/suma/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1115 ++++ b/ndb/src/kernel/blocks/suma/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1116 +@@ -196,6 +196,7 @@
1117 + LIBDL = @LIBDL@
1118 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1119 + LIBOBJS = @LIBOBJS@
1120 ++LIBRT = @LIBRT@
1121 + LIBS = @LIBS@
1122 + LIBTOOL = @LIBTOOL@
1123 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1124 +diff -r 592f6c3641ba ndb/src/kernel/blocks/trix/Makefile.in
1125 +--- a/ndb/src/kernel/blocks/trix/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1126 ++++ b/ndb/src/kernel/blocks/trix/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1127 +@@ -196,6 +196,7 @@
1128 + LIBDL = @LIBDL@
1129 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1130 + LIBOBJS = @LIBOBJS@
1131 ++LIBRT = @LIBRT@
1132 + LIBS = @LIBS@
1133 + LIBTOOL = @LIBTOOL@
1134 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1135 +diff -r 592f6c3641ba ndb/src/kernel/error/Makefile.in
1136 +--- a/ndb/src/kernel/error/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1137 ++++ b/ndb/src/kernel/error/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1138 +@@ -206,6 +206,7 @@
1139 + LIBDL = @LIBDL@
1140 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1141 + LIBOBJS = @LIBOBJS@
1142 ++LIBRT = @LIBRT@
1143 + LIBS = @LIBS@
1144 + LIBTOOL = @LIBTOOL@
1145 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1146 +diff -r 592f6c3641ba ndb/src/kernel/vm/Makefile.in
1147 +--- a/ndb/src/kernel/vm/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1148 ++++ b/ndb/src/kernel/vm/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1149 +@@ -207,6 +207,7 @@
1150 + LIBDL = @LIBDL@
1151 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1152 + LIBOBJS = @LIBOBJS@
1153 ++LIBRT = @LIBRT@
1154 + LIBS = @LIBS@
1155 + LIBTOOL = @LIBTOOL@
1156 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1157 +diff -r 592f6c3641ba ndb/src/mgmapi/Makefile.in
1158 +--- a/ndb/src/mgmapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1159 ++++ b/ndb/src/mgmapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1160 +@@ -205,6 +205,7 @@
1161 + LIBDL = @LIBDL@
1162 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1163 + LIBOBJS = @LIBOBJS@
1164 ++LIBRT = @LIBRT@
1165 + LIBS = @LIBS@
1166 + LIBTOOL = @LIBTOOL@
1167 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1168 +diff -r 592f6c3641ba ndb/src/mgmclient/Makefile.in
1169 +--- a/ndb/src/mgmclient/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1170 ++++ b/ndb/src/mgmclient/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1171 +@@ -216,6 +216,7 @@
1172 + LIBDL = @LIBDL@
1173 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1174 + LIBOBJS = @LIBOBJS@
1175 ++LIBRT = @LIBRT@
1176 + LIBS = @LIBS@
1177 + LIBTOOL = @LIBTOOL@
1178 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1179 +diff -r 592f6c3641ba ndb/src/mgmsrv/Makefile.in
1180 +--- a/ndb/src/mgmsrv/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1181 ++++ b/ndb/src/mgmsrv/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1182 +@@ -213,6 +213,7 @@
1183 + LIBDL = @LIBDL@
1184 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1185 + LIBOBJS = @LIBOBJS@
1186 ++LIBRT = @LIBRT@
1187 + LIBS = @LIBS@
1188 + LIBTOOL = @LIBTOOL@
1189 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1190 +diff -r 592f6c3641ba ndb/src/ndbapi/Makefile.in
1191 +--- a/ndb/src/ndbapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1192 ++++ b/ndb/src/ndbapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1193 +@@ -215,6 +215,7 @@
1194 + LIBDL = @LIBDL@
1195 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1196 + LIBOBJS = @LIBOBJS@
1197 ++LIBRT = @LIBRT@
1198 + LIBS = @LIBS@
1199 + LIBTOOL = @LIBTOOL@
1200 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1201 +diff -r 592f6c3641ba ndb/test/Makefile.in
1202 +--- a/ndb/test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1203 ++++ b/ndb/test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1204 +@@ -156,6 +156,7 @@
1205 + LIBDL = @LIBDL@
1206 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1207 + LIBOBJS = @LIBOBJS@
1208 ++LIBRT = @LIBRT@
1209 + LIBS = @LIBS@
1210 + LIBTOOL = @LIBTOOL@
1211 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1212 +diff -r 592f6c3641ba ndb/test/ndbapi/Makefile.in
1213 +--- a/ndb/test/ndbapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1214 ++++ b/ndb/test/ndbapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1215 +@@ -595,6 +595,7 @@
1216 + LIBDL = @LIBDL@
1217 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1218 + LIBOBJS = @LIBOBJS@
1219 ++LIBRT = @LIBRT@
1220 + LIBS = @LIBS@
1221 + LIBTOOL = @LIBTOOL@
1222 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1223 +diff -r 592f6c3641ba ndb/test/ndbapi/bank/Makefile.in
1224 +--- a/ndb/test/ndbapi/bank/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1225 ++++ b/ndb/test/ndbapi/bank/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1226 +@@ -282,6 +282,7 @@
1227 + LIBDL = @LIBDL@
1228 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1229 + LIBOBJS = @LIBOBJS@
1230 ++LIBRT = @LIBRT@
1231 + LIBS = @LIBS@
1232 + LIBTOOL = @LIBTOOL@
1233 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1234 +diff -r 592f6c3641ba ndb/test/run-test/Makefile.in
1235 +--- a/ndb/test/run-test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1236 ++++ b/ndb/test/run-test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1237 +@@ -243,6 +243,7 @@
1238 + LIBDL = @LIBDL@
1239 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1240 + LIBOBJS = @LIBOBJS@
1241 ++LIBRT = @LIBRT@
1242 + LIBS = @LIBS@
1243 + LIBTOOL = @LIBTOOL@
1244 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1245 +diff -r 592f6c3641ba ndb/test/src/Makefile.in
1246 +--- a/ndb/test/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1247 ++++ b/ndb/test/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1248 +@@ -213,6 +213,7 @@
1249 + LIBDL = @LIBDL@
1250 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1251 + LIBOBJS = @LIBOBJS@
1252 ++LIBRT = @LIBRT@
1253 + LIBS = @LIBS@
1254 + LIBTOOL = @LIBTOOL@
1255 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1256 +diff -r 592f6c3641ba ndb/test/tools/Makefile.in
1257 +--- a/ndb/test/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1258 ++++ b/ndb/test/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1259 +@@ -325,6 +325,7 @@
1260 + LIBDL = @LIBDL@
1261 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1262 + LIBOBJS = @LIBOBJS@
1263 ++LIBRT = @LIBRT@
1264 + LIBS = @LIBS@
1265 + LIBTOOL = @LIBTOOL@
1266 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1267 +diff -r 592f6c3641ba ndb/tools/Makefile.in
1268 +--- a/ndb/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1269 ++++ b/ndb/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1270 +@@ -344,6 +344,7 @@
1271 + LIBDL = @LIBDL@
1272 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1273 + LIBOBJS = @LIBOBJS@
1274 ++LIBRT = @LIBRT@
1275 + LIBS = @LIBS@
1276 + LIBTOOL = @LIBTOOL@
1277 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1278 +diff -r 592f6c3641ba netware/Makefile.in
1279 +--- a/netware/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1280 ++++ b/netware/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1281 +@@ -199,6 +199,7 @@
1282 + LIBDL = @LIBDL@
1283 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1284 + LIBOBJS = @LIBOBJS@
1285 ++LIBRT = @LIBRT@
1286 + LIBS = @LIBS@
1287 + LIBTOOL = @LIBTOOL@
1288 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1289 +diff -r 592f6c3641ba patch_info/userstats.info
1290 +--- /dev/null Thu Jan 01 00:00:00 1970 +0000
1291 ++++ b/patch_info/userstats.info Wed Jul 29 13:34:11 2009 -0700
1292 +@@ -0,0 +1,14 @@
1293 ++File=userstatsv2.patch
1294 ++Name=SHOW USER/TABLE/INDEX statistics
1295 ++Version=V2
1296 ++Author=Google
1297 ++License=GPL
1298 ++Comment=Added INFORMATION_SCHEMA.*_STATISTICS
1299 ++2008-12-01
1300 ++YK: fix behavior for prepared statements
1301 ++
1302 ++2008-11-26
1303 ++YK: add switch variable "userstat_running" to control INFORMATION_SCHEMA.*_STATISTICS (default:OFF)
1304 ++
1305 ++2008-12-09
1306 ++YK: fixed "Row_sent: 0" problem at microslow_innodb.patch
1307 +diff -r 592f6c3641ba pstack/Makefile.in
1308 +--- a/pstack/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1309 ++++ b/pstack/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1310 +@@ -196,6 +196,7 @@
1311 + LIBDL = @LIBDL@
1312 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1313 + LIBOBJS = @LIBOBJS@
1314 ++LIBRT = @LIBRT@
1315 + LIBS = @LIBS@
1316 + LIBTOOL = @LIBTOOL@
1317 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1318 +diff -r 592f6c3641ba pstack/aout/Makefile.in
1319 +--- a/pstack/aout/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1320 ++++ b/pstack/aout/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1321 +@@ -134,6 +134,7 @@
1322 + LIBDL = @LIBDL@
1323 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1324 + LIBOBJS = @LIBOBJS@
1325 ++LIBRT = @LIBRT@
1326 + LIBS = @LIBS@
1327 + LIBTOOL = @LIBTOOL@
1328 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1329 +diff -r 592f6c3641ba regex/Makefile.in
1330 +--- a/regex/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1331 ++++ b/regex/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1332 +@@ -180,6 +180,7 @@
1333 + LIBDL = @LIBDL@
1334 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1335 + LIBOBJS = @LIBOBJS@
1336 ++LIBRT = @LIBRT@
1337 + LIBS = @LIBS@
1338 + LIBTOOL = @LIBTOOL@
1339 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1340 +diff -r 592f6c3641ba scripts/Makefile.in
1341 +--- a/scripts/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1342 ++++ b/scripts/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1343 +@@ -176,6 +176,7 @@
1344 + LIBDL = @LIBDL@
1345 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1346 + LIBOBJS = @LIBOBJS@
1347 ++LIBRT = @LIBRT@
1348 + LIBS = @LIBS@
1349 + LIBTOOL = @LIBTOOL@
1350 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1351 +diff -r 592f6c3641ba server-tools/Makefile.in
1352 +--- a/server-tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1353 ++++ b/server-tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1354 +@@ -155,6 +155,7 @@
1355 + LIBDL = @LIBDL@
1356 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1357 + LIBOBJS = @LIBOBJS@
1358 ++LIBRT = @LIBRT@
1359 + LIBS = @LIBS@
1360 + LIBTOOL = @LIBTOOL@
1361 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1362 +diff -r 592f6c3641ba server-tools/instance-manager/Makefile.in
1363 +--- a/server-tools/instance-manager/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1364 ++++ b/server-tools/instance-manager/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1365 +@@ -205,6 +205,7 @@
1366 + LIBDL = @LIBDL@
1367 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1368 + LIBOBJS = @LIBOBJS@
1369 ++LIBRT = @LIBRT@
1370 + LIBS = @LIBS@
1371 + LIBTOOL = @LIBTOOL@
1372 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1373 +diff -r 592f6c3641ba sql/Makefile.in
1374 +--- a/sql/Makefile.in Wed Jul 29 13:33:34 2009 -0700
1375 ++++ b/sql/Makefile.in Wed Jul 29 13:34:11 2009 -0700
1376 +@@ -274,6 +274,7 @@
1377 + LIBDL = @LIBDL@
1378 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
1379 + LIBOBJS = @LIBOBJS@
1380 ++LIBRT = @LIBRT@
1381 + LIBS = @LIBS@
1382 + LIBTOOL = @LIBTOOL@
1383 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
1384 +diff -r 592f6c3641ba sql/ha_innodb.cc
1385 +--- a/sql/ha_innodb.cc Wed Jul 29 13:33:34 2009 -0700
1386 ++++ b/sql/ha_innodb.cc Wed Jul 29 13:34:11 2009 -0700
1387 +@@ -3341,6 +3341,8 @@
1388 +
1389 + error = row_insert_for_mysql((byte*) record, prebuilt);
1390 +
1391 ++ if (error == DB_SUCCESS) rows_changed++;
1392 ++
1393 + if (error == DB_SUCCESS && auto_inc_used) {
1394 +
1395 + /* Fetch the value that was set in the autoincrement field */
1396 +@@ -3613,6 +3615,8 @@
1397 + }
1398 + }
1399 +
1400 ++ if (error == DB_SUCCESS) rows_changed++;
1401 ++
1402 + innodb_srv_conc_exit_innodb(prebuilt->trx);
1403 +
1404 + error = convert_error_code_to_mysql(error, user_thd);
1405 +@@ -3661,6 +3665,8 @@
1406 +
1407 + error = row_update_for_mysql((byte*) record, prebuilt);
1408 +
1409 ++ if (error == DB_SUCCESS) rows_changed++;
1410 ++
1411 + innodb_srv_conc_exit_innodb(prebuilt->trx);
1412 +
1413 + error = convert_error_code_to_mysql(error, user_thd);
1414 +@@ -4092,6 +4098,9 @@
1415 + if (ret == DB_SUCCESS) {
1416 + error = 0;
1417 + table->status = 0;
1418 ++ rows_read++;
1419 ++ if (active_index >= 0 && active_index < MAX_KEY)
1420 ++ index_rows_read[active_index]++;
1421 +
1422 + } else if (ret == DB_RECORD_NOT_FOUND) {
1423 + error = HA_ERR_END_OF_FILE;
1424 +diff -r 592f6c3641ba sql/ha_myisam.cc
1425 +--- a/sql/ha_myisam.cc Wed Jul 29 13:33:34 2009 -0700
1426 ++++ b/sql/ha_myisam.cc Wed Jul 29 13:34:11 2009 -0700
1427 +@@ -670,7 +670,9 @@
1428 + if ((error= update_auto_increment()))
1429 + return error;
1430 + }
1431 +- return mi_write(file,buf);
1432 ++ int error=mi_write(file,buf);
1433 ++ if (!error) rows_changed++;
1434 ++ return error;
1435 + }
1436 +
1437 + int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
1438 +@@ -1521,13 +1523,17 @@
1439 + statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status);
1440 + if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1441 + table->timestamp_field->set_time();
1442 +- return mi_update(file,old_data,new_data);
1443 ++ int error=mi_update(file,old_data,new_data);
1444 ++ if (!error) rows_changed++;
1445 ++ return error;
1446 + }
1447 +
1448 + int ha_myisam::delete_row(const byte * buf)
1449 + {
1450 + statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status);
1451 +- return mi_delete(file,buf);
1452 ++ int error=mi_delete(file,buf);
1453 ++ if (!error) rows_changed++;
1454 ++ return error;
1455 + }
1456 +
1457 + int ha_myisam::index_read(byte * buf, const byte * key,
1458 +@@ -1538,6 +1544,13 @@
1459 + &LOCK_status);
1460 + int error=mi_rkey(file,buf,active_index, key, key_len, find_flag);
1461 + table->status=error ? STATUS_NOT_FOUND: 0;
1462 ++ if (!error) {
1463 ++ rows_read++;
1464 ++
1465 ++ int inx = (active_index == -1) ? file->lastinx : active_index;
1466 ++ if (inx >= 0 && inx < MAX_KEY)
1467 ++ index_rows_read[inx]++;
1468 ++ }
1469 + return error;
1470 + }
1471 +
1472 +@@ -1548,6 +1561,13 @@
1473 + &LOCK_status);
1474 + int error=mi_rkey(file,buf,index, key, key_len, find_flag);
1475 + table->status=error ? STATUS_NOT_FOUND: 0;
1476 ++ if (!error) {
1477 ++ rows_read++;
1478 ++
1479 ++ int inx = index;
1480 ++ if (inx >= 0 && inx < MAX_KEY)
1481 ++ index_rows_read[inx]++;
1482 ++ }
1483 + return error;
1484 + }
1485 +
1486 +@@ -1558,6 +1578,13 @@
1487 + &LOCK_status);
1488 + int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
1489 + table->status=error ? STATUS_NOT_FOUND: 0;
1490 ++ if (!error) {
1491 ++ rows_read++;
1492 ++
1493 ++ int inx = (active_index == -1) ? file->lastinx : active_index;
1494 ++ if (inx >= 0 && inx < MAX_KEY)
1495 ++ index_rows_read[inx]++;
1496 ++ }
1497 + return error;
1498 + }
1499 +
1500 +@@ -1568,6 +1595,13 @@
1501 + &LOCK_status);
1502 + int error=mi_rnext(file,buf,active_index);
1503 + table->status=error ? STATUS_NOT_FOUND: 0;
1504 ++ if (!error) {
1505 ++ rows_read++;
1506 ++
1507 ++ int inx = (active_index == -1) ? file->lastinx : active_index;
1508 ++ if (inx >= 0 && inx < MAX_KEY)
1509 ++ index_rows_read[inx]++;
1510 ++ }
1511 + return error;
1512 + }
1513 +
1514 +@@ -1578,6 +1612,13 @@
1515 + &LOCK_status);
1516 + int error=mi_rprev(file,buf, active_index);
1517 + table->status=error ? STATUS_NOT_FOUND: 0;
1518 ++ if (!error) {
1519 ++ rows_read++;
1520 ++
1521 ++ int inx = (active_index == -1) ? file->lastinx : active_index;
1522 ++ if (inx >= 0 && inx < MAX_KEY)
1523 ++ index_rows_read[inx]++;
1524 ++ }
1525 + return error;
1526 + }
1527 +
1528 +@@ -1588,6 +1629,13 @@
1529 + &LOCK_status);
1530 + int error=mi_rfirst(file, buf, active_index);
1531 + table->status=error ? STATUS_NOT_FOUND: 0;
1532 ++ if (!error) {
1533 ++ rows_read++;
1534 ++
1535 ++ int inx = (active_index == -1) ? file->lastinx : active_index;
1536 ++ if (inx >= 0 && inx < MAX_KEY)
1537 ++ index_rows_read[inx]++;
1538 ++ }
1539 + return error;
1540 + }
1541 +
1542 +@@ -1598,6 +1646,13 @@
1543 + &LOCK_status);
1544 + int error=mi_rlast(file, buf, active_index);
1545 + table->status=error ? STATUS_NOT_FOUND: 0;
1546 ++ if (!error) {
1547 ++ rows_read++;
1548 ++
1549 ++ int inx = (active_index == -1) ? file->lastinx : active_index;
1550 ++ if (inx >= 0 && inx < MAX_KEY)
1551 ++ index_rows_read[inx]++;
1552 ++ }
1553 + return error;
1554 + }
1555 +
1556 +@@ -1614,6 +1669,13 @@
1557 + error= mi_rnext_same(file,buf);
1558 + } while (error == HA_ERR_RECORD_DELETED);
1559 + table->status=error ? STATUS_NOT_FOUND: 0;
1560 ++ if (!error) {
1561 ++ rows_read++;
1562 ++
1563 ++ int inx = (active_index == -1) ? file->lastinx : active_index;
1564 ++ if (inx >= 0 && inx < MAX_KEY)
1565 ++ index_rows_read[inx]++;
1566 ++ }
1567 + return error;
1568 + }
1569 +
1570 +@@ -1631,6 +1693,7 @@
1571 + &LOCK_status);
1572 + int error=mi_scan(file, buf);
1573 + table->status=error ? STATUS_NOT_FOUND: 0;
1574 ++ if (!error) rows_read++;
1575 + return error;
1576 + }
1577 +
1578 +@@ -1645,6 +1708,7 @@
1579 + &LOCK_status);
1580 + int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
1581 + table->status=error ? STATUS_NOT_FOUND: 0;
1582 ++ if (!error) rows_read++;
1583 + return error;
1584 + }
1585 +
1586 +diff -r 592f6c3641ba sql/handler.cc
1587 +--- a/sql/handler.cc Wed Jul 29 13:33:34 2009 -0700
1588 ++++ b/sql/handler.cc Wed Jul 29 13:34:11 2009 -0700
1589 +@@ -726,6 +726,8 @@
1590 + if (cookie)
1591 + tc_log->unlog(cookie, xid);
1592 + DBUG_EXECUTE_IF("crash_commit_after", abort(););
1593 ++ if (is_real_trans)
1594 ++ thd->diff_commit_trans++;
1595 + end:
1596 + if (is_real_trans)
1597 + start_waiting_global_read_lock(thd);
1598 +@@ -783,6 +785,7 @@
1599 + thd->transaction.cleanup();
1600 + }
1601 + }
1602 ++ thd->diff_rollback_trans++;
1603 + #endif /* USING_TRANSACTIONS */
1604 + DBUG_RETURN(error);
1605 + }
1606 +@@ -1223,6 +1226,7 @@
1607 + statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status);
1608 + *ht=0; // keep it conveniently zero-filled
1609 + }
1610 ++ thd->diff_rollback_trans++;
1611 + DBUG_RETURN(error);
1612 + }
1613 +
1614 +@@ -1453,6 +1457,8 @@
1615 + else
1616 + dupp_ref=ref+ALIGN_SIZE(ref_length);
1617 + }
1618 ++ rows_read = rows_changed = 0;
1619 ++ memset(index_rows_read, 0, sizeof(index_rows_read));
1620 + DBUG_RETURN(error);
1621 + }
1622 +
1623 +@@ -2287,6 +2293,111 @@
1624 + return error;
1625 + }
1626 +
1627 ++// Updates the global table stats with the TABLE this handler represents.
1628 ++void handler::update_global_table_stats() {
1629 ++ if (!opt_userstat_running) {
1630 ++ rows_read = rows_changed = 0;
1631 ++ return;
1632 ++ }
1633 ++
1634 ++ if (!rows_read && !rows_changed) return; // Nothing to update.
1635 ++ // table_cache_key is db_name + '\0' + table_name + '\0'.
1636 ++ if (!table->s || !table->s->table_cache_key || !table->s->table_name) return;
1637 ++
1638 ++ TABLE_STATS* table_stats;
1639 ++ char key[NAME_LEN * 2 + 2];
1640 ++ // [db] + '.' + [table]
1641 ++ sprintf(key, "%s.%s", table->s->table_cache_key, table->s->table_name);
1642 ++
1643 ++ pthread_mutex_lock(&LOCK_global_table_stats);
1644 ++ // Gets the global table stats, creating one if necessary.
1645 ++ if (!(table_stats = (TABLE_STATS*)hash_search(&global_table_stats,
1646 ++ (byte*)key,
1647 ++ strlen(key)))) {
1648 ++ if (!(table_stats = ((TABLE_STATS*)
1649 ++ my_malloc(sizeof(TABLE_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
1650 ++ // Out of memory.
1651 ++ sql_print_error("Allocating table stats failed.");
1652 ++ goto end;
1653 ++ }
1654 ++ strncpy(table_stats->table, key, sizeof(table_stats->table));
1655 ++ table_stats->rows_read = 0;
1656 ++ table_stats->rows_changed = 0;
1657 ++ table_stats->rows_changed_x_indexes = 0;
1658 ++ table_stats->engine_type = (int) ht->db_type;
1659 ++
1660 ++ if (my_hash_insert(&global_table_stats, (byte*)table_stats)) {
1661 ++ // Out of memory.
1662 ++ sql_print_error("Inserting table stats failed.");
1663 ++ my_free((char*)table_stats, 0);
1664 ++ goto end;
1665 ++ }
1666 ++ }
1667 ++ // Updates the global table stats.
1668 ++ table_stats->rows_read += rows_read;
1669 ++ table_stats->rows_changed += rows_changed;
1670 ++ table_stats->rows_changed_x_indexes +=
1671 ++ rows_changed * (table->s->keys ? table->s->keys : 1);
1672 ++ current_thd->diff_total_read_rows += rows_read;
1673 ++ rows_read = rows_changed = 0;
1674 ++end:
1675 ++ pthread_mutex_unlock(&LOCK_global_table_stats);
1676 ++}
1677 ++
1678 ++// Updates the global index stats with this handler's accumulated index reads.
1679 ++void handler::update_global_index_stats() {
1680 ++ // table_cache_key is db_name + '\0' + table_name + '\0'.
1681 ++ if (!table->s || !table->s->table_cache_key || !table->s->table_name) return;
1682 ++
1683 ++ if (!opt_userstat_running) {
1684 ++ for (int x = 0; x < table->s->keys; x++) {
1685 ++ index_rows_read[x] = 0;
1686 ++ }
1687 ++ return;
1688 ++ }
1689 ++
1690 ++ for (int x = 0; x < table->s->keys; x++) {
1691 ++ if (index_rows_read[x]) {
1692 ++ // Rows were read using this index.
1693 ++ KEY* key_info = &table->key_info[x];
1694 ++
1695 ++ if (!key_info->name) continue;
1696 ++
1697 ++ INDEX_STATS* index_stats;
1698 ++ char key[NAME_LEN * 3 + 3];
1699 ++ // [db] + '.' + [table] + '.' + [index]
1700 ++ sprintf(key, "%s.%s.%s", table->s->table_cache_key,
1701 ++ table->s->table_name, key_info->name);
1702 ++
1703 ++ pthread_mutex_lock(&LOCK_global_index_stats);
1704 ++ // Gets the global index stats, creating one if necessary.
1705 ++ if (!(index_stats = (INDEX_STATS*)hash_search(&global_index_stats,
1706 ++ (byte*)key,
1707 ++ strlen(key)))) {
1708 ++ if (!(index_stats = ((INDEX_STATS*)
1709 ++ my_malloc(sizeof(INDEX_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
1710 ++ // Out of memory.
1711 ++ sql_print_error("Allocating index stats failed.");
1712 ++ goto end;
1713 ++ }
1714 ++ strncpy(index_stats->index, key, sizeof(index_stats->index));
1715 ++ index_stats->rows_read = 0;
1716 ++
1717 ++ if (my_hash_insert(&global_index_stats, (byte*)index_stats)) {
1718 ++ // Out of memory.
1719 ++ sql_print_error("Inserting index stats failed.");
1720 ++ my_free((char*)index_stats, 0);
1721 ++ goto end;
1722 ++ }
1723 ++ }
1724 ++ // Updates the global index stats.
1725 ++ index_stats->rows_read += index_rows_read[x];
1726 ++ index_rows_read[x] = 0;
1727 ++end:
1728 ++ pthread_mutex_unlock(&LOCK_global_index_stats);
1729 ++ }
1730 ++ }
1731 ++}
1732 +
1733 + /****************************************************************************
1734 + ** Some general functions that isn't in the handler class
1735 +diff -r 592f6c3641ba sql/handler.h
1736 +--- a/sql/handler.h Wed Jul 29 13:33:34 2009 -0700
1737 ++++ b/sql/handler.h Wed Jul 29 13:34:11 2009 -0700
1738 +@@ -32,6 +32,10 @@
1739 + #define USING_TRANSACTIONS
1740 + #endif
1741 +
1742 ++#if MAX_KEY > 128
1743 ++#error MAX_KEY is too large. Values up to 128 are supported.
1744 ++#endif
1745 ++
1746 + // the following is for checking tables
1747 +
1748 + #define HA_ADMIN_ALREADY_DONE 1
1749 +@@ -604,6 +608,9 @@
1750 + bool auto_increment_column_changed;
1751 + bool implicit_emptied; /* Can be !=0 only if HEAP */
1752 + const COND *pushed_cond;
1753 ++ ulonglong rows_read;
1754 ++ ulonglong rows_changed;
1755 ++ ulonglong index_rows_read[MAX_KEY];
1756 +
1757 + handler(const handlerton *ht_arg, TABLE *table_arg) :table(table_arg),
1758 + ht(ht_arg),
1759 +@@ -615,8 +622,10 @@
1760 + ref_length(sizeof(my_off_t)), block_size(0),
1761 + raid_type(0), ft_handler(0), inited(NONE),
1762 + locked(FALSE), implicit_emptied(0),
1763 +- pushed_cond(NULL)
1764 +- {}
1765 ++ pushed_cond(NULL), rows_read(0), rows_changed(0)
1766 ++ {
1767 ++ memset(index_rows_read, 0, sizeof(index_rows_read));
1768 ++ }
1769 + virtual ~handler(void) { DBUG_ASSERT(locked == FALSE); /* TODO: DBUG_ASSERT(inited == NONE); */ }
1770 + virtual handler *clone(MEM_ROOT *mem_root);
1771 + int ha_open(const char *name, int mode, int test_if_locked);
1772 +@@ -625,7 +634,11 @@
1773 + virtual void print_error(int error, myf errflag);
1774 + virtual bool get_error_message(int error, String *buf);
1775 + uint get_dup_key(int error);
1776 +- void change_table_ptr(TABLE *table_arg) { table=table_arg; }
1777 ++ void change_table_ptr(TABLE *table_arg) {
1778 ++ table=table_arg;
1779 ++ rows_read = rows_changed = 0;
1780 ++ memset(index_rows_read, 0, sizeof(index_rows_read));
1781 ++ }
1782 + virtual double scan_time()
1783 + { return ulonglong2double(data_file_length) / IO_SIZE + 2; }
1784 + virtual double read_time(uint index, uint ranges, ha_rows rows)
1785 +@@ -886,6 +899,9 @@
1786 + virtual bool is_crashed() const { return 0; }
1787 + virtual bool auto_repair() const { return 0; }
1788 +
1789 ++ void update_global_table_stats();
1790 ++ void update_global_index_stats();
1791 ++
1792 + /*
1793 + default rename_table() and delete_table() rename/delete files with a
1794 + given name and extensions from bas_ext()
1795 +diff -r 592f6c3641ba sql/lex.h
1796 +--- a/sql/lex.h Wed Jul 29 13:33:34 2009 -0700
1797 ++++ b/sql/lex.h Wed Jul 29 13:34:11 2009 -0700
1798 +@@ -109,6 +109,7 @@
1799 + { "CHECKSUM", SYM(CHECKSUM_SYM)},
1800 + { "CIPHER", SYM(CIPHER_SYM)},
1801 + { "CLIENT", SYM(CLIENT_SYM)},
1802 ++ { "CLIENT_STATISTICS", SYM(CLIENT_STATS_SYM)},
1803 + { "CLOSE", SYM(CLOSE_SYM)},
1804 + { "CODE", SYM(CODE_SYM)},
1805 + { "COLLATE", SYM(COLLATE_SYM)},
1806 +@@ -238,6 +239,7 @@
1807 + { "IN", SYM(IN_SYM)},
1808 + { "INDEX", SYM(INDEX_SYM)},
1809 + { "INDEXES", SYM(INDEXES)},
1810 ++ { "INDEX_STATISTICS", SYM(INDEX_STATS_SYM)},
1811 + { "INFILE", SYM(INFILE)},
1812 + { "INNER", SYM(INNER_SYM)},
1813 + { "INNOBASE", SYM(INNOBASE_SYM)},
1814 +@@ -443,6 +445,7 @@
1815 + { "SIGNED", SYM(SIGNED_SYM)},
1816 + { "SIMPLE", SYM(SIMPLE_SYM)},
1817 + { "SLAVE", SYM(SLAVE)},
1818 ++ { "SLOW", SYM(SLOW_SYM)},
1819 + { "SNAPSHOT", SYM(SNAPSHOT_SYM)},
1820 + { "SMALLINT", SYM(SMALLINT)},
1821 + { "SOME", SYM(ANY_SYM)},
1822 +@@ -488,6 +491,7 @@
1823 + { "TABLE", SYM(TABLE_SYM)},
1824 + { "TABLES", SYM(TABLES)},
1825 + { "TABLESPACE", SYM(TABLESPACE)},
1826 ++ { "TABLE_STATISTICS", SYM(TABLE_STATS_SYM)},
1827 + { "TEMPORARY", SYM(TEMPORARY)},
1828 + { "TEMPTABLE", SYM(TEMPTABLE_SYM)},
1829 + { "TERMINATED", SYM(TERMINATED)},
1830 +@@ -525,6 +529,7 @@
1831 + { "USE", SYM(USE_SYM)},
1832 + { "USER", SYM(USER)},
1833 + { "USER_RESOURCES", SYM(RESOURCES)},
1834 ++ { "USER_STATISTICS", SYM(USER_STATS_SYM)},
1835 + { "USE_FRM", SYM(USE_FRM)},
1836 + { "USING", SYM(USING)},
1837 + { "UTC_DATE", SYM(UTC_DATE_SYM)},
1838 +diff -r 592f6c3641ba sql/log.cc
1839 +--- a/sql/log.cc Wed Jul 29 13:33:34 2009 -0700
1840 ++++ b/sql/log.cc Wed Jul 29 13:34:11 2009 -0700
1841 +@@ -1958,18 +1958,24 @@
1842 + thd->current_insert_id);
1843 + if (e.write(file))
1844 + goto err;
1845 ++ if (file == &log_file)
1846 ++ thd->binlog_bytes_written += e.data_written;
1847 + }
1848 + if (thd->insert_id_used)
1849 + {
1850 + Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id);
1851 + if (e.write(file))
1852 + goto err;
1853 ++ if (file == &log_file)
1854 ++ thd->binlog_bytes_written += e.data_written;
1855 + }
1856 + if (thd->rand_used)
1857 + {
1858 + Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
1859 + if (e.write(file))
1860 + goto err;
1861 ++ if (file == &log_file)
1862 ++ thd->binlog_bytes_written += e.data_written;
1863 + }
1864 + if (thd->user_var_events.elements)
1865 + {
1866 +@@ -1985,6 +1991,8 @@
1867 + user_var_event->charset_number);
1868 + if (e.write(file))
1869 + goto err;
1870 ++ if (file == &log_file)
1871 ++ thd->binlog_bytes_written += e.data_written;
1872 + }
1873 + }
1874 + }
1875 +@@ -1995,6 +2003,8 @@
1876 +
1877 + if (event_info->write(file))
1878 + goto err;
1879 ++ if (file == &log_file)
1880 ++ thd->binlog_bytes_written += event_info->data_written;
1881 +
1882 + if (file == &log_file) // we are writing to the real log (disk)
1883 + {
1884 +@@ -2117,6 +2127,7 @@
1885 + */
1886 + if (qinfo.write(&log_file))
1887 + goto err;
1888 ++ thd->binlog_bytes_written += qinfo.data_written;
1889 +
1890 + /* Read from the file used to cache the queries .*/
1891 + if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
1892 +@@ -2163,6 +2174,7 @@
1893 + /* write the first half of the split header */
1894 + if (my_b_write(&log_file, header, carry))
1895 + goto err;
1896 ++ thd->binlog_bytes_written += carry;
1897 +
1898 + /*
1899 + copy fixed second half of header to cache so the correct
1900 +@@ -2231,6 +2243,8 @@
1901 + /* Write data to the binary log file */
1902 + if (my_b_write(&log_file, cache->read_pos, length))
1903 + goto err;
1904 ++ thd->binlog_bytes_written += length;
1905 ++
1906 + cache->read_pos=cache->read_end; // Mark buffer used up
1907 + DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;);
1908 + } while ((length=my_b_fill(cache)));
1909 +@@ -2239,6 +2253,8 @@
1910 +
1911 + if (commit_event->write(&log_file))
1912 + goto err;
1913 ++ thd->binlog_bytes_written += commit_event->data_written;
1914 ++
1915 + #ifndef DBUG_OFF
1916 + DBUG_skip_commit:
1917 + #endif
1918 +diff -r 592f6c3641ba sql/mysql_priv.h
1919 +--- a/sql/mysql_priv.h Wed Jul 29 13:33:34 2009 -0700
1920 ++++ b/sql/mysql_priv.h Wed Jul 29 13:34:11 2009 -0700
1921 +@@ -837,7 +837,15 @@
1922 + bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
1923 + void init_max_user_conn(void);
1924 + void init_update_queries(void);
1925 ++void init_global_user_stats(void);
1926 ++void init_global_table_stats(void);
1927 ++void init_global_index_stats(void);
1928 ++void init_global_client_stats(void);
1929 + void free_max_user_conn(void);
1930 ++void free_global_user_stats(void);
1931 ++void free_global_table_stats(void);
1932 ++void free_global_index_stats(void);
1933 ++void free_global_client_stats(void);
1934 + pthread_handler_t handle_one_connection(void *arg);
1935 + pthread_handler_t handle_bootstrap(void *arg);
1936 + void end_thread(THD *thd,bool put_in_cache);
1937 +@@ -1416,6 +1424,7 @@
1938 + extern ulong max_connections,max_connect_errors, connect_timeout;
1939 + extern ulong slave_net_timeout, slave_trans_retries;
1940 + extern uint max_user_connections;
1941 ++extern ulonglong denied_connections;
1942 + extern ulong what_to_log,flush_time;
1943 + extern ulong query_buff_size, thread_stack;
1944 + extern ulong max_prepared_stmt_count, prepared_stmt_count;
1945 +@@ -1446,6 +1455,7 @@
1946 + extern my_bool opt_safe_show_db, opt_local_infile;
1947 + extern my_bool opt_slave_compressed_protocol, use_temp_pool;
1948 + extern my_bool opt_readonly, lower_case_file_system;
1949 ++extern my_bool opt_userstat_running;
1950 + extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
1951 + extern my_bool opt_secure_auth;
1952 + extern char* opt_secure_file_priv;
1953 +@@ -1493,6 +1503,14 @@
1954 + extern struct system_variables max_system_variables;
1955 + extern struct system_status_var global_status_var;
1956 + extern struct rand_struct sql_rand;
1957 ++extern HASH global_user_stats;
1958 ++extern HASH global_client_stats;
1959 ++extern pthread_mutex_t LOCK_global_user_client_stats;
1960 ++extern HASH global_table_stats;
1961 ++extern pthread_mutex_t LOCK_global_table_stats;
1962 ++extern HASH global_index_stats;
1963 ++extern pthread_mutex_t LOCK_global_index_stats;
1964 ++extern pthread_mutex_t LOCK_stats;
1965 +
1966 + extern const char *opt_date_time_formats[];
1967 + extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
1968 +diff -r 592f6c3641ba sql/mysqld.cc
1969 +--- a/sql/mysqld.cc Wed Jul 29 13:33:34 2009 -0700
1970 ++++ b/sql/mysqld.cc Wed Jul 29 13:34:11 2009 -0700
1971 +@@ -417,6 +417,7 @@
1972 + uint opt_large_page_size= 0;
1973 + my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
1974 + char* opt_slow_logname= 0;
1975 ++my_bool opt_userstat_running= 0;
1976 + /*
1977 + True if there is at least one per-hour limit for some user, so we should
1978 + check them before each query (and possibly reset counters when hour is
1979 +@@ -453,6 +454,7 @@
1980 + ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
1981 + ulong max_connections, max_connect_errors;
1982 + uint max_user_connections= 0;
1983 ++ulonglong denied_connections = 0;
1984 + /*
1985 + Limit of the total number of prepared statements in the server.
1986 + Is necessary to protect the server against out-of-memory attacks.
1987 +@@ -555,6 +557,10 @@
1988 + LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
1989 + LOCK_global_system_variables,
1990 + LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
1991 ++pthread_mutex_t LOCK_stats;
1992 ++pthread_mutex_t LOCK_global_user_client_stats;
1993 ++pthread_mutex_t LOCK_global_table_stats;
1994 ++pthread_mutex_t LOCK_global_index_stats;
1995 + /*
1996 + The below lock protects access to two global server variables:
1997 + max_prepared_stmt_count and prepared_stmt_count. These variables
1998 +@@ -1196,6 +1202,10 @@
1999 + x_free(opt_secure_file_priv);
2000 + bitmap_free(&temp_pool);
2001 + free_max_user_conn();
2002 ++ free_global_user_stats();
2003 ++ free_global_client_stats();
2004 ++ free_global_table_stats();
2005 ++ free_global_index_stats();
2006 + #ifdef HAVE_REPLICATION
2007 + end_slave_list();
2008 + free_list(&replicate_do_db);
2009 +@@ -1310,6 +1320,10 @@
2010 + (void) pthread_cond_destroy(&COND_thread_cache);
2011 + (void) pthread_cond_destroy(&COND_flush_thread_cache);
2012 + (void) pthread_cond_destroy(&COND_manager);
2013 ++ (void) pthread_mutex_destroy(&LOCK_stats);
2014 ++ (void) pthread_mutex_destroy(&LOCK_global_user_client_stats);
2015 ++ (void) pthread_mutex_destroy(&LOCK_global_table_stats);
2016 ++ (void) pthread_mutex_destroy(&LOCK_global_index_stats);
2017 + }
2018 +
2019 + #endif /*EMBEDDED_LIBRARY*/
2020 +@@ -3157,6 +3171,10 @@
2021 + (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
2022 + (void) pthread_cond_init(&COND_rpl_status, NULL);
2023 + #endif
2024 ++ (void) pthread_mutex_init(&LOCK_stats, MY_MUTEX_INIT_FAST);
2025 ++ (void) pthread_mutex_init(&LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST);
2026 ++ (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
2027 ++ (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
2028 + sp_cache_init();
2029 + /* Parameter for threads created for connections */
2030 + (void) pthread_attr_init(&connection_attrib);
2031 +@@ -3428,6 +3446,10 @@
2032 + sql_print_error("Out of memory");
2033 + unireg_abort(1);
2034 + }
2035 ++
2036 ++ init_global_table_stats();
2037 ++ init_global_index_stats();
2038 ++
2039 + if (ha_init())
2040 + {
2041 + sql_print_error("Can't init databases");
2042 +@@ -3510,6 +3532,8 @@
2043 +
2044 + init_max_user_conn();
2045 + init_update_queries();
2046 ++ init_global_user_stats();
2047 ++ init_global_client_stats();
2048 + DBUG_RETURN(0);
2049 + }
2050 +
2051 +@@ -4236,6 +4260,7 @@
2052 + {
2053 + DBUG_PRINT("error",("Too many connections"));
2054 + close_connection(thd, ER_CON_COUNT_ERROR, 1);
2055 ++ statistic_increment(denied_connections, &LOCK_status);
2056 + delete thd;
2057 + DBUG_VOID_RETURN;
2058 + }
2059 +@@ -5056,6 +5081,7 @@
2060 + OPT_PROFILING_USE_GETRUSAGE,
2061 + OPT_SLOW_LOG,
2062 + OPT_SLOW_QUERY_LOG_FILE,
2063 ++ OPT_USERSTAT_RUNNING,
2064 + OPT_USE_GLOBAL_LONG_QUERY_TIME,
2065 + OPT_INNODB_ROLLBACK_ON_TIMEOUT,
2066 + OPT_SECURE_FILE_PRIV,
2067 +@@ -6523,6 +6549,10 @@
2068 + (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
2069 + REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
2070 + 0, 1, 0},
2071 ++ {"userstat_running", OPT_USERSTAT_RUNNING,
2072 ++ "Control USER_STATISTICS, CLIENT_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS running",
2073 ++ (gptr*) &opt_userstat_running, (gptr*) &opt_userstat_running,
2074 ++ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
2075 + {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2076 + };
2077 +
2078 +diff -r 592f6c3641ba sql/set_var.cc
2079 +--- a/sql/set_var.cc Wed Jul 29 13:33:34 2009 -0700
2080 ++++ b/sql/set_var.cc Wed Jul 29 13:34:11 2009 -0700
2081 +@@ -325,6 +325,7 @@
2082 + sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
2083 + &SV::read_buff_size);
2084 + sys_var_bool_ptr sys_readonly("read_only", &opt_readonly);
2085 ++sys_var_bool_ptr sys_userstat_running("userstat_running", &opt_userstat_running);
2086 + sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size",
2087 + &SV::read_rnd_buff_size);
2088 + sys_var_thd_ulong sys_div_precincrement("div_precision_increment",
2089 +@@ -837,6 +838,7 @@
2090 + &sys_trans_alloc_block_size,
2091 + &sys_trans_prealloc_size,
2092 + &sys_tx_isolation,
2093 ++ &sys_userstat_running,
2094 + &sys_version,
2095 + #ifdef HAVE_BERKELEY_DB
2096 + &sys_version_bdb,
2097 +@@ -1190,6 +1192,7 @@
2098 + {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS},
2099 + {sys_updatable_views_with_limit.name,
2100 + (char*) &sys_updatable_views_with_limit,SHOW_SYS},
2101 ++ {sys_userstat_running.name, (char*) &sys_userstat_running, SHOW_SYS},
2102 + {sys_use_global_long_query_time.name, (char*) &sys_use_global_long_query_time, SHOW_SYS},
2103 + {sys_version.name, (char*) &sys_version, SHOW_SYS},
2104 + #ifdef HAVE_BERKELEY_DB
2105 +diff -r 592f6c3641ba sql/share/Makefile.in
2106 +--- a/sql/share/Makefile.in Wed Jul 29 13:33:34 2009 -0700
2107 ++++ b/sql/share/Makefile.in Wed Jul 29 13:34:11 2009 -0700
2108 +@@ -144,6 +144,7 @@
2109 + LIBDL = @LIBDL@
2110 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
2111 + LIBOBJS = @LIBOBJS@
2112 ++LIBRT = @LIBRT@
2113 + LIBS = @LIBS@
2114 + LIBTOOL = @LIBTOOL@
2115 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
2116 +diff -r 592f6c3641ba sql/sql_base.cc
2117 +--- a/sql/sql_base.cc Wed Jul 29 13:33:34 2009 -0700
2118 ++++ b/sql/sql_base.cc Wed Jul 29 13:34:11 2009 -0700
2119 +@@ -624,6 +624,12 @@
2120 + DBUG_ENTER("close_thread_table");
2121 + DBUG_ASSERT(table->key_read == 0);
2122 + DBUG_ASSERT(!table->file || table->file->inited == handler::NONE);
2123 ++
2124 ++ if(table->file)
2125 ++ {
2126 ++ table->file->update_global_table_stats();
2127 ++ table->file->update_global_index_stats();
2128 ++ }
2129 +
2130 + *table_ptr=table->next;
2131 + if (table->needs_reopen_or_name_lock() ||
2132 +@@ -670,6 +676,9 @@
2133 + {
2134 + DBUG_ENTER("close_temporary");
2135 + char path[FN_REFLEN];
2136 ++
2137 ++ table->file->update_global_table_stats();
2138 ++ table->file->update_global_index_stats();
2139 + db_type table_type=table->s->db_type;
2140 + strmov(path,table->s->path);
2141 + free_io_cache(table);
2142 +diff -r 592f6c3641ba sql/sql_class.cc
2143 +--- a/sql/sql_class.cc Wed Jul 29 13:33:34 2009 -0700
2144 ++++ b/sql/sql_class.cc Wed Jul 29 13:34:11 2009 -0700
2145 +@@ -239,6 +239,13 @@
2146 + bzero(ha_data, sizeof(ha_data));
2147 + mysys_var=0;
2148 + binlog_evt_union.do_union= FALSE;
2149 ++ busy_time = 0;
2150 ++ cpu_time = 0;
2151 ++ bytes_received = 0;
2152 ++ bytes_sent = 0;
2153 ++ binlog_bytes_written = 0;
2154 ++ updated_row_count = 0;
2155 ++ sent_row_count_2 = 0;
2156 + #ifndef DBUG_OFF
2157 + dbug_sentry=THD_SENTRY_MAGIC;
2158 + #endif
2159 +@@ -378,6 +385,88 @@
2160 + total_warn_count= 0;
2161 + update_charset();
2162 + bzero((char *) &status_var, sizeof(status_var));
2163 ++ reset_stats();
2164 ++}
2165 ++
2166 ++// Resets stats in a THD.
2167 ++void THD::reset_stats(void) {
2168 ++ current_connect_time = time(NULL);
2169 ++ last_global_update_time = current_connect_time;
2170 ++ reset_diff_stats();
2171 ++}
2172 ++
2173 ++// Resets the 'diff' stats, which are used to update global stats.
2174 ++void THD::reset_diff_stats(void) {
2175 ++ diff_total_busy_time = 0;
2176 ++ diff_total_cpu_time = 0;
2177 ++ diff_total_bytes_received = 0;
2178 ++ diff_total_bytes_sent = 0;
2179 ++ diff_total_binlog_bytes_written = 0;
2180 ++ diff_total_sent_rows = 0;
2181 ++ diff_total_updated_rows = 0;
2182 ++ diff_total_read_rows = 0;
2183 ++ diff_select_commands = 0;
2184 ++ diff_update_commands = 0;
2185 ++ diff_other_commands = 0;
2186 ++ diff_commit_trans = 0;
2187 ++ diff_rollback_trans = 0;
2188 ++ diff_denied_connections = 0;
2189 ++ diff_lost_connections = 0;
2190 ++ diff_access_denied_errors = 0;
2191 ++ diff_empty_queries = 0;
2192 ++}
2193 ++
2194 ++// Updates 'diff' stats of a THD.
2195 ++void THD::update_stats(bool ran_command) {
2196 ++ if (opt_userstat_running) {
2197 ++ diff_total_busy_time += busy_time;
2198 ++ diff_total_cpu_time += cpu_time;
2199 ++ diff_total_bytes_received += bytes_received;
2200 ++ diff_total_bytes_sent += bytes_sent;
2201 ++ diff_total_binlog_bytes_written += binlog_bytes_written;
2202 ++ diff_total_sent_rows += sent_row_count_2;
2203 ++ diff_total_updated_rows += updated_row_count;
2204 ++ // diff_total_read_rows is updated in handler.cc.
2205 ++
2206 ++ if (ran_command) {
2207 ++ // The replication thread has the COM_CONNECT command.
2208 ++ if ((old_command == COM_QUERY || command == COM_CONNECT) &&
2209 ++ (lex->sql_command >= 0 && lex->sql_command < SQLCOM_END)) {
2210 ++ // A SQL query.
2211 ++ if (lex->sql_command == SQLCOM_SELECT) {
2212 ++ if (lex->orig_sql_command == SQLCOM_END) {
2213 ++ diff_select_commands++;
2214 ++ if (!sent_row_count_2)
2215 ++ diff_empty_queries++;
2216 ++ } else {
2217 ++ // 'SHOW ' commands become SQLCOM_SELECT.
2218 ++ diff_other_commands++;
2219 ++ // 'SHOW ' commands shouldn't inflate total sent row count.
2220 ++ diff_total_sent_rows -= sent_row_count_2;
2221 ++ }
2222 ++ } else if (is_update_query(lex->sql_command)) {
2223 ++ diff_update_commands++;
2224 ++ } else {
2225 ++ diff_other_commands++;
2226 ++ }
2227 ++ }
2228 ++ }
2229 ++ // diff_commit_trans is updated in handler.cc.
2230 ++ // diff_rollback_trans is updated in handler.cc.
2231 ++ // diff_denied_connections is updated in sql_parse.cc.
2232 ++ // diff_lost_connections is updated in sql_parse.cc.
2233 ++ // diff_access_denied_errors is updated in sql_parse.cc.
2234 ++
2235 ++ /* reset counters to zero to avoid double-counting since values
2236 ++ are already store in diff_total_*. */
2237 ++ }
2238 ++ busy_time = 0;
2239 ++ cpu_time = 0;
2240 ++ bytes_received = 0;
2241 ++ bytes_sent = 0;
2242 ++ binlog_bytes_written = 0;
2243 ++ updated_row_count = 0;
2244 ++ sent_row_count_2 = 0;
2245 + }
2246 +
2247 +
2248 +@@ -907,6 +996,33 @@
2249 + }
2250 + #endif
2251 +
2252 ++char *THD::get_client_host_port(THD *client)
2253 ++{
2254 ++ Security_context *client_sctx= client->security_ctx;
2255 ++ char *client_host= NULL;
2256 ++
2257 ++ if (client->peer_port && (client_sctx->host || client_sctx->ip) &&
2258 ++ security_ctx->host_or_ip[0])
2259 ++ {
2260 ++ if ((client_host= this->alloc(LIST_PROCESS_HOST_LEN+1)))
2261 ++ my_snprintf((char *) client_host, LIST_PROCESS_HOST_LEN,
2262 ++ "%s:%u", client_sctx->host_or_ip, client->peer_port);
2263 ++ }
2264 ++ else
2265 ++ client_host= this->strdup(client_sctx->host_or_ip[0] ?
2266 ++ client_sctx->host_or_ip :
2267 ++ client_sctx->host ? client_sctx->host : "");
2268 ++
2269 ++ return client_host;
2270 ++}
2271 ++
2272 ++const char *get_client_host(THD *client)
2273 ++{
2274 ++ return client->security_ctx->host_or_ip[0] ?
2275 ++ client->security_ctx->host_or_ip :
2276 ++ client->security_ctx->host ? client->security_ctx->host : "";
2277 ++}
2278 ++
2279 +
2280 + struct Item_change_record: public ilink
2281 + {
2282 +@@ -1082,6 +1198,7 @@
2283 + buffer.set(buff, sizeof(buff), &my_charset_bin);
2284 + }
2285 + thd->sent_row_count++;
2286 ++ thd->sent_row_count_2++;
2287 + if (!thd->vio_ok())
2288 + DBUG_RETURN(0);
2289 + if (!thd->net.report_error)
2290 +@@ -1174,6 +1291,7 @@
2291 + select_export::~select_export()
2292 + {
2293 + thd->sent_row_count=row_count;
2294 ++ thd->sent_row_count_2=row_count;
2295 + }
2296 +
2297 +
2298 +@@ -2108,6 +2226,7 @@
2299 + if (likely(thd != 0))
2300 + { /* current_thd==0 when close_connection() calls net_send_error() */
2301 + thd->status_var.bytes_sent+= length;
2302 ++ thd->bytes_sent+= length;
2303 + }
2304 + }
2305 +
2306 +@@ -2115,6 +2234,7 @@
2307 + void thd_increment_bytes_received(ulong length)
2308 + {
2309 + current_thd->status_var.bytes_received+= length;
2310 ++ current_thd->bytes_received+= length;
2311 + }
2312 +
2313 +
2314 +diff -r 592f6c3641ba sql/sql_class.h
2315 +--- a/sql/sql_class.h Wed Jul 29 13:33:34 2009 -0700
2316 ++++ b/sql/sql_class.h Wed Jul 29 13:34:11 2009 -0700
2317 +@@ -1302,6 +1302,8 @@
2318 + first byte of the packet in do_command()
2319 + */
2320 + enum enum_server_command command;
2321 ++ // Used to save the command, before it is set to COM_SLEEP.
2322 ++ enum enum_server_command old_command;
2323 + uint32 server_id;
2324 + uint32 file_id; // for LOAD DATA INFILE
2325 + /*
2326 +@@ -1498,6 +1500,8 @@
2327 + /* variables.transaction_isolation is reset to this after each commit */
2328 + enum_tx_isolation session_tx_isolation;
2329 + enum_check_fields count_cuted_fields;
2330 ++ ha_rows updated_row_count;
2331 ++ ha_rows sent_row_count_2; /* for userstat */
2332 +
2333 + DYNAMIC_ARRAY user_var_events; /* For user variables replication */
2334 + MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
2335 +@@ -1607,6 +1611,49 @@
2336 + */
2337 + LOG_INFO* current_linfo;
2338 + NET* slave_net; // network connection from slave -> m.
2339 ++
2340 ++ /*
2341 ++ Used to update global user stats. The global user stats are updated
2342 ++ occasionally with the 'diff' variables. After the update, the 'diff'
2343 ++ variables are reset to 0.
2344 ++ */
2345 ++ // Time when the current thread connected to MySQL.
2346 ++ time_t current_connect_time;
2347 ++ // Last time when THD stats were updated in global_user_stats.
2348 ++ time_t last_global_update_time;
2349 ++ // Busy (non-idle) time for just one command.
2350 ++ double busy_time;
2351 ++ // Busy time not updated in global_user_stats yet.
2352 ++ double diff_total_busy_time;
2353 ++ // Cpu (non-idle) time for just one thread.
2354 ++ double cpu_time;
2355 ++ // Cpu time not updated in global_user_stats yet.
2356 ++ double diff_total_cpu_time;
2357 ++ /* bytes counting */
2358 ++ ulonglong bytes_received;
2359 ++ ulonglong diff_total_bytes_received;
2360 ++ ulonglong bytes_sent;
2361 ++ ulonglong diff_total_bytes_sent;
2362 ++ ulonglong binlog_bytes_written;
2363 ++ ulonglong diff_total_binlog_bytes_written;
2364 ++
2365 ++ // Number of rows not reflected in global_user_stats yet.
2366 ++ ha_rows diff_total_sent_rows, diff_total_updated_rows, diff_total_read_rows;
2367 ++ // Number of commands not reflected in global_user_stats yet.
2368 ++ ulonglong diff_select_commands, diff_update_commands, diff_other_commands;
2369 ++ // Number of transactions not reflected in global_user_stats yet.
2370 ++ ulonglong diff_commit_trans, diff_rollback_trans;
2371 ++ // Number of connection errors not reflected in global_user_stats yet.
2372 ++ ulonglong diff_denied_connections, diff_lost_connections;
2373 ++ // Number of db access denied, not reflected in global_user_stats yet.
2374 ++ ulonglong diff_access_denied_errors;
2375 ++ // Number of queries that return 0 rows
2376 ++ ulonglong diff_empty_queries;
2377 ++
2378 ++ // Per account query delay in miliseconds. When not 0, sleep this number of
2379 ++ // milliseconds before every SQL command.
2380 ++ ulonglong query_delay_millis;
2381 ++
2382 + /* Used by the sys_var class to store temporary values */
2383 + union
2384 + {
2385 +@@ -1662,6 +1709,11 @@
2386 + alloc_root.
2387 + */
2388 + void init_for_queries();
2389 ++ void reset_stats(void);
2390 ++ void reset_diff_stats(void);
2391 ++ // ran_command is true when this is called immediately after a
2392 ++ // command has been run.
2393 ++ void update_stats(bool ran_command);
2394 + void change_user(void);
2395 + void cleanup(void);
2396 + void cleanup_after_query();
2397 +@@ -1891,8 +1943,14 @@
2398 + if (p_db_length)
2399 + *p_db_length= db_length;
2400 + return FALSE;
2401 ++
2402 ++ // Returns string as 'IP:port' for the client-side of the connnection represented
2403 ++ // by 'client' as displayed by SHOW PROCESSLIST. Allocates memory from the heap of
2404 ++ // this THD and that is not reclaimed immediately, so use sparingly. May return NULL.
2405 + }
2406 +
2407 ++ char *get_client_host_port(THD *client);
2408 ++
2409 + public:
2410 + /**
2411 + Add an internal error handler to the thread execution context.
2412 +@@ -1935,6 +1993,10 @@
2413 + MEM_ROOT main_mem_root;
2414 + };
2415 +
2416 ++// Returns string as 'IP' for the client-side of the connection represented by
2417 ++// 'client'. Does not allocate memory. May return "".
2418 ++const char *get_client_host(THD *client);
2419 ++
2420 +
2421 + #define tmp_disable_binlog(A) \
2422 + {ulonglong tmp_disable_binlog__save_options= (A)->options; \
2423 +diff -r 592f6c3641ba sql/sql_delete.cc
2424 +--- a/sql/sql_delete.cc Wed Jul 29 13:33:34 2009 -0700
2425 ++++ b/sql/sql_delete.cc Wed Jul 29 13:34:11 2009 -0700
2426 +@@ -358,6 +358,7 @@
2427 + send_ok(thd,deleted);
2428 + DBUG_PRINT("info",("%ld records deleted",(long) deleted));
2429 + }
2430 ++ thd->updated_row_count += deleted;
2431 + DBUG_RETURN(error >= 0 || thd->net.report_error);
2432 + }
2433 +
2434 +@@ -887,6 +888,7 @@
2435 + thd->row_count_func= deleted;
2436 + ::send_ok(thd, deleted);
2437 + }
2438 ++ thd->updated_row_count += deleted;
2439 + return 0;
2440 + }
2441 +
2442 +diff -r 592f6c3641ba sql/sql_insert.cc
2443 +--- a/sql/sql_insert.cc Wed Jul 29 13:33:34 2009 -0700
2444 ++++ b/sql/sql_insert.cc Wed Jul 29 13:34:11 2009 -0700
2445 +@@ -990,6 +990,7 @@
2446 + thd->row_count_func= info.copied + info.deleted + updated;
2447 + ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
2448 + }
2449 ++ thd->updated_row_count += thd->row_count_func;
2450 + thd->abort_on_warning= 0;
2451 + DBUG_RETURN(FALSE);
2452 +
2453 +@@ -3094,6 +3095,7 @@
2454 + autoinc_value_of_first_inserted_row : thd->insert_id_used ?
2455 + thd->last_insert_id : 0;
2456 + ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
2457 ++ thd->updated_row_count += thd->row_count_func;
2458 + DBUG_RETURN(0);
2459 + }
2460 +
2461 +diff -r 592f6c3641ba sql/sql_lex.h
2462 +--- a/sql/sql_lex.h Wed Jul 29 13:33:34 2009 -0700
2463 ++++ b/sql/sql_lex.h Wed Jul 29 13:34:11 2009 -0700
2464 +@@ -101,6 +101,9 @@
2465 + When a command is added here, be sure it's also added in mysqld.cc
2466 + in "struct show_var_st status_vars[]= {" ...
2467 + */
2468 ++ // TODO(mcallaghan): update status_vars in mysqld to export these
2469 ++ SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS,
2470 ++ SQLCOM_SHOW_CLIENT_STATS,
2471 + /* This should be the last !!! */
2472 + SQLCOM_END
2473 + };
2474 +diff -r 592f6c3641ba sql/sql_parse.cc
2475 +--- a/sql/sql_parse.cc Wed Jul 29 13:33:34 2009 -0700
2476 ++++ b/sql/sql_parse.cc Wed Jul 29 13:34:11 2009 -0700
2477 +@@ -78,6 +78,12 @@
2478 + const char *table_name);
2479 + static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
2480 +
2481 ++// Increments connection count for user.
2482 ++static int increment_connection_count(THD* thd, bool use_lock);
2483 ++
2484 ++// Uses the THD to update the global stats by user name and client IP
2485 ++void update_global_user_stats(THD* thd, bool create_user, time_t now);
2486 ++
2487 + const char *any_db="*any*"; // Special symbol for check_access
2488 +
2489 + const char *command_name[]={
2490 +@@ -146,6 +152,17 @@
2491 + static bool do_command(THD *thd);
2492 + #endif // EMBEDDED_LIBRARY
2493 +
2494 ++HASH global_user_stats;
2495 ++HASH global_client_stats;
2496 ++// Protects global_user_stats and global_client_stats
2497 ++extern pthread_mutex_t LOCK_global_user_client_stats;
2498 ++
2499 ++HASH global_table_stats;
2500 ++extern pthread_mutex_t LOCK_global_table_stats;
2501 ++
2502 ++HASH global_index_stats;
2503 ++extern pthread_mutex_t LOCK_global_index_stats;
2504 ++
2505 + #ifdef __WIN__
2506 + extern void win_install_sigabrt_handler(void);
2507 + #endif
2508 +@@ -504,6 +521,7 @@
2509 + mysql_log.write(thd,COM_CONNECT,"%s",ER(ER_NOT_SUPPORTED_AUTH_MODE));
2510 + DBUG_RETURN(-1);
2511 + }
2512 ++ thd->diff_access_denied_errors++;
2513 + net_printf_error(thd, ER_ACCESS_DENIED_ERROR,
2514 + thd->main_security_ctx.user,
2515 + thd->main_security_ctx.host_or_ip,
2516 +@@ -536,12 +554,190 @@
2517 + void init_max_user_conn(void)
2518 + {
2519 + #ifndef NO_EMBEDDED_ACCESS_CHECKS
2520 +- (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
2521 +- 0,0,
2522 +- (hash_get_key) get_key_conn, (hash_free_key) free_user,
2523 +- 0);
2524 +-#endif
2525 +-}
2526 ++ if (hash_init(&hash_user_connections,system_charset_info,max_connections,
2527 ++ 0,0,
2528 ++ (hash_get_key) get_key_conn, (hash_free_key) free_user,
2529 ++ 0)) {
2530 ++ sql_print_error("Initializing hash_user_connections failed.");
2531 ++ exit(1);
2532 ++ }
2533 ++#endif
2534 ++}
2535 ++
2536 ++byte *get_key_user_stats(USER_STATS *user_stats, uint *length,
2537 ++ my_bool not_used __attribute__((unused)))
2538 ++{
2539 ++ *length = strlen(user_stats->user);
2540 ++ return (byte*)user_stats->user;
2541 ++}
2542 ++
2543 ++void free_user_stats(USER_STATS* user_stats)
2544 ++{
2545 ++ my_free((char*)user_stats, MYF(0));
2546 ++}
2547 ++
2548 ++void init_user_stats(USER_STATS *user_stats,
2549 ++ const char *user,
2550 ++ const char *priv_user,
2551 ++ uint total_connections,
2552 ++ uint concurrent_connections,
2553 ++ time_t connected_time,
2554 ++ double busy_time,
2555 ++ double cpu_time,
2556 ++ ulonglong bytes_received,
2557 ++ ulonglong bytes_sent,
2558 ++ ulonglong binlog_bytes_written,
2559 ++ ha_rows rows_fetched,
2560 ++ ha_rows rows_updated,
2561 ++ ha_rows rows_read,
2562 ++ ulonglong select_commands,
2563 ++ ulonglong update_commands,
2564 ++ ulonglong other_commands,
2565 ++ ulonglong commit_trans,
2566 ++ ulonglong rollback_trans,
2567 ++ ulonglong denied_connections,
2568 ++ ulonglong lost_connections,
2569 ++ ulonglong access_denied_errors,
2570 ++ ulonglong empty_queries)
2571 ++{
2572 ++ DBUG_ENTER("init_user_stats");
2573 ++ DBUG_PRINT("info",
2574 ++ ("Add user_stats entry for user %s - priv_user %s",
2575 ++ user, priv_user));
2576 ++ strncpy(user_stats->user, user, sizeof(user_stats->user));
2577 ++ strncpy(user_stats->priv_user, priv_user, sizeof(user_stats->priv_user));
2578 ++
2579 ++ user_stats->total_connections = total_connections;
2580 ++ user_stats->concurrent_connections = concurrent_connections;
2581 ++ user_stats->connected_time = connected_time;
2582 ++ user_stats->busy_time = busy_time;
2583 ++ user_stats->cpu_time = cpu_time;
2584 ++ user_stats->bytes_received = bytes_received;
2585 ++ user_stats->bytes_sent = bytes_sent;
2586 ++ user_stats->binlog_bytes_written = binlog_bytes_written;
2587 ++ user_stats->rows_fetched = rows_fetched;
2588 ++ user_stats->rows_updated = rows_updated;
2589 ++ user_stats->rows_read = rows_read;
2590 ++ user_stats->select_commands = select_commands;
2591 ++ user_stats->update_commands = update_commands;
2592 ++ user_stats->other_commands = other_commands;
2593 ++ user_stats->commit_trans = commit_trans;
2594 ++ user_stats->rollback_trans = rollback_trans;
2595 ++ user_stats->denied_connections = denied_connections;
2596 ++ user_stats->lost_connections = lost_connections;
2597 ++ user_stats->access_denied_errors = access_denied_errors;
2598 ++ user_stats->empty_queries = empty_queries;
2599 ++ DBUG_VOID_RETURN;
2600 ++}
2601 ++
2602 ++void add_user_stats(USER_STATS *user_stats,
2603 ++ uint total_connections,
2604 ++ uint concurrent_connections,
2605 ++ time_t connected_time,
2606 ++ double busy_time,
2607 ++ double cpu_time,
2608 ++ ulonglong bytes_received,
2609 ++ ulonglong bytes_sent,
2610 ++ ulonglong binlog_bytes_written,
2611 ++ ha_rows rows_fetched,
2612 ++ ha_rows rows_updated,
2613 ++ ha_rows rows_read,
2614 ++ ulonglong select_commands,
2615 ++ ulonglong update_commands,
2616 ++ ulonglong other_commands,
2617 ++ ulonglong commit_trans,
2618 ++ ulonglong rollback_trans,
2619 ++ ulonglong denied_connections,
2620 ++ ulonglong lost_connections,
2621 ++ ulonglong access_denied_errors,
2622 ++ ulonglong empty_queries)
2623 ++{
2624 ++ user_stats->total_connections += total_connections;
2625 ++ user_stats->concurrent_connections += concurrent_connections;
2626 ++ user_stats->connected_time += connected_time;
2627 ++ user_stats->busy_time += busy_time;
2628 ++ user_stats->cpu_time += cpu_time;
2629 ++ user_stats->bytes_received += bytes_received;
2630 ++ user_stats->bytes_sent += bytes_sent;
2631 ++ user_stats->binlog_bytes_written += binlog_bytes_written;
2632 ++ user_stats->rows_fetched += rows_fetched;
2633 ++ user_stats->rows_updated += rows_updated;
2634 ++ user_stats->rows_read += rows_read;
2635 ++ user_stats->select_commands += select_commands;
2636 ++ user_stats->update_commands += update_commands;
2637 ++ user_stats->other_commands += other_commands;
2638 ++ user_stats->commit_trans += commit_trans;
2639 ++ user_stats->rollback_trans += rollback_trans;
2640 ++ user_stats->denied_connections += denied_connections;
2641 ++ user_stats->lost_connections += lost_connections;
2642 ++ user_stats->access_denied_errors += access_denied_errors;
2643 ++ user_stats->empty_queries += empty_queries;
2644 ++}
2645 ++
2646 ++void init_global_user_stats(void)
2647 ++{
2648 ++ if (hash_init(&global_user_stats, system_charset_info, max_connections,
2649 ++ 0, 0, (hash_get_key)get_key_user_stats,
2650 ++ (hash_free_key)free_user_stats, 0)) {
2651 ++ sql_print_error("Initializing global_user_stats failed.");
2652 ++ exit(1);
2653 ++ }
2654 ++}
2655 ++
2656 ++void init_global_client_stats(void)
2657 ++{
2658 ++ if (hash_init(&global_client_stats, system_charset_info, max_connections,
2659 ++ 0, 0, (hash_get_key)get_key_user_stats,
2660 ++ (hash_free_key)free_user_stats, 0)) {
2661 ++ sql_print_error("Initializing global_client_stats failed.");
2662 ++ exit(1);
2663 ++ }
2664 ++}
2665 ++
2666 ++extern "C" byte *get_key_table_stats(TABLE_STATS *table_stats, uint *length,
2667 ++ my_bool not_used __attribute__((unused)))
2668 ++{
2669 ++ *length = strlen(table_stats->table);
2670 ++ return (byte*)table_stats->table;
2671 ++}
2672 ++
2673 ++extern "C" void free_table_stats(TABLE_STATS* table_stats)
2674 ++{
2675 ++ my_free((char*)table_stats, MYF(0));
2676 ++}
2677 ++
2678 ++void init_global_table_stats(void)
2679 ++{
2680 ++ if (hash_init(&global_table_stats, system_charset_info, max_connections,
2681 ++ 0, 0, (hash_get_key)get_key_table_stats,
2682 ++ (hash_free_key)free_table_stats, 0)) {
2683 ++ sql_print_error("Initializing global_table_stats failed.");
2684 ++ exit(1);
2685 ++ }
2686 ++}
2687 ++
2688 ++extern "C" byte *get_key_index_stats(INDEX_STATS *index_stats, uint *length,
2689 ++ my_bool not_used __attribute__((unused)))
2690 ++{
2691 ++ *length = strlen(index_stats->index);
2692 ++ return (byte*)index_stats->index;
2693 ++}
2694 ++
2695 ++extern "C" void free_index_stats(INDEX_STATS* index_stats)
2696 ++{
2697 ++ my_free((char*)index_stats, MYF(0));
2698 ++}
2699 ++
2700 ++void init_global_index_stats(void)
2701 ++{
2702 ++ if (hash_init(&global_index_stats, system_charset_info, max_connections,
2703 ++ 0, 0, (hash_get_key)get_key_index_stats,
2704 ++ (hash_free_key)free_index_stats, 0)) {
2705 ++ sql_print_error("Initializing global_index_stats failed.");
2706 ++ exit(1);
2707 ++ }
2708 ++}
2709 ++
2710 +
2711 +
2712 + /*
2713 +@@ -599,7 +795,10 @@
2714 +
2715 + end:
2716 + if (error)
2717 ++ {
2718 ++ statistic_increment(denied_connections, &LOCK_status);
2719 + uc->connections--; // no need for decrease_user_connections() here
2720 ++ }
2721 + (void) pthread_mutex_unlock(&LOCK_user_conn);
2722 + DBUG_RETURN(error);
2723 + }
2724 +@@ -646,6 +845,25 @@
2725 + #endif /* NO_EMBEDDED_ACCESS_CHECKS */
2726 + }
2727 +
2728 ++void free_global_user_stats(void)
2729 ++{
2730 ++ hash_free(&global_user_stats);
2731 ++}
2732 ++
2733 ++void free_global_table_stats(void)
2734 ++{
2735 ++ hash_free(&global_table_stats);
2736 ++}
2737 ++
2738 ++void free_global_index_stats(void)
2739 ++{
2740 ++ hash_free(&global_index_stats);
2741 ++}
2742 ++
2743 ++void free_global_client_stats(void)
2744 ++{
2745 ++ hash_free(&global_client_stats);
2746 ++}
2747 +
2748 +
2749 + /*
2750 +@@ -698,6 +916,214 @@
2751 + return uc_update_queries[command] != 0;
2752 + }
2753 +
2754 ++// 'mysql_system_user' is used for when the user is not defined for a THD.
2755 ++static char mysql_system_user[] = "#mysql_system#";
2756 ++
2757 ++// Returns 'user' if it's not NULL. Returns 'mysql_system_user' otherwise.
2758 ++static char* get_valid_user_string(char* user) {
2759 ++ return user ? user : mysql_system_user;
2760 ++}
2761 ++
2762 ++// Increments the global stats connection count for an entry from
2763 ++// global_client_stats or global_user_stats. Returns 0 on success
2764 ++// and 1 on error.
2765 ++static int increment_count_by_name(const char *name, const char *role_name,
2766 ++ HASH *users_or_clients, THD *thd)
2767 ++{
2768 ++ USER_STATS* user_stats;
2769 ++
2770 ++ if (!(user_stats = (USER_STATS*)hash_search(users_or_clients, name,
2771 ++ strlen(name))))
2772 ++ {
2773 ++ // First connection for this user or client
2774 ++ if (!(user_stats = ((USER_STATS*)
2775 ++ my_malloc(sizeof(USER_STATS), MYF(MY_WME | MY_ZEROFILL)))))
2776 ++ {
2777 ++ return 1; // Out of memory
2778 ++ }
2779 ++
2780 ++ init_user_stats(user_stats, name, role_name,
2781 ++ 0, 0, // connections
2782 ++ 0, 0, 0, // time
2783 ++ 0, 0, 0, // bytes sent, received and written
2784 ++ 0, 0, 0, // rows fetched, updated and read
2785 ++ 0, 0, 0, // select, update and other commands
2786 ++ 0, 0, // commit and rollback trans
2787 ++ thd->diff_denied_connections,
2788 ++ 0, // lost connections
2789 ++ 0, // access denied errors
2790 ++ 0); // empty queries
2791 ++
2792 ++ if (my_hash_insert(users_or_clients, (byte*)user_stats))
2793 ++ {
2794 ++ my_free((char*)user_stats, 0);
2795 ++ return 1; // Out of memory
2796 ++ }
2797 ++ }
2798 ++ user_stats->total_connections++;
2799 ++ return 0;
2800 ++}
2801 ++
2802 ++// Increments the global user and client stats connection count. If 'use_lock'
2803 ++// is true, LOCK_global_user_client_stats will be locked/unlocked. Returns
2804 ++// 0 on success, 1 on error.
2805 ++static int increment_connection_count(THD* thd, bool use_lock)
2806 ++{
2807 ++ char* user_string = get_valid_user_string(thd->main_security_ctx.user);
2808 ++ const char* client_string = get_client_host(thd);
2809 ++ int return_value = 0;
2810 ++
2811 ++ if (!opt_userstat_running)
2812 ++ return return_value;
2813 ++
2814 ++ if (use_lock) pthread_mutex_lock(&LOCK_global_user_client_stats);
2815 ++
2816 ++ if (increment_count_by_name(user_string, user_string,
2817 ++ &global_user_stats, thd))
2818 ++ {
2819 ++ return_value = 1;
2820 ++ goto end;
2821 ++ }
2822 ++ if (increment_count_by_name(client_string,
2823 ++ user_string,
2824 ++ &global_client_stats, thd))
2825 ++ {
2826 ++ return_value = 1;
2827 ++ goto end;
2828 ++ }
2829 ++
2830 ++end:
2831 ++ if (use_lock) pthread_mutex_unlock(&LOCK_global_user_client_stats);
2832 ++ return return_value;
2833 ++}
2834 ++
2835 ++// Used to update the global user and client stats.
2836 ++static void update_global_user_stats_with_user(THD* thd,
2837 ++ USER_STATS* user_stats,
2838 ++ time_t now)
2839 ++{
2840 ++ user_stats->connected_time += now - thd->last_global_update_time;
2841 ++ thd->last_global_update_time = now;
2842 ++ user_stats->busy_time += thd->diff_total_busy_time;
2843 ++ user_stats->cpu_time += thd->diff_total_cpu_time;
2844 ++ user_stats->bytes_received += thd->diff_total_bytes_received;
2845 ++ user_stats->bytes_sent += thd->diff_total_bytes_sent;
2846 ++ user_stats->binlog_bytes_written += thd->diff_total_binlog_bytes_written;
2847 ++ user_stats->rows_fetched += thd->diff_total_sent_rows;
2848 ++ user_stats->rows_updated += thd->diff_total_updated_rows;
2849 ++ user_stats->rows_read += thd->diff_total_read_rows;
2850 ++ user_stats->select_commands += thd->diff_select_commands;
2851 ++ user_stats->update_commands += thd->diff_update_commands;
2852 ++ user_stats->other_commands += thd->diff_other_commands;
2853 ++ user_stats->commit_trans += thd->diff_commit_trans;
2854 ++ user_stats->rollback_trans += thd->diff_rollback_trans;
2855 ++ user_stats->denied_connections += thd->diff_denied_connections;
2856 ++ user_stats->lost_connections += thd->diff_lost_connections;
2857 ++ user_stats->access_denied_errors += thd->diff_access_denied_errors;
2858 ++ user_stats->empty_queries += thd->diff_empty_queries;
2859 ++}
2860 ++
2861 ++// Updates the global stats of a user or client
2862 ++void update_global_user_stats(THD* thd, bool create_user, time_t now)
2863 ++{
2864 ++ if (opt_userstat_running) {
2865 ++ char* user_string = get_valid_user_string(thd->main_security_ctx.user);
2866 ++ const char* client_string = get_client_host(thd);
2867 ++
2868 ++ USER_STATS* user_stats;
2869 ++ pthread_mutex_lock(&LOCK_global_user_client_stats);
2870 ++
2871 ++ // Update by user name
2872 ++ if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
2873 ++ (byte*)user_string,
2874 ++ strlen(user_string)))) {
2875 ++ // Found user.
2876 ++ update_global_user_stats_with_user(thd, user_stats, now);
2877 ++ } else {
2878 ++ // Create the entry
2879 ++ if (create_user) {
2880 ++ increment_count_by_name(user_string, user_string,
2881 ++ &global_user_stats, thd);
2882 ++ }
2883 ++ }
2884 ++
2885 ++ // Update by client IP
2886 ++ if ((user_stats = (USER_STATS*)hash_search(&global_client_stats,
2887 ++ (byte*)client_string,
2888 ++ strlen(client_string)))) {
2889 ++ // Found by client IP
2890 ++ update_global_user_stats_with_user(thd, user_stats, now);
2891 ++ } else {
2892 ++ // Create the entry
2893 ++ if (create_user) {
2894 ++ increment_count_by_name(client_string,
2895 ++ user_string,
2896 ++ &global_client_stats, thd);
2897 ++ }
2898 ++ }
2899 ++ thd->reset_diff_stats();
2900 ++
2901 ++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
2902 ++ } else {
2903 ++ thd->reset_diff_stats();
2904 ++ }
2905 ++}
2906 ++
2907 ++// Determines the concurrent number of connections of current threads.
2908 ++static void set_connections_stats()
2909 ++{
2910 ++ USER_STATS* user_stats;
2911 ++
2912 ++ pthread_mutex_lock(&LOCK_global_user_client_stats);
2913 ++ pthread_mutex_lock(&LOCK_thread_count);
2914 ++
2915 ++ // Resets all concurrent connections to 0.
2916 ++ for (int i = 0; i < global_user_stats.records; ++i) {
2917 ++ user_stats = (USER_STATS*)hash_element(&global_user_stats, i);
2918 ++ user_stats->concurrent_connections = 0;
2919 ++ }
2920 ++ for (int i = 0; i < global_client_stats.records; ++i) {
2921 ++ user_stats = (USER_STATS*)hash_element(&global_client_stats, i);
2922 ++ user_stats->concurrent_connections = 0;
2923 ++ }
2924 ++
2925 ++ I_List_iterator<THD> it(threads);
2926 ++ THD* thd;
2927 ++ time_t now = time(NULL);
2928 ++ // Iterates through the current threads.
2929 ++ while ((thd = it++)) {
2930 ++ char* user_string = get_valid_user_string(thd->main_security_ctx.user);
2931 ++ if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
2932 ++ (byte*)user_string,
2933 ++ strlen(user_string)))) {
2934 ++ // Found user.
2935 ++ user_stats->concurrent_connections++;
2936 ++ update_global_user_stats_with_user(thd, user_stats, now);
2937 ++ } else {
2938 ++ // The user name should exist.
2939 ++ if (user_string == mysql_system_user) {
2940 ++ // Only create the user if it is the mysql_system_user
2941 ++ increment_count_by_name(user_string, user_string,
2942 ++ &global_user_stats, thd);
2943 ++ }
2944 ++ }
2945 ++
2946 ++ const char* client_string = get_client_host(thd);
2947 ++ if ((user_stats = (USER_STATS*)hash_search(&global_client_stats,
2948 ++ (byte*)client_string,
2949 ++ strlen(client_string)))) {
2950 ++ // Found user.
2951 ++ user_stats->concurrent_connections++;
2952 ++ update_global_user_stats_with_user(thd, user_stats, now);
2953 ++ } else {
2954 ++ // Do nothing, unlike what is done for global_user_stats
2955 ++ }
2956 ++ thd->reset_diff_stats();
2957 ++ }
2958 ++ pthread_mutex_unlock(&LOCK_thread_count);
2959 ++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
2960 ++}
2961 ++
2962 + /*
2963 + Reset per-hour user resource limits when it has been more than
2964 + an hour since they were last checked
2965 +@@ -1184,6 +1610,8 @@
2966 + my_net_set_read_timeout(net, connect_timeout);
2967 + my_net_set_write_timeout(net, connect_timeout);
2968 +
2969 ++ bool create_user = true;
2970 ++
2971 + if ((error=check_connection(thd)))
2972 + { // Wrong permissions
2973 + if (error > 0)
2974 +@@ -1193,8 +1621,22 @@
2975 + my_sleep(1000); /* must wait after eof() */
2976 + #endif
2977 + statistic_increment(aborted_connects,&LOCK_status);
2978 ++ thd->diff_denied_connections++;
2979 ++ if (error == -2) {
2980 ++ // Do not create statistics for a user who does not exist, or failed
2981 ++ // to authenticate.
2982 ++ create_user = false;
2983 ++ }
2984 + goto end_thread;
2985 + }
2986 ++
2987 ++ thd->reset_stats();
2988 ++ // Updates global user connection stats.
2989 ++ if (increment_connection_count(thd, true)) {
2990 ++ net_send_error(thd, ER_OUTOFMEMORY); // Out of memory
2991 ++ goto end_thread;
2992 ++ }
2993 ++
2994 + #ifdef __NETWARE__
2995 + netware_reg_user(sctx->ip, sctx->user, "MySQL");
2996 + #endif
2997 +@@ -1251,6 +1693,7 @@
2998 + (net->vio && net->error && net->report_error))
2999 + {
3000 + statistic_increment(aborted_threads, &LOCK_status);
3001 ++ thd->diff_lost_connections++;
3002 + }
3003 +
3004 + if (net->error && net->vio != 0 && net->report_error)
3005 +@@ -1270,6 +1713,8 @@
3006 +
3007 + end_thread:
3008 + close_connection(thd, 0, 1);
3009 ++ thd->update_stats(false);
3010 ++ update_global_user_stats(thd, create_user, time(NULL));
3011 + end_thread(thd,1);
3012 + /*
3013 + If end_thread returns, we are either running with --one-thread
3014 +@@ -1601,6 +2046,13 @@
3015 +
3016 + thd->clear_error(); // Clear error message
3017 +
3018 ++ thd->updated_row_count=0;
3019 ++ thd->busy_time=0;
3020 ++ thd->cpu_time=0;
3021 ++ thd->bytes_received=0;
3022 ++ thd->bytes_sent=0;
3023 ++ thd->binlog_bytes_written=0;
3024 ++
3025 + net_new_transaction(net);
3026 +
3027 + packet_length= my_net_read(net);
3028 +@@ -1759,6 +2211,9 @@
3029 + }
3030 +
3031 + thd->command=command;
3032 ++ // To increment the corrent command counter for user stats, 'command' must
3033 ++ // be saved because it is set to COM_SLEEP at the end of this function.
3034 ++ thd->old_command = command;
3035 + /*
3036 + Commands which always take a long time are logged into
3037 + the slow log only if opt_log_slow_admin_statements is set.
3038 +@@ -4539,6 +4994,15 @@
3039 + if (check_global_access(thd,RELOAD_ACL))
3040 + goto error;
3041 +
3042 ++ if(lex->type & REFRESH_SLOW_QUERY_LOG) {
3043 ++ /* We are only flushing slow query log */
3044 ++ mysql_slow_log.new_file(1);
3045 ++
3046 ++ send_ok(thd);
3047 ++ break;
3048 ++ }
3049 ++
3050 ++
3051 + /*
3052 + reload_acl_and_cache() will tell us if we are allowed to write to the
3053 + binlog or not.
3054 +@@ -4847,6 +5311,7 @@
3055 + {
3056 + if (check_global_access(thd, SUPER_ACL))
3057 + {
3058 ++ thd->diff_access_denied_errors++;
3059 + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
3060 + goto create_sp_error;
3061 + }
3062 +@@ -5691,6 +6156,7 @@
3063 + if (!no_errors)
3064 + {
3065 + const char *db_name= db ? db : thd->db;
3066 ++ thd->diff_access_denied_errors++;
3067 + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
3068 + sctx->priv_user, sctx->priv_host, db_name);
3069 + }
3070 +@@ -5726,6 +6192,7 @@
3071 + { // We can never grant this
3072 + DBUG_PRINT("error",("No possible access"));
3073 + if (!no_errors)
3074 ++ thd->diff_access_denied_errors++;
3075 + my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
3076 + sctx->priv_user,
3077 + sctx->priv_host,
3078 +@@ -5758,11 +6225,15 @@
3079 +
3080 + DBUG_PRINT("error",("Access denied"));
3081 + if (!no_errors)
3082 ++ {
3083 ++ // increment needs !no_errors condition, otherwise double counting.
3084 ++ thd->diff_access_denied_errors++;
3085 + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
3086 + sctx->priv_user, sctx->priv_host,
3087 + (db ? db : (thd->db ?
3088 + thd->db :
3089 + "unknown"))); /* purecov: tested */
3090 ++ }
3091 + DBUG_RETURN(TRUE); /* purecov: tested */
3092 + #endif /* NO_EMBEDDED_ACCESS_CHECKS */
3093 + }
3094 +@@ -5796,6 +6267,7 @@
3095 + if ((thd->security_ctx->master_access & want_access))
3096 + return 0;
3097 + get_privilege_desc(command, sizeof(command), want_access);
3098 ++ thd->diff_access_denied_errors++;
3099 + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
3100 + return 1;
3101 + #endif /* NO_EMBEDDED_ACCESS_CHECKS */
3102 +@@ -5828,6 +6300,7 @@
3103 +
3104 + if (!thd->col_access && check_grant_db(thd, dst_db_name))
3105 + {
3106 ++ thd->diff_access_denied_errors++;
3107 + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
3108 + thd->security_ctx->priv_user,
3109 + thd->security_ctx->priv_host,
3110 +@@ -5859,6 +6332,12 @@
3111 + check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE);
3112 + }
3113 +
3114 ++
3115 ++ case SCH_USER_STATS:
3116 ++ case SCH_CLIENT_STATS:
3117 ++ return check_global_access(thd, SUPER_ACL | PROCESS_ACL);
3118 ++ case SCH_TABLE_STATS:
3119 ++ case SCH_INDEX_STATS:
3120 + case SCH_OPEN_TABLES:
3121 + case SCH_VARIABLES:
3122 + case SCH_STATUS:
3123 +@@ -5912,8 +6391,8 @@
3124 + #ifndef NO_EMBEDDED_ACCESS_CHECKS
3125 + TABLE_LIST *org_tables= tables;
3126 + #endif
3127 ++ Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
3128 + TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
3129 +- Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
3130 + /*
3131 + The check that first_not_own_table is not reached is for the case when
3132 + the given table list refers to the list for prelocking (contains tables
3133 +@@ -5930,9 +6409,12 @@
3134 + (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
3135 + {
3136 + if (!no_errors)
3137 ++ {
3138 ++ thd->diff_access_denied_errors++;
3139 + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
3140 + sctx->priv_user, sctx->priv_host,
3141 + INFORMATION_SCHEMA_NAME.str);
3142 ++ }
3143 + return TRUE;
3144 + }
3145 + /*
3146 +@@ -6442,6 +6924,30 @@
3147 + lex_start(thd);
3148 + mysql_reset_thd_for_next_command(thd);
3149 +
3150 ++ int start_time_error = 0;
3151 ++ int end_time_error = 0;
3152 ++ struct timeval start_time, end_time;
3153 ++ double start_usecs = 0;
3154 ++ double end_usecs = 0;
3155 ++ /* cpu time */
3156 ++ int cputime_error = 0;
3157 ++ struct timespec tp;
3158 ++ double start_cpu_nsecs = 0;
3159 ++ double end_cpu_nsecs = 0;
3160 ++
3161 ++ if (opt_userstat_running) {
3162 ++#ifdef HAVE_CLOCK_GETTIME
3163 ++ /* get start cputime */
3164 ++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3165 ++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3166 ++#endif
3167 ++
3168 ++ // Gets the start time, in order to measure how long this command takes.
3169 ++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
3170 ++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
3171 ++ }
3172 ++ }
3173 ++
3174 + if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
3175 + {
3176 + LEX *lex= thd->lex;
3177 +@@ -6520,6 +7026,43 @@
3178 + *found_semicolon= NULL;
3179 + }
3180 +
3181 ++ if (opt_userstat_running) {
3182 ++ // Gets the end time.
3183 ++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
3184 ++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
3185 ++ }
3186 ++
3187 ++ // Calculates the difference between the end and start times.
3188 ++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
3189 ++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
3190 ++ // In case there are bad values, 2629743 is the #seconds in a month.
3191 ++ if (thd->busy_time > 2629743) {
3192 ++ thd->busy_time = 0;
3193 ++ }
3194 ++ } else {
3195 ++ // end time went back in time, or gettimeofday() failed.
3196 ++ thd->busy_time = 0;
3197 ++ }
3198 ++
3199 ++#ifdef HAVE_CLOCK_GETTIME
3200 ++ /* get end cputime */
3201 ++ if (!cputime_error &&
3202 ++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3203 ++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3204 ++#endif
3205 ++ if (start_cpu_nsecs && !cputime_error) {
3206 ++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
3207 ++ // In case there are bad values, 2629743 is the #seconds in a month.
3208 ++ if (thd->cpu_time > 2629743) {
3209 ++ thd->cpu_time = 0;
3210 ++ }
3211 ++ } else
3212 ++ thd->cpu_time = 0;
3213 ++ }
3214 ++ // Updates THD stats and the global user stats.
3215 ++ thd->update_stats(true);
3216 ++ update_global_user_stats(thd, true, time(NULL));
3217 ++
3218 + DBUG_VOID_RETURN;
3219 + }
3220 +
3221 +@@ -7531,8 +8074,35 @@
3222 + pthread_mutex_unlock(&LOCK_active_mi);
3223 + }
3224 + #endif
3225 +- if (options & REFRESH_USER_RESOURCES)
3226 +- reset_mqh((LEX_USER *) NULL);
3227 ++ if (options & REFRESH_TABLE_STATS)
3228 ++ {
3229 ++ pthread_mutex_lock(&LOCK_global_table_stats);
3230 ++ free_global_table_stats();
3231 ++ init_global_table_stats();
3232 ++ pthread_mutex_unlock(&LOCK_global_table_stats);
3233 ++ }
3234 ++ if (options & REFRESH_INDEX_STATS)
3235 ++ {
3236 ++ pthread_mutex_lock(&LOCK_global_index_stats);
3237 ++ free_global_index_stats();
3238 ++ init_global_index_stats();
3239 ++ pthread_mutex_unlock(&LOCK_global_index_stats);
3240 ++ }
3241 ++ if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS))
3242 ++ {
3243 ++ pthread_mutex_lock(&LOCK_global_user_client_stats);
3244 ++ if (options & REFRESH_USER_STATS)
3245 ++ {
3246 ++ free_global_user_stats();
3247 ++ init_global_user_stats();
3248 ++ }
3249 ++ if (options & REFRESH_CLIENT_STATS)
3250 ++ {
3251 ++ free_global_client_stats();
3252 ++ init_global_client_stats();
3253 ++ }
3254 ++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
3255 ++ }
3256 + *write_to_binlog= tmp_write_to_binlog;
3257 + return result;
3258 + }
3259 +diff -r 592f6c3641ba sql/sql_prepare.cc
3260 +--- a/sql/sql_prepare.cc Wed Jul 29 13:33:34 2009 -0700
3261 ++++ b/sql/sql_prepare.cc Wed Jul 29 13:34:11 2009 -0700
3262 +@@ -81,6 +81,9 @@
3263 + #include <mysql_com.h>
3264 + #endif
3265 +
3266 ++// Uses the THD to update the global stats by user name and client IP
3267 ++void update_global_user_stats(THD* thd, bool create_user, time_t now);
3268 ++
3269 + /* A result class used to send cursor rows using the binary protocol. */
3270 +
3271 + class Select_fetch_protocol_prep: public select_send
3272 +@@ -1910,8 +1913,32 @@
3273 + /* First of all clear possible warnings from the previous command */
3274 + mysql_reset_thd_for_next_command(thd);
3275 +
3276 ++ int start_time_error = 0;
3277 ++ int end_time_error = 0;
3278 ++ struct timeval start_time, end_time;
3279 ++ double start_usecs = 0;
3280 ++ double end_usecs = 0;
3281 ++ /* cpu time */
3282 ++ int cputime_error = 0;
3283 ++ struct timespec tp;
3284 ++ double start_cpu_nsecs = 0;
3285 ++ double end_cpu_nsecs = 0;
3286 ++
3287 ++ if (opt_userstat_running) {
3288 ++#ifdef HAVE_CLOCK_GETTIME
3289 ++ /* get start cputime */
3290 ++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3291 ++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3292 ++#endif
3293 ++
3294 ++ // Gets the start time, in order to measure how long this command takes.
3295 ++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
3296 ++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
3297 ++ }
3298 ++ }
3299 ++
3300 + if (! (stmt= new Prepared_statement(thd, &thd->protocol_prep)))
3301 +- DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */
3302 ++ goto end; /* out of memory: error is set in Sql_alloc */
3303 +
3304 + if (thd->stmt_map.insert(thd, stmt))
3305 + {
3306 +@@ -1919,7 +1946,7 @@
3307 + The error is set in the insert. The statement itself
3308 + will be also deleted there (this is how the hash works).
3309 + */
3310 +- DBUG_VOID_RETURN;
3311 ++ goto end;
3312 + }
3313 +
3314 + /* Reset warnings from previous command */
3315 +@@ -1941,6 +1968,44 @@
3316 + thd->stmt_map.erase(stmt);
3317 + }
3318 + /* check_prepared_statemnt sends the metadata packet in case of success */
3319 ++end:
3320 ++ if (opt_userstat_running) {
3321 ++ // Gets the end time.
3322 ++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
3323 ++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
3324 ++ }
3325 ++
3326 ++ // Calculates the difference between the end and start times.
3327 ++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
3328 ++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
3329 ++ // In case there are bad values, 2629743 is the #seconds in a month.
3330 ++ if (thd->busy_time > 2629743) {
3331 ++ thd->busy_time = 0;
3332 ++ }
3333 ++ } else {
3334 ++ // end time went back in time, or gettimeofday() failed.
3335 ++ thd->busy_time = 0;
3336 ++ }
3337 ++
3338 ++#ifdef HAVE_CLOCK_GETTIME
3339 ++ /* get end cputime */
3340 ++ if (!cputime_error &&
3341 ++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3342 ++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3343 ++#endif
3344 ++ if (start_cpu_nsecs && !cputime_error) {
3345 ++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
3346 ++ // In case there are bad values, 2629743 is the #seconds in a month.
3347 ++ if (thd->cpu_time > 2629743) {
3348 ++ thd->cpu_time = 0;
3349 ++ }
3350 ++ } else
3351 ++ thd->cpu_time = 0;
3352 ++ }
3353 ++ // Updates THD stats and the global user stats.
3354 ++ thd->update_stats(true);
3355 ++ update_global_user_stats(thd, true, time(NULL));
3356 ++
3357 + DBUG_VOID_RETURN;
3358 + }
3359 +
3360 +@@ -2281,8 +2346,32 @@
3361 + /* First of all clear possible warnings from the previous command */
3362 + mysql_reset_thd_for_next_command(thd);
3363 +
3364 ++ int start_time_error = 0;
3365 ++ int end_time_error = 0;
3366 ++ struct timeval start_time, end_time;
3367 ++ double start_usecs = 0;
3368 ++ double end_usecs = 0;
3369 ++ /* cpu time */
3370 ++ int cputime_error = 0;
3371 ++ struct timespec tp;
3372 ++ double start_cpu_nsecs = 0;
3373 ++ double end_cpu_nsecs = 0;
3374 ++
3375 ++ if (opt_userstat_running) {
3376 ++#ifdef HAVE_CLOCK_GETTIME
3377 ++ /* get start cputime */
3378 ++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3379 ++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3380 ++#endif
3381 ++
3382 ++ // Gets the start time, in order to measure how long this command takes.
3383 ++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
3384 ++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
3385 ++ }
3386 ++ }
3387 ++
3388 + if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
3389 +- DBUG_VOID_RETURN;
3390 ++ goto end;
3391 +
3392 + #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
3393 + thd->profiling.set_query_source(stmt->query, stmt->query_length);
3394 +@@ -2325,11 +2414,50 @@
3395 + test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
3396 + if (!(specialflag & SPECIAL_NO_PRIOR))
3397 + my_pthread_setprio(pthread_self(), WAIT_PRIOR);
3398 +- DBUG_VOID_RETURN;
3399 ++ goto end;
3400 +
3401 + set_params_data_err:
3402 + my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_execute");
3403 + reset_stmt_params(stmt);
3404 ++
3405 ++end:
3406 ++ if (opt_userstat_running) {
3407 ++ // Gets the end time.
3408 ++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
3409 ++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
3410 ++ }
3411 ++
3412 ++ // Calculates the difference between the end and start times.
3413 ++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
3414 ++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
3415 ++ // In case there are bad values, 2629743 is the #seconds in a month.
3416 ++ if (thd->busy_time > 2629743) {
3417 ++ thd->busy_time = 0;
3418 ++ }
3419 ++ } else {
3420 ++ // end time went back in time, or gettimeofday() failed.
3421 ++ thd->busy_time = 0;
3422 ++ }
3423 ++
3424 ++#ifdef HAVE_CLOCK_GETTIME
3425 ++ /* get end cputime */
3426 ++ if (!cputime_error &&
3427 ++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3428 ++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3429 ++#endif
3430 ++ if (start_cpu_nsecs && !cputime_error) {
3431 ++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
3432 ++ // In case there are bad values, 2629743 is the #seconds in a month.
3433 ++ if (thd->cpu_time > 2629743) {
3434 ++ thd->cpu_time = 0;
3435 ++ }
3436 ++ } else
3437 ++ thd->cpu_time = 0;
3438 ++ }
3439 ++ // Updates THD stats and the global user stats.
3440 ++ thd->update_stats(true);
3441 ++ update_global_user_stats(thd, true, time(NULL));
3442 ++
3443 + DBUG_VOID_RETURN;
3444 + }
3445 +
3446 +@@ -2423,6 +2551,31 @@
3447 +
3448 + /* First of all clear possible warnings from the previous command */
3449 + mysql_reset_thd_for_next_command(thd);
3450 ++
3451 ++ int start_time_error = 0;
3452 ++ int end_time_error = 0;
3453 ++ struct timeval start_time, end_time;
3454 ++ double start_usecs = 0;
3455 ++ double end_usecs = 0;
3456 ++ /* cpu time */
3457 ++ int cputime_error = 0;
3458 ++ struct timespec tp;
3459 ++ double start_cpu_nsecs = 0;
3460 ++ double end_cpu_nsecs = 0;
3461 ++
3462 ++ if (opt_userstat_running) {
3463 ++#ifdef HAVE_CLOCK_GETTIME
3464 ++ /* get start cputime */
3465 ++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3466 ++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3467 ++#endif
3468 ++
3469 ++ // Gets the start time, in order to measure how long this command takes.
3470 ++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
3471 ++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
3472 ++ }
3473 ++ }
3474 ++
3475 + statistic_increment(thd->status_var.com_stmt_fetch, &LOCK_status);
3476 + if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_fetch")))
3477 + DBUG_VOID_RETURN;
3478 +@@ -2455,6 +2608,43 @@
3479 + thd->restore_backup_statement(stmt, &stmt_backup);
3480 + thd->stmt_arena= thd;
3481 +
3482 ++ if (opt_userstat_running) {
3483 ++ // Gets the end time.
3484 ++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
3485 ++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
3486 ++ }
3487 ++
3488 ++ // Calculates the difference between the end and start times.
3489 ++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
3490 ++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
3491 ++ // In case there are bad values, 2629743 is the #seconds in a month.
3492 ++ if (thd->busy_time > 2629743) {
3493 ++ thd->busy_time = 0;
3494 ++ }
3495 ++ } else {
3496 ++ // end time went back in time, or gettimeofday() failed.
3497 ++ thd->busy_time = 0;
3498 ++ }
3499 ++
3500 ++#ifdef HAVE_CLOCK_GETTIME
3501 ++ /* get end cputime */
3502 ++ if (!cputime_error &&
3503 ++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3504 ++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3505 ++#endif
3506 ++ if (start_cpu_nsecs && !cputime_error) {
3507 ++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
3508 ++ // In case there are bad values, 2629743 is the #seconds in a month.
3509 ++ if (thd->cpu_time > 2629743) {
3510 ++ thd->cpu_time = 0;
3511 ++ }
3512 ++ } else
3513 ++ thd->cpu_time = 0;
3514 ++ }
3515 ++ // Updates THD stats and the global user stats.
3516 ++ thd->update_stats(true);
3517 ++ update_global_user_stats(thd, true, time(NULL));
3518 ++
3519 + DBUG_VOID_RETURN;
3520 + }
3521 +
3522 +@@ -2487,6 +2677,30 @@
3523 + /* First of all clear possible warnings from the previous command */
3524 + mysql_reset_thd_for_next_command(thd);
3525 +
3526 ++ int start_time_error = 0;
3527 ++ int end_time_error = 0;
3528 ++ struct timeval start_time, end_time;
3529 ++ double start_usecs = 0;
3530 ++ double end_usecs = 0;
3531 ++ /* cpu time */
3532 ++ int cputime_error = 0;
3533 ++ struct timespec tp;
3534 ++ double start_cpu_nsecs = 0;
3535 ++ double end_cpu_nsecs = 0;
3536 ++
3537 ++ if (opt_userstat_running) {
3538 ++#ifdef HAVE_CLOCK_GETTIME
3539 ++ /* get start cputime */
3540 ++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3541 ++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3542 ++#endif
3543 ++
3544 ++ // Gets the start time, in order to measure how long this command takes.
3545 ++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
3546 ++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
3547 ++ }
3548 ++ }
3549 ++
3550 + statistic_increment(thd->status_var.com_stmt_reset, &LOCK_status);
3551 + if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
3552 + DBUG_VOID_RETURN;
3553 +@@ -2503,6 +2717,43 @@
3554 +
3555 + send_ok(thd);
3556 +
3557 ++ if (opt_userstat_running) {
3558 ++ // Gets the end time.
3559 ++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
3560 ++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
3561 ++ }
3562 ++
3563 ++ // Calculates the difference between the end and start times.
3564 ++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
3565 ++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
3566 ++ // In case there are bad values, 2629743 is the #seconds in a month.
3567 ++ if (thd->busy_time > 2629743) {
3568 ++ thd->busy_time = 0;
3569 ++ }
3570 ++ } else {
3571 ++ // end time went back in time, or gettimeofday() failed.
3572 ++ thd->busy_time = 0;
3573 ++ }
3574 ++
3575 ++#ifdef HAVE_CLOCK_GETTIME
3576 ++ /* get end cputime */
3577 ++ if (!cputime_error &&
3578 ++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
3579 ++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
3580 ++#endif
3581 ++ if (start_cpu_nsecs && !cputime_error) {
3582 ++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
3583 ++ // In case there are bad values, 2629743 is the #seconds in a month.
3584 ++ if (thd->cpu_time > 2629743) {
3585 ++ thd->cpu_time = 0;
3586 ++ }
3587 ++ } else
3588 ++ thd->cpu_time = 0;
3589 ++ }
3590 ++ // Updates THD stats and the global user stats.
3591 ++ thd->update_stats(true);
3592 ++ update_global_user_stats(thd, true, time(NULL));
3593 ++
3594 + DBUG_VOID_RETURN;
3595 + }
3596 +
3597 +diff -r 592f6c3641ba sql/sql_show.cc
3598 +--- a/sql/sql_show.cc Wed Jul 29 13:33:34 2009 -0700
3599 ++++ b/sql/sql_show.cc Wed Jul 29 13:34:11 2009 -0700
3600 +@@ -540,6 +540,7 @@
3601 + sctx->master_access);
3602 + if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
3603 + {
3604 ++ thd->diff_access_denied_errors++;
3605 + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
3606 + sctx->priv_user, sctx->host_or_ip, dbname);
3607 + mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
3608 +@@ -1890,6 +1891,300 @@
3609 + DBUG_RETURN(FALSE);
3610 + }
3611 +
3612 ++/*
3613 ++ Aggregate values for mapped_user entries by their role.
3614 ++
3615 ++ SYNOPSIS
3616 ++ aggregate_user_stats
3617 ++ all_user_stats - input to aggregate
3618 ++ agg_user_stats - returns aggregated values
3619 ++
3620 ++ RETURN
3621 ++ 0 - OK
3622 ++ 1 - error
3623 ++ */
3624 ++static int
3625 ++aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats)
3626 ++{
3627 ++ DBUG_ENTER("aggregate_user_stats");
3628 ++ if (hash_init(agg_user_stats, system_charset_info,
3629 ++ max(all_user_stats->records, 1),
3630 ++ 0, 0, (hash_get_key)get_key_user_stats,
3631 ++ (hash_free_key)free_user_stats, 0))
3632 ++ {
3633 ++ sql_print_error("Malloc in aggregate_user_stats failed");
3634 ++ DBUG_RETURN(1);
3635 ++ }
3636 ++
3637 ++ for (int i = 0; i < all_user_stats->records; ++i) {
3638 ++ USER_STATS *user = (USER_STATS*)hash_element(all_user_stats, i);
3639 ++ USER_STATS *agg_user;
3640 ++ if (!(agg_user = (USER_STATS*)hash_search(agg_user_stats,
3641 ++ (byte*)user->priv_user,
3642 ++ strlen(user->priv_user))))
3643 ++ {
3644 ++ // First entry for this role.
3645 ++ if (!(agg_user =
3646 ++ (USER_STATS*) my_malloc(sizeof(USER_STATS), MYF(MY_WME | MY_ZEROFILL))))
3647 ++ {
3648 ++ sql_print_error("Malloc in aggregate_user_stats failed");
3649 ++ DBUG_RETURN(1);
3650 ++ }
3651 ++
3652 ++ init_user_stats(agg_user, user->priv_user, user->priv_user,
3653 ++ user->total_connections, user->concurrent_connections,
3654 ++ user->connected_time, user->busy_time, user->cpu_time,
3655 ++ user->bytes_received, user->bytes_sent,
3656 ++ user->binlog_bytes_written,
3657 ++ user->rows_fetched, user->rows_updated, user->rows_read,
3658 ++ user->select_commands, user->update_commands,
3659 ++ user->other_commands,
3660 ++ user->commit_trans, user->rollback_trans,
3661 ++ user->denied_connections, user->lost_connections,
3662 ++ user->access_denied_errors, user->empty_queries);
3663 ++
3664 ++ if (my_hash_insert(agg_user_stats, (byte*)agg_user))
3665 ++ {
3666 ++ // Out of memory.
3667 ++ my_free((char*)agg_user, 0);
3668 ++ sql_print_error("Malloc in aggregate_user_stats failed");
3669 ++ DBUG_RETURN(1);
3670 ++ }
3671 ++ }
3672 ++ else
3673 ++ {
3674 ++ // Aggregate with existing values for this role.
3675 ++ add_user_stats(agg_user,
3676 ++ user->total_connections, user->concurrent_connections,
3677 ++ user->connected_time, user->busy_time, user->cpu_time,
3678 ++ user->bytes_received, user->bytes_sent,
3679 ++ user->binlog_bytes_written,
3680 ++ user->rows_fetched, user->rows_updated, user->rows_read,
3681 ++ user->select_commands, user->update_commands,
3682 ++ user->other_commands,
3683 ++ user->commit_trans, user->rollback_trans,
3684 ++ user->denied_connections, user->lost_connections,
3685 ++ user->access_denied_errors, user->empty_queries);
3686 ++ }
3687 ++ }
3688 ++ DBUG_PRINT("exit", ("aggregated %d input into %d output entries",
3689 ++ all_user_stats->records, agg_user_stats->records));
3690 ++ DBUG_RETURN(0);
3691 ++}
3692 ++
3693 ++/*
3694 ++ Write result to network for SHOW USER_STATISTICS
3695 ++
3696 ++ SYNOPSIS
3697 ++ send_user_stats
3698 ++ all_user_stats - values to return
3699 ++ table - I_S table
3700 ++
3701 ++ RETURN
3702 ++ 0 - OK
3703 ++ 1 - error
3704 ++ */
3705 ++int send_user_stats(THD* thd, HASH *all_user_stats, TABLE *table)
3706 ++{
3707 ++ DBUG_ENTER("send_user_stats");
3708 ++ for (int i = 0; i < all_user_stats->records; ++i) {
3709 ++ restore_record(table, s->default_values);
3710 ++ USER_STATS *user_stats = (USER_STATS*)hash_element(all_user_stats, i);
3711 ++ table->field[0]->store(user_stats->user, strlen(user_stats->user), system_charset_info);
3712 ++ table->field[1]->store((longlong)user_stats->total_connections);
3713 ++ table->field[2]->store((longlong)user_stats->concurrent_connections);
3714 ++ table->field[3]->store((longlong)user_stats->connected_time);
3715 ++ table->field[4]->store((longlong)user_stats->busy_time);
3716 ++ table->field[5]->store((longlong)user_stats->cpu_time);
3717 ++ table->field[6]->store((longlong)user_stats->bytes_received);
3718 ++ table->field[7]->store((longlong)user_stats->bytes_sent);
3719 ++ table->field[8]->store((longlong)user_stats->binlog_bytes_written);
3720 ++ table->field[9]->store((longlong)user_stats->rows_fetched);
3721 ++ table->field[10]->store((longlong)user_stats->rows_updated);
3722 ++ table->field[11]->store((longlong)user_stats->rows_read);
3723 ++ table->field[12]->store((longlong)user_stats->select_commands);
3724 ++ table->field[13]->store((longlong)user_stats->update_commands);
3725 ++ table->field[14]->store((longlong)user_stats->other_commands);
3726 ++ table->field[15]->store((longlong)user_stats->commit_trans);
3727 ++ table->field[16]->store((longlong)user_stats->rollback_trans);
3728 ++ table->field[17]->store((longlong)user_stats->denied_connections);
3729 ++ table->field[18]->store((longlong)user_stats->lost_connections);
3730 ++ table->field[19]->store((longlong)user_stats->access_denied_errors);
3731 ++ table->field[20]->store((longlong)user_stats->empty_queries);
3732 ++ if (schema_table_store_record(thd, table))
3733 ++ {
3734 ++ DBUG_PRINT("error", ("store record error"));
3735 ++ DBUG_RETURN(1);
3736 ++ }
3737 ++ }
3738 ++ DBUG_RETURN(0);
3739 ++}
3740 ++
3741 ++/*
3742 ++ Process SHOW USER_STATISTICS
3743 ++
3744 ++ SYNOPSIS
3745 ++ mysqld_show_user_stats
3746 ++ thd - current thread
3747 ++ wild - limit results to the entry for this user
3748 ++ with_roles - when true, display role for mapped users
3749 ++
3750 ++ RETURN
3751 ++ 0 - OK
3752 ++ 1 - error
3753 ++ */
3754 ++
3755 ++
3756 ++int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond)
3757 ++{
3758 ++ TABLE *table= tables->table;
3759 ++ DBUG_ENTER("fill_schema_user_stats");
3760 ++
3761 ++ if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
3762 ++ DBUG_RETURN(1);
3763 ++
3764 ++ // Iterates through all the global stats and sends them to the client.
3765 ++ // Pattern matching on the client IP is supported.
3766 ++
3767 ++ pthread_mutex_lock(&LOCK_global_user_client_stats);
3768 ++ int result= send_user_stats(thd, &global_user_stats, table);
3769 ++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
3770 ++ if (result)
3771 ++ goto err;
3772 ++
3773 ++ DBUG_PRINT("exit", ("fill_schema_user_stats result is 0"));
3774 ++ DBUG_RETURN(0);
3775 ++
3776 ++ err:
3777 ++ DBUG_PRINT("exit", ("fill_schema_user_stats result is 1"));
3778 ++ DBUG_RETURN(1);
3779 ++}
3780 ++
3781 ++/*
3782 ++ Process SHOW CLIENT_STATISTICS
3783 ++
3784 ++ SYNOPSIS
3785 ++ mysqld_show_client_stats
3786 ++ thd - current thread
3787 ++ wild - limit results to the entry for this client
3788 ++
3789 ++ RETURN
3790 ++ 0 - OK
3791 ++ 1 - error
3792 ++ */
3793 ++
3794 ++
3795 ++int fill_schema_client_stats(THD* thd, TABLE_LIST* tables, COND* cond)
3796 ++{
3797 ++ TABLE *table= tables->table;
3798 ++ DBUG_ENTER("fill_schema_client_stats");
3799 ++
3800 ++ if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
3801 ++ DBUG_RETURN(1);
3802 ++
3803 ++ // Iterates through all the global stats and sends them to the client.
3804 ++ // Pattern matching on the client IP is supported.
3805 ++
3806 ++ pthread_mutex_lock(&LOCK_global_user_client_stats);
3807 ++ int result= send_user_stats(thd, &global_client_stats, table);
3808 ++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
3809 ++ if (result)
3810 ++ goto err;
3811 ++
3812 ++ DBUG_PRINT("exit", ("mysqld_show_client_stats result is 0"));
3813 ++ DBUG_RETURN(0);
3814 ++
3815 ++ err:
3816 ++ DBUG_PRINT("exit", ("mysqld_show_client_stats result is 1"));
3817 ++ DBUG_RETURN(1);
3818 ++}
3819 ++
3820 ++
3821 ++// Sends the global table stats back to the client.
3822 ++int fill_schema_table_stats(THD* thd, TABLE_LIST* tables, COND* cond)
3823 ++{
3824 ++ TABLE *table= tables->table;
3825 ++ DBUG_ENTER("fill_schema_table_stats");
3826 ++ char *table_full_name, *table_schema;
3827 ++
3828 ++ pthread_mutex_lock(&LOCK_global_table_stats);
3829 ++ for (int i = 0; i < global_table_stats.records; ++i) {
3830 ++ restore_record(table, s->default_values);
3831 ++ TABLE_STATS *table_stats =
3832 ++ (TABLE_STATS*)hash_element(&global_table_stats, i);
3833 ++
3834 ++ table_full_name= thd->strdup(table_stats->table);
3835 ++ table_schema= strsep(&table_full_name, ".");
3836 ++
3837 ++ TABLE_LIST tmp_table;
3838 ++ bzero((char*) &tmp_table,sizeof(tmp_table));
3839 ++ tmp_table.table_name= table_full_name;
3840 ++ tmp_table.db= table_schema;
3841 ++ tmp_table.grant.privilege= 0;
3842 ++ if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
3843 ++ &tmp_table.grant.privilege, 0, 0,
3844 ++ is_schema_db(table_schema)) ||
3845 ++ grant_option && check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
3846 ++ continue;
3847 ++
3848 ++ table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
3849 ++ table->field[1]->store(table_full_name, strlen(table_full_name), system_charset_info);
3850 ++ table->field[2]->store((longlong)table_stats->rows_read, TRUE);
3851 ++ table->field[3]->store((longlong)table_stats->rows_changed, TRUE);
3852 ++ table->field[4]->store((longlong)table_stats->rows_changed_x_indexes, TRUE);
3853 ++
3854 ++ if (schema_table_store_record(thd, table))
3855 ++ {
3856 ++ VOID(pthread_mutex_unlock(&LOCK_global_table_stats));
3857 ++ DBUG_RETURN(1);
3858 ++ }
3859 ++ }
3860 ++ pthread_mutex_unlock(&LOCK_global_table_stats);
3861 ++ DBUG_RETURN(0);
3862 ++}
3863 ++
3864 ++// Sends the global index stats back to the client.
3865 ++int fill_schema_index_stats(THD* thd, TABLE_LIST* tables, COND* cond)
3866 ++{
3867 ++ TABLE *table= tables->table;
3868 ++ DBUG_ENTER("fill_schema_index_stats");
3869 ++ char *index_full_name, *table_schema, *table_name;
3870 ++
3871 ++ pthread_mutex_lock(&LOCK_global_index_stats);
3872 ++ for (int i = 0; i < global_index_stats.records; ++i) {
3873 ++ restore_record(table, s->default_values);
3874 ++ INDEX_STATS *index_stats =
3875 ++ (INDEX_STATS*)hash_element(&global_index_stats, i);
3876 ++
3877 ++ index_full_name= thd->strdup(index_stats->index);
3878 ++ table_schema= strsep(&index_full_name, ".");
3879 ++ table_name= strsep(&index_full_name, ".");
3880 ++
3881 ++ TABLE_LIST tmp_table;
3882 ++ bzero((char*) &tmp_table,sizeof(tmp_table));
3883 ++ tmp_table.table_name= table_name;
3884 ++ tmp_table.db= table_schema;
3885 ++ tmp_table.grant.privilege= 0;
3886 ++ if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
3887 ++ &tmp_table.grant.privilege, 0, 0,
3888 ++ is_schema_db(table_schema)) ||
3889 ++ grant_option && check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
3890 ++ continue;
3891 ++
3892 ++ table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
3893 ++ table->field[1]->store(table_name, strlen(table_name), system_charset_info);
3894 ++ table->field[2]->store(index_full_name, strlen(index_full_name), system_charset_info);
3895 ++ table->field[3]->store((longlong)index_stats->rows_read, TRUE);
3896 ++
3897 ++ if (schema_table_store_record(thd, table))
3898 ++ {
3899 ++ VOID(pthread_mutex_unlock(&LOCK_global_index_stats));
3900 ++ DBUG_RETURN(1);
3901 ++ }
3902 ++ }
3903 ++ pthread_mutex_unlock(&LOCK_global_index_stats);
3904 ++ DBUG_RETURN(0);
3905 ++}
3906 +
3907 + /* collect status for all running threads */
3908 +
3909 +@@ -4500,6 +4795,77 @@
3910 + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
3911 + };
3912 +
3913 ++ST_FIELD_INFO user_stats_fields_info[]=
3914 ++{
3915 ++ {"USER", USERNAME_LENGTH, MYSQL_TYPE_STRING, 0, 0, "User"},
3916 ++ {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections"},
3917 ++ {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections"},
3918 ++ {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time"},
3919 ++ {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time"},
3920 ++ {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time"},
3921 ++ {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received"},
3922 ++ {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent"},
3923 ++ {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written"},
3924 ++ {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched"},
3925 ++ {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated"},
3926 ++ {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read"},
3927 ++ {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands"},
3928 ++ {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands"},
3929 ++ {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands"},
3930 ++ {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions"},
3931 ++ {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions"},
3932 ++ {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections"},
3933 ++ {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections"},
3934 ++ {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied"},
3935 ++ {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries"},
3936 ++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
3937 ++};
3938 ++
3939 ++ST_FIELD_INFO client_stats_fields_info[]=
3940 ++{
3941 ++ {"CLIENT", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Client"},
3942 ++ {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections"},
3943 ++ {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections"},
3944 ++ {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time"},
3945 ++ {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time"},
3946 ++ {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time"},
3947 ++ {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received"},
3948 ++ {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent"},
3949 ++ {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written"},
3950 ++ {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched"},
3951 ++ {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated"},
3952 ++ {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read"},
3953 ++ {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands"},
3954 ++ {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands"},
3955 ++ {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands"},
3956 ++ {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions"},
3957 ++ {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions"},
3958 ++ {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections"},
3959 ++ {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections"},
3960 ++ {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied"},
3961 ++ {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries"},
3962 ++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
3963 ++};
3964 ++
3965 ++
3966 ++ST_FIELD_INFO table_stats_fields_info[]=
3967 ++{
3968 ++ {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema"},
3969 ++ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name"},
3970 ++ {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read"},
3971 ++ {"ROWS_CHANGED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed"},
3972 ++ {"ROWS_CHANGED_X_INDEXES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed_x_#indexes"},
3973 ++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
3974 ++};
3975 ++
3976 ++ST_FIELD_INFO index_stats_fields_info[]=
3977 ++{
3978 ++ {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema"},
3979 ++ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name"},
3980 ++ {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name"},
3981 ++ {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read"},
3982 ++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
3983 ++};
3984 +
3985 + /*
3986 + Description of ST_FIELD_INFO in table.h
3987 +@@ -4509,6 +4875,8 @@
3988 + {
3989 + {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
3990 + fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0},
3991 ++ {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table,
3992 ++ fill_schema_client_stats, make_old_format, 0, -1, -1, 0},
3993 + {"COLLATIONS", collation_fields_info, create_schema_table,
3994 + fill_schema_collation, make_old_format, 0, -1, -1, 0},
3995 + {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
3996 +@@ -4517,6 +4885,8 @@
3997 + get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0},
3998 + {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
3999 + fill_schema_column_privileges, 0, 0, -1, -1, 0},
4000 ++ {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table,
4001 ++ fill_schema_index_stats, make_old_format, 0, -1, -1, 0},
4002 + {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4003 + get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
4004 + {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4005 +@@ -4542,6 +4912,8 @@
4006 + get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0},
4007 + {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4008 + get_all_tables, 0, get_schema_constraints_record, 3, 4, 0},
4009 ++ {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
4010 ++ fill_schema_table_stats, make_old_format, 0, -1, -1, 0},
4011 + {"TABLE_NAMES", table_names_fields_info, create_schema_table,
4012 + get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
4013 + {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
4014 +@@ -4550,6 +4920,8 @@
4015 + get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
4016 + {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
4017 + fill_schema_user_privileges, 0, 0, -1, -1, 0},
4018 ++ {"USER_STATISTICS", user_stats_fields_info, create_schema_table,
4019 ++ fill_schema_user_stats, make_old_format, 0, -1, -1, 0},
4020 + {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4021 + make_old_format, 0, -1, -1, 1},
4022 + {"VIEWS", view_fields_info, create_schema_table,
4023 +diff -r 592f6c3641ba sql/sql_update.cc
4024 +--- a/sql/sql_update.cc Wed Jul 29 13:33:34 2009 -0700
4025 ++++ b/sql/sql_update.cc Wed Jul 29 13:34:11 2009 -0700
4026 +@@ -601,7 +601,8 @@
4027 + (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
4028 + send_ok(thd, (ulong) thd->row_count_func,
4029 + thd->insert_id_used ? thd->last_insert_id : 0L,buff);
4030 +- DBUG_PRINT("info",("%ld records updated", (long) updated));
4031 ++ thd->updated_row_count += thd->row_count_func;
4032 ++ DBUG_PRINT("info",("%d records updated",updated));
4033 + }
4034 + thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
4035 + thd->abort_on_warning= 0;
4036 +@@ -1832,5 +1833,6 @@
4037 + (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
4038 + ::send_ok(thd, (ulong) thd->row_count_func,
4039 + thd->insert_id_used ? thd->last_insert_id : 0L,buff);
4040 ++ thd->updated_row_count += thd->row_count_func;
4041 + return FALSE;
4042 + }
4043 +diff -r 592f6c3641ba sql/sql_yacc.yy
4044 +--- a/sql/sql_yacc.yy Wed Jul 29 13:33:34 2009 -0700
4045 ++++ b/sql/sql_yacc.yy Wed Jul 29 13:34:11 2009 -0700
4046 +@@ -523,6 +523,7 @@
4047 + %token CHECK_SYM
4048 + %token CIPHER_SYM
4049 + %token CLIENT_SYM
4050 ++%token CLIENT_STATS_SYM
4051 + %token CLOSE_SYM
4052 + %token COALESCE
4053 + %token CODE_SYM
4054 +@@ -680,6 +681,7 @@
4055 + %token IMPORT
4056 + %token INDEXES
4057 + %token INDEX_SYM
4058 ++%token INDEX_STATS_SYM
4059 + %token INFILE
4060 + %token INNER_SYM
4061 + %token INNOBASE_SYM
4062 +@@ -909,6 +911,7 @@
4063 + %token SIGNED_SYM
4064 + %token SIMPLE_SYM
4065 + %token SLAVE
4066 ++%token SLOW_SYM
4067 + %token SMALLINT
4068 + %token SNAPSHOT_SYM
4069 + %token SOUNDS_SYM
4070 +@@ -949,6 +952,7 @@
4071 + %token TABLES
4072 + %token TABLESPACE
4073 + %token TABLE_SYM
4074 ++%token TABLE_STATS_SYM
4075 + %token TEMPORARY
4076 + %token TEMPTABLE_SYM
4077 + %token TERMINATED
4078 +@@ -991,6 +995,7 @@
4079 + %token UPGRADE_SYM
4080 + %token USAGE
4081 + %token USER
4082 ++%token USER_STATS_SYM
4083 + %token USE_FRM
4084 + %token USE_SYM
4085 + %token USING
4086 +@@ -8255,6 +8260,38 @@
4087 + {
4088 + Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
4089 + }
4090 ++ | CLIENT_STATS_SYM wild_and_where
4091 ++ {
4092 ++ LEX *lex= Lex;
4093 ++ Lex->sql_command = SQLCOM_SELECT;
4094 ++ lex->orig_sql_command= SQLCOM_SHOW_CLIENT_STATS;
4095 ++ if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS))
4096 ++ MYSQL_YYABORT;
4097 ++ }
4098 ++ | USER_STATS_SYM wild_and_where
4099 ++ {
4100 ++ LEX *lex= Lex;
4101 ++ lex->sql_command = SQLCOM_SELECT;
4102 ++ lex->orig_sql_command= SQLCOM_SHOW_USER_STATS;
4103 ++ if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
4104 ++ MYSQL_YYABORT;
4105 ++ }
4106 ++ | TABLE_STATS_SYM wild_and_where
4107 ++ {
4108 ++ LEX *lex= Lex;
4109 ++ lex->sql_command= SQLCOM_SELECT;
4110 ++ lex->orig_sql_command= SQLCOM_SHOW_TABLE_STATS;
4111 ++ if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
4112 ++ MYSQL_YYABORT;
4113 ++ }
4114 ++ | INDEX_STATS_SYM wild_and_where
4115 ++ {
4116 ++ LEX *lex= Lex;
4117 ++ lex->sql_command= SQLCOM_SELECT;
4118 ++ lex->orig_sql_command= SQLCOM_SHOW_INDEX_STATS;
4119 ++ if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
4120 ++ MYSQL_YYABORT;
4121 ++ }
4122 + | CREATE PROCEDURE sp_name
4123 + {
4124 + LEX *lex= Lex;
4125 +@@ -8459,9 +8496,14 @@
4126 + | LOGS_SYM { Lex->type|= REFRESH_LOG; }
4127 + | STATUS_SYM { Lex->type|= REFRESH_STATUS; }
4128 + | SLAVE { Lex->type|= REFRESH_SLAVE; }
4129 ++ | SLOW_SYM QUERY_SYM LOGS_SYM { Lex->type |= REFRESH_SLOW_QUERY_LOG; }
4130 + | MASTER_SYM { Lex->type|= REFRESH_MASTER; }
4131 + | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; }
4132 +- | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; };
4133 ++ | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; }
4134 ++ | CLIENT_STATS_SYM { Lex->type|= REFRESH_CLIENT_STATS; }
4135 ++ | USER_STATS_SYM { Lex->type|= REFRESH_USER_STATS; }
4136 ++ | TABLE_STATS_SYM { Lex->type|= REFRESH_TABLE_STATS; }
4137 ++ | INDEX_STATS_SYM { Lex->type|= REFRESH_INDEX_STATS; };
4138 +
4139 + opt_table_list:
4140 + /* empty */ {;}
4141 +@@ -9450,6 +9492,7 @@
4142 + | CHAIN_SYM {}
4143 + | CHANGED {}
4144 + | CIPHER_SYM {}
4145 ++ | CLIENT_STATS_SYM {}
4146 + | CLIENT_SYM {}
4147 + | CODE_SYM {}
4148 + | COLLATION_SYM {}
4149 +@@ -9502,6 +9545,7 @@
4150 + | HOSTS_SYM {}
4151 + | HOUR_SYM {}
4152 + | IDENTIFIED_SYM {}
4153 ++ | INDEX_STATS_SYM {}
4154 + | INVOKER_SYM {}
4155 + | IMPORT {}
4156 + | INDEXES {}
4157 +@@ -9611,6 +9655,7 @@
4158 + | SIMPLE_SYM {}
4159 + | SHARE_SYM {}
4160 + | SHUTDOWN {}
4161 ++ | SLOW_SYM {}
4162 + | SNAPSHOT_SYM {}
4163 + | SOUNDS_SYM {}
4164 + | SOURCE_SYM {}
4165 +@@ -9627,6 +9672,7 @@
4166 + | SUSPEND_SYM {}
4167 + | SWAPS_SYM {}
4168 + | SWITCHES_SYM {}
4169 ++ | TABLE_STATS_SYM {}
4170 + | TABLES {}
4171 + | TABLESPACE {}
4172 + | TEMPORARY {}
4173 +@@ -9647,6 +9693,7 @@
4174 + | UNKNOWN_SYM {}
4175 + | UNTIL_SYM {}
4176 + | USER {}
4177 ++ | USER_STATS_SYM {}
4178 + | USE_FRM {}
4179 + | VARIABLES {}
4180 + | VIEW_SYM {}
4181 +diff -r 592f6c3641ba sql/structs.h
4182 +--- a/sql/structs.h Wed Jul 29 13:33:34 2009 -0700
4183 ++++ b/sql/structs.h Wed Jul 29 13:34:11 2009 -0700
4184 +@@ -273,6 +273,98 @@
4185 + time_t intime;
4186 + } USER_CONN;
4187 +
4188 ++typedef struct st_user_stats {
4189 ++ char user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
4190 ++ // Account name the user is mapped to when this is a user from mapped_user.
4191 ++ // Otherwise, the same value as user.
4192 ++ char priv_user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
4193 ++ uint total_connections;
4194 ++ uint concurrent_connections;
4195 ++ time_t connected_time; // in seconds
4196 ++ double busy_time; // in seconds
4197 ++ double cpu_time; // in seconds
4198 ++ ulonglong bytes_received;
4199 ++ ulonglong bytes_sent;
4200 ++ ulonglong binlog_bytes_written;
4201 ++ ha_rows rows_fetched, rows_updated, rows_read;
4202 ++ ulonglong select_commands, update_commands, other_commands;
4203 ++ ulonglong commit_trans, rollback_trans;
4204 ++ ulonglong denied_connections, lost_connections;
4205 ++ ulonglong access_denied_errors;
4206 ++ ulonglong empty_queries;
4207 ++} USER_STATS;
4208 ++
4209 ++/* Lookup function for hash tables with USER_STATS entries */
4210 ++extern byte *get_key_user_stats(USER_STATS *user_stats, uint *length,
4211 ++ my_bool not_used __attribute__((unused)));
4212 ++
4213 ++/* Free all memory for a hash table with USER_STATS entries */
4214 ++extern void free_user_stats(USER_STATS* user_stats);
4215 ++
4216 ++/* Intialize an instance of USER_STATS */
4217 ++extern void
4218 ++init_user_stats(USER_STATS *user_stats,
4219 ++ const char *user,
4220 ++ const char *priv_user,
4221 ++ uint total_connections,
4222 ++ uint concurrent_connections,
4223 ++ time_t connected_time,
4224 ++ double busy_time,
4225 ++ double cpu_time,
4226 ++ ulonglong bytes_received,
4227 ++ ulonglong bytes_sent,
4228 ++ ulonglong binlog_bytes_written,
4229 ++ ha_rows rows_fetched,
4230 ++ ha_rows rows_updated,
4231 ++ ha_rows rows_read,
4232 ++ ulonglong select_commands,
4233 ++ ulonglong update_commands,
4234 ++ ulonglong other_commands,
4235 ++ ulonglong commit_trans,
4236 ++ ulonglong rollback_trans,
4237 ++ ulonglong denied_connections,
4238 ++ ulonglong lost_connections,
4239 ++ ulonglong access_denied_errors,
4240 ++ ulonglong empty_queries);
4241 ++
4242 ++/* Increment values of an instance of USER_STATS */
4243 ++extern void
4244 ++add_user_stats(USER_STATS *user_stats,
4245 ++ uint total_connections,
4246 ++ uint concurrent_connections,
4247 ++ time_t connected_time,
4248 ++ double busy_time,
4249 ++ double cpu_time,
4250 ++ ulonglong bytes_received,
4251 ++ ulonglong bytes_sent,
4252 ++ ulonglong binlog_bytes_written,
4253 ++ ha_rows rows_fetched,
4254 ++ ha_rows rows_updated,
4255 ++ ha_rows rows_read,
4256 ++ ulonglong select_commands,
4257 ++ ulonglong update_commands,
4258 ++ ulonglong other_commands,
4259 ++ ulonglong commit_trans,
4260 ++ ulonglong rollback_trans,
4261 ++ ulonglong denied_connections,
4262 ++ ulonglong lost_connections,
4263 ++ ulonglong access_denied_errors,
4264 ++ ulonglong empty_queries);
4265 ++
4266 ++typedef struct st_table_stats {
4267 ++ char table[NAME_LEN * 2 + 2]; // [db] + '.' + [table] + '\0'
4268 ++ ulonglong rows_read, rows_changed;
4269 ++ ulonglong rows_changed_x_indexes;
4270 ++ /* Stores enum db_type, but forward declarations cannot be done */
4271 ++ int engine_type;
4272 ++} TABLE_STATS;
4273 ++
4274 ++typedef struct st_index_stats {
4275 ++ char index[NAME_LEN * 3 + 3]; // [db] + '.' + [table] + '.' + [index] + '\0'
4276 ++ ulonglong rows_read;
4277 ++} INDEX_STATS;
4278 ++
4279 ++
4280 + /* Bits in form->update */
4281 + #define REG_MAKE_DUPP 1 /* Make a copy of record when read */
4282 + #define REG_NEW_RECORD 2 /* Write a new record if not found */
4283 +diff -r 592f6c3641ba sql/table.h
4284 +--- a/sql/table.h Wed Jul 29 13:33:34 2009 -0700
4285 ++++ b/sql/table.h Wed Jul 29 13:34:11 2009 -0700
4286 +@@ -371,10 +371,12 @@
4287 + enum enum_schema_tables
4288 + {
4289 + SCH_CHARSETS= 0,
4290 ++ SCH_CLIENT_STATS,
4291 + SCH_COLLATIONS,
4292 + SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
4293 + SCH_COLUMNS,
4294 + SCH_COLUMN_PRIVILEGES,
4295 ++ SCH_INDEX_STATS,
4296 + SCH_KEY_COLUMN_USAGE,
4297 + SCH_OPEN_TABLES,
4298 + SCH_PROFILES,
4299 +@@ -387,8 +389,10 @@
4300 + SCH_TABLE_CONSTRAINTS,
4301 + SCH_TABLE_NAMES,
4302 + SCH_TABLE_PRIVILEGES,
4303 ++ SCH_TABLE_STATS,
4304 + SCH_TRIGGERS,
4305 + SCH_USER_PRIVILEGES,
4306 ++ SCH_USER_STATS,
4307 + SCH_VARIABLES,
4308 + SCH_VIEWS
4309 + };
4310 +diff -r 592f6c3641ba strings/Makefile.in
4311 +--- a/strings/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4312 ++++ b/strings/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4313 +@@ -342,6 +342,7 @@
4314 + LIBDL = @LIBDL@
4315 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4316 + LIBOBJS = @LIBOBJS@
4317 ++LIBRT = @LIBRT@
4318 + LIBS = @LIBS@
4319 + LIBTOOL = @LIBTOOL@
4320 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4321 +diff -r 592f6c3641ba support-files/MacOSX/Makefile.in
4322 +--- a/support-files/MacOSX/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4323 ++++ b/support-files/MacOSX/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4324 +@@ -148,6 +148,7 @@
4325 + LIBDL = @LIBDL@
4326 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4327 + LIBOBJS = @LIBOBJS@
4328 ++LIBRT = @LIBRT@
4329 + LIBS = @LIBS@
4330 + LIBTOOL = @LIBTOOL@
4331 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4332 +diff -r 592f6c3641ba support-files/Makefile.in
4333 +--- a/support-files/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4334 ++++ b/support-files/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4335 +@@ -171,6 +171,7 @@
4336 + LIBDL = @LIBDL@
4337 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4338 + LIBOBJS = @LIBOBJS@
4339 ++LIBRT = @LIBRT@
4340 + LIBS = @LIBS@
4341 + LIBTOOL = @LIBTOOL@
4342 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4343 +diff -r 592f6c3641ba support-files/RHEL4-SElinux/Makefile.in
4344 +--- a/support-files/RHEL4-SElinux/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4345 ++++ b/support-files/RHEL4-SElinux/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4346 +@@ -146,6 +146,7 @@
4347 + LIBDL = @LIBDL@
4348 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4349 + LIBOBJS = @LIBOBJS@
4350 ++LIBRT = @LIBRT@
4351 + LIBS = @LIBS@
4352 + LIBTOOL = @LIBTOOL@
4353 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4354 +diff -r 592f6c3641ba tests/Makefile.in
4355 +--- a/tests/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4356 ++++ b/tests/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4357 +@@ -193,6 +193,7 @@
4358 + LIBDL = @LIBDL@
4359 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4360 + LIBOBJS = @LIBOBJS@
4361 ++LIBRT = @LIBRT@
4362 + LIBS = @CLIENT_LIBS@
4363 + LIBTOOL = @LIBTOOL@
4364 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4365 +diff -r 592f6c3641ba tools/Makefile.in
4366 +--- a/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4367 ++++ b/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4368 +@@ -167,6 +167,7 @@
4369 + LIBDL = @LIBDL@
4370 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4371 + LIBOBJS = @LIBOBJS@
4372 ++LIBRT = @LIBRT@
4373 + LIBS = @LIBS@
4374 + LIBTOOL = @LIBTOOL@
4375 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4376 +diff -r 592f6c3641ba vio/Makefile.in
4377 +--- a/vio/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4378 ++++ b/vio/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4379 +@@ -176,6 +176,7 @@
4380 + LIBDL = @LIBDL@
4381 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4382 + LIBOBJS = @LIBOBJS@
4383 ++LIBRT = @LIBRT@
4384 + LIBS = @LIBS@
4385 + LIBTOOL = @LIBTOOL@
4386 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4387 +diff -r 592f6c3641ba win/Makefile.in
4388 +--- a/win/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4389 ++++ b/win/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4390 +@@ -144,6 +144,7 @@
4391 + LIBDL = @LIBDL@
4392 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4393 + LIBOBJS = @LIBOBJS@
4394 ++LIBRT = @LIBRT@
4395 + LIBS = @LIBS@
4396 + LIBTOOL = @LIBTOOL@
4397 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4398 +diff -r 592f6c3641ba zlib/Makefile.in
4399 +--- a/zlib/Makefile.in Wed Jul 29 13:33:34 2009 -0700
4400 ++++ b/zlib/Makefile.in Wed Jul 29 13:34:11 2009 -0700
4401 +@@ -187,6 +187,7 @@
4402 + LIBDL = @LIBDL@
4403 + LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
4404 + LIBOBJS = @LIBOBJS@
4405 ++LIBRT = @LIBRT@
4406 + LIBS = $(NON_THREADED_LIBS)
4407 + LIBTOOL = @LIBTOOL@
4408 + LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
4409 +diff -Nur a/include/mysql_com.h b/include/mysql_com.h
4410 +--- a/include/mysql_com.h 2010-05-22 00:26:45.000000000 -0700
4411 ++++ b/include/mysql_com.h 2010-05-22 00:27:14.000000000 -0700
4412 +@@ -228,7 +228,7 @@
4413 +
4414 + my_bool report_error; /* We should report error (we have unreported error) */
4415 + my_bool return_errno;
4416 +-#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
4417 ++#if defined(MYSQL_SERVER)
4418 + /*
4419 + Controls whether a big packet should be skipped.
4420 +