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