diff -Naur mysql.orig/aclocal.m4 mysql/aclocal.m4 --- mysql.orig/aclocal.m4 2007-12-14 21:44:56.000000000 +0100 +++ mysql/aclocal.m4 2008-11-27 20:08:06.000000000 +0100 @@ -1597,7 +1597,7 @@ # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" fi @@ -4305,6 +4305,9 @@ # Is the compiler the GNU C compiler? with_gcc=$_LT_AC_TAGVAR(GCC, $1) +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + # An ERE matcher. EGREP=$lt_EGREP @@ -4438,11 +4441,11 @@ # Dependencies to place before the objects being linked to create a # shared library. -predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) +predep_objects=\`echo $lt_[]_LT_AC_TAGVAR(predep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) +postdep_objects=\`echo $lt_[]_LT_AC_TAGVAR(postdep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place before the objects being linked to create a # shared library. @@ -4454,7 +4457,7 @@ # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) +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"\` # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method @@ -4534,7 +4537,7 @@ link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) # Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec +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"\` # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec @@ -6370,6 +6373,7 @@ done done done +IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris @@ -6402,6 +6406,7 @@ done ]) SED=$lt_cv_path_SED +AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ]) diff -Naur mysql.orig/BUILD/Makefile.in mysql/BUILD/Makefile.in --- mysql.orig/BUILD/Makefile.in 2007-12-14 21:45:22.000000000 +0100 +++ mysql/BUILD/Makefile.in 2008-11-27 20:08:06.000000000 +0100 @@ -167,6 +167,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/client/Makefile.in mysql/client/Makefile.in --- mysql.orig/client/Makefile.in 2007-12-14 21:45:24.000000000 +0100 +++ mysql/client/Makefile.in 2008-11-27 20:08:06.000000000 +0100 @@ -266,6 +266,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @CLIENT_LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/cmd-line-utils/libedit/Makefile.in mysql/cmd-line-utils/libedit/Makefile.in --- mysql.orig/cmd-line-utils/libedit/Makefile.in 2007-12-14 21:45:25.000000000 +0100 +++ mysql/cmd-line-utils/libedit/Makefile.in 2008-11-27 20:08:06.000000000 +0100 @@ -195,6 +195,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/cmd-line-utils/Makefile.in mysql/cmd-line-utils/Makefile.in --- mysql.orig/cmd-line-utils/Makefile.in 2007-12-14 21:45:24.000000000 +0100 +++ mysql/cmd-line-utils/Makefile.in 2008-11-27 20:08:06.000000000 +0100 @@ -175,6 +175,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/cmd-line-utils/readline/Makefile.in mysql/cmd-line-utils/readline/Makefile.in --- mysql.orig/cmd-line-utils/readline/Makefile.in 2007-12-14 21:45:26.000000000 +0100 +++ mysql/cmd-line-utils/readline/Makefile.in 2008-11-27 20:08:06.000000000 +0100 @@ -193,6 +193,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/configure mysql/configure --- mysql.orig/configure 2007-12-14 21:46:16.000000000 +0100 +++ mysql/configure 2008-11-27 20:08:06.000000000 +0100 @@ -477,7 +477,7 @@ #endif" ac_subdirs_all="$ac_subdirs_all innobase" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MYSQL_NO_DASH_VERSION MYSQL_BASE_VERSION MYSQL_VERSION_ID MYSQL_PREVIOUS_BASE_VERSION PROTOCOL_VERSION DOT_FRM_VERSION SHARED_LIB_MAJOR_VERSION SHARED_LIB_VERSION NDB_SHARED_LIB_MAJOR_VERSION NDB_SHARED_LIB_VERSION AVAILABLE_LANGUAGES NDB_VERSION_MAJOR NDB_VERSION_MINOR NDB_VERSION_BUILD NDB_VERSION_STATUS SYSTEM_TYPE MACHINE_TYPE CONF_COMMAND SAVE_CC SAVE_CXX SAVE_ASFLAGS SAVE_CFLAGS SAVE_CXXFLAGS SAVE_LDFLAGS SAVE_CXXLDFLAGS CXXLDFLAGS AR RANLIB DARWIN_MWCC_TRUE DARWIN_MWCC_FALSE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CPP CC_VERSION CXX_VERSION AS ac_ct_RANLIB EGREP LN_S ECHO ac_ct_AR CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL NM YACC PDFMANUAL DVIS uname_prog ASFLAGS LD ARFLAGS LD_VERSION_SCRIPT MYSQLD_DEFAULT_SWITCHES TARGET_LINUX LN LN_CP_F MV RM CP SED CMP CHMOD HOSTNAME TAR PERL PERL5 DOXYGEN PDFLATEX MAKEINDEX ICHECK PS FIND_PROC KILL CHECK_PID CCAS CCASFLAGS NOINST_LDFLAGS MYSQL_SERVER_SUFFIX ASSEMBLER_x86_TRUE ASSEMBLER_x86_FALSE ASSEMBLER_sparc32_TRUE ASSEMBLER_sparc32_FALSE ASSEMBLER_sparc64_TRUE ASSEMBLER_sparc64_FALSE ASSEMBLER_TRUE ASSEMBLER_FALSE MYSQL_UNIX_ADDR MYSQL_TCP_PORT MYSQL_TCP_PORT_DEFAULT MYSQLD_USER GETCONF ac_ct_GETCONF zlib_dir ZLIB_LIBS ZLIB_DEPS ZLIB_INCLUDES WRAPLIBS pstack_dirs pstack_libs COMPILE_PSTACK_TRUE COMPILE_PSTACK_FALSE LIBDL MYSQLD_EXTRA_LDFLAGS CLIENT_EXTRA_LDFLAGS MYSQLD_EXTRA_LIBS LIB_EXTRA_CCFLAGS LM_CFLAGS COMPILATION_COMMENT ALLOCA MAKE_SHELL TERMCAP_LIB LIBEDIT_LOBJECTS tools_dirs openssl_libs openssl_includes yassl_taocrypt_extra_cxxflags yassl_h_ln_cmd yassl_libs yassl_dir HAVE_YASSL_TRUE HAVE_YASSL_FALSE libmysqld_dirs linked_libmysqld_targets docs_dirs extra_docs bench_dirs readline_dir readline_topdir readline_basedir readline_link readline_h_ln_cmd bdb_includes bdb_libs bdb_libs_with_path innodb_includes innodb_libs innodb_system_libs NDB_SCI_INCLUDES NDB_SCI_LIBS NDB_LD_VERSION_SCRIPT HAVE_NDBCLUSTER_DB_TRUE HAVE_NDBCLUSTER_DB_FALSE ndbcluster_includes ndbcluster_libs ndbcluster_system_libs ndb_mgmclient_libs man_dirs man1_files man8_files CLIENT_LIBS NON_THREADED_LIBS STATIC_NSS_FLAGS sql_client_dirs linked_client_targets netware_dir linked_netware_sources HAVE_NETWARE_TRUE HAVE_NETWARE_FALSE THREAD_LOBJECTS subdirs sql_server_dirs thread_dirs server_scripts sql_union_dirs GXX NDB_DEFS ndb_cxxflags_fix ndb_port ndb_transporter_opt_objs ndb_bin_am_ldflags ndb_opt_subdirs NDB_SIZEOF_CHARP NDB_SIZEOF_CHAR NDB_SIZEOF_SHORT NDB_SIZEOF_INT NDB_SIZEOF_LONG NDB_SIZEOF_LONG_LONG MAKE_BINARY_DISTRIBUTION_OPTIONS LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MYSQL_NO_DASH_VERSION MYSQL_BASE_VERSION MYSQL_VERSION_ID MYSQL_PREVIOUS_BASE_VERSION PROTOCOL_VERSION DOT_FRM_VERSION SHARED_LIB_MAJOR_VERSION SHARED_LIB_VERSION NDB_SHARED_LIB_MAJOR_VERSION NDB_SHARED_LIB_VERSION AVAILABLE_LANGUAGES NDB_VERSION_MAJOR NDB_VERSION_MINOR NDB_VERSION_BUILD NDB_VERSION_STATUS SYSTEM_TYPE MACHINE_TYPE CONF_COMMAND SAVE_CC SAVE_CXX SAVE_ASFLAGS SAVE_CFLAGS SAVE_CXXFLAGS SAVE_LDFLAGS SAVE_CXXLDFLAGS CXXLDFLAGS AR RANLIB DARWIN_MWCC_TRUE DARWIN_MWCC_FALSE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CPP CC_VERSION CXX_VERSION AS ac_ct_RANLIB SED EGREP LN_S ECHO ac_ct_AR CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL NM YACC PDFMANUAL DVIS uname_prog ASFLAGS LD ARFLAGS LD_VERSION_SCRIPT MYSQLD_DEFAULT_SWITCHES TARGET_LINUX LN LN_CP_F MV RM CP CMP CHMOD HOSTNAME TAR PERL PERL5 DOXYGEN PDFLATEX MAKEINDEX ICHECK PS FIND_PROC KILL CHECK_PID CCAS CCASFLAGS NOINST_LDFLAGS MYSQL_SERVER_SUFFIX ASSEMBLER_x86_TRUE ASSEMBLER_x86_FALSE ASSEMBLER_sparc32_TRUE ASSEMBLER_sparc32_FALSE ASSEMBLER_sparc64_TRUE ASSEMBLER_sparc64_FALSE ASSEMBLER_TRUE ASSEMBLER_FALSE MYSQL_UNIX_ADDR MYSQL_TCP_PORT MYSQL_TCP_PORT_DEFAULT MYSQLD_USER GETCONF ac_ct_GETCONF zlib_dir ZLIB_LIBS ZLIB_DEPS ZLIB_INCLUDES WRAPLIBS pstack_dirs pstack_libs COMPILE_PSTACK_TRUE COMPILE_PSTACK_FALSE LIBDL MYSQLD_EXTRA_LDFLAGS CLIENT_EXTRA_LDFLAGS MYSQLD_EXTRA_LIBS LIB_EXTRA_CCFLAGS LM_CFLAGS COMPILATION_COMMENT ALLOCA MAKE_SHELL TERMCAP_LIB LIBEDIT_LOBJECTS LIBRT tools_dirs openssl_libs openssl_includes yassl_taocrypt_extra_cxxflags yassl_h_ln_cmd yassl_libs yassl_dir HAVE_YASSL_TRUE HAVE_YASSL_FALSE libmysqld_dirs linked_libmysqld_targets docs_dirs extra_docs bench_dirs readline_dir readline_topdir readline_basedir readline_link readline_h_ln_cmd bdb_includes bdb_libs bdb_libs_with_path innodb_includes innodb_libs innodb_system_libs NDB_SCI_INCLUDES NDB_SCI_LIBS NDB_LD_VERSION_SCRIPT HAVE_NDBCLUSTER_DB_TRUE HAVE_NDBCLUSTER_DB_FALSE ndbcluster_includes ndbcluster_libs ndbcluster_system_libs ndb_mgmclient_libs man_dirs man1_files man8_files CLIENT_LIBS NON_THREADED_LIBS STATIC_NSS_FLAGS sql_client_dirs linked_client_targets netware_dir linked_netware_sources HAVE_NETWARE_TRUE HAVE_NETWARE_FALSE THREAD_LOBJECTS subdirs sql_server_dirs thread_dirs server_scripts sql_union_dirs GXX NDB_DEFS ndb_cxxflags_fix ndb_port ndb_transporter_opt_objs ndb_bin_am_ldflags ndb_opt_subdirs NDB_SIZEOF_CHARP NDB_SIZEOF_CHAR NDB_SIZEOF_SHORT NDB_SIZEOF_INT NDB_SIZEOF_LONG NDB_SIZEOF_LONG_LONG MAKE_BINARY_DISTRIBUTION_OPTIONS LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -38058,7 +38058,91 @@ # We also disable for SCO for the time being, the headers for the # thread library we use conflicts with other headers. ;; - *) +*) + # most systems require the program be linked with librt library to use + # the function clock_gettime + my_save_LIBS="$LIBS" + LIBS="" + +echo "$as_me:$LINENO: checking for clock_gettime in -lrt" >&5 +echo $ECHO_N "checking for clock_gettime in -lrt... $ECHO_C" >&6 +if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char clock_gettime (); +int +main () +{ +clock_gettime (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_rt_clock_gettime=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_rt_clock_gettime=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_rt_clock_gettime" >&5 +echo "${ECHO_T}$ac_cv_lib_rt_clock_gettime" >&6 +if test $ac_cv_lib_rt_clock_gettime = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBRT 1 +_ACEOF + + LIBS="-lrt $LIBS" + +fi + + LIBRT=$LIBS + LIBS="$my_save_LIBS" + + + LIBS="$LIBS $LIBRT" + for ac_func in clock_gettime do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` @@ -41466,7 +41550,7 @@ fi -CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS" +CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT" @@ -42763,6 +42847,7 @@ s,@MAKE_SHELL@,$MAKE_SHELL,;t t s,@TERMCAP_LIB@,$TERMCAP_LIB,;t t s,@LIBEDIT_LOBJECTS@,$LIBEDIT_LOBJECTS,;t t +s,@LIBRT@,$LIBRT,;t t s,@tools_dirs@,$tools_dirs,;t t s,@openssl_libs@,$openssl_libs,;t t s,@openssl_includes@,$openssl_includes,;t t diff -Naur mysql.orig/configure.in mysql/configure.in --- mysql.orig/configure.in 2007-12-14 21:43:00.000000000 +0100 +++ mysql/configure.in 2008-11-27 20:08:07.000000000 +0100 @@ -2062,7 +2062,18 @@ # We also disable for SCO for the time being, the headers for the # thread library we use conflicts with other headers. ;; - *) AC_CHECK_FUNCS(clock_gettime) +*) + # most systems require the program be linked with librt library to use + # the function clock_gettime + my_save_LIBS="$LIBS" + LIBS="" + AC_CHECK_LIB(rt,clock_gettime) + LIBRT=$LIBS + LIBS="$my_save_LIBS" + AC_SUBST(LIBRT) + + LIBS="$LIBS $LIBRT" + AC_CHECK_FUNCS(clock_gettime) ;; esac @@ -2677,7 +2688,7 @@ AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe]) fi -CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS" +CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT" AC_SUBST(CLIENT_LIBS) AC_SUBST(NON_THREADED_LIBS) diff -Naur mysql.orig/dbug/Makefile.in mysql/dbug/Makefile.in --- mysql.orig/dbug/Makefile.in 2007-12-14 21:45:26.000000000 +0100 +++ mysql/dbug/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -212,6 +212,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/Docs/Makefile.in mysql/Docs/Makefile.in --- mysql.orig/Docs/Makefile.in 2007-12-14 21:45:23.000000000 +0100 +++ mysql/Docs/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -165,6 +165,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/extra/Makefile.in mysql/extra/Makefile.in --- mysql.orig/extra/Makefile.in 2007-12-14 21:45:27.000000000 +0100 +++ mysql/extra/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -254,6 +254,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/extra/yassl/Makefile.in mysql/extra/yassl/Makefile.in --- mysql.orig/extra/yassl/Makefile.in 2007-12-14 21:45:27.000000000 +0100 +++ mysql/extra/yassl/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -160,6 +160,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/extra/yassl/src/Makefile.in mysql/extra/yassl/src/Makefile.in --- mysql.orig/extra/yassl/src/Makefile.in 2007-12-14 21:45:28.000000000 +0100 +++ mysql/extra/yassl/src/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -171,6 +171,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/extra/yassl/taocrypt/benchmark/Makefile.in mysql/extra/yassl/taocrypt/benchmark/Makefile.in --- mysql.orig/extra/yassl/taocrypt/benchmark/Makefile.in 2007-12-14 21:45:29.000000000 +0100 +++ mysql/extra/yassl/taocrypt/benchmark/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -170,6 +170,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/extra/yassl/taocrypt/Makefile.in mysql/extra/yassl/taocrypt/Makefile.in --- mysql.orig/extra/yassl/taocrypt/Makefile.in 2007-12-14 21:45:28.000000000 +0100 +++ mysql/extra/yassl/taocrypt/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -160,6 +160,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/extra/yassl/taocrypt/src/Makefile.in mysql/extra/yassl/taocrypt/src/Makefile.in --- mysql.orig/extra/yassl/taocrypt/src/Makefile.in 2007-12-14 21:45:29.000000000 +0100 +++ mysql/extra/yassl/taocrypt/src/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -180,6 +180,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/extra/yassl/taocrypt/test/Makefile.in mysql/extra/yassl/taocrypt/test/Makefile.in --- mysql.orig/extra/yassl/taocrypt/test/Makefile.in 2007-12-14 21:45:30.000000000 +0100 +++ mysql/extra/yassl/taocrypt/test/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -170,6 +170,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/extra/yassl/testsuite/Makefile.in mysql/extra/yassl/testsuite/Makefile.in --- mysql.orig/extra/yassl/testsuite/Makefile.in 2007-12-14 21:45:30.000000000 +0100 +++ mysql/extra/yassl/testsuite/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -173,6 +173,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/heap/Makefile.in mysql/heap/Makefile.in --- mysql.orig/heap/Makefile.in 2007-12-14 21:45:31.000000000 +0100 +++ mysql/heap/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -216,6 +216,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/include/Makefile.in mysql/include/Makefile.in --- mysql.orig/include/Makefile.in 2007-12-14 21:45:32.000000000 +0100 +++ mysql/include/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -181,6 +181,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/include/mysql_com.h mysql/include/mysql_com.h --- mysql.orig/include/mysql_com.h 2007-12-14 21:42:51.000000000 +0100 +++ mysql/include/mysql_com.h 2008-11-27 20:08:07.000000000 +0100 @@ -106,6 +106,11 @@ thread */ #define REFRESH_MASTER 128 /* Remove all bin logs in the index and truncate the index */ +#define REFRESH_TABLE_STATS 256 /* Refresh table stats hash table */ +#define REFRESH_INDEX_STATS 512 /* Refresh index stats hash table */ +#define REFRESH_USER_STATS 1024 /* Refresh user stats hash table */ +#define REFRESH_SLOW_QUERY_LOG 4096 /* Flush slow query log and rotate*/ +#define REFRESH_CLIENT_STATS 8192 /* Refresh client stats hash table */ /* The following can't be set with mysql_refresh() */ #define REFRESH_READ_LOCK 16384 /* Lock tables for read */ diff -Naur mysql.orig/libmysql/Makefile.in mysql/libmysql/Makefile.in --- mysql.orig/libmysql/Makefile.in 2007-12-14 21:45:32.000000000 +0100 +++ mysql/libmysql/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -276,6 +276,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @CLIENT_LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/libmysqld/examples/Makefile.in mysql/libmysqld/examples/Makefile.in --- mysql.orig/libmysqld/examples/Makefile.in 2007-12-14 21:45:35.000000000 +0100 +++ mysql/libmysqld/examples/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -211,6 +211,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs) LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/libmysqld/Makefile.in mysql/libmysqld/Makefile.in --- mysql.orig/libmysqld/Makefile.in 2007-12-14 21:45:34.000000000 +0100 +++ mysql/libmysqld/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -262,6 +262,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/libmysql_r/Makefile.in mysql/libmysql_r/Makefile.in --- mysql.orig/libmysql_r/Makefile.in 2007-12-14 21:45:33.000000000 +0100 +++ mysql/libmysql_r/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -273,6 +273,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ @ZLIB_LIBS@ @openssl_libs@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/Makefile.in mysql/Makefile.in --- mysql.orig/Makefile.in 2007-12-14 21:46:14.000000000 +0100 +++ mysql/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -189,6 +189,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/man/Makefile.in mysql/man/Makefile.in --- mysql.orig/man/Makefile.in 2007-12-14 21:45:35.000000000 +0100 +++ mysql/man/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -172,6 +172,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/myisam/Makefile.in mysql/myisam/Makefile.in --- mysql.orig/myisam/Makefile.in 2007-12-14 21:45:36.000000000 +0100 +++ mysql/myisam/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -255,6 +255,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/myisammrg/Makefile.in mysql/myisammrg/Makefile.in --- mysql.orig/myisammrg/Makefile.in 2007-12-14 21:45:37.000000000 +0100 +++ mysql/myisammrg/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -203,6 +203,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/mysql-test/Makefile.in mysql/mysql-test/Makefile.in --- mysql.orig/mysql-test/Makefile.in 2007-12-14 21:45:38.000000000 +0100 +++ mysql/mysql-test/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -179,6 +179,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/mysql-test/ndb/Makefile.in mysql/mysql-test/ndb/Makefile.in --- mysql.orig/mysql-test/ndb/Makefile.in 2007-12-14 21:45:39.000000000 +0100 +++ mysql/mysql-test/ndb/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -168,6 +168,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/mysql-test/r/information_schema_db.result mysql/mysql-test/r/information_schema_db.result --- mysql.orig/mysql-test/r/information_schema_db.result 2007-12-14 22:14:18.000000000 +0100 +++ mysql/mysql-test/r/information_schema_db.result 2008-11-27 20:08:07.000000000 +0100 @@ -6,10 +6,12 @@ show tables; Tables_in_information_schema CHARACTER_SETS +CLIENT_STATISTICS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY COLUMNS COLUMN_PRIVILEGES +INDEX_STATISTICS KEY_COLUMN_USAGE ROUTINES SCHEMATA @@ -18,14 +20,17 @@ TABLES TABLE_CONSTRAINTS TABLE_PRIVILEGES +TABLE_STATISTICS TRIGGERS USER_PRIVILEGES +USER_STATISTICS VIEWS show tables from INFORMATION_SCHEMA like 'T%'; Tables_in_information_schema (T%) TABLES TABLE_CONSTRAINTS TABLE_PRIVILEGES +TABLE_STATISTICS TRIGGERS create database `inf%`; create database mbase; diff -Naur mysql.orig/mysql-test/r/information_schema.result mysql/mysql-test/r/information_schema.result --- mysql.orig/mysql-test/r/information_schema.result 2007-12-14 22:14:18.000000000 +0100 +++ mysql/mysql-test/r/information_schema.result 2008-11-27 20:08:07.000000000 +0100 @@ -37,10 +37,12 @@ select * from v1; c CHARACTER_SETS +CLIENT_STATISTICS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY COLUMNS COLUMN_PRIVILEGES +INDEX_STATISTICS KEY_COLUMN_USAGE ROUTINES SCHEMATA @@ -49,8 +51,10 @@ TABLES TABLE_CONSTRAINTS TABLE_PRIVILEGES +TABLE_STATISTICS TRIGGERS USER_PRIVILEGES +USER_STATISTICS VIEWS columns_priv db @@ -82,6 +86,7 @@ TABLES TABLES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES +TABLE_STATISTICS TABLE_STATISTICS TRIGGERS TRIGGERS tables_priv tables_priv time_zone time_zone @@ -101,6 +106,7 @@ TABLES TABLES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES +TABLE_STATISTICS TABLE_STATISTICS TRIGGERS TRIGGERS tables_priv tables_priv time_zone time_zone @@ -120,6 +126,7 @@ TABLES TABLES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES +TABLE_STATISTICS TABLE_STATISTICS TRIGGERS TRIGGERS tables_priv tables_priv time_zone time_zone @@ -593,12 +600,13 @@ where table_schema='information_schema' limit 2; TABLE_NAME TABLE_TYPE ENGINE CHARACTER_SETS SYSTEM VIEW MEMORY -COLLATIONS SYSTEM VIEW MEMORY +CLIENT_STATISTICS SYSTEM VIEW MEMORY show tables from information_schema like "T%"; Tables_in_information_schema (T%) TABLES TABLE_CONSTRAINTS TABLE_PRIVILEGES +TABLE_STATISTICS TRIGGERS create database information_schema; ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' @@ -608,6 +616,7 @@ TABLES SYSTEM VIEW TABLE_CONSTRAINTS SYSTEM VIEW TABLE_PRIVILEGES SYSTEM VIEW +TABLE_STATISTICS SYSTEM VIEW TRIGGERS SYSTEM VIEW create table t1(a int); ERROR 42S02: Unknown table 't1' in information_schema @@ -620,6 +629,7 @@ TABLES TABLE_CONSTRAINTS TABLE_PRIVILEGES +TABLE_STATISTICS TRIGGERS select table_name from tables where table_name='user'; table_name @@ -729,7 +739,7 @@ CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1; CREATE VIEW a2 AS SELECT t_CRASHME FROM a1; count(*) -101 +106 drop view a2, a1; drop table t_crashme; select table_schema,table_name, column_name from @@ -789,18 +799,20 @@ TABLE_NAME COLUMN_NAME PRIVILEGES COLUMNS TABLE_NAME select COLUMN_PRIVILEGES TABLE_NAME select +INDEX_STATISTICS TABLE_NAME select KEY_COLUMN_USAGE TABLE_NAME select STATISTICS TABLE_NAME select TABLES TABLE_NAME select TABLE_CONSTRAINTS TABLE_NAME select TABLE_PRIVILEGES TABLE_NAME select +TABLE_STATISTICS TABLE_NAME select VIEWS TABLE_NAME select delete from mysql.user where user='mysqltest_4'; delete from mysql.db where user='mysqltest_4'; flush privileges; SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 16 +information_schema 21 mysql 17 create table t1 (i int, j int); create trigger trg1 before insert on t1 for each row @@ -1186,10 +1198,12 @@ ); table_name column_name CHARACTER_SETS CHARACTER_SET_NAME +CLIENT_STATISTICS CLIENT COLLATIONS COLLATION_NAME COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME COLUMNS TABLE_SCHEMA COLUMN_PRIVILEGES TABLE_SCHEMA +INDEX_STATISTICS TABLE_SCHEMA KEY_COLUMN_USAGE CONSTRAINT_SCHEMA ROUTINES ROUTINE_SCHEMA SCHEMATA SCHEMA_NAME @@ -1198,8 +1212,10 @@ TABLES TABLE_SCHEMA TABLE_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_PRIVILEGES TABLE_SCHEMA +TABLE_STATISTICS TABLE_SCHEMA TRIGGERS TRIGGER_SCHEMA USER_PRIVILEGES GRANTEE +USER_STATISTICS USER VIEWS TABLE_SCHEMA SELECT t.table_name, c1.column_name FROM information_schema.tables t @@ -1217,10 +1233,12 @@ ); table_name column_name CHARACTER_SETS CHARACTER_SET_NAME +CLIENT_STATISTICS CLIENT COLLATIONS COLLATION_NAME COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME COLUMNS TABLE_SCHEMA COLUMN_PRIVILEGES TABLE_SCHEMA +INDEX_STATISTICS TABLE_SCHEMA KEY_COLUMN_USAGE CONSTRAINT_SCHEMA ROUTINES ROUTINE_SCHEMA SCHEMATA SCHEMA_NAME @@ -1229,8 +1247,10 @@ TABLES TABLE_SCHEMA TABLE_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_PRIVILEGES TABLE_SCHEMA +TABLE_STATISTICS TABLE_SCHEMA TRIGGERS TRIGGER_SCHEMA USER_PRIVILEGES GRANTEE +USER_STATISTICS USER VIEWS TABLE_SCHEMA SELECT MAX(table_name) FROM information_schema.tables; MAX(table_name) @@ -1299,10 +1319,12 @@ group by t.table_name order by num1, t.table_name; table_name group_concat(t.table_schema, '.', t.table_name) num1 CHARACTER_SETS information_schema.CHARACTER_SETS 1 +CLIENT_STATISTICS information_schema.CLIENT_STATISTICS 1 COLLATIONS information_schema.COLLATIONS 1 COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 1 COLUMNS information_schema.COLUMNS 1 COLUMN_PRIVILEGES information_schema.COLUMN_PRIVILEGES 1 +INDEX_STATISTICS information_schema.INDEX_STATISTICS 1 KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1 ROUTINES information_schema.ROUTINES 1 SCHEMATA information_schema.SCHEMATA 1 @@ -1311,8 +1333,10 @@ TABLES information_schema.TABLES 1 TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1 TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1 +TABLE_STATISTICS information_schema.TABLE_STATISTICS 1 TRIGGERS information_schema.TRIGGERS 1 USER_PRIVILEGES information_schema.USER_PRIVILEGES 1 +USER_STATISTICS information_schema.USER_STATISTICS 1 VIEWS information_schema.VIEWS 1 create table t1(f1 int); create view v1 as select f1+1 as a from t1; diff -Naur mysql.orig/mysql-test/r/mysqlshow.result mysql/mysql-test/r/mysqlshow.result --- mysql.orig/mysql-test/r/mysqlshow.result 2007-12-14 22:14:18.000000000 +0100 +++ mysql/mysql-test/r/mysqlshow.result 2008-11-27 20:08:07.000000000 +0100 @@ -80,10 +80,12 @@ | Tables | +---------------------------------------+ | CHARACTER_SETS | +| CLIENT_STATISTICS | | COLLATIONS | | COLLATION_CHARACTER_SET_APPLICABILITY | | COLUMNS | | COLUMN_PRIVILEGES | +| INDEX_STATISTICS | | KEY_COLUMN_USAGE | | ROUTINES | | SCHEMATA | @@ -92,8 +94,10 @@ | TABLES | | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | +| TABLE_STATISTICS | | TRIGGERS | | USER_PRIVILEGES | +| USER_STATISTICS | | VIEWS | +---------------------------------------+ Database: INFORMATION_SCHEMA @@ -101,10 +105,12 @@ | Tables | +---------------------------------------+ | CHARACTER_SETS | +| CLIENT_STATISTICS | | COLLATIONS | | COLLATION_CHARACTER_SET_APPLICABILITY | | COLUMNS | | COLUMN_PRIVILEGES | +| INDEX_STATISTICS | | KEY_COLUMN_USAGE | | ROUTINES | | SCHEMATA | @@ -113,8 +119,10 @@ | TABLES | | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | +| TABLE_STATISTICS | | TRIGGERS | | USER_PRIVILEGES | +| USER_STATISTICS | | VIEWS | +---------------------------------------+ Wildcard: inf_rmation_schema diff -Naur mysql.orig/mysys/Makefile.in mysql/mysys/Makefile.in --- mysql.orig/mysys/Makefile.in 2007-12-14 21:45:40.000000000 +0100 +++ mysql/mysys/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -247,6 +247,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/docs/Makefile.in mysql/ndb/docs/Makefile.in --- mysql.orig/ndb/docs/Makefile.in 2007-12-14 21:45:40.000000000 +0100 +++ mysql/ndb/docs/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -170,6 +170,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/include/Makefile.in mysql/ndb/include/Makefile.in --- mysql.orig/ndb/include/Makefile.in 2007-12-14 21:45:41.000000000 +0100 +++ mysql/ndb/include/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -200,6 +200,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/Makefile.in mysql/ndb/Makefile.in --- mysql.orig/ndb/Makefile.in 2007-12-14 21:45:40.000000000 +0100 +++ mysql/ndb/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -189,6 +189,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/common/debugger/Makefile.in mysql/ndb/src/common/debugger/Makefile.in --- mysql.orig/ndb/src/common/debugger/Makefile.in 2007-12-14 21:45:43.000000000 +0100 +++ mysql/ndb/src/common/debugger/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -223,6 +223,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/common/debugger/signaldata/Makefile.in mysql/ndb/src/common/debugger/signaldata/Makefile.in --- mysql.orig/ndb/src/common/debugger/signaldata/Makefile.in 2007-12-14 21:45:43.000000000 +0100 +++ mysql/ndb/src/common/debugger/signaldata/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -231,6 +231,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/common/logger/Makefile.in mysql/ndb/src/common/logger/Makefile.in --- mysql.orig/ndb/src/common/logger/Makefile.in 2007-12-14 21:45:44.000000000 +0100 +++ mysql/ndb/src/common/logger/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -217,6 +217,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/common/Makefile.in mysql/ndb/src/common/Makefile.in --- mysql.orig/ndb/src/common/Makefile.in 2007-12-14 21:45:42.000000000 +0100 +++ mysql/ndb/src/common/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -191,6 +191,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/common/mgmcommon/Makefile.in mysql/ndb/src/common/mgmcommon/Makefile.in --- mysql.orig/ndb/src/common/mgmcommon/Makefile.in 2007-12-14 21:45:45.000000000 +0100 +++ mysql/ndb/src/common/mgmcommon/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -231,6 +231,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/common/portlib/Makefile.in mysql/ndb/src/common/portlib/Makefile.in --- mysql.orig/ndb/src/common/portlib/Makefile.in 2007-12-14 21:45:45.000000000 +0100 +++ mysql/ndb/src/common/portlib/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -241,6 +241,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/common/transporter/Makefile.in mysql/ndb/src/common/transporter/Makefile.in --- mysql.orig/ndb/src/common/transporter/Makefile.in 2007-12-14 21:45:46.000000000 +0100 +++ mysql/ndb/src/common/transporter/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -217,6 +217,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/common/util/Makefile.in mysql/ndb/src/common/util/Makefile.in --- mysql.orig/ndb/src/common/util/Makefile.in 2007-12-14 21:45:47.000000000 +0100 +++ mysql/ndb/src/common/util/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -233,6 +233,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/cw/cpcd/Makefile.in mysql/ndb/src/cw/cpcd/Makefile.in --- mysql.orig/ndb/src/cw/cpcd/Makefile.in 2007-12-14 21:45:48.000000000 +0100 +++ mysql/ndb/src/cw/cpcd/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -224,6 +224,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/cw/Makefile.in mysql/ndb/src/cw/Makefile.in --- mysql.orig/ndb/src/cw/Makefile.in 2007-12-14 21:45:47.000000000 +0100 +++ mysql/ndb/src/cw/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -174,6 +174,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/backup/Makefile.in mysql/ndb/src/kernel/blocks/backup/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/backup/Makefile.in 2007-12-14 21:45:49.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/backup/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -216,6 +216,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/cmvmi/Makefile.in mysql/ndb/src/kernel/blocks/cmvmi/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/cmvmi/Makefile.in 2007-12-14 21:45:50.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/cmvmi/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -216,6 +216,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/dbacc/Makefile.in mysql/ndb/src/kernel/blocks/dbacc/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/dbacc/Makefile.in 2007-12-14 21:45:50.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/dbacc/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -216,6 +216,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/dbdict/Makefile.in mysql/ndb/src/kernel/blocks/dbdict/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/dbdict/Makefile.in 2007-12-14 21:45:51.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/dbdict/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -226,6 +226,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/dbdih/Makefile.in mysql/ndb/src/kernel/blocks/dbdih/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/dbdih/Makefile.in 2007-12-14 21:45:52.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/dbdih/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -223,6 +223,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/dblqh/Makefile.in mysql/ndb/src/kernel/blocks/dblqh/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/dblqh/Makefile.in 2007-12-14 21:45:52.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/dblqh/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -224,6 +224,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/dbtc/Makefile.in mysql/ndb/src/kernel/blocks/dbtc/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/dbtc/Makefile.in 2007-12-14 21:45:53.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/dbtc/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -216,6 +216,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/dbtup/Makefile.in mysql/ndb/src/kernel/blocks/dbtup/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/dbtup/Makefile.in 2007-12-14 21:45:53.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/dbtup/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -224,6 +224,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/dbtux/Makefile.in mysql/ndb/src/kernel/blocks/dbtux/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/dbtux/Makefile.in 2007-12-14 21:45:54.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/dbtux/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -219,6 +219,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/dbutil/Makefile.in mysql/ndb/src/kernel/blocks/dbutil/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/dbutil/Makefile.in 2007-12-14 21:45:54.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/dbutil/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -216,6 +216,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/Makefile.in mysql/ndb/src/kernel/blocks/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/Makefile.in 2007-12-14 21:45:49.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -174,6 +174,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/ndbcntr/Makefile.in mysql/ndb/src/kernel/blocks/ndbcntr/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/ndbcntr/Makefile.in 2007-12-14 21:45:55.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/ndbcntr/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -217,6 +217,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/ndbfs/Makefile.in mysql/ndb/src/kernel/blocks/ndbfs/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/ndbfs/Makefile.in 2007-12-14 21:45:56.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/ndbfs/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -217,6 +217,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/qmgr/Makefile.in mysql/ndb/src/kernel/blocks/qmgr/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/qmgr/Makefile.in 2007-12-14 21:45:56.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/qmgr/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -216,6 +216,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/suma/Makefile.in mysql/ndb/src/kernel/blocks/suma/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/suma/Makefile.in 2007-12-14 21:45:57.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/suma/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -216,6 +216,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/blocks/trix/Makefile.in mysql/ndb/src/kernel/blocks/trix/Makefile.in --- mysql.orig/ndb/src/kernel/blocks/trix/Makefile.in 2007-12-14 21:45:57.000000000 +0100 +++ mysql/ndb/src/kernel/blocks/trix/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -216,6 +216,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/error/Makefile.in mysql/ndb/src/kernel/error/Makefile.in --- mysql.orig/ndb/src/kernel/error/Makefile.in 2007-12-14 21:45:58.000000000 +0100 +++ mysql/ndb/src/kernel/error/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -225,6 +225,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/Makefile.in mysql/ndb/src/kernel/Makefile.in --- mysql.orig/ndb/src/kernel/Makefile.in 2007-12-14 21:45:48.000000000 +0100 +++ mysql/ndb/src/kernel/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -244,6 +244,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/kernel/vm/Makefile.in mysql/ndb/src/kernel/vm/Makefile.in --- mysql.orig/ndb/src/kernel/vm/Makefile.in 2007-12-14 21:45:59.000000000 +0100 +++ mysql/ndb/src/kernel/vm/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -227,6 +227,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/Makefile.in mysql/ndb/src/Makefile.in --- mysql.orig/ndb/src/Makefile.in 2007-12-14 21:45:42.000000000 +0100 +++ mysql/ndb/src/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -218,6 +218,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/mgmapi/Makefile.in mysql/ndb/src/mgmapi/Makefile.in --- mysql.orig/ndb/src/mgmapi/Makefile.in 2007-12-14 21:45:59.000000000 +0100 +++ mysql/ndb/src/mgmapi/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -224,6 +224,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/mgmclient/Makefile.in mysql/ndb/src/mgmclient/Makefile.in --- mysql.orig/ndb/src/mgmclient/Makefile.in 2007-12-14 21:46:00.000000000 +0100 +++ mysql/ndb/src/mgmclient/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -234,6 +234,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/mgmsrv/Makefile.in mysql/ndb/src/mgmsrv/Makefile.in --- mysql.orig/ndb/src/mgmsrv/Makefile.in 2007-12-14 21:46:00.000000000 +0100 +++ mysql/ndb/src/mgmsrv/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -230,6 +230,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/src/ndbapi/Makefile.in mysql/ndb/src/ndbapi/Makefile.in --- mysql.orig/ndb/src/ndbapi/Makefile.in 2007-12-14 21:46:01.000000000 +0100 +++ mysql/ndb/src/ndbapi/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -234,6 +234,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/test/Makefile.in mysql/ndb/test/Makefile.in --- mysql.orig/ndb/test/Makefile.in 2007-12-14 21:46:01.000000000 +0100 +++ mysql/ndb/test/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -174,6 +174,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/test/ndbapi/bank/Makefile.in mysql/ndb/test/ndbapi/bank/Makefile.in --- mysql.orig/ndb/test/ndbapi/bank/Makefile.in 2007-12-14 21:46:03.000000000 +0100 +++ mysql/ndb/test/ndbapi/bank/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -303,6 +303,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/test/ndbapi/Makefile.in mysql/ndb/test/ndbapi/Makefile.in --- mysql.orig/ndb/test/ndbapi/Makefile.in 2007-12-14 21:46:02.000000000 +0100 +++ mysql/ndb/test/ndbapi/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -611,6 +611,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/test/run-test/Makefile.in mysql/ndb/test/run-test/Makefile.in --- mysql.orig/ndb/test/run-test/Makefile.in 2007-12-14 21:46:04.000000000 +0100 +++ mysql/ndb/test/run-test/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -262,6 +262,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/test/src/Makefile.in mysql/ndb/test/src/Makefile.in --- mysql.orig/ndb/test/src/Makefile.in 2007-12-14 21:46:04.000000000 +0100 +++ mysql/ndb/test/src/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -232,6 +232,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/test/tools/Makefile.in mysql/ndb/test/tools/Makefile.in --- mysql.orig/ndb/test/tools/Makefile.in 2007-12-14 21:46:05.000000000 +0100 +++ mysql/ndb/test/tools/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -345,6 +345,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/ndb/tools/Makefile.in mysql/ndb/tools/Makefile.in --- mysql.orig/ndb/tools/Makefile.in 2007-12-14 21:46:06.000000000 +0100 +++ mysql/ndb/tools/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -331,6 +331,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/netware/Makefile.in mysql/netware/Makefile.in --- mysql.orig/netware/Makefile.in 2007-12-14 21:46:06.000000000 +0100 +++ mysql/netware/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -219,6 +219,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/os2/include/Makefile.in mysql/os2/include/Makefile.in --- mysql.orig/os2/include/Makefile.in 2007-12-14 21:46:07.000000000 +0100 +++ mysql/os2/include/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -174,6 +174,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/os2/include/sys/Makefile.in mysql/os2/include/sys/Makefile.in --- mysql.orig/os2/include/sys/Makefile.in 2007-12-14 21:46:07.000000000 +0100 +++ mysql/os2/include/sys/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -165,6 +165,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/os2/Makefile.in mysql/os2/Makefile.in --- mysql.orig/os2/Makefile.in 2007-12-14 21:46:06.000000000 +0100 +++ mysql/os2/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -174,6 +174,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/patch_info/userstats.info mysql/patch_info/userstats.info --- mysql.orig/patch_info/userstats.info 1970-01-01 01:00:00.000000000 +0100 +++ mysql/patch_info/userstats.info 2008-11-27 20:08:07.000000000 +0100 @@ -0,0 +1,6 @@ +File=userstatsv2.patch +Name=SHOW USER/TABLE/INDEX statistics +Version=V2 +Author=Google +License=GPL +Comment=Added INFORMATION_SCHEMA.*_STATISTICS diff -Naur mysql.orig/pstack/aout/Makefile.in mysql/pstack/aout/Makefile.in --- mysql.orig/pstack/aout/Makefile.in 2007-12-14 21:46:08.000000000 +0100 +++ mysql/pstack/aout/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -155,6 +155,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/pstack/Makefile.in mysql/pstack/Makefile.in --- mysql.orig/pstack/Makefile.in 2007-12-14 21:46:07.000000000 +0100 +++ mysql/pstack/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -213,6 +213,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/regex/Makefile.in mysql/regex/Makefile.in --- mysql.orig/regex/Makefile.in 2007-12-14 21:46:08.000000000 +0100 +++ mysql/regex/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -197,6 +197,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/scripts/Makefile.in mysql/scripts/Makefile.in --- mysql.orig/scripts/Makefile.in 2007-12-14 21:46:08.000000000 +0100 +++ mysql/scripts/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -196,6 +196,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/server-tools/instance-manager/Makefile.in mysql/server-tools/instance-manager/Makefile.in --- mysql.orig/server-tools/instance-manager/Makefile.in 2007-12-14 21:46:09.000000000 +0100 +++ mysql/server-tools/instance-manager/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -221,6 +221,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/server-tools/Makefile.in mysql/server-tools/Makefile.in --- mysql.orig/server-tools/Makefile.in 2007-12-14 21:46:09.000000000 +0100 +++ mysql/server-tools/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -173,6 +173,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/sql/ha_innodb.cc mysql/sql/ha_innodb.cc --- mysql.orig/sql/ha_innodb.cc 2007-12-14 21:43:42.000000000 +0100 +++ mysql/sql/ha_innodb.cc 2008-11-27 20:08:07.000000000 +0100 @@ -3286,6 +3286,8 @@ error = row_insert_for_mysql((byte*) record, prebuilt); + if (error == DB_SUCCESS) rows_changed++; + if (error == DB_SUCCESS && auto_inc_used) { /* Fetch the value that was set in the autoincrement field */ @@ -3558,6 +3560,8 @@ } } + if (error == DB_SUCCESS) rows_changed++; + innodb_srv_conc_exit_innodb(prebuilt->trx); error = convert_error_code_to_mysql(error, user_thd); @@ -3606,6 +3610,8 @@ error = row_update_for_mysql((byte*) record, prebuilt); + if (error == DB_SUCCESS) rows_changed++; + innodb_srv_conc_exit_innodb(prebuilt->trx); error = convert_error_code_to_mysql(error, user_thd); @@ -4038,6 +4044,9 @@ if (ret == DB_SUCCESS) { error = 0; table->status = 0; + rows_read++; + if (active_index >= 0 && active_index < MAX_KEY) + index_rows_read[active_index]++; } else if (ret == DB_RECORD_NOT_FOUND) { error = HA_ERR_END_OF_FILE; diff -Naur mysql.orig/sql/ha_myisam.cc mysql/sql/ha_myisam.cc --- mysql.orig/sql/ha_myisam.cc 2007-12-14 21:43:13.000000000 +0100 +++ mysql/sql/ha_myisam.cc 2008-11-27 20:08:07.000000000 +0100 @@ -670,7 +670,9 @@ if ((error= update_auto_increment())) return error; } - return mi_write(file,buf); + int error=mi_write(file,buf); + if (!error) rows_changed++; + return error; } int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) @@ -1518,13 +1520,17 @@ statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); - return mi_update(file,old_data,new_data); + int error=mi_update(file,old_data,new_data); + if (!error) rows_changed++; + return error; } int ha_myisam::delete_row(const byte * buf) { statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status); - return mi_delete(file,buf); + int error=mi_delete(file,buf); + if (!error) rows_changed++; + return error; } int ha_myisam::index_read(byte * buf, const byte * key, @@ -1535,6 +1541,13 @@ &LOCK_status); int error=mi_rkey(file,buf,active_index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; + if (!error) { + rows_read++; + + int inx = (active_index == -1) ? file->lastinx : active_index; + if (inx >= 0 && inx < MAX_KEY) + index_rows_read[inx]++; + } return error; } @@ -1545,6 +1558,13 @@ &LOCK_status); int error=mi_rkey(file,buf,index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; + if (!error) { + rows_read++; + + int inx = index; + if (inx >= 0 && inx < MAX_KEY) + index_rows_read[inx]++; + } return error; } @@ -1555,6 +1575,13 @@ &LOCK_status); int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; + if (!error) { + rows_read++; + + int inx = (active_index == -1) ? file->lastinx : active_index; + if (inx >= 0 && inx < MAX_KEY) + index_rows_read[inx]++; + } return error; } @@ -1565,6 +1592,13 @@ &LOCK_status); int error=mi_rnext(file,buf,active_index); table->status=error ? STATUS_NOT_FOUND: 0; + if (!error) { + rows_read++; + + int inx = (active_index == -1) ? file->lastinx : active_index; + if (inx >= 0 && inx < MAX_KEY) + index_rows_read[inx]++; + } return error; } @@ -1575,6 +1609,13 @@ &LOCK_status); int error=mi_rprev(file,buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + if (!error) { + rows_read++; + + int inx = (active_index == -1) ? file->lastinx : active_index; + if (inx >= 0 && inx < MAX_KEY) + index_rows_read[inx]++; + } return error; } @@ -1585,6 +1626,13 @@ &LOCK_status); int error=mi_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + if (!error) { + rows_read++; + + int inx = (active_index == -1) ? file->lastinx : active_index; + if (inx >= 0 && inx < MAX_KEY) + index_rows_read[inx]++; + } return error; } @@ -1595,6 +1643,13 @@ &LOCK_status); int error=mi_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + if (!error) { + rows_read++; + + int inx = (active_index == -1) ? file->lastinx : active_index; + if (inx >= 0 && inx < MAX_KEY) + index_rows_read[inx]++; + } return error; } @@ -1611,6 +1666,13 @@ error= mi_rnext_same(file,buf); } while (error == HA_ERR_RECORD_DELETED); table->status=error ? STATUS_NOT_FOUND: 0; + if (!error) { + rows_read++; + + int inx = (active_index == -1) ? file->lastinx : active_index; + if (inx >= 0 && inx < MAX_KEY) + index_rows_read[inx]++; + } return error; } @@ -1628,6 +1690,7 @@ &LOCK_status); int error=mi_scan(file, buf); table->status=error ? STATUS_NOT_FOUND: 0; + if (!error) rows_read++; return error; } @@ -1642,6 +1705,7 @@ &LOCK_status); int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; + if (!error) rows_read++; return error; } diff -Naur mysql.orig/sql/handler.cc mysql/sql/handler.cc --- mysql.orig/sql/handler.cc 2007-12-14 21:43:00.000000000 +0100 +++ mysql/sql/handler.cc 2008-11-27 20:08:07.000000000 +0100 @@ -20,6 +20,13 @@ #pragma implementation // gcc: Class implementation #endif +/* + * Ugh. Something is fishy with the SAFE_MUTEX stuff in include/my_pthread.h. + * This makes things compile with gcc 4.1 + */ +#include + + #include "mysql_priv.h" #include "ha_heap.h" #include "ha_myisam.h" @@ -725,6 +732,8 @@ if (cookie) tc_log->unlog(cookie, xid); DBUG_EXECUTE_IF("crash_commit_after", abort();); + if (is_real_trans) + thd->diff_commit_trans++; end: if (is_real_trans) start_waiting_global_read_lock(thd); @@ -824,6 +833,7 @@ thd->transaction.cleanup(); } } + thd->diff_rollback_trans++; #endif /* USING_TRANSACTIONS */ if (all) thd->transaction_rollback_request= FALSE; @@ -1207,6 +1217,7 @@ statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status); *ht=0; // keep it conveniently zero-filled } + thd->diff_rollback_trans++; DBUG_RETURN(error); } @@ -1429,6 +1440,8 @@ else dupp_ref=ref+ALIGN_SIZE(ref_length); } + rows_read = rows_changed = 0; + memset(index_rows_read, 0, sizeof(index_rows_read)); DBUG_RETURN(error); } @@ -2212,6 +2225,99 @@ return error; } +// Updates the global table stats with the TABLE this handler represents. +void handler::update_global_table_stats() { + if (!rows_read && !rows_changed) return; // Nothing to update. + // table_cache_key is db_name + '\0' + table_name + '\0'. + if (!table->s || !table->s->table_cache_key || !table->s->table_name) return; + + TABLE_STATS* table_stats; + char key[NAME_LEN * 2 + 2]; + // [db] + '.' + [table] + sprintf(key, "%s.%s", table->s->table_cache_key, table->s->table_name); + + pthread_mutex_lock(&LOCK_global_table_stats); + // Gets the global table stats, creating one if necessary. + if (!(table_stats = (TABLE_STATS*)hash_search(&global_table_stats, + (byte*)key, + strlen(key)))) { + if (!(table_stats = ((TABLE_STATS*) + my_malloc(sizeof(TABLE_STATS), MYF(MY_WME))))) { + // Out of memory. + sql_print_error("Allocating table stats failed."); + goto end; + } + strncpy(table_stats->table, key, sizeof(table_stats->table)); + table_stats->rows_read = 0; + table_stats->rows_changed = 0; + table_stats->rows_changed_x_indexes = 0; + table_stats->engine_type = (int) ht->db_type; + + if (my_hash_insert(&global_table_stats, (byte*)table_stats)) { + // Out of memory. + sql_print_error("Inserting table stats failed."); + my_free((char*)table_stats, 0); + goto end; + } + } + // Updates the global table stats. + table_stats->rows_read += rows_read; + table_stats->rows_changed += rows_changed; + table_stats->rows_changed_x_indexes += + rows_changed * (table->s->keys ? table->s->keys : 1); + current_thd->diff_total_read_rows += rows_read; + rows_read = rows_changed = 0; +end: + pthread_mutex_unlock(&LOCK_global_table_stats); +} + +// Updates the global index stats with this handler's accumulated index reads. +void handler::update_global_index_stats() { + // table_cache_key is db_name + '\0' + table_name + '\0'. + if (!table->s || !table->s->table_cache_key || !table->s->table_name) return; + + for (int x = 0; x < table->s->keys; x++) { + if (index_rows_read[x]) { + // Rows were read using this index. + KEY* key_info = &table->key_info[x]; + + if (!key_info->name) continue; + + INDEX_STATS* index_stats; + char key[NAME_LEN * 3 + 3]; + // [db] + '.' + [table] + '.' + [index] + sprintf(key, "%s.%s.%s", table->s->table_cache_key, + table->s->table_name, key_info->name); + + pthread_mutex_lock(&LOCK_global_index_stats); + // Gets the global index stats, creating one if necessary. + if (!(index_stats = (INDEX_STATS*)hash_search(&global_index_stats, + (byte*)key, + strlen(key)))) { + if (!(index_stats = ((INDEX_STATS*) + my_malloc(sizeof(INDEX_STATS), MYF(MY_WME))))) { + // Out of memory. + sql_print_error("Allocating index stats failed."); + goto end; + } + strncpy(index_stats->index, key, sizeof(index_stats->index)); + index_stats->rows_read = 0; + + if (my_hash_insert(&global_index_stats, (byte*)index_stats)) { + // Out of memory. + sql_print_error("Inserting index stats failed."); + my_free((char*)index_stats, 0); + goto end; + } + } + // Updates the global index stats. + index_stats->rows_read += index_rows_read[x]; + index_rows_read[x] = 0; +end: + pthread_mutex_unlock(&LOCK_global_index_stats); + } + } +} /**************************************************************************** ** Some general functions that isn't in the handler class diff -Naur mysql.orig/sql/handler.h mysql/sql/handler.h --- mysql.orig/sql/handler.h 2007-12-14 21:43:15.000000000 +0100 +++ mysql/sql/handler.h 2008-11-27 20:08:07.000000000 +0100 @@ -32,6 +32,10 @@ #define USING_TRANSACTIONS #endif +#if MAX_KEY > 128 +#error MAX_KEY is too large. Values up to 128 are supported. +#endif + // the following is for checking tables #define HA_ADMIN_ALREADY_DONE 1 @@ -604,6 +608,9 @@ bool auto_increment_column_changed; bool implicit_emptied; /* Can be !=0 only if HEAP */ const COND *pushed_cond; + ulonglong rows_read; + ulonglong rows_changed; + ulonglong index_rows_read[MAX_KEY]; handler(const handlerton *ht_arg, TABLE *table_arg) :table(table_arg), ht(ht_arg), @@ -615,8 +622,10 @@ ref_length(sizeof(my_off_t)), block_size(0), raid_type(0), ft_handler(0), inited(NONE), locked(FALSE), implicit_emptied(0), - pushed_cond(NULL) - {} + pushed_cond(NULL), rows_read(0), rows_changed(0) + { + memset(index_rows_read, 0, sizeof(index_rows_read)); + } virtual ~handler(void) { DBUG_ASSERT(locked == FALSE); /* TODO: DBUG_ASSERT(inited == NONE); */ } virtual handler *clone(MEM_ROOT *mem_root); int ha_open(const char *name, int mode, int test_if_locked); @@ -625,7 +634,11 @@ virtual void print_error(int error, myf errflag); virtual bool get_error_message(int error, String *buf); uint get_dup_key(int error); - void change_table_ptr(TABLE *table_arg) { table=table_arg; } + void change_table_ptr(TABLE *table_arg) { + table=table_arg; + rows_read = rows_changed = 0; + memset(index_rows_read, 0, sizeof(index_rows_read)); + } virtual double scan_time() { return ulonglong2double(data_file_length) / IO_SIZE + 2; } virtual double read_time(uint index, uint ranges, ha_rows rows) @@ -885,6 +898,9 @@ virtual bool is_crashed() const { return 0; } virtual bool auto_repair() const { return 0; } + void update_global_table_stats(); + void update_global_index_stats(); + /* default rename_table() and delete_table() rename/delete files with a given name and extensions from bas_ext() diff -Naur mysql.orig/sql/lex.h mysql/sql/lex.h --- mysql.orig/sql/lex.h 2007-12-14 21:43:42.000000000 +0100 +++ mysql/sql/lex.h 2008-11-27 20:08:07.000000000 +0100 @@ -108,6 +108,7 @@ { "CHECKSUM", SYM(CHECKSUM_SYM)}, { "CIPHER", SYM(CIPHER_SYM)}, { "CLIENT", SYM(CLIENT_SYM)}, + { "CLIENT_STATISTICS", SYM(CLIENT_STATS_SYM)}, { "CLOSE", SYM(CLOSE_SYM)}, { "CODE", SYM(CODE_SYM)}, { "COLLATE", SYM(COLLATE_SYM)}, @@ -234,6 +235,7 @@ { "IN", SYM(IN_SYM)}, { "INDEX", SYM(INDEX_SYM)}, { "INDEXES", SYM(INDEXES)}, + { "INDEX_STATISTICS", SYM(INDEX_STATS_SYM)}, { "INFILE", SYM(INFILE)}, { "INNER", SYM(INNER_SYM)}, { "INNOBASE", SYM(INNOBASE_SYM)}, @@ -432,6 +434,7 @@ { "SIGNED", SYM(SIGNED_SYM)}, { "SIMPLE", SYM(SIMPLE_SYM)}, { "SLAVE", SYM(SLAVE)}, + { "SLOW", SYM(SLOW_SYM)}, { "SNAPSHOT", SYM(SNAPSHOT_SYM)}, { "SMALLINT", SYM(SMALLINT)}, { "SOME", SYM(ANY_SYM)}, @@ -474,6 +477,7 @@ { "TABLE", SYM(TABLE_SYM)}, { "TABLES", SYM(TABLES)}, { "TABLESPACE", SYM(TABLESPACE)}, + { "TABLE_STATISTICS", SYM(TABLE_STATS_SYM)}, { "TEMPORARY", SYM(TEMPORARY)}, { "TEMPTABLE", SYM(TEMPTABLE_SYM)}, { "TERMINATED", SYM(TERMINATED)}, @@ -511,6 +515,7 @@ { "USE", SYM(USE_SYM)}, { "USER", SYM(USER)}, { "USER_RESOURCES", SYM(RESOURCES)}, + { "USER_STATISTICS", SYM(USER_STATS_SYM)}, { "USE_FRM", SYM(USE_FRM)}, { "USING", SYM(USING)}, { "UTC_DATE", SYM(UTC_DATE_SYM)}, diff -Naur mysql.orig/sql/log.cc mysql/sql/log.cc --- mysql.orig/sql/log.cc 2007-12-14 21:43:51.000000000 +0100 +++ mysql/sql/log.cc 2008-11-27 20:08:52.000000000 +0100 @@ -1708,18 +1708,24 @@ thd->current_insert_id); if (e.write(file)) goto err; + if (file == &log_file) + thd->binlog_bytes_written += e.data_written; } if (thd->insert_id_used) { Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id); if (e.write(file)) goto err; + if (file == &log_file) + thd->binlog_bytes_written += e.data_written; } if (thd->rand_used) { Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2); if (e.write(file)) goto err; + if (file == &log_file) + thd->binlog_bytes_written += e.data_written; } if (thd->user_var_events.elements) { @@ -1735,6 +1741,8 @@ user_var_event->charset_number); if (e.write(file)) goto err; + if (file == &log_file) + thd->binlog_bytes_written += e.data_written; } } } @@ -1745,6 +1753,8 @@ if (event_info->write(file)) goto err; + if (file == &log_file) + thd->binlog_bytes_written += event_info->data_written; if (file == &log_file) // we are writing to the real log (disk) { @@ -1862,6 +1872,7 @@ */ if (qinfo.write(&log_file)) goto err; + thd->binlog_bytes_written += qinfo.data_written; } /* Read from the file used to cache the queries .*/ if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0)) @@ -1908,6 +1919,7 @@ /* write the first half of the split header */ if (my_b_write(&log_file, header, carry)) goto err; + thd->binlog_bytes_written += carry; /* copy fixed second half of header to cache so the correct @@ -1976,6 +1988,8 @@ /* Write data to the binary log file */ if (my_b_write(&log_file, cache->read_pos, length)) goto err; + thd->binlog_bytes_written += length; + cache->read_pos=cache->read_end; // Mark buffer used up DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;); } while ((length=my_b_fill(cache))); @@ -1984,6 +1998,8 @@ if (commit_event->write(&log_file)) goto err; + thd->binlog_bytes_written += commit_event->data_written; + #ifndef DBUG_OFF DBUG_skip_commit: #endif diff -Naur mysql.orig/sql/Makefile.in mysql/sql/Makefile.in --- mysql.orig/sql/Makefile.in 2007-12-14 21:46:10.000000000 +0100 +++ mysql/sql/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -282,6 +282,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/sql/mysqld.cc mysql/sql/mysqld.cc --- mysql.orig/sql/mysqld.cc 2007-12-14 21:42:59.000000000 +0100 +++ mysql/sql/mysqld.cc 2008-11-27 20:08:07.000000000 +0100 @@ -438,6 +438,7 @@ ulong binlog_cache_use= 0, binlog_cache_disk_use= 0; ulong max_connections, max_connect_errors; uint max_user_connections= 0; +ulonglong denied_connections = 0; /* Limit of the total number of prepared statements in the server. Is necessary to protect the server against out-of-memory attacks. @@ -537,6 +538,10 @@ LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_global_system_variables, LOCK_user_conn, LOCK_slave_list, LOCK_active_mi; +pthread_mutex_t LOCK_stats; +pthread_mutex_t LOCK_global_user_client_stats; +pthread_mutex_t LOCK_global_table_stats; +pthread_mutex_t LOCK_global_index_stats; /* The below lock protects access to two global server variables: max_prepared_stmt_count and prepared_stmt_count. These variables @@ -1184,6 +1189,10 @@ x_free(opt_secure_file_priv); bitmap_free(&temp_pool); free_max_user_conn(); + free_global_user_stats(); + free_global_client_stats(); + free_global_table_stats(); + free_global_index_stats(); #ifdef HAVE_REPLICATION end_slave_list(); free_list(&replicate_do_db); @@ -1298,6 +1307,10 @@ (void) pthread_cond_destroy(&COND_thread_cache); (void) pthread_cond_destroy(&COND_flush_thread_cache); (void) pthread_cond_destroy(&COND_manager); + (void) pthread_mutex_destroy(&LOCK_stats); + (void) pthread_mutex_destroy(&LOCK_global_user_client_stats); + (void) pthread_mutex_destroy(&LOCK_global_table_stats); + (void) pthread_mutex_destroy(&LOCK_global_index_stats); } #endif /*EMBEDDED_LIBRARY*/ @@ -3014,6 +3027,10 @@ (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST); (void) pthread_cond_init(&COND_rpl_status, NULL); #endif + (void) pthread_mutex_init(&LOCK_stats, MY_MUTEX_INIT_FAST); + (void) pthread_mutex_init(&LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST); + (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST); + (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST); sp_cache_init(); /* Parameter for threads created for connections */ (void) pthread_attr_init(&connection_attrib); @@ -3285,6 +3302,10 @@ sql_print_error("Out of memory"); unireg_abort(1); } + + init_global_table_stats(); + init_global_index_stats(); + if (ha_init()) { sql_print_error("Can't init databases"); @@ -3367,6 +3388,8 @@ init_max_user_conn(); init_update_queries(); + init_global_user_stats(); + init_global_client_stats(); DBUG_RETURN(0); } @@ -4053,6 +4076,7 @@ { DBUG_PRINT("error",("Too many connections")); close_connection(thd, ER_CON_COUNT_ERROR, 1); + statistic_increment(denied_connections, &LOCK_status); delete thd; DBUG_VOID_RETURN; } diff -Naur mysql.orig/sql/mysql_priv.h mysql/sql/mysql_priv.h --- mysql.orig/sql/mysql_priv.h 2007-12-14 21:43:41.000000000 +0100 +++ mysql/sql/mysql_priv.h 2008-11-27 20:08:07.000000000 +0100 @@ -725,7 +725,15 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex); void init_max_user_conn(void); void init_update_queries(void); +void init_global_user_stats(void); +void init_global_table_stats(void); +void init_global_index_stats(void); +void init_global_client_stats(void); void free_max_user_conn(void); +void free_global_user_stats(void); +void free_global_table_stats(void); +void free_global_index_stats(void); +void free_global_client_stats(void); pthread_handler_t handle_one_connection(void *arg); pthread_handler_t handle_bootstrap(void *arg); void end_thread(THD *thd,bool put_in_cache); @@ -1291,6 +1299,7 @@ extern ulong max_connections,max_connect_errors, connect_timeout; extern ulong slave_net_timeout, slave_trans_retries; extern uint max_user_connections; +extern ulonglong denied_connections; extern ulong what_to_log,flush_time; extern ulong query_buff_size, thread_stack; extern ulong max_prepared_stmt_count, prepared_stmt_count; @@ -1363,6 +1372,14 @@ extern struct system_variables max_system_variables; extern struct system_status_var global_status_var; extern struct rand_struct sql_rand; +extern HASH global_user_stats; +extern HASH global_client_stats; +extern pthread_mutex_t LOCK_global_user_client_stats; +extern HASH global_table_stats; +extern pthread_mutex_t LOCK_global_table_stats; +extern HASH global_index_stats; +extern pthread_mutex_t LOCK_global_index_stats; +extern pthread_mutex_t LOCK_stats; extern const char *opt_date_time_formats[]; extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[]; diff -Naur mysql.orig/sql/share/Makefile.in mysql/sql/share/Makefile.in --- mysql.orig/sql/share/Makefile.in 2007-12-14 21:46:10.000000000 +0100 +++ mysql/sql/share/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -165,6 +165,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/sql/sql_base.cc mysql/sql/sql_base.cc --- mysql.orig/sql/sql_base.cc 2007-12-14 21:43:00.000000000 +0100 +++ mysql/sql/sql_base.cc 2008-11-27 20:08:07.000000000 +0100 @@ -624,6 +624,12 @@ DBUG_ENTER("close_thread_table"); DBUG_ASSERT(table->key_read == 0); DBUG_ASSERT(!table->file || table->file->inited == handler::NONE); + + if(table->file) + { + table->file->update_global_table_stats(); + table->file->update_global_index_stats(); + } *table_ptr=table->next; if (table->needs_reopen_or_name_lock() || @@ -670,6 +676,9 @@ { DBUG_ENTER("close_temporary"); char path[FN_REFLEN]; + + table->file->update_global_table_stats(); + table->file->update_global_index_stats(); db_type table_type=table->s->db_type; strmov(path,table->s->path); free_io_cache(table); diff -Naur mysql.orig/sql/sql_class.cc mysql/sql/sql_class.cc --- mysql.orig/sql/sql_class.cc 2007-12-14 21:43:42.000000000 +0100 +++ mysql/sql/sql_class.cc 2008-11-27 20:08:07.000000000 +0100 @@ -221,6 +221,12 @@ bzero(ha_data, sizeof(ha_data)); mysys_var=0; binlog_evt_union.do_union= FALSE; + busy_time = 0; + cpu_time = 0; + bytes_received = 0; + bytes_sent = 0; + binlog_bytes_written = 0; + updated_row_count = 0; #ifndef DBUG_OFF dbug_sentry=THD_SENTRY_MAGIC; #endif @@ -351,6 +357,86 @@ total_warn_count= 0; update_charset(); bzero((char *) &status_var, sizeof(status_var)); + reset_stats(); +} + +// Resets stats in a THD. +void THD::reset_stats(void) { + current_connect_time = time(NULL); + last_global_update_time = current_connect_time; + reset_diff_stats(); +} + +// Resets the 'diff' stats, which are used to update global stats. +void THD::reset_diff_stats(void) { + diff_total_busy_time = 0; + diff_total_cpu_time = 0; + diff_total_bytes_received = 0; + diff_total_bytes_sent = 0; + diff_total_binlog_bytes_written = 0; + diff_total_sent_rows = 0; + diff_total_updated_rows = 0; + diff_total_read_rows = 0; + diff_select_commands = 0; + diff_update_commands = 0; + diff_other_commands = 0; + diff_commit_trans = 0; + diff_rollback_trans = 0; + diff_denied_connections = 0; + diff_lost_connections = 0; + diff_access_denied_errors = 0; + diff_empty_queries = 0; +} + +// Updates 'diff' stats of a THD. +void THD::update_stats(bool ran_command) { + diff_total_busy_time += busy_time; + diff_total_cpu_time += cpu_time; + diff_total_bytes_received += bytes_received; + diff_total_bytes_sent += bytes_sent; + diff_total_binlog_bytes_written += binlog_bytes_written; + diff_total_sent_rows += sent_row_count; + diff_total_updated_rows += updated_row_count; + // diff_total_read_rows is updated in handler.cc. + + if (ran_command) { + // The replication thread has the COM_CONNECT command. + if ((old_command == COM_QUERY || command == COM_CONNECT) && + (lex->sql_command >= 0 && lex->sql_command < SQLCOM_END)) { + // A SQL query. + if (lex->sql_command == SQLCOM_SELECT) { + if (lex->orig_sql_command == SQLCOM_END) { + diff_select_commands++; + if (!sent_row_count) + diff_empty_queries++; + } else { + // 'SHOW ' commands become SQLCOM_SELECT. + diff_other_commands++; + // 'SHOW ' commands shouldn't inflate total sent row count. + diff_total_sent_rows -= sent_row_count; + } + } else if (is_update_query(lex->sql_command)) { + diff_update_commands++; + } else { + diff_other_commands++; + } + } + } + // diff_commit_trans is updated in handler.cc. + // diff_rollback_trans is updated in handler.cc. + // diff_denied_connections is updated in sql_parse.cc. + // diff_lost_connections is updated in sql_parse.cc. + // diff_access_denied_errors is updated in sql_parse.cc. + + /* reset counters to zero to avoid double-counting since values + are already store in diff_total_*. */ + busy_time = 0; + cpu_time = 0; + bytes_received = 0; + bytes_sent = 0; + binlog_bytes_written = 0; + sent_row_count = 0; + updated_row_count = 0; } @@ -390,6 +476,9 @@ void THD::change_user(void) { + pthread_mutex_lock(&LOCK_status); + add_to_status(&global_status_var, &status_var); + pthread_mutex_unlock(&LOCK_status); cleanup(); cleanup_done= 0; init(); @@ -867,6 +956,33 @@ } #endif +char *THD::get_client_host_port(THD *client) +{ + Security_context *client_sctx= client->security_ctx; + char *client_host= NULL; + + if (client->peer_port && (client_sctx->host || client_sctx->ip) && + security_ctx->host_or_ip[0]) + { + if ((client_host= this->alloc(LIST_PROCESS_HOST_LEN+1))) + my_snprintf((char *) client_host, LIST_PROCESS_HOST_LEN, + "%s:%u", client_sctx->host_or_ip, client->peer_port); + } + else + client_host= this->strdup(client_sctx->host_or_ip[0] ? + client_sctx->host_or_ip : + client_sctx->host ? client_sctx->host : ""); + + return client_host; +} + +const char *get_client_host(THD *client) +{ + return client->security_ctx->host_or_ip[0] ? + client->security_ctx->host_or_ip : + client->security_ctx->host ? client->security_ctx->host : ""; +} + struct Item_change_record: public ilink { @@ -2053,6 +2169,7 @@ if (likely(thd != 0)) { /* current_thd==0 when close_connection() calls net_send_error() */ thd->status_var.bytes_sent+= length; + thd->bytes_sent+= length; } } @@ -2060,6 +2177,7 @@ void thd_increment_bytes_received(ulong length) { current_thd->status_var.bytes_received+= length; + current_thd->bytes_received+= length; } diff -Naur mysql.orig/sql/sql_class.h mysql/sql/sql_class.h --- mysql.orig/sql/sql_class.h 2007-12-14 21:43:41.000000000 +0100 +++ mysql/sql/sql_class.h 2008-11-27 20:08:07.000000000 +0100 @@ -1263,6 +1263,8 @@ first byte of the packet in do_command() */ enum enum_server_command command; + // Used to save the command, before it is set to COM_SLEEP. + enum enum_server_command old_command; uint32 server_id; uint32 file_id; // for LOAD DATA INFILE /* @@ -1434,6 +1436,7 @@ /* variables.transaction_isolation is reset to this after each commit */ enum_tx_isolation session_tx_isolation; enum_check_fields count_cuted_fields; + ha_rows updated_row_count; DYNAMIC_ARRAY user_var_events; /* For user variables replication */ MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */ @@ -1540,6 +1543,49 @@ */ LOG_INFO* current_linfo; NET* slave_net; // network connection from slave -> m. + + /* + Used to update global user stats. The global user stats are updated + occasionally with the 'diff' variables. After the update, the 'diff' + variables are reset to 0. + */ + // Time when the current thread connected to MySQL. + time_t current_connect_time; + // Last time when THD stats were updated in global_user_stats. + time_t last_global_update_time; + // Busy (non-idle) time for just one command. + double busy_time; + // Busy time not updated in global_user_stats yet. + double diff_total_busy_time; + // Cpu (non-idle) time for just one thread. + double cpu_time; + // Cpu time not updated in global_user_stats yet. + double diff_total_cpu_time; + /* bytes counting */ + ulonglong bytes_received; + ulonglong diff_total_bytes_received; + ulonglong bytes_sent; + ulonglong diff_total_bytes_sent; + ulonglong binlog_bytes_written; + ulonglong diff_total_binlog_bytes_written; + + // Number of rows not reflected in global_user_stats yet. + ha_rows diff_total_sent_rows, diff_total_updated_rows, diff_total_read_rows; + // Number of commands not reflected in global_user_stats yet. + ulonglong diff_select_commands, diff_update_commands, diff_other_commands; + // Number of transactions not reflected in global_user_stats yet. + ulonglong diff_commit_trans, diff_rollback_trans; + // Number of connection errors not reflected in global_user_stats yet. + ulonglong diff_denied_connections, diff_lost_connections; + // Number of db access denied, not reflected in global_user_stats yet. + ulonglong diff_access_denied_errors; + // Number of queries that return 0 rows + ulonglong diff_empty_queries; + + // Per account query delay in miliseconds. When not 0, sleep this number of + // milliseconds before every SQL command. + ulonglong query_delay_millis; + /* Used by the sys_var class to store temporary values */ union { @@ -1597,6 +1643,11 @@ alloc_root. */ void init_for_queries(); + void reset_stats(void); + void reset_diff_stats(void); + // ran_command is true when this is called immediately after a + // command has been run. + void update_stats(bool ran_command); void change_user(void); void cleanup(void); void cleanup_after_query(); @@ -1826,8 +1877,14 @@ if (p_db_length) *p_db_length= db_length; return FALSE; + + // Returns string as 'IP:port' for the client-side of the connnection represented + // by 'client' as displayed by SHOW PROCESSLIST. Allocates memory from the heap of + // this THD and that is not reclaimed immediately, so use sparingly. May return NULL. } + char *get_client_host_port(THD *client); + public: /** Add an internal error handler to the thread execution context. @@ -1870,6 +1927,11 @@ MEM_ROOT main_mem_root; }; +// Returns string as 'IP' for the client-side of the connection represented by +// 'client'. Does not allocate memory. May return "". +const char *get_client_host(THD *client); + +#define LIST_PROCESS_HOST_LEN 64 #define tmp_disable_binlog(A) \ {ulonglong tmp_disable_binlog__save_options= (A)->options; \ diff -Naur mysql.orig/sql/sql_delete.cc mysql/sql/sql_delete.cc --- mysql.orig/sql/sql_delete.cc 2007-12-14 21:43:51.000000000 +0100 +++ mysql/sql/sql_delete.cc 2008-11-27 20:08:07.000000000 +0100 @@ -353,6 +353,7 @@ send_ok(thd,deleted); DBUG_PRINT("info",("%ld records deleted",(long) deleted)); } + thd->updated_row_count += deleted; DBUG_RETURN(error >= 0 || thd->net.report_error); } @@ -868,6 +869,7 @@ thd->row_count_func= deleted; ::send_ok(thd, deleted); } + thd->updated_row_count += deleted; return 0; } diff -Naur mysql.orig/sql/sql_insert.cc mysql/sql/sql_insert.cc --- mysql.orig/sql/sql_insert.cc 2007-12-14 21:42:41.000000000 +0100 +++ mysql/sql/sql_insert.cc 2008-11-27 20:08:07.000000000 +0100 @@ -978,6 +978,7 @@ thd->row_count_func= info.copied + info.deleted + updated; ::send_ok(thd, (ulong) thd->row_count_func, id, buff); } + thd->updated_row_count += thd->row_count_func; thd->abort_on_warning= 0; DBUG_RETURN(FALSE); @@ -3007,6 +3008,7 @@ id= autoinc_value_of_first_inserted_row > 0 ? autoinc_value_of_first_inserted_row : thd->last_insert_id; ::send_ok(thd, (ulong) thd->row_count_func, id, buff); + thd->updated_row_count += thd->row_count_func; DBUG_RETURN(0); } diff -Naur mysql.orig/sql/sql_lex.h mysql/sql/sql_lex.h --- mysql.orig/sql/sql_lex.h 2007-12-14 21:42:51.000000000 +0100 +++ mysql/sql/sql_lex.h 2008-11-27 20:08:07.000000000 +0100 @@ -94,6 +94,9 @@ SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE, SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER, SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE, + // TODO(mcallaghan): update status_vars in mysqld to export these + SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, + SQLCOM_SHOW_CLIENT_STATS, /* This should be the last !!! */ SQLCOM_END diff -Naur mysql.orig/sql/sql_parse.cc mysql/sql/sql_parse.cc --- mysql.orig/sql/sql_parse.cc 2007-12-14 21:43:41.000000000 +0100 +++ mysql/sql/sql_parse.cc 2008-11-27 20:08:07.000000000 +0100 @@ -77,6 +77,12 @@ const char *table_name); static bool check_show_create_table_access(THD *thd, TABLE_LIST *table); +// Increments connection count for user. +static int increment_connection_count(THD* thd, bool use_lock); + +// Uses the THD to update the global stats by user name and client IP +static void update_global_user_stats(THD* thd, bool create_user, time_t now); + const char *any_db="*any*"; // Special symbol for check_access const char *command_name[]={ @@ -97,6 +103,17 @@ static bool do_command(THD *thd); #endif // EMBEDDED_LIBRARY +HASH global_user_stats; +HASH global_client_stats; +// Protects global_user_stats and global_client_stats +extern pthread_mutex_t LOCK_global_user_client_stats; + +HASH global_table_stats; +extern pthread_mutex_t LOCK_global_table_stats; + +HASH global_index_stats; +extern pthread_mutex_t LOCK_global_index_stats; + #ifdef __WIN__ static void test_signal(int sig_ptr) { @@ -470,6 +487,7 @@ mysql_log.write(thd,COM_CONNECT,ER(ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN(-1); } + thd->diff_access_denied_errors++; net_printf_error(thd, ER_ACCESS_DENIED_ERROR, thd->main_security_ctx.user, thd->main_security_ctx.host_or_ip, @@ -502,13 +520,191 @@ void init_max_user_conn(void) { #ifndef NO_EMBEDDED_ACCESS_CHECKS - (void) hash_init(&hash_user_connections,system_charset_info,max_connections, - 0,0, - (hash_get_key) get_key_conn, (hash_free_key) free_user, - 0); + if (hash_init(&hash_user_connections,system_charset_info,max_connections, + 0,0, + (hash_get_key) get_key_conn, (hash_free_key) free_user, + 0)) { + sql_print_error("Initializing hash_user_connections failed."); + exit(1); + } #endif } +byte *get_key_user_stats(USER_STATS *user_stats, uint *length, + my_bool not_used __attribute__((unused))) +{ + *length = strlen(user_stats->user); + return (byte*)user_stats->user; +} + +void free_user_stats(USER_STATS* user_stats) +{ + my_free((char*)user_stats, MYF(0)); +} + +void init_user_stats(USER_STATS *user_stats, + const char *user, + const char *priv_user, + uint total_connections, + uint concurrent_connections, + time_t connected_time, + double busy_time, + double cpu_time, + ulonglong bytes_received, + ulonglong bytes_sent, + ulonglong binlog_bytes_written, + ha_rows rows_fetched, + ha_rows rows_updated, + ha_rows rows_read, + ulonglong select_commands, + ulonglong update_commands, + ulonglong other_commands, + ulonglong commit_trans, + ulonglong rollback_trans, + ulonglong denied_connections, + ulonglong lost_connections, + ulonglong access_denied_errors, + ulonglong empty_queries) +{ + DBUG_ENTER("init_user_stats"); + DBUG_PRINT("info", + ("Add user_stats entry for user %s - priv_user %s", + user, priv_user)); + strncpy(user_stats->user, user, sizeof(user_stats->user)); + strncpy(user_stats->priv_user, priv_user, sizeof(user_stats->priv_user)); + + user_stats->total_connections = total_connections; + user_stats->concurrent_connections = concurrent_connections; + user_stats->connected_time = connected_time; + user_stats->busy_time = busy_time; + user_stats->cpu_time = cpu_time; + user_stats->bytes_received = bytes_received; + user_stats->bytes_sent = bytes_sent; + user_stats->binlog_bytes_written = binlog_bytes_written; + user_stats->rows_fetched = rows_fetched; + user_stats->rows_updated = rows_updated; + user_stats->rows_read = rows_read; + user_stats->select_commands = select_commands; + user_stats->update_commands = update_commands; + user_stats->other_commands = other_commands; + user_stats->commit_trans = commit_trans; + user_stats->rollback_trans = rollback_trans; + user_stats->denied_connections = denied_connections; + user_stats->lost_connections = lost_connections; + user_stats->access_denied_errors = access_denied_errors; + user_stats->empty_queries = empty_queries; + DBUG_VOID_RETURN; +} + +void add_user_stats(USER_STATS *user_stats, + uint total_connections, + uint concurrent_connections, + time_t connected_time, + double busy_time, + double cpu_time, + ulonglong bytes_received, + ulonglong bytes_sent, + ulonglong binlog_bytes_written, + ha_rows rows_fetched, + ha_rows rows_updated, + ha_rows rows_read, + ulonglong select_commands, + ulonglong update_commands, + ulonglong other_commands, + ulonglong commit_trans, + ulonglong rollback_trans, + ulonglong denied_connections, + ulonglong lost_connections, + ulonglong access_denied_errors, + ulonglong empty_queries) +{ + user_stats->total_connections += total_connections; + user_stats->concurrent_connections += concurrent_connections; + user_stats->connected_time += connected_time; + user_stats->busy_time += busy_time; + user_stats->cpu_time += cpu_time; + user_stats->bytes_received += bytes_received; + user_stats->bytes_sent += bytes_sent; + user_stats->binlog_bytes_written += binlog_bytes_written; + user_stats->rows_fetched += rows_fetched; + user_stats->rows_updated += rows_updated; + user_stats->rows_read += rows_read; + user_stats->select_commands += select_commands; + user_stats->update_commands += update_commands; + user_stats->other_commands += other_commands; + user_stats->commit_trans += commit_trans; + user_stats->rollback_trans += rollback_trans; + user_stats->denied_connections += denied_connections; + user_stats->lost_connections += lost_connections; + user_stats->access_denied_errors += access_denied_errors; + user_stats->empty_queries += empty_queries; +} + +void init_global_user_stats(void) +{ + if (hash_init(&global_user_stats, system_charset_info, max_connections, + 0, 0, (hash_get_key)get_key_user_stats, + (hash_free_key)free_user_stats, 0)) { + sql_print_error("Initializing global_user_stats failed."); + exit(1); + } +} + +void init_global_client_stats(void) +{ + if (hash_init(&global_client_stats, system_charset_info, max_connections, + 0, 0, (hash_get_key)get_key_user_stats, + (hash_free_key)free_user_stats, 0)) { + sql_print_error("Initializing global_client_stats failed."); + exit(1); + } +} + +extern "C" byte *get_key_table_stats(TABLE_STATS *table_stats, uint *length, + my_bool not_used __attribute__((unused))) +{ + *length = strlen(table_stats->table); + return (byte*)table_stats->table; +} + +extern "C" void free_table_stats(TABLE_STATS* table_stats) +{ + my_free((char*)table_stats, MYF(0)); +} + +void init_global_table_stats(void) +{ + if (hash_init(&global_table_stats, system_charset_info, max_connections, + 0, 0, (hash_get_key)get_key_table_stats, + (hash_free_key)free_table_stats, 0)) { + sql_print_error("Initializing global_table_stats failed."); + exit(1); + } +} + +extern "C" byte *get_key_index_stats(INDEX_STATS *index_stats, uint *length, + my_bool not_used __attribute__((unused))) +{ + *length = strlen(index_stats->index); + return (byte*)index_stats->index; +} + +extern "C" void free_index_stats(INDEX_STATS* index_stats) +{ + my_free((char*)index_stats, MYF(0)); +} + +void init_global_index_stats(void) +{ + if (hash_init(&global_index_stats, system_charset_info, max_connections, + 0, 0, (hash_get_key)get_key_index_stats, + (hash_free_key)free_index_stats, 0)) { + sql_print_error("Initializing global_index_stats failed."); + exit(1); + } +} + + /* check if user has already too many connections @@ -565,7 +761,10 @@ end: if (error) + { + statistic_increment(denied_connections, &LOCK_status); uc->connections--; // no need for decrease_user_connections() here + } (void) pthread_mutex_unlock(&LOCK_user_conn); DBUG_RETURN(error); } @@ -612,6 +811,25 @@ #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } +void free_global_user_stats(void) +{ + hash_free(&global_user_stats); +} + +void free_global_table_stats(void) +{ + hash_free(&global_table_stats); +} + +void free_global_index_stats(void) +{ + hash_free(&global_index_stats); +} + +void free_global_client_stats(void) +{ + hash_free(&global_client_stats); +} /* @@ -664,6 +882,207 @@ return uc_update_queries[command] != 0; } +// 'mysql_system_user' is used for when the user is not defined for a THD. +static char mysql_system_user[] = "#mysql_system#"; + +// Returns 'user' if it's not NULL. Returns 'mysql_system_user' otherwise. +static char* get_valid_user_string(char* user) { + return user ? user : mysql_system_user; +} + +// Increments the global stats connection count for an entry from +// global_client_stats or global_user_stats. Returns 0 on success +// and 1 on error. +static int increment_count_by_name(const char *name, const char *role_name, + HASH *users_or_clients, THD *thd) +{ + USER_STATS* user_stats; + + if (!(user_stats = (USER_STATS*)hash_search(users_or_clients, name, + strlen(name)))) + { + // First connection for this user or client + if (!(user_stats = ((USER_STATS*) + my_malloc(sizeof(USER_STATS), MYF(MY_WME))))) + { + return 1; // Out of memory + } + + init_user_stats(user_stats, name, role_name, + 0, 0, // connections + 0, 0, 0, // time + 0, 0, 0, // bytes sent, received and written + 0, 0, 0, // rows fetched, updated and read + 0, 0, 0, // select, update and other commands + 0, 0, // commit and rollback trans + thd->diff_denied_connections, + 0, // lost connections + 0, // access denied errors + 0); // empty queries + + if (my_hash_insert(users_or_clients, (byte*)user_stats)) + { + my_free((char*)user_stats, 0); + return 1; // Out of memory + } + } + user_stats->total_connections++; + return 0; +} + +// Increments the global user and client stats connection count. If 'use_lock' +// is true, LOCK_global_user_client_stats will be locked/unlocked. Returns +// 0 on success, 1 on error. +static int increment_connection_count(THD* thd, bool use_lock) +{ + char* user_string = get_valid_user_string(thd->main_security_ctx.user); + const char* client_string = get_client_host(thd); + int return_value = 0; + + if (use_lock) pthread_mutex_lock(&LOCK_global_user_client_stats); + + if (increment_count_by_name(user_string, user_string, + &global_user_stats, thd)) + { + return_value = 1; + goto end; + } + if (increment_count_by_name(client_string, + user_string, + &global_client_stats, thd)) + { + return_value = 1; + goto end; + } + +end: + if (use_lock) pthread_mutex_unlock(&LOCK_global_user_client_stats); + return return_value; +} + +// Used to update the global user and client stats. +static void update_global_user_stats_with_user(THD* thd, + USER_STATS* user_stats, + time_t now) +{ + user_stats->connected_time += now - thd->last_global_update_time; + thd->last_global_update_time = now; + user_stats->busy_time += thd->diff_total_busy_time; + user_stats->cpu_time += thd->diff_total_cpu_time; + user_stats->bytes_received += thd->diff_total_bytes_received; + user_stats->bytes_sent += thd->diff_total_bytes_sent; + user_stats->binlog_bytes_written += thd->diff_total_binlog_bytes_written; + user_stats->rows_fetched += thd->diff_total_sent_rows; + user_stats->rows_updated += thd->diff_total_updated_rows; + user_stats->rows_read += thd->diff_total_read_rows; + user_stats->select_commands += thd->diff_select_commands; + user_stats->update_commands += thd->diff_update_commands; + user_stats->other_commands += thd->diff_other_commands; + user_stats->commit_trans += thd->diff_commit_trans; + user_stats->rollback_trans += thd->diff_rollback_trans; + user_stats->denied_connections += thd->diff_denied_connections; + user_stats->lost_connections += thd->diff_lost_connections; + user_stats->access_denied_errors += thd->diff_access_denied_errors; + user_stats->empty_queries += thd->diff_empty_queries; +} + +// Updates the global stats of a user or client +static void update_global_user_stats(THD* thd, bool create_user, time_t now) +{ + char* user_string = get_valid_user_string(thd->main_security_ctx.user); + const char* client_string = get_client_host(thd); + + USER_STATS* user_stats; + pthread_mutex_lock(&LOCK_global_user_client_stats); + + // Update by user name + if ((user_stats = (USER_STATS*)hash_search(&global_user_stats, + (byte*)user_string, + strlen(user_string)))) { + // Found user. + update_global_user_stats_with_user(thd, user_stats, now); + } else { + // Create the entry + if (create_user) { + increment_count_by_name(user_string, user_string, + &global_user_stats, thd); + } + } + + // Update by client IP + if ((user_stats = (USER_STATS*)hash_search(&global_client_stats, + (byte*)client_string, + strlen(client_string)))) { + // Found by client IP + update_global_user_stats_with_user(thd, user_stats, now); + } else { + // Create the entry + if (create_user) { + increment_count_by_name(client_string, + user_string, + &global_client_stats, thd); + } + } + thd->reset_diff_stats(); + + pthread_mutex_unlock(&LOCK_global_user_client_stats); +} + +// Determines the concurrent number of connections of current threads. +static void set_connections_stats() +{ + USER_STATS* user_stats; + + pthread_mutex_lock(&LOCK_global_user_client_stats); + pthread_mutex_lock(&LOCK_thread_count); + + // Resets all concurrent connections to 0. + for (int i = 0; i < global_user_stats.records; ++i) { + user_stats = (USER_STATS*)hash_element(&global_user_stats, i); + user_stats->concurrent_connections = 0; + } + for (int i = 0; i < global_client_stats.records; ++i) { + user_stats = (USER_STATS*)hash_element(&global_client_stats, i); + user_stats->concurrent_connections = 0; + } + + I_List_iterator it(threads); + THD* thd; + time_t now = time(NULL); + // Iterates through the current threads. + while ((thd = it++)) { + char* user_string = get_valid_user_string(thd->main_security_ctx.user); + if ((user_stats = (USER_STATS*)hash_search(&global_user_stats, + (byte*)user_string, + strlen(user_string)))) { + // Found user. + user_stats->concurrent_connections++; + update_global_user_stats_with_user(thd, user_stats, now); + } else { + // The user name should exist. + if (user_string == mysql_system_user) { + // Only create the user if it is the mysql_system_user + increment_count_by_name(user_string, user_string, + &global_user_stats, thd); + } + } + + const char* client_string = get_client_host(thd); + if ((user_stats = (USER_STATS*)hash_search(&global_client_stats, + (byte*)client_string, + strlen(client_string)))) { + // Found user. + user_stats->concurrent_connections++; + update_global_user_stats_with_user(thd, user_stats, now); + } else { + // Do nothing, unlike what is done for global_user_stats + } + thd->reset_diff_stats(); + } + pthread_mutex_unlock(&LOCK_thread_count); + pthread_mutex_unlock(&LOCK_global_user_client_stats); +} + /* Reset per-hour user resource limits when it has been more than an hour since they were last checked @@ -1150,6 +1569,8 @@ my_net_set_read_timeout(net, connect_timeout); my_net_set_write_timeout(net, connect_timeout); + bool create_user = true; + if ((error=check_connection(thd))) { // Wrong permissions if (error > 0) @@ -1159,8 +1580,22 @@ my_sleep(1000); /* must wait after eof() */ #endif statistic_increment(aborted_connects,&LOCK_status); + thd->diff_denied_connections++; + if (error == -2) { + // Do not create statistics for a user who does not exist, or failed + // to authenticate. + create_user = false; + } + goto end_thread; + } + + thd->reset_stats(); + // Updates global user connection stats. + if (increment_connection_count(thd, true)) { + net_send_error(thd, ER_OUTOFMEMORY); // Out of memory goto end_thread; } + #ifdef __NETWARE__ netware_reg_user(sctx->ip, sctx->user, "MySQL"); #endif @@ -1208,6 +1643,7 @@ net->vio && net->error && net->report_error) { statistic_increment(aborted_threads, &LOCK_status); + thd->diff_lost_connections++; } if (net->error && net->vio != 0 && net->report_error) @@ -1227,6 +1663,8 @@ end_thread: close_connection(thd, 0, 1); + thd->update_stats(false); + update_global_user_stats(thd, create_user, time(NULL)); end_thread(thd,1); /* If end_thread returns, we are either running with --one-thread @@ -1553,6 +1991,13 @@ thd->clear_error(); // Clear error message + thd->updated_row_count=0; + thd->busy_time=0; + thd->cpu_time=0; + thd->bytes_received=0; + thd->bytes_sent=0; + thd->binlog_bytes_written=0; + net_new_transaction(net); if ((packet_length=my_net_read(net)) == packet_error) { @@ -1628,6 +2073,9 @@ } thd->command=command; + // To increment the corrent command counter for user stats, 'command' must + // be saved because it is set to COM_SLEEP at the end of this function. + thd->old_command = command; /* Commands which always take a long time are logged into the slow log only if opt_log_slow_admin_statements is set. @@ -4204,6 +4652,15 @@ if (check_global_access(thd,RELOAD_ACL)) goto error; + if(lex->type & REFRESH_SLOW_QUERY_LOG) { + /* We are only flushing slow query log */ + mysql_slow_log.new_file(1); + + send_ok(thd); + break; + } + + /* reload_acl_and_cache() will tell us if we are allowed to write to the binlog or not. @@ -4511,6 +4968,7 @@ { if (check_global_access(thd, SUPER_ACL)) { + thd->diff_access_denied_errors++; my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); goto create_sp_error; } @@ -5334,6 +5792,7 @@ if (!no_errors) { const char *db_name= db ? db : thd->db; + thd->diff_access_denied_errors++; my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->priv_host, db_name); } @@ -5369,6 +5828,7 @@ { // We can never grant this DBUG_PRINT("error",("No possible access")); if (!no_errors) + thd->diff_access_denied_errors++; my_error(ER_ACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->priv_host, @@ -5401,11 +5861,15 @@ DBUG_PRINT("error",("Access denied")); if (!no_errors) + { + // increment needs !no_errors condition, otherwise double counting. + thd->diff_access_denied_errors++; my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->priv_host, (db ? db : (thd->db ? thd->db : "unknown"))); /* purecov: tested */ + } DBUG_RETURN(TRUE); /* purecov: tested */ #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -5439,6 +5903,7 @@ if ((thd->security_ctx->master_access & want_access)) return 0; get_privilege_desc(command, sizeof(command), want_access); + thd->diff_access_denied_errors++; my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); return 1; #endif /* NO_EMBEDDED_ACCESS_CHECKS */ @@ -5471,6 +5936,7 @@ if (!thd->col_access && check_grant_db(thd, dst_db_name)) { + thd->diff_access_denied_errors++; my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), thd->security_ctx->priv_user, thd->security_ctx->priv_host, @@ -5502,6 +5968,12 @@ check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE); } + + case SCH_USER_STATS: + case SCH_CLIENT_STATS: + return check_global_access(thd, SUPER_ACL | PROCESS_ACL); + case SCH_TABLE_STATS: + case SCH_INDEX_STATS: case SCH_OPEN_TABLES: case SCH_VARIABLES: case SCH_STATUS: @@ -5554,8 +6026,8 @@ #ifndef NO_EMBEDDED_ACCESS_CHECKS TABLE_LIST *org_tables= tables; #endif - TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table(); Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx; + TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table(); /* The check that first_not_own_table is not reached is for the case when the given table list refers to the list for prelocking (contains tables @@ -5572,9 +6044,12 @@ (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL))) { if (!no_errors) + { + thd->diff_access_denied_errors++; my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->priv_host, INFORMATION_SCHEMA_NAME.str); + } return TRUE; } /* @@ -6069,6 +6544,29 @@ lex_start(thd); mysql_reset_thd_for_next_command(thd); + int start_time_error = 0; + int end_time_error = 0; + struct timeval start_time, end_time; + double start_usecs = 0; + double end_usecs = 0; + /* cpu time */ + int cputime_error = 0; + struct timespec tp; + double start_cpu_nsecs = 0; + double end_cpu_nsecs = 0; + +#ifdef HAVE_CLOCK_GETTIME + /* get start cputime */ + if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp))) + start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec; +#endif + + // Gets the start time, in order to measure how long this command takes. + if (!(start_time_error = gettimeofday(&start_time, NULL))) { + start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec; + } + + if (query_cache_send_result_to_client(thd, (char*) inBuf, length) <= 0) { LEX *lex= thd->lex; @@ -6140,6 +6638,39 @@ *found_semicolon= NULL; } + + // Gets the end time. + if (!(end_time_error = gettimeofday(&end_time, NULL))) { + end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec; + } + + // Calculates the difference between the end and start times. + if (end_usecs >= start_usecs && !start_time_error && !end_time_error) { + thd->busy_time = (end_usecs - start_usecs) / 1000000; + // In case there are bad values, 2629743 is the #seconds in a month. + if (thd->busy_time > 2629743) { + thd->busy_time = 0; + } + } else { + // end time went back in time, or gettimeofday() failed. + thd->busy_time = 0; + } + +#ifdef HAVE_CLOCK_GETTIME + /* get end cputime */ + if (!cputime_error && + !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp))) + end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec; +#endif + if (!cputime_error) + thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000; + else + thd->cpu_time = 0; + + // Updates THD stats and the global user stats. + thd->update_stats(true); + update_global_user_stats(thd, true, time(NULL)); + DBUG_VOID_RETURN; } @@ -7132,8 +7663,35 @@ pthread_mutex_unlock(&LOCK_active_mi); } #endif - if (options & REFRESH_USER_RESOURCES) - reset_mqh((LEX_USER *) NULL); + if (options & REFRESH_TABLE_STATS) + { + pthread_mutex_lock(&LOCK_global_table_stats); + free_global_table_stats(); + init_global_table_stats(); + pthread_mutex_unlock(&LOCK_global_table_stats); + } + if (options & REFRESH_INDEX_STATS) + { + pthread_mutex_lock(&LOCK_global_index_stats); + free_global_index_stats(); + init_global_index_stats(); + pthread_mutex_unlock(&LOCK_global_index_stats); + } + if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS)) + { + pthread_mutex_lock(&LOCK_global_user_client_stats); + if (options & REFRESH_USER_STATS) + { + free_global_user_stats(); + init_global_user_stats(); + } + if (options & REFRESH_CLIENT_STATS) + { + free_global_client_stats(); + init_global_client_stats(); + } + pthread_mutex_unlock(&LOCK_global_user_client_stats); + } *write_to_binlog= tmp_write_to_binlog; return result; } diff -Naur mysql.orig/sql/sql_show.cc mysql/sql/sql_show.cc --- mysql.orig/sql/sql_show.cc 2007-12-14 21:43:13.000000000 +0100 +++ mysql/sql/sql_show.cc 2008-11-27 20:08:07.000000000 +0100 @@ -488,6 +488,7 @@ sctx->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { + thd->diff_access_denied_errors++; my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->host_or_ip, dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), @@ -1807,6 +1808,300 @@ DBUG_RETURN(FALSE); } +/* + Aggregate values for mapped_user entries by their role. + + SYNOPSIS + aggregate_user_stats + all_user_stats - input to aggregate + agg_user_stats - returns aggregated values + + RETURN + 0 - OK + 1 - error + */ +static int +aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats) +{ + DBUG_ENTER("aggregate_user_stats"); + if (hash_init(agg_user_stats, system_charset_info, + MYSQL_MAX(all_user_stats->records, 1), + 0, 0, (hash_get_key)get_key_user_stats, + (hash_free_key)free_user_stats, 0)) + { + sql_print_error("Malloc in aggregate_user_stats failed"); + DBUG_RETURN(1); + } + + for (int i = 0; i < all_user_stats->records; ++i) { + USER_STATS *user = (USER_STATS*)hash_element(all_user_stats, i); + USER_STATS *agg_user; + if (!(agg_user = (USER_STATS*)hash_search(agg_user_stats, + (byte*)user->priv_user, + strlen(user->priv_user)))) + { + // First entry for this role. + if (!(agg_user = + (USER_STATS*) my_malloc(sizeof(USER_STATS), MYF(MY_WME)))) + { + sql_print_error("Malloc in aggregate_user_stats failed"); + DBUG_RETURN(1); + } + + init_user_stats(agg_user, user->priv_user, user->priv_user, + user->total_connections, user->concurrent_connections, + user->connected_time, user->busy_time, user->cpu_time, + user->bytes_received, user->bytes_sent, + user->binlog_bytes_written, + user->rows_fetched, user->rows_updated, user->rows_read, + user->select_commands, user->update_commands, + user->other_commands, + user->commit_trans, user->rollback_trans, + user->denied_connections, user->lost_connections, + user->access_denied_errors, user->empty_queries); + + if (my_hash_insert(agg_user_stats, (byte*)agg_user)) + { + // Out of memory. + my_free((char*)agg_user, 0); + sql_print_error("Malloc in aggregate_user_stats failed"); + DBUG_RETURN(1); + } + } + else + { + // Aggregate with existing values for this role. + add_user_stats(agg_user, + user->total_connections, user->concurrent_connections, + user->connected_time, user->busy_time, user->cpu_time, + user->bytes_received, user->bytes_sent, + user->binlog_bytes_written, + user->rows_fetched, user->rows_updated, user->rows_read, + user->select_commands, user->update_commands, + user->other_commands, + user->commit_trans, user->rollback_trans, + user->denied_connections, user->lost_connections, + user->access_denied_errors, user->empty_queries); + } + } + DBUG_PRINT("exit", ("aggregated %d input into %d output entries", + all_user_stats->records, agg_user_stats->records)); + DBUG_RETURN(0); +} + +/* + Write result to network for SHOW USER_STATISTICS + + SYNOPSIS + send_user_stats + all_user_stats - values to return + table - I_S table + + RETURN + 0 - OK + 1 - error + */ +int send_user_stats(THD* thd, HASH *all_user_stats, TABLE *table) +{ + DBUG_ENTER("send_user_stats"); + for (int i = 0; i < all_user_stats->records; ++i) { + restore_record(table, s->default_values); + USER_STATS *user_stats = (USER_STATS*)hash_element(all_user_stats, i); + table->field[0]->store(user_stats->user, strlen(user_stats->user), system_charset_info); + table->field[1]->store((longlong)user_stats->total_connections); + table->field[2]->store((longlong)user_stats->concurrent_connections); + table->field[3]->store((longlong)user_stats->connected_time); + table->field[4]->store((longlong)user_stats->busy_time); + table->field[5]->store((longlong)user_stats->cpu_time); + table->field[6]->store((longlong)user_stats->bytes_received); + table->field[7]->store((longlong)user_stats->bytes_sent); + table->field[8]->store((longlong)user_stats->binlog_bytes_written); + table->field[9]->store((longlong)user_stats->rows_fetched); + table->field[10]->store((longlong)user_stats->rows_updated); + table->field[11]->store((longlong)user_stats->rows_read); + table->field[12]->store((longlong)user_stats->select_commands); + table->field[13]->store((longlong)user_stats->update_commands); + table->field[14]->store((longlong)user_stats->other_commands); + table->field[15]->store((longlong)user_stats->commit_trans); + table->field[16]->store((longlong)user_stats->rollback_trans); + table->field[17]->store((longlong)user_stats->denied_connections); + table->field[18]->store((longlong)user_stats->lost_connections); + table->field[19]->store((longlong)user_stats->access_denied_errors); + table->field[20]->store((longlong)user_stats->empty_queries); + if (schema_table_store_record(thd, table)) + { + DBUG_PRINT("error", ("store record error")); + DBUG_RETURN(1); + } + } + DBUG_RETURN(0); +} + +/* + Process SHOW USER_STATISTICS + + SYNOPSIS + mysqld_show_user_stats + thd - current thread + wild - limit results to the entry for this user + with_roles - when true, display role for mapped users + + RETURN + 0 - OK + 1 - error + */ + + +int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond) +{ + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_user_stats"); + + if (check_global_access(thd, SUPER_ACL | PROCESS_ACL)) + DBUG_RETURN(1); + + // Iterates through all the global stats and sends them to the client. + // Pattern matching on the client IP is supported. + + pthread_mutex_lock(&LOCK_global_user_client_stats); + int result= send_user_stats(thd, &global_user_stats, table); + pthread_mutex_unlock(&LOCK_global_user_client_stats); + if (result) + goto err; + + DBUG_PRINT("exit", ("fill_schema_user_stats result is 0")); + DBUG_RETURN(0); + + err: + DBUG_PRINT("exit", ("fill_schema_user_stats result is 1")); + DBUG_RETURN(1); +} + +/* + Process SHOW CLIENT_STATISTICS + + SYNOPSIS + mysqld_show_client_stats + thd - current thread + wild - limit results to the entry for this client + + RETURN + 0 - OK + 1 - error + */ + + +int fill_schema_client_stats(THD* thd, TABLE_LIST* tables, COND* cond) +{ + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_client_stats"); + + if (check_global_access(thd, SUPER_ACL | PROCESS_ACL)) + DBUG_RETURN(1); + + // Iterates through all the global stats and sends them to the client. + // Pattern matching on the client IP is supported. + + pthread_mutex_lock(&LOCK_global_user_client_stats); + int result= send_user_stats(thd, &global_client_stats, table); + pthread_mutex_unlock(&LOCK_global_user_client_stats); + if (result) + goto err; + + DBUG_PRINT("exit", ("mysqld_show_client_stats result is 0")); + DBUG_RETURN(0); + + err: + DBUG_PRINT("exit", ("mysqld_show_client_stats result is 1")); + DBUG_RETURN(1); +} + + +// Sends the global table stats back to the client. +int fill_schema_table_stats(THD* thd, TABLE_LIST* tables, COND* cond) +{ + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_table_stats"); + char *table_full_name, *table_schema; + + pthread_mutex_lock(&LOCK_global_table_stats); + for (int i = 0; i < global_table_stats.records; ++i) { + restore_record(table, s->default_values); + TABLE_STATS *table_stats = + (TABLE_STATS*)hash_element(&global_table_stats, i); + + table_full_name= thd->strdup(table_stats->table); + table_schema= strsep(&table_full_name, "."); + + TABLE_LIST tmp_table; + bzero((char*) &tmp_table,sizeof(tmp_table)); + tmp_table.table_name= table_full_name; + tmp_table.db= table_schema; + tmp_table.grant.privilege= 0; + if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db, + &tmp_table.grant.privilege, 0, 0, + is_schema_db(table_schema)) || + grant_option && check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1)) + continue; + + table->field[0]->store(table_schema, strlen(table_schema), system_charset_info); + table->field[1]->store(table_full_name, strlen(table_full_name), system_charset_info); + table->field[2]->store((longlong)table_stats->rows_read, TRUE); + table->field[3]->store((longlong)table_stats->rows_changed, TRUE); + table->field[4]->store((longlong)table_stats->rows_changed_x_indexes, TRUE); + + if (schema_table_store_record(thd, table)) + { + VOID(pthread_mutex_unlock(&LOCK_global_table_stats)); + DBUG_RETURN(1); + } + } + pthread_mutex_unlock(&LOCK_global_table_stats); + DBUG_RETURN(0); +} + +// Sends the global index stats back to the client. +int fill_schema_index_stats(THD* thd, TABLE_LIST* tables, COND* cond) +{ + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_index_stats"); + char *index_full_name, *table_schema, *table_name; + + pthread_mutex_lock(&LOCK_global_index_stats); + for (int i = 0; i < global_index_stats.records; ++i) { + restore_record(table, s->default_values); + INDEX_STATS *index_stats = + (INDEX_STATS*)hash_element(&global_index_stats, i); + + index_full_name= thd->strdup(index_stats->index); + table_schema= strsep(&index_full_name, "."); + table_name= strsep(&index_full_name, "."); + + TABLE_LIST tmp_table; + bzero((char*) &tmp_table,sizeof(tmp_table)); + tmp_table.table_name= table_name; + tmp_table.db= table_schema; + tmp_table.grant.privilege= 0; + if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db, + &tmp_table.grant.privilege, 0, 0, + is_schema_db(table_schema)) || + grant_option && check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1)) + continue; + + table->field[0]->store(table_schema, strlen(table_schema), system_charset_info); + table->field[1]->store(table_name, strlen(table_name), system_charset_info); + table->field[2]->store(index_full_name, strlen(index_full_name), system_charset_info); + table->field[3]->store((longlong)index_stats->rows_read, TRUE); + + if (schema_table_store_record(thd, table)) + { + VOID(pthread_mutex_unlock(&LOCK_global_index_stats)); + DBUG_RETURN(1); + } + } + pthread_mutex_unlock(&LOCK_global_index_stats); + DBUG_RETURN(0); +} /* collect status for all running threads */ @@ -4372,6 +4667,77 @@ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; +ST_FIELD_INFO user_stats_fields_info[]= +{ + {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User"}, + {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections"}, + {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections"}, + {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time"}, + {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time"}, + {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time"}, + {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received"}, + {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent"}, + {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written"}, + {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched"}, + {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated"}, + {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read"}, + {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands"}, + {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands"}, + {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands"}, + {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions"}, + {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions"}, + {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections"}, + {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections"}, + {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied"}, + {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} +}; + +ST_FIELD_INFO client_stats_fields_info[]= +{ + {"CLIENT", 16, MYSQL_TYPE_STRING, 0, 0, "Client"}, + {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections"}, + {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections"}, + {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time"}, + {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time"}, + {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time"}, + {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received"}, + {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent"}, + {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written"}, + {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched"}, + {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated"}, + {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read"}, + {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands"}, + {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands"}, + {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands"}, + {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions"}, + {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions"}, + {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections"}, + {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections"}, + {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied"}, + {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} +}; + + +ST_FIELD_INFO table_stats_fields_info[]= +{ + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema"}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name"}, + {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read"}, + {"ROWS_CHANGED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed"}, + {"ROWS_CHANGED_X_INDEXES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed_x_#indexes"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} +}; + +ST_FIELD_INFO index_stats_fields_info[]= +{ + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema"}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name"}, + {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name"}, + {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} +}; /* Description of ST_FIELD_INFO in table.h @@ -4381,6 +4747,8 @@ { {"CHARACTER_SETS", charsets_fields_info, create_schema_table, fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0}, + {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table, + fill_schema_client_stats, make_old_format, 0, -1, -1, 0}, {"COLLATIONS", collation_fields_info, create_schema_table, fill_schema_collation, make_old_format, 0, -1, -1, 0}, {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info, @@ -4389,6 +4757,8 @@ get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0}, {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table, fill_schema_column_privileges, 0, 0, -1, -1, 0}, + {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table, + fill_schema_index_stats, make_old_format, 0, -1, -1, 0}, {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table, get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0}, {"OPEN_TABLES", open_tables_fields_info, create_schema_table, @@ -4411,10 +4781,14 @@ get_all_tables, make_table_names_old_format, 0, 1, 2, 1}, {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table, fill_schema_table_privileges, 0, 0, -1, -1, 0}, + {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table, + fill_schema_table_stats, make_old_format, 0, -1, -1, 0}, {"TRIGGERS", triggers_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0}, {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, fill_schema_user_privileges, 0, 0, -1, -1, 0}, + {"USER_STATISTICS", user_stats_fields_info, create_schema_table, + fill_schema_user_stats, make_old_format, 0, -1, -1, 0}, {"VARIABLES", variables_fields_info, create_schema_table, fill_variables, make_old_format, 0, -1, -1, 1}, {"VIEWS", view_fields_info, create_schema_table, diff -Naur mysql.orig/sql/sql_update.cc mysql/sql/sql_update.cc --- mysql.orig/sql/sql_update.cc 2007-12-14 21:43:00.000000000 +0100 +++ mysql/sql/sql_update.cc 2008-11-27 20:08:07.000000000 +0100 @@ -601,7 +601,8 @@ (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated; send_ok(thd, (ulong) thd->row_count_func, thd->insert_id_used ? thd->last_insert_id : 0L,buff); - DBUG_PRINT("info",("%ld records updated", (long) updated)); + thd->updated_row_count += thd->row_count_func; + DBUG_PRINT("info",("%d records updated",updated)); } thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */ thd->abort_on_warning= 0; @@ -1769,5 +1770,6 @@ (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated; ::send_ok(thd, (ulong) thd->row_count_func, thd->insert_id_used ? thd->last_insert_id : 0L,buff); + thd->updated_row_count += thd->row_count_func; return FALSE; } diff -Naur mysql.orig/sql/sql_yacc.yy mysql/sql/sql_yacc.yy --- mysql.orig/sql/sql_yacc.yy 2007-12-14 21:43:24.000000000 +0100 +++ mysql/sql/sql_yacc.yy 2008-11-27 20:08:07.000000000 +0100 @@ -521,6 +521,7 @@ %token CHECK_SYM %token CIPHER_SYM %token CLIENT_SYM +%token CLIENT_STATS_SYM %token CLOSE_SYM %token COALESCE %token CODE_SYM @@ -675,6 +676,7 @@ %token IMPORT %token INDEXES %token INDEX_SYM +%token INDEX_STATS_SYM %token INFILE %token INNER_SYM %token INNOBASE_SYM @@ -897,6 +899,7 @@ %token SIGNED_SYM %token SIMPLE_SYM %token SLAVE +%token SLOW_SYM %token SMALLINT %token SNAPSHOT_SYM %token SOUNDS_SYM @@ -934,6 +937,7 @@ %token TABLES %token TABLESPACE %token TABLE_SYM +%token TABLE_STATS_SYM %token TEMPORARY %token TEMPTABLE_SYM %token TERMINATED @@ -976,6 +980,7 @@ %token UPGRADE_SYM %token USAGE %token USER +%token USER_STATS_SYM %token USE_FRM %token USE_SYM %token USING @@ -7120,6 +7125,38 @@ { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; } + | CLIENT_STATS_SYM wild_and_where + { + LEX *lex= Lex; + Lex->sql_command = SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_CLIENT_STATS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS)) + MYSQL_YYABORT; + } + | USER_STATS_SYM wild_and_where + { + LEX *lex= Lex; + lex->sql_command = SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_USER_STATS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS)) + MYSQL_YYABORT; + } + | TABLE_STATS_SYM wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_TABLE_STATS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS)) + MYSQL_YYABORT; + } + | INDEX_STATS_SYM wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_INDEX_STATS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS)) + MYSQL_YYABORT; + } | CREATE PROCEDURE sp_name { LEX *lex= Lex; @@ -7313,9 +7350,14 @@ | LOGS_SYM { Lex->type|= REFRESH_LOG; } | STATUS_SYM { Lex->type|= REFRESH_STATUS; } | SLAVE { Lex->type|= REFRESH_SLAVE; } + | SLOW_SYM QUERY_SYM LOGS_SYM { Lex->type |= REFRESH_SLOW_QUERY_LOG; } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; } - | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; }; + | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; } + | CLIENT_STATS_SYM { Lex->type|= REFRESH_CLIENT_STATS; } + | USER_STATS_SYM { Lex->type|= REFRESH_USER_STATS; } + | TABLE_STATS_SYM { Lex->type|= REFRESH_TABLE_STATS; } + | INDEX_STATS_SYM { Lex->type|= REFRESH_INDEX_STATS; }; opt_table_list: /* empty */ {;} diff -Naur mysql.orig/sql/structs.h mysql/sql/structs.h --- mysql.orig/sql/structs.h 2007-12-14 21:43:13.000000000 +0100 +++ mysql/sql/structs.h 2008-11-27 20:08:07.000000000 +0100 @@ -272,6 +272,98 @@ time_t intime; } USER_CONN; +typedef struct st_user_stats { + char user[USERNAME_LENGTH + 1]; + // Account name the user is mapped to when this is a user from mapped_user. + // Otherwise, the same value as user. + char priv_user[USERNAME_LENGTH + 1]; + uint total_connections; + uint concurrent_connections; + time_t connected_time; // in seconds + double busy_time; // in seconds + double cpu_time; // in seconds + ulonglong bytes_received; + ulonglong bytes_sent; + ulonglong binlog_bytes_written; + ha_rows rows_fetched, rows_updated, rows_read; + ulonglong select_commands, update_commands, other_commands; + ulonglong commit_trans, rollback_trans; + ulonglong denied_connections, lost_connections; + ulonglong access_denied_errors; + ulonglong empty_queries; +} USER_STATS; + +/* Lookup function for hash tables with USER_STATS entries */ +extern byte *get_key_user_stats(USER_STATS *user_stats, uint *length, + my_bool not_used __attribute__((unused))); + +/* Free all memory for a hash table with USER_STATS entries */ +extern void free_user_stats(USER_STATS* user_stats); + +/* Intialize an instance of USER_STATS */ +extern void +init_user_stats(USER_STATS *user_stats, + const char *user, + const char *priv_user, + uint total_connections, + uint concurrent_connections, + time_t connected_time, + double busy_time, + double cpu_time, + ulonglong bytes_received, + ulonglong bytes_sent, + ulonglong binlog_bytes_written, + ha_rows rows_fetched, + ha_rows rows_updated, + ha_rows rows_read, + ulonglong select_commands, + ulonglong update_commands, + ulonglong other_commands, + ulonglong commit_trans, + ulonglong rollback_trans, + ulonglong denied_connections, + ulonglong lost_connections, + ulonglong access_denied_errors, + ulonglong empty_queries); + +/* Increment values of an instance of USER_STATS */ +extern void +add_user_stats(USER_STATS *user_stats, + uint total_connections, + uint concurrent_connections, + time_t connected_time, + double busy_time, + double cpu_time, + ulonglong bytes_received, + ulonglong bytes_sent, + ulonglong binlog_bytes_written, + ha_rows rows_fetched, + ha_rows rows_updated, + ha_rows rows_read, + ulonglong select_commands, + ulonglong update_commands, + ulonglong other_commands, + ulonglong commit_trans, + ulonglong rollback_trans, + ulonglong denied_connections, + ulonglong lost_connections, + ulonglong access_denied_errors, + ulonglong empty_queries); + +typedef struct st_table_stats { + char table[NAME_LEN * 2 + 2]; // [db] + '.' + [table] + '\0' + ulonglong rows_read, rows_changed; + ulonglong rows_changed_x_indexes; + /* Stores enum db_type, but forward declarations cannot be done */ + int engine_type; +} TABLE_STATS; + +typedef struct st_index_stats { + char index[NAME_LEN * 3 + 3]; // [db] + '.' + [table] + '.' + [index] + '\0' + ulonglong rows_read; +} INDEX_STATS; + + /* Bits in form->update */ #define REG_MAKE_DUPP 1 /* Make a copy of record when read */ #define REG_NEW_RECORD 2 /* Write a new record if not found */ diff -Naur mysql.orig/sql/table.h mysql/sql/table.h --- mysql.orig/sql/table.h 2007-12-14 21:43:00.000000000 +0100 +++ mysql/sql/table.h 2008-11-27 20:08:07.000000000 +0100 @@ -370,10 +370,12 @@ enum enum_schema_tables { SCH_CHARSETS= 0, + SCH_CLIENT_STATS, SCH_COLLATIONS, SCH_COLLATION_CHARACTER_SET_APPLICABILITY, SCH_COLUMNS, SCH_COLUMN_PRIVILEGES, + SCH_INDEX_STATS, SCH_KEY_COLUMN_USAGE, SCH_OPEN_TABLES, SCH_PROCEDURES, @@ -385,8 +387,10 @@ SCH_TABLE_CONSTRAINTS, SCH_TABLE_NAMES, SCH_TABLE_PRIVILEGES, + SCH_TABLE_STATS, SCH_TRIGGERS, SCH_USER_PRIVILEGES, + SCH_USER_STATS, SCH_VARIABLES, SCH_VIEWS }; diff -Naur mysql.orig/sql-bench/Makefile.in mysql/sql-bench/Makefile.in --- mysql.orig/sql-bench/Makefile.in 2007-12-14 21:46:09.000000000 +0100 +++ mysql/sql-bench/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -172,6 +172,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/sql-common/Makefile.in mysql/sql-common/Makefile.in --- mysql.orig/sql-common/Makefile.in 2007-12-14 21:46:10.000000000 +0100 +++ mysql/sql-common/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -165,6 +165,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/SSL/Makefile.in mysql/SSL/Makefile.in --- mysql.orig/SSL/Makefile.in 2007-12-14 21:45:23.000000000 +0100 +++ mysql/SSL/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -165,6 +165,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/strings/Makefile.in mysql/strings/Makefile.in --- mysql.orig/strings/Makefile.in 2007-12-14 21:46:11.000000000 +0100 +++ mysql/strings/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -359,6 +359,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/support-files/MacOSX/Makefile.in mysql/support-files/MacOSX/Makefile.in --- mysql.orig/support-files/MacOSX/Makefile.in 2007-12-14 21:46:11.000000000 +0100 +++ mysql/support-files/MacOSX/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -169,6 +169,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/support-files/Makefile.in mysql/support-files/Makefile.in --- mysql.orig/support-files/Makefile.in 2007-12-14 21:46:11.000000000 +0100 +++ mysql/support-files/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -189,6 +189,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/support-files/RHEL4-SElinux/Makefile.in mysql/support-files/RHEL4-SElinux/Makefile.in --- mysql.orig/support-files/RHEL4-SElinux/Makefile.in 2007-12-14 21:46:12.000000000 +0100 +++ mysql/support-files/RHEL4-SElinux/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -167,6 +167,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/tests/Makefile.in mysql/tests/Makefile.in --- mysql.orig/tests/Makefile.in 2007-12-14 21:46:12.000000000 +0100 +++ mysql/tests/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -213,6 +213,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @CLIENT_LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/tools/Makefile.in mysql/tools/Makefile.in --- mysql.orig/tools/Makefile.in 2007-12-14 21:46:12.000000000 +0100 +++ mysql/tools/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -187,6 +187,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/vio/Makefile.in mysql/vio/Makefile.in --- mysql.orig/vio/Makefile.in 2007-12-14 21:46:13.000000000 +0100 +++ mysql/vio/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -196,6 +196,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/win/Makefile.in mysql/win/Makefile.in --- mysql.orig/win/Makefile.in 2007-12-14 21:46:13.000000000 +0100 +++ mysql/win/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -165,6 +165,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@ diff -Naur mysql.orig/zlib/Makefile.in mysql/zlib/Makefile.in --- mysql.orig/zlib/Makefile.in 2007-12-14 21:46:13.000000000 +0100 +++ mysql/zlib/Makefile.in 2008-11-27 20:08:07.000000000 +0100 @@ -204,6 +204,7 @@ LIBDL = @LIBDL@ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@ LIBOBJS = @LIBOBJS@ +LIBRT = @LIBRT@ LIBS = $(NON_THREADED_LIBS) LIBTOOL = @LIBTOOL@ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@