diff options
author | Mikael Ronstrom <mikael@mysql.com> | 2008-12-20 11:01:41 +0100 |
---|---|---|
committer | Mikael Ronstrom <mikael@mysql.com> | 2008-12-20 11:01:41 +0100 |
commit | cc958a18dd9554870edd3b1c6119edf72b661879 (patch) | |
tree | 36aa1edfd94289934ffa3aa66af64b899e9a9e77 | |
parent | 602f612af09c3ccb6db19286291ae0bca403db5c (diff) | |
download | mariadb-git-cc958a18dd9554870edd3b1c6119edf72b661879.tar.gz |
Backport of DTrace patches from 6.0
46 files changed, 1521 insertions, 74 deletions
diff --git a/config/ac-macros/dtrace.m4 b/config/ac-macros/dtrace.m4 new file mode 100644 index 00000000000..d37667767d1 --- /dev/null +++ b/config/ac-macros/dtrace.m4 @@ -0,0 +1,38 @@ +dnl --------------------------------------------------------------------------- +dnl Macro: DTRACE_TEST +dnl --------------------------------------------------------------------------- +AC_ARG_ENABLE(dtrace, + AC_HELP_STRING([--enable-dtrace],[Build with support for the DTRACE.]), + [ + ENABLE_DTRACE="$enable_dtrace" + ], + [ + ENABLE_DTRACE="yes" + ] +) +DTRACEFLAGS="" +HAVE_DTRACE="" +HAVE_DTRACE_DASH_G="" +if test "$ENABLE_DTRACE" = "yes"; then + AC_CHECK_PROGS(DTRACE, dtrace, [not found]) + if test "$DTRACE" = "not found"; then + ENABLE_DTRACE="no" + else + AC_DEFINE([HAVE_DTRACE], [1], [Defined to 1 if DTrace support is enabled]) + case "$target_os" in + *solaris*) + HAVE_DTRACE_DASH_G="yes" + ;; + *) + HAVE_DTRACE_DASH_G="no" + ;; + esac + fi +fi +AC_SUBST(DTRACEFLAGS) +AC_SUBST(HAVE_DTRACE) +AM_CONDITIONAL([HAVE_DTRACE], [ test "$ENABLE_DTRACE" = "yes" ]) +AM_CONDITIONAL([HAVE_DTRACE_DASH_G], [ test "$HAVE_DTRACE_DASH_G" = "yes" ]) +dnl --------------------------------------------------------------------------- +dnl End Macro: DTRACE_TEST +dnl --------------------------------------------------------------------------- diff --git a/configure.in b/configure.in index 52b8018c36c..4a3af3c878d 100644 --- a/configure.in +++ b/configure.in @@ -50,6 +50,7 @@ sinclude(config/ac-macros/check_cpu.m4) sinclude(config/ac-macros/character_sets.m4) sinclude(config/ac-macros/compiler_flag.m4) sinclude(config/ac-macros/plugins.m4) +sinclude(config/ac-macros/dtrace.m4) sinclude(config/ac-macros/ha_ndbcluster.m4) sinclude(config/ac-macros/large_file.m4) sinclude(config/ac-macros/misc.m4) diff --git a/include/Makefile.am b/include/Makefile.am index 9438f0d0f25..e0dbfa84f23 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -36,7 +36,8 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \ mysql_version.h.in my_handler.h my_time.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \ - atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h + atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \ + probes_mysql.h probes_mysql_nodtrace.h EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp @@ -64,5 +65,17 @@ my_config.h: config.h dist-hook: $(RM) -f $(distdir)/mysql_version.h $(distdir)/my_config.h +if HAVE_DTRACE +BUILT_SOURCES += probes_mysql_dtrace.h +CLEANFILES += probes_mysql_dtrace.h +DTRACEPROVIDER = $(top_srcdir)/sql/probes_mysql.d + +probes_mysql_dtrace.h: $(DTRACEPROVIDER) + $(DTRACE) $(DTRACEFLAGS) -h -s $< -o $@ +endif + +probes_mysql_nodtrace.h: $(DTRACEPROVIDER) + $(top_srcdir)/scripts/dheadgen.pl -f $^ > $@ + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/include/probes_mysql.h b/include/probes_mysql.h new file mode 100644 index 00000000000..13491c661fd --- /dev/null +++ b/include/probes_mysql.h @@ -0,0 +1,13 @@ +#ifndef PROBES_MYSQL_H + +#define PROBES_MYSQL_H + +#include <my_global.h> + +#if defined(HAVE_DTRACE) && !defined(DISABLE_DTRACE) +#include "probes_mysql_dtrace.h" +#else +#include "probes_mysql_nodtrace.h" +#endif + +#endif /* PROBES_MYSQL_H */ diff --git a/include/probes_mysql_nodtrace.h b/include/probes_mysql_nodtrace.h new file mode 100644 index 00000000000..e879a06e494 --- /dev/null +++ b/include/probes_mysql_nodtrace.h @@ -0,0 +1,129 @@ +/* + * Generated by dheadgen(1). + */ + +#ifndef _PROBES_MYSQL_D +#define _PROBES_MYSQL_D + +#ifdef __cplusplus +extern "C" { +#endif + +#define MYSQL_CONNECTION_START(arg0, arg1, arg2) +#define MYSQL_CONNECTION_START_ENABLED() (0) +#define MYSQL_CONNECTION_DONE(arg0, arg1) +#define MYSQL_CONNECTION_DONE_ENABLED() (0) +#define MYSQL_COMMAND_START(arg0, arg1, arg2, arg3) +#define MYSQL_COMMAND_START_ENABLED() (0) +#define MYSQL_COMMAND_DONE(arg0) +#define MYSQL_COMMAND_DONE_ENABLED() (0) +#define MYSQL_QUERY_START(arg0, arg1, arg2, arg3, arg4) +#define MYSQL_QUERY_START_ENABLED() (0) +#define MYSQL_QUERY_DONE(arg0) +#define MYSQL_QUERY_DONE_ENABLED() (0) +#define MYSQL_QUERY_PARSE_START(arg0) +#define MYSQL_QUERY_PARSE_START_ENABLED() (0) +#define MYSQL_QUERY_PARSE_DONE(arg0) +#define MYSQL_QUERY_PARSE_DONE_ENABLED() (0) +#define MYSQL_QUERY_CACHE_HIT(arg0, arg1) +#define MYSQL_QUERY_CACHE_HIT_ENABLED() (0) +#define MYSQL_QUERY_CACHE_MISS(arg0) +#define MYSQL_QUERY_CACHE_MISS_ENABLED() (0) +#define MYSQL_QUERY_EXEC_START(arg0, arg1, arg2, arg3, arg4, arg5) +#define MYSQL_QUERY_EXEC_START_ENABLED() (0) +#define MYSQL_QUERY_EXEC_DONE(arg0) +#define MYSQL_QUERY_EXEC_DONE_ENABLED() (0) +#define MYSQL_INSERT_ROW_START(arg0, arg1) +#define MYSQL_INSERT_ROW_START_ENABLED() (0) +#define MYSQL_INSERT_ROW_DONE(arg0) +#define MYSQL_INSERT_ROW_DONE_ENABLED() (0) +#define MYSQL_UPDATE_ROW_START(arg0, arg1) +#define MYSQL_UPDATE_ROW_START_ENABLED() (0) +#define MYSQL_UPDATE_ROW_DONE(arg0) +#define MYSQL_UPDATE_ROW_DONE_ENABLED() (0) +#define MYSQL_DELETE_ROW_START(arg0, arg1) +#define MYSQL_DELETE_ROW_START_ENABLED() (0) +#define MYSQL_DELETE_ROW_DONE(arg0) +#define MYSQL_DELETE_ROW_DONE_ENABLED() (0) +#define MYSQL_READ_ROW_START(arg0, arg1, arg2) +#define MYSQL_READ_ROW_START_ENABLED() (0) +#define MYSQL_READ_ROW_DONE(arg0) +#define MYSQL_READ_ROW_DONE_ENABLED() (0) +#define MYSQL_INDEX_READ_ROW_START(arg0, arg1) +#define MYSQL_INDEX_READ_ROW_START_ENABLED() (0) +#define MYSQL_INDEX_READ_ROW_DONE(arg0) +#define MYSQL_INDEX_READ_ROW_DONE_ENABLED() (0) +#define MYSQL_HANDLER_RDLOCK_START(arg0, arg1) +#define MYSQL_HANDLER_RDLOCK_START_ENABLED() (0) +#define MYSQL_HANDLER_WRLOCK_START(arg0, arg1) +#define MYSQL_HANDLER_WRLOCK_START_ENABLED() (0) +#define MYSQL_HANDLER_UNLOCK_START(arg0, arg1) +#define MYSQL_HANDLER_UNLOCK_START_ENABLED() (0) +#define MYSQL_HANDLER_RDLOCK_DONE(arg0) +#define MYSQL_HANDLER_RDLOCK_DONE_ENABLED() (0) +#define MYSQL_HANDLER_WRLOCK_DONE(arg0) +#define MYSQL_HANDLER_WRLOCK_DONE_ENABLED() (0) +#define MYSQL_HANDLER_UNLOCK_DONE(arg0) +#define MYSQL_HANDLER_UNLOCK_DONE_ENABLED() (0) +#define MYSQL_FILESORT_START(arg0, arg1) +#define MYSQL_FILESORT_START_ENABLED() (0) +#define MYSQL_FILESORT_DONE(arg0, arg1) +#define MYSQL_FILESORT_DONE_ENABLED() (0) +#define MYSQL_SELECT_START(arg0) +#define MYSQL_SELECT_START_ENABLED() (0) +#define MYSQL_SELECT_DONE(arg0, arg1) +#define MYSQL_SELECT_DONE_ENABLED() (0) +#define MYSQL_INSERT_START(arg0) +#define MYSQL_INSERT_START_ENABLED() (0) +#define MYSQL_INSERT_DONE(arg0, arg1) +#define MYSQL_INSERT_DONE_ENABLED() (0) +#define MYSQL_INSERT_SELECT_START(arg0) +#define MYSQL_INSERT_SELECT_START_ENABLED() (0) +#define MYSQL_INSERT_SELECT_DONE(arg0, arg1) +#define MYSQL_INSERT_SELECT_DONE_ENABLED() (0) +#define MYSQL_UPDATE_START(arg0) +#define MYSQL_UPDATE_START_ENABLED() (0) +#define MYSQL_UPDATE_DONE(arg0, arg1, arg2) +#define MYSQL_UPDATE_DONE_ENABLED() (0) +#define MYSQL_MULTI_UPDATE_START(arg0) +#define MYSQL_MULTI_UPDATE_START_ENABLED() (0) +#define MYSQL_MULTI_UPDATE_DONE(arg0, arg1, arg2) +#define MYSQL_MULTI_UPDATE_DONE_ENABLED() (0) +#define MYSQL_DELETE_START(arg0) +#define MYSQL_DELETE_START_ENABLED() (0) +#define MYSQL_DELETE_DONE(arg0, arg1) +#define MYSQL_DELETE_DONE_ENABLED() (0) +#define MYSQL_MULTI_DELETE_START(arg0) +#define MYSQL_MULTI_DELETE_START_ENABLED() (0) +#define MYSQL_MULTI_DELETE_DONE(arg0, arg1) +#define MYSQL_MULTI_DELETE_DONE_ENABLED() (0) +#define MYSQL_NET_READ_START() +#define MYSQL_NET_READ_START_ENABLED() (0) +#define MYSQL_NET_READ_DONE(arg0, arg1) +#define MYSQL_NET_READ_DONE_ENABLED() (0) +#define MYSQL_NET_WRITE_START(arg0) +#define MYSQL_NET_WRITE_START_ENABLED() (0) +#define MYSQL_NET_WRITE_DONE(arg0) +#define MYSQL_NET_WRITE_DONE_ENABLED() (0) +#define MYSQL_KEYCACHE_READ_START(arg0, arg1, arg2, arg3) +#define MYSQL_KEYCACHE_READ_START_ENABLED() (0) +#define MYSQL_KEYCACHE_READ_BLOCK(arg0) +#define MYSQL_KEYCACHE_READ_BLOCK_ENABLED() (0) +#define MYSQL_KEYCACHE_READ_HIT() +#define MYSQL_KEYCACHE_READ_HIT_ENABLED() (0) +#define MYSQL_KEYCACHE_READ_MISS() +#define MYSQL_KEYCACHE_READ_MISS_ENABLED() (0) +#define MYSQL_KEYCACHE_READ_DONE(arg0, arg1) +#define MYSQL_KEYCACHE_READ_DONE_ENABLED() (0) +#define MYSQL_KEYCACHE_WRITE_START(arg0, arg1, arg2, arg3) +#define MYSQL_KEYCACHE_WRITE_START_ENABLED() (0) +#define MYSQL_KEYCACHE_WRITE_BLOCK(arg0) +#define MYSQL_KEYCACHE_WRITE_BLOCK_ENABLED() (0) +#define MYSQL_KEYCACHE_WRITE_DONE(arg0, arg1) +#define MYSQL_KEYCACHE_WRITE_DONE_ENABLED() (0) + +#ifdef __cplusplus +} +#endif + +#endif /* _PROBES_MYSQL_D */ diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index 43e86ea31e8..c66c1de2f22 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -89,7 +89,8 @@ DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \ -DDEFAULT_HOME_ENV=MYSQL_HOME \ -DDEFAULT_GROUP_SUFFIX_ENV=MYSQL_GROUP_SUFFIX \ -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \ - -DSHAREDIR="\"$(MYSQLSHAREdir)\"" $(target_defs) + -DSHAREDIR="\"$(MYSQLSHAREdir)\"" -DDISABLE_DTRACE \ + $(target_defs) if HAVE_YASSL yassl_las = $(top_builddir)/extra/yassl/src/libyassl.la \ diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index ef2fab2da6d..1657afc47fd 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -28,7 +28,8 @@ DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ -DDATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ - -DPLUGINDIR="\"$(pkgplugindir)\"" + -DPLUGINDIR="\"$(pkgplugindir)\"" \ + -DDISABLE_DTRACE INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/sql -I$(top_srcdir)/sql \ -I$(top_srcdir)/sql/examples \ diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 3312c692c09..a3c581a3c46 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -126,5 +126,21 @@ test_base64$(EXEEXT): base64.c $(LIBRARIES) $(LINK) $(FLAGS) -DMAIN ./test_base64.c $(LDADD) $(LIBS) $(RM) -f ./test_base64.c +if HAVE_DTRACE_DASH_G +abs_top_srcdir = @abs_top_srcdir@ +libmysys_a_LIBADD += probes_mysql.o +libmysys_a_DEPENDENCIES += probes_mysql.o dtrace_files dtrace_providers +CLEANFILES = probes_mysql.o dtrace_files dtrace_providers +DTRACEFILES = mf_keycache.o +DTRACEPROVIDER = $(abs_top_srcdir)/sql/probes_mysql.d + +dtrace_files: + echo $(DTRACEFILES) > $@ +dtrace_providers: + echo $(DTRACEPROVIDER) > $@ +probes_mysql.o: $(DTRACEPROVIDER) $(DTRACEFILES) + $(DTRACE) $(DTRACEFLAGS) -G -s $< $(DTRACEFILES) -o $@ +endif + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 7cbd35580f1..5274509a1d5 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -109,6 +109,7 @@ #include <my_bit.h> #include <errno.h> #include <stdarg.h> +#include "probes_mysql.h" /* Some compilation flags have been added specifically for this module @@ -2537,6 +2538,15 @@ uchar *key_cache_read(KEY_CACHE *keycache, uint status; int page_st; + if (MYSQL_KEYCACHE_READ_START_ENABLED()) + { + MYSQL_KEYCACHE_READ_START(my_filename(file), length, + (ulong) (keycache->blocks_used * + keycache->key_cache_block_size), + (ulong) (keycache->blocks_unused * + keycache->key_cache_block_size)); + } + /* When the key cache is once initialized, we use the cache_lock to reliably distinguish the cases of normal operation, resizing, and @@ -2586,6 +2596,9 @@ uchar *key_cache_read(KEY_CACHE *keycache, /* Request the cache block that matches file/pos. */ keycache->global_cache_r_requests++; + + MYSQL_KEYCACHE_READ_BLOCK(keycache->key_cache_block_size); + block=find_key_block(keycache, file, filepos, level, 0, &page_st); if (!block) { @@ -2605,6 +2618,7 @@ uchar *key_cache_read(KEY_CACHE *keycache, { if (page_st != PAGE_READ) { + MYSQL_KEYCACHE_READ_MISS(); /* The requested page is to be read into the block buffer */ read_block(keycache, block, keycache->key_cache_block_size, read_length+offset, @@ -2629,6 +2643,10 @@ uchar *key_cache_read(KEY_CACHE *keycache, my_errno= -1; block->status|= BLOCK_ERROR; } + else + { + MYSQL_KEYCACHE_READ_HIT(); + } } /* block status may have added BLOCK_ERROR in the above 'if'. */ @@ -2673,7 +2691,16 @@ uchar *key_cache_read(KEY_CACHE *keycache, #ifndef THREAD /* This is only true if we where able to read everything in one block */ if (return_buffer) + { + if (MYSQL_KEYCACHE_READ_DONE_ENABLED()) + { + MYSQL_KEYCACHE_READ_DONE((ulong) (keycache->blocks_used * + keycache->key_cache_block_size), + (ulong) (keycache->blocks_unused * + keycache->key_cache_block_size)); + } DBUG_RETURN(block->buffer); + } #endif next_block: buff+= read_length; @@ -2681,6 +2708,13 @@ uchar *key_cache_read(KEY_CACHE *keycache, offset= 0; } while ((length-= read_length)); + if (MYSQL_KEYCACHE_READ_DONE_ENABLED()) + { + MYSQL_KEYCACHE_READ_DONE((ulong) (keycache->blocks_used * + keycache->key_cache_block_size), + (ulong) (keycache->blocks_unused * + keycache->key_cache_block_size)); + } goto end; } @@ -3009,6 +3043,15 @@ int key_cache_write(KEY_CACHE *keycache, uint offset; int page_st; + if (MYSQL_KEYCACHE_WRITE_START_ENABLED()) + { + MYSQL_KEYCACHE_WRITE_START(my_filename(file), length, + (ulong) (keycache->blocks_used * + keycache->key_cache_block_size), + (ulong) (keycache->blocks_unused * + keycache->key_cache_block_size)); + } + /* When the key cache is once initialized, we use the cache_lock to reliably distinguish the cases of normal operation, resizing, and @@ -3044,6 +3087,8 @@ int key_cache_write(KEY_CACHE *keycache, /* Cache could be disabled in a later iteration. */ if (!keycache->can_be_used) goto no_key_cache; + + MYSQL_KEYCACHE_WRITE_BLOCK(keycache->key_cache_block_size); /* Start writing at the beginning of the cache block. */ filepos-= offset; /* Do not write beyond the end of the cache block. */ @@ -3247,6 +3292,15 @@ end: dec_counter_for_resize_op(keycache); keycache_pthread_mutex_unlock(&keycache->cache_lock); } + + if (MYSQL_KEYCACHE_WRITE_DONE_ENABLED()) + { + MYSQL_KEYCACHE_WRITE_DONE((ulong) (keycache->blocks_used * + keycache->key_cache_block_size), + (ulong) (keycache->blocks_unused * + keycache->key_cache_block_size)); + } + #if !defined(DBUG_OFF) && defined(EXTRA_DEBUG) DBUG_EXECUTE("exec", test_key_cache(keycache, "end of key_cache_write", 1);); diff --git a/scripts/Makefile.am b/scripts/Makefile.am index ac43bb7b0a4..6c552d96bc9 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -37,7 +37,8 @@ bin_SCRIPTS = @server_scripts@ \ mysqld_multi noinst_SCRIPTS = make_binary_distribution \ - make_sharedlib_distribution + make_sharedlib_distribution \ + dheadgen.pl EXTRA_SCRIPTS = make_binary_distribution.sh \ make_sharedlib_distribution.sh \ @@ -59,7 +60,8 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \ mysqlhotcopy.sh \ mysqldumpslow.sh \ mysqld_multi.sh \ - mysqld_safe.sh + mysqld_safe.sh \ + dheadgen.pl EXTRA_DIST = $(EXTRA_SCRIPTS) \ mysqlaccess.conf \ @@ -110,7 +112,7 @@ mysqlbug: ${top_builddir}/config.status mysqlbug.sh mysql_fix_privilege_tables.sql: mysql_system_tables.sql \ mysql_system_tables_fix.sql @echo "Building $@"; - @cat mysql_system_tables.sql mysql_system_tables_fix.sql > $@ + @cat $(srcdir)/mysql_system_tables.sql $(srcdir)/mysql_system_tables_fix.sql > $@ # # Build mysql_fix_privilege_tables_sql.c from @@ -123,7 +125,7 @@ mysql_fix_privilege_tables_sql.c: comp_sql.c mysql_fix_privilege_tables.sql sleep 2 $(top_builddir)/scripts/comp_sql$(EXEEXT) \ mysql_fix_privilege_tables \ - $(top_srcdir)/scripts/mysql_fix_privilege_tables.sql $@ + $(top_builddir)/scripts/mysql_fix_privilege_tables.sql $@ SUFFIXES = .sh diff --git a/scripts/dheadgen.pl b/scripts/dheadgen.pl new file mode 100644 index 00000000000..5ead0f90a31 --- /dev/null +++ b/scripts/dheadgen.pl @@ -0,0 +1,338 @@ +#!/usr/bin/perl -w + +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of the above-listed copyright holders nor the names +# of its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# ident "@(#)dheadgen.pl 1.4 07/06/24 SMI" + +# +# DTrace Header Generator +# ----------------------- +# +# This script is meant to mimic the output of dtrace(1M) with the -h +# (headergen) flag on system that lack native support for DTrace. This script +# is intended to be integrated into projects that use DTrace's static tracing +# facilities (USDT), and invoked as part of the build process to have a +# common build process on all target systems. To facilitate this, this script +# is licensed under a BSD license. On system with native DTrace support, the +# dtrace(1M) command will be invoked to create the full header file; on other +# systems, this script will generated a stub header file. +# +# Normally, generated macros take the form PROVIDER_PROBENAME(). It may be +# desirable to customize the output of this script and of dtrace(1M) to +# tailor the precise macro name. To do this, edit the emit_dtrace() subroutine +# to pattern match for the lines you want to customize. +# + +use strict; + +my @lines; +my @tokens = (); +my $lineno = 0; +my $newline = 1; +my $eof = 0; +my $infile; +my $outfile; +my $force = 0; + +sub emit_dtrace { + my ($line) = @_; + + # + # Insert customization here. For example, if you want to change the + # name of the macros you may do something like this: + # + # $line =~ s/(\s)[A-Z]+_/\1TRACE_MOZILLA_/; + # + + print $line; +} + +# +# The remaining code deals with parsing D provider definitions and emitting +# the stub header file. There should be no need to edit this absent a bug. +# + +# +# Emit the two relevant macros for each probe in the given provider: +# PROVIDER_PROBENAME(<args>) +# PROVIDER_PROBENAME_ENABLED() (0) +# +sub emit_provider { + my ($provname, @probes) = @_; + + $provname = uc($provname); + + foreach my $probe (@probes) { + my $probename = uc($$probe{'name'}); + my $argc = $$probe{'argc'}; + my $line; + + $probename =~ s/__/_/g; + + $line = "#define\t${provname}_${probename}("; + for (my $i = 0; $i < $argc; $i++) { + $line .= ($i == 0 ? '' : ', '); + $line .= "arg$i"; + } + $line .= ")\n"; + emit_dtrace($line); + + $line = "#define\t${provname}_${probename}_ENABLED() (0)\n"; + emit_dtrace($line); + } + + emit_dtrace("\n"); +} + +sub emit_prologue { + my ($filename) = @_; + + $filename =~ s/.*\///g; + $filename = uc($filename); + $filename =~ s/\./_/g; + + emit_dtrace <<"EOF"; +/* + * Generated by dheadgen(1). + */ + +#ifndef\t_${filename} +#define\t_${filename} + +#ifdef\t__cplusplus +extern "C" { +#endif + +EOF +} + +sub emit_epilogue { + my ($filename) = @_; + + $filename =~ s/.*\///g; + $filename = uc($filename); + $filename =~ s/\./_/g; + + emit_dtrace <<"EOF"; +#ifdef __cplusplus +} +#endif + +#endif /* _$filename */ +EOF +} + +# +# Get the next token from the file keeping track of the line number. +# +sub get_token { + my ($eof_ok) = @_; + my $tok; + + while (1) { + while (scalar(@tokens) == 0) { + if (scalar(@lines) == 0) { + $eof = 1; + return if ($eof_ok); + die "expected more data at line $lineno"; + } + + $lineno++; + push(@tokens, split(/(\s+|\n|[(){},#;]|\/\*|\*\/)/, + shift(@lines))); + } + + $tok = shift(@tokens); + next if ($tok eq ''); + next if ($tok =~ /^[ \t]+$/); + + return ($tok); + } +} + +# +# Ignore newlines, comments and typedefs +# +sub next_token { + my ($eof_ok) = @_; + my $tok; + + while (1) { + $tok = get_token($eof_ok); + return if ($eof_ok && $eof); + if ($tok eq "typedef" or $tok =~ /^#/) { + while (1) { + $tok = get_token(0); + last if ($tok eq "\n"); + } + next; + } elsif ($tok eq '/*') { + while (get_token(0) ne '*/') { + next; + } + next; + } elsif ($tok eq "\n") { + next; + } + + last; + } + + return ($tok); +} + +sub expect_token { + my ($t) = @_; + my $tok; + + while (($tok = next_token(0)) eq "\n") { + next; + } + + die "expected '$t' at line $lineno rather than '$tok'" if ($t ne $tok); +} + +sub get_args { + expect_token('('); + + my $tok = next_token(0); + my @args = (); + + return (@args) if ($tok eq ')'); + + if ($tok eq 'void') { + expect_token(')'); + return (@args); + } + + my $arg = $tok; + + while (1) { + $tok = next_token(0); + if ($tok eq ',' || $tok eq ')') { + push(@args, $arg); + $arg = ''; + last if ($tok eq ')'); + } else { + $arg = "$arg $tok"; + } + } + + return (@args); +} + +sub usage { + die "usage: $0 [-f] <filename.d>\n"; +} + +usage() if (scalar(@ARGV) < 1); +if ($ARGV[0] eq '-f') { + usage() if (scalar(@ARGV < 2)); + $force = 1; + shift; +} +$infile = $ARGV[0]; +usage() if ($infile !~ /(.+)\.d$/); + +# +# If the system has native support for DTrace, we'll use that binary instead. +# +if (-x '/usr/sbin/dtrace' && !$force) { + open(my $dt, '-|', "/usr/sbin/dtrace -C -h -s $infile -o /dev/stdout") + or die "can't invoke dtrace(1M)"; + + while (<$dt>) { + emit_dtrace($_); + } + + close($dt); + + exit(0); +} + +emit_prologue($infile); + +open(my $d, '<', $infile) or die "couldn't open $infile"; +@lines = <$d>; +close($d); + +while (1) { + my $nl = 0; + my $tok = next_token(1); + last if $eof; + + if ($newline && $tok eq '#') { + while (1) { + $tok = get_token(0); + + last if ($tok eq "\n"); + } + $nl = 1; + } elsif ($tok eq "\n") { + $nl = 1; + } elsif ($tok eq 'provider') { + my $provname = next_token(0); + my @probes = (); + expect_token('{'); + + while (1) { + $tok = next_token(0); + if ($tok eq 'probe') { + my $probename = next_token(0); + my @args = get_args(); + + next while (next_token(0) ne ';'); + + push(@probes, { + 'name' => $probename, + 'argc' => scalar(@args) + }); + + } elsif ($tok eq '}') { + expect_token(';'); + + emit_provider($provname, @probes); + + last; + } + } + + } else { + die "syntax error at line $lineno near '$tok'\n"; + } + + $newline = $nl; +} + +emit_epilogue($infile); + +exit(0); diff --git a/sql/Makefile.am b/sql/Makefile.am index b9de9b279a3..1f82e660f73 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -28,6 +28,23 @@ SUBDIRS = share libexec_PROGRAMS = mysqld EXTRA_PROGRAMS = gen_lex_hash bin_PROGRAMS = mysql_tzinfo_to_sql +DTRACEFILES = filesort.o \ + ha_ndbcluster.o \ + handler.o \ + mysqld.o \ + net_serv.o \ + scheduler.o \ + sp_head.o \ + sql_cache.o \ + sql_connect.o \ + sql_cursor.o \ + sql_delete.o \ + sql_insert.o \ + sql_parse.o \ + sql_prepare.o \ + sql_select.o \ + sql_update.o + noinst_LTLIBRARIES= libndb.la \ udf_example.la @@ -147,6 +164,7 @@ BUILT_MAINT_SRC = sql_yacc.cc sql_yacc.h BUILT_SOURCES = $(BUILT_MAINT_SRC) lex_hash.h link_sources EXTRA_DIST = udf_example.c udf_example.def $(BUILT_MAINT_SRC) \ nt_servc.cc nt_servc.h message.mc CMakeLists.txt \ + probes_mysql.d \ udf_example.c udf_example.def CLEANFILES = lex_hash.h sql_yacc.output link_sources DISTCLEANFILES = $(EXTRA_PROGRAMS) @@ -186,5 +204,27 @@ install-exec-hook: test ! -f mysqld-debug.sym.gz || $(INSTALL_DATA) mysqld-debug.sym.gz $(DESTDIR)$(pkglibdir) test ! -f mysqld.sym.gz || $(INSTALL_DATA) mysqld.sym.gz $(DESTDIR)$(pkglibdir) +if HAVE_DTRACE_DASH_G +abs_top_srcdir = @abs_top_srcdir@ +mysqld_LDADD += probes_all.o +mysqld_DEPENDENCIES += probes_all.o dtrace_files dtrace_providers +CLEANFILES += dtrace_files dtrace_providers probes_all.o +DTRACEPROVIDER = $(abs_top_srcdir)/sql/probes_mysql.d + +dtrace_files: + echo $(DTRACEFILES) > $@ +dtrace_providers: + echo $(DTRACEPROVIDER) > $@ + +DTRACEDIRS = . ../mysys $(patsubst %,$(top_builddir)/storage/%,@mysql_se_dirs@) + +probes_all.o: probes_mysql.d $(DTRACEFILES) + providers=`(for i in $(DTRACEDIRS); do cat $$i/dtrace_providers 2>/dev/null; done) | +tr " " "\n" | sort | uniq | sed -e '/^$$/d' -e 's/^/-s /'`; \ + objects=`for i in $(DTRACEDIRS); do f=\`cat $$i/dtrace_files 2>/dev/null\`; for j in +$$f; do test -f $$i/$$j && echo -n "$$i/$$j "; done; done`; \ + $(DTRACE) $(DTRACEFLAGS) -G $$providers $$objects -o $@ +endif + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/sql/filesort.cc b/sql/filesort.cc index 2850ada1ffb..e95d1741b06 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -27,6 +27,7 @@ #endif #include <m_ctype.h> #include "sql_sort.h" +#include "probes_mysql.h" #ifndef THREAD #define SKIP_DBUG_IN_FILESORT @@ -121,6 +122,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, TABLE_LIST *tab= table->pos_in_table_list; Item_subselect *subselect= tab ? tab->containing_subselect() : 0; + MYSQL_FILESORT_START(table->s->db.str, table->s->tablename.str); + /* Release InnoDB's adaptive hash index latch (if holding) before running a sort. @@ -331,6 +334,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, #endif memcpy(&table->sort, &table_sort, sizeof(FILESORT_INFO)); DBUG_PRINT("exit",("records: %ld", (long) records)); + MYSQL_FILESORT_DONE(error, records); DBUG_RETURN(error ? HA_POS_ERROR : records); } /* filesort */ diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 1cfe403407e..a1e492d9abc 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -41,6 +41,7 @@ #include "ha_ndbcluster_tables.h" #include <mysql/plugin.h> +#include "probes_mysql.h" #ifdef ndb_dynamite #undef assert @@ -128,6 +129,13 @@ static uint ndbcluster_alter_table_flags(uint flags) DBUG_RETURN(ndb_to_mysql_error(&tmp)); \ } +#define ERR_RETURN_PREPARE(rc, err) \ +{ \ + const NdbError& tmp= err; \ + set_ndb_err(current_thd, tmp); \ + rc= ndb_to_mysql_error(&tmp); \ +} + #define ERR_BREAK(err, code) \ { \ const NdbError& tmp= err; \ @@ -3601,9 +3609,11 @@ int ha_ndbcluster::index_read(uchar *buf, { key_range start_key; bool descending= FALSE; + int rc; DBUG_ENTER("ha_ndbcluster::index_read"); DBUG_PRINT("enter", ("active_index: %u, key_len: %u, find_flag: %d", active_index, key_len, find_flag)); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); start_key.key= key; start_key.length= key_len; @@ -3619,43 +3629,61 @@ int ha_ndbcluster::index_read(uchar *buf, default: break; } - DBUG_RETURN(read_range_first_to_buf(&start_key, 0, descending, - m_sorted, buf)); + rc= read_range_first_to_buf(&start_key, 0, descending, + m_sorted, buf); + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_ndbcluster::index_next(uchar *buf) { + int rc; DBUG_ENTER("ha_ndbcluster::index_next"); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_next_count); - DBUG_RETURN(next_result(buf)); + rc= next_result(buf); + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_ndbcluster::index_prev(uchar *buf) { + int rc; DBUG_ENTER("ha_ndbcluster::index_prev"); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_prev_count); - DBUG_RETURN(next_result(buf)); + rc= next_result(buf); + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_ndbcluster::index_first(uchar *buf) { + int rc; DBUG_ENTER("ha_ndbcluster::index_first"); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_first_count); // Start the ordered index scan and fetch the first row // Only HA_READ_ORDER indexes get called by index_first - DBUG_RETURN(ordered_index_scan(0, 0, TRUE, FALSE, buf, NULL)); + rc= ordered_index_scan(0, 0, TRUE, FALSE, buf, NULL); + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_ndbcluster::index_last(uchar *buf) { + int rc; DBUG_ENTER("ha_ndbcluster::index_last"); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_last_count); - DBUG_RETURN(ordered_index_scan(0, 0, TRUE, TRUE, buf, NULL)); + rc= ordered_index_scan(0, 0, TRUE, TRUE, buf, NULL); + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_ndbcluster::index_read_last(uchar * buf, const uchar * key, uint key_len) @@ -3747,16 +3775,24 @@ int ha_ndbcluster::read_range_first(const key_range *start_key, const key_range *end_key, bool eq_r, bool sorted) { + int rc; uchar* buf= table->record[0]; DBUG_ENTER("ha_ndbcluster::read_range_first"); - DBUG_RETURN(read_range_first_to_buf(start_key, end_key, FALSE, - sorted, buf)); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= read_range_first_to_buf(start_key, end_key, FALSE, + sorted, buf); + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_ndbcluster::read_range_next() { + int rc; DBUG_ENTER("ha_ndbcluster::read_range_next"); - DBUG_RETURN(next_result(table->record[0])); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= next_result(table->record[0]); + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } @@ -3839,12 +3875,18 @@ int ha_ndbcluster::rnd_end() int ha_ndbcluster::rnd_next(uchar *buf) { + int rc; DBUG_ENTER("rnd_next"); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + TRUE); ha_statistic_increment(&SSV::ha_read_rnd_next_count); if (!m_active_cursor) - DBUG_RETURN(full_table_scan(buf)); - DBUG_RETURN(next_result(buf)); + rc= full_table_scan(buf); + else + rc= next_result(buf); + MYSQL_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } @@ -3856,7 +3898,10 @@ int ha_ndbcluster::rnd_next(uchar *buf) int ha_ndbcluster::rnd_pos(uchar *buf, uchar *pos) { + int rc; DBUG_ENTER("rnd_pos"); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + FALSE); ha_statistic_increment(&SSV::ha_read_rnd_count); // The primary key for the record is stored in pos // Perform a pk_read using primary key "index" @@ -3889,7 +3934,9 @@ int ha_ndbcluster::rnd_pos(uchar *buf, uchar *pos) DBUG_PRINT("info", ("partition id %u", part_spec.start_part)); } DBUG_DUMP("key", pos, key_length); - DBUG_RETURN(pk_read(pos, key_length, buf, part_spec.start_part)); + rc= pk_read(pos, key_length, buf, part_spec.start_part); + MYSQL_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } } @@ -8721,6 +8768,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, sorted, buffer)); } + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); thd_ndb->query_state|= NDB_QUERY_MULTI_READ_RANGE; m_disable_multi_read= FALSE; @@ -8802,7 +8850,13 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, (op->setPartitionId(part_spec.start_part), TRUE))) curr += reclength; else - ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError()); + { + ERR_RETURN_PREPARE(res, + op ? op->getNdbError() : + m_active_trans->getNdbError()) + MYSQL_INDEX_READ_ROW_DONE(res); + DBUG_RETURN(res); + } break; } break; @@ -8822,7 +8876,13 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, !define_read_attrs(curr, op)) curr += reclength; else - ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError()); + { + ERR_RETURN_PREPARE(res, + op ? op->getNdbError() : + m_active_trans->getNdbError()); + MYSQL_INDEX_READ_ROW_DONE(res); + DBUG_RETURN(res); + } break; } case ORDERED_INDEX: { @@ -8837,7 +8897,11 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, DBUG_ASSERT(scanOp->getLockMode() == (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type)); if (scanOp->reset_bounds(m_force_send)) - DBUG_RETURN(ndb_err(m_active_trans)); + { + res= ndb_err(m_active_trans); + MYSQL_INDEX_READ_ROW_DONE(res); + DBUG_RETURN(res); + } end_of_buffer -= reclength; } @@ -8852,8 +8916,11 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, } else { - ERR_RETURN(scanOp ? scanOp->getNdbError() : - m_active_trans->getNdbError()); + ERR_RETURN_PREPARE(res, + scanOp ? scanOp->getNdbError() : + m_active_trans->getNdbError()); + MYSQL_INDEX_READ_ROW_DONE(res); + DBUG_RETURN(res); } } @@ -8861,11 +8928,15 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, &multi_range_curr->end_key }; if ((res= set_bounds(scanOp, active_index, FALSE, keys, multi_range_curr-ranges))) + { + MYSQL_INDEX_READ_ROW_DONE(res); DBUG_RETURN(res); + } break; } case UNDEFINED_INDEX: DBUG_ASSERT(FALSE); + MYSQL_INDEX_READ_ROW_DONE(1); DBUG_RETURN(1); break; } @@ -8896,9 +8967,13 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, m_multi_range_defined= multi_range_curr; multi_range_curr= ranges; m_multi_range_result_ptr= (uchar*)buffer->buffer; - DBUG_RETURN(read_multi_range_next(found_range_p)); + res= loc_read_multi_range_next(found_range_p); + MYSQL_INDEX_READ_ROW_DONE(res); + DBUG_RETURN(res); } - ERR_RETURN(m_active_trans->getNdbError()); + ERR_RETURN_PREPARE(res, m_active_trans->getNdbError()); + MYSQL_INDEX_READ_ROW_DONE(res); + DBUG_RETURN(res); } #if 0 @@ -8910,17 +8985,28 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, int ha_ndbcluster::read_multi_range_next(KEY_MULTI_RANGE ** multi_range_found_p) { + int rc; DBUG_ENTER("ha_ndbcluster::read_multi_range_next"); if (m_disable_multi_read) { DBUG_MULTI_RANGE(11); DBUG_RETURN(handler::read_multi_range_next(multi_range_found_p)); } - + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= loc_read_multi_range_next(multi_range_found_p); + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); +} + +int ha_ndbcluster::loc_read_multi_range_next( + KEY_MULTI_RANGE **multi_range_found_p) +{ int res; int range_no; ulong reclength= table_share->reclength; const NdbOperation* op= m_current_multi_operation; + DBUG_ENTER("ha_ndbcluster::loc_read_multi_range_next"); + for (;multi_range_curr < m_multi_range_defined; multi_range_curr++) { DBUG_MULTI_RANGE(12); @@ -9027,6 +9113,7 @@ close_scan: /* * Read remaining ranges */ + MYSQL_INDEX_READ_ROW_DONE(1); DBUG_RETURN(read_multi_range_first(multi_range_found_p, multi_range_curr, multi_range_end - multi_range_curr, diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index a17323d3fd6..9106fd60731 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -385,6 +385,7 @@ static void set_tabname(const char *pathname, char *tabname); uint table_changes); private: + int loc_read_multi_range_next(KEY_MULTI_RANGE **found_range_p); friend int ndbcluster_drop_database_impl(const char *path); friend int ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp, diff --git a/sql/handler.cc b/sql/handler.cc index f26e84bdfdf..0832ae44a7e 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -27,6 +27,7 @@ #include "rpl_filter.h" #include <myisampack.h> #include <errno.h> +#include "probes_mysql.h" #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" @@ -4425,11 +4426,51 @@ int handler::ha_external_lock(THD *thd, int lock_type) */ DBUG_ASSERT(next_insert_id == 0); + if (MYSQL_HANDLER_RDLOCK_START_ENABLED() || + MYSQL_HANDLER_WRLOCK_START_ENABLED() || + MYSQL_HANDLER_UNLOCK_START_ENABLED()) + { + if (lock_type == F_RDLCK) + { + MYSQL_HANDLER_RDLOCK_START(table_share->db.str, + table_share->table_name.str); + } + else if (lock_type == F_WRLCK) + { + MYSQL_HANDLER_WRLOCK_START(table_share->db.str, + table_share->table_name.str); + } + else if (lock_type == F_UNLCK) + { + MYSQL_HANDLER_UNLOCK_START(table_share->db.str, + table_share->table_name.str); + } + } + /* We cache the table flags if the locking succeeded. Otherwise, we keep them as they were when they were fetched in ha_open(). */ int error= external_lock(thd, lock_type); + + if (MYSQL_HANDLER_RDLOCK_DONE_ENABLED() || + MYSQL_HANDLER_WRLOCK_DONE_ENABLED() || + MYSQL_HANDLER_UNLOCK_DONE_ENABLED()) + { + if (lock_type == F_RDLCK) + { + MYSQL_HANDLER_RDLOCK_DONE(error); + } + else if (lock_type == F_WRLCK) + { + MYSQL_HANDLER_WRLOCK_DONE(error); + } + else if (lock_type == F_UNLCK) + { + MYSQL_HANDLER_UNLOCK_DONE(error); + } + } + if (error == 0) cached_table_flags= table_flags(); DBUG_RETURN(error); @@ -4464,10 +4505,14 @@ int handler::ha_write_row(uchar *buf) Log_func *log_func= Write_rows_log_event::binlog_row_logging_function; DBUG_ENTER("handler::ha_write_row"); + MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str); mark_trx_read_write(); - if (unlikely(error= write_row(buf))) + error= write_row(buf); + MYSQL_INSERT_ROW_DONE(error); + if (unlikely(error)) DBUG_RETURN(error); + if (unlikely(error= binlog_log_row(table, 0, buf, log_func))) DBUG_RETURN(error); /* purecov: inspected */ DBUG_RETURN(0); @@ -4485,9 +4530,12 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data) */ DBUG_ASSERT(new_data == table->record[0]); + MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str); mark_trx_read_write(); - if (unlikely(error= update_row(old_data, new_data))) + error= update_row(old_data, new_data); + MYSQL_UPDATE_ROW_DONE(error); + if (unlikely(error)) return error; if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func))) return error; @@ -4499,9 +4547,12 @@ int handler::ha_delete_row(const uchar *buf) int error; Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function; + MYSQL_DELETE_ROW_START(table_share->db.str, table_share->table_name.str); mark_trx_read_write(); - if (unlikely(error= delete_row(buf))) + error= delete_row(buf); + MYSQL_DELETE_ROW_DONE(error); + if (unlikely(error)) return error; if (unlikely(error= binlog_log_row(table, buf, 0, log_func))) return error; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 13338e34ddb..f31cc1b3eac 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1218,7 +1218,8 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields, List<Item> &values,COND *conds, uint order_num, ORDER *order, ha_rows limit, - enum enum_duplicates handle_duplicates, bool ignore); + enum enum_duplicates handle_duplicates, bool ignore, + ha_rows *found_return, ha_rows *updated_return); bool mysql_multi_update(THD *thd, TABLE_LIST *table_list, List<Item> *fields, List<Item> *values, COND *conds, ulonglong options, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5e28b8bea6d..8b1939baa0e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -26,6 +26,7 @@ #include "mysqld_suffix.h" #include "mysys_err.h" #include "events.h" +#include "probes_mysql.h" #include "../storage/myisam/ha_myisam.h" @@ -1757,6 +1758,7 @@ void close_connection(THD *thd, uint errcode, bool lock) } if (lock) (void) pthread_mutex_unlock(&LOCK_thread_count); + MYSQL_CONNECTION_DONE((int) errcode, thd->thread_id); DBUG_VOID_RETURN; } #endif /* EMBEDDED_LIBRARY */ diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 1098e8e6832..19645786433 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -48,6 +48,7 @@ #include <violite.h> #include <signal.h> #include <errno.h> +#include "probes_mysql.h" #ifdef __NETWARE__ #include <sys/select.h> #endif @@ -368,8 +369,13 @@ my_bool my_net_write(NET *net,const uchar *packet,size_t len) { uchar buff[NET_HEADER_SIZE]; + int rc; + if (unlikely(!net->vio)) /* nowhere to write */ return 0; + + MYSQL_NET_WRITE_START(len); + /* Big packets are handled by splitting them in packets of MAX_PACKET_LENGTH length. The last packet is always a packet that is < MAX_PACKET_LENGTH. @@ -382,7 +388,10 @@ my_net_write(NET *net,const uchar *packet,size_t len) buff[3]= (uchar) net->pkt_nr++; if (net_write_buff(net, buff, NET_HEADER_SIZE) || net_write_buff(net, packet, z_size)) + { + MYSQL_NET_WRITE_DONE(1); return 1; + } packet += z_size; len-= z_size; } @@ -390,11 +399,16 @@ my_net_write(NET *net,const uchar *packet,size_t len) int3store(buff,len); buff[3]= (uchar) net->pkt_nr++; if (net_write_buff(net, buff, NET_HEADER_SIZE)) + { + MYSQL_NET_WRITE_DONE(1); return 1; + } #ifndef DEBUG_DATA_PACKETS DBUG_DUMP("packet_header", buff, NET_HEADER_SIZE); #endif - return test(net_write_buff(net,packet,len)); + rc= test(net_write_buff(net,packet,len)); + MYSQL_NET_WRITE_DONE(rc); + return rc; } /** @@ -432,9 +446,12 @@ net_write_command(NET *net,uchar command, ulong length=len+1+head_len; /* 1 extra byte for command */ uchar buff[NET_HEADER_SIZE+1]; uint header_size=NET_HEADER_SIZE+1; + int rc; DBUG_ENTER("net_write_command"); DBUG_PRINT("enter",("length: %lu", (ulong) len)); + MYSQL_NET_WRITE_START(length); + buff[4]=command; /* For first packet */ if (length >= MAX_PACKET_LENGTH) @@ -448,7 +465,10 @@ net_write_command(NET *net,uchar command, if (net_write_buff(net, buff, header_size) || net_write_buff(net, header, head_len) || net_write_buff(net, packet, len)) + { + MYSQL_NET_WRITE_DONE(1); DBUG_RETURN(1); + } packet+= len; length-= MAX_PACKET_LENGTH; len= MAX_PACKET_LENGTH; @@ -459,9 +479,11 @@ net_write_command(NET *net,uchar command, } int3store(buff,length); buff[3]= (uchar) net->pkt_nr++; - DBUG_RETURN(test(net_write_buff(net, buff, header_size) || - (head_len && net_write_buff(net, header, head_len)) || - net_write_buff(net, packet, len) || net_flush(net))); + rc= test(net_write_buff(net, buff, header_size) || + (head_len && net_write_buff(net, header, head_len)) || + net_write_buff(net, packet, len) || net_flush(net)); + MYSQL_NET_WRITE_DONE(rc); + return rc; } /** @@ -989,6 +1011,8 @@ my_net_read(NET *net) { size_t len, complen; + MYSQL_NET_READ_START(); + #ifdef HAVE_COMPRESS if (!net->compress) { @@ -1012,6 +1036,7 @@ my_net_read(NET *net) net->read_pos = net->buff + net->where_b; if (len != packet_error) net->read_pos[len]=0; /* Safeguard for mysql_use_result */ + MYSQL_NET_READ_DONE(0, len); return len; #ifdef HAVE_COMPRESS } @@ -1095,7 +1120,10 @@ my_net_read(NET *net) net->where_b=buf_length; if ((packet_len = my_real_read(net,&complen)) == packet_error) + { + MYSQL_NET_READ_DONE(1, 0); return packet_error; + } if (my_uncompress(net->buff + net->where_b, packet_len, &complen)) { @@ -1104,6 +1132,7 @@ my_net_read(NET *net) #ifdef MYSQL_SERVER my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0)); #endif + MYSQL_NET_READ_DONE(1, 0); return packet_error; } buf_length+= complen; @@ -1118,6 +1147,7 @@ my_net_read(NET *net) net->read_pos[len]=0; /* Safeguard for mysql_use_result */ } #endif /* HAVE_COMPRESS */ + MYSQL_NET_READ_DONE(0, len); return len; } diff --git a/sql/probes_mysql.d b/sql/probes_mysql.d new file mode 100644 index 00000000000..958e3042dde --- /dev/null +++ b/sql/probes_mysql.d @@ -0,0 +1,176 @@ +/* Copyright (C) 2008 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + The actual probe names in DTrace scripts will replace '__' by '-'. Thus + insert__row__start will be insert-row-start. + + Recommendations for adding new probes: + + - each probe should have the minimal set of arguments required to + unambiguously identify the context in which the probe fires. Redundant + arguments (i.e. the ones that can be obtained in user scripts from previous + probes' arguments or otherwise) may be added for convenience. + + - try to avoid computationally expensive probe arguments. If impossible, + use *_ENABLED() macros to check if the probe is activated before + performing expensive calculations for a probe argument. + + - all *-done probes should have a status argument wherever applicable to make + it possible for user scripts to figure out whether the completed operation + was successful or not. + + - for all status arguments, a non-zero value should be returned on error or + failure, 0 should be returned on success. +*/ + +provider mysql { + + /* The following ones fire when creating or closing a client connection */ + probe connection__start(unsigned long conn_id, char *user, char *host); + probe connection__done(int status, unsigned long conn_id); + + /* + Fire at the start/end of any client command processing (including SQL + queries). + */ + probe command__start(unsigned long conn_id, int command, + char *user, char *host); + probe command__done(int status); + + /* + The following probes fire at the start/end of any SQL query processing, + respectively. + + query_start() has a lot of parameters that can be used to pick up + parameters for a lot of other probes here. For simplicity reasons we also + add the query string to most other DTrace probes as well. Hostname is + either the hostname or the IP address of the MySQL Client. + */ + probe query__start(char *query, + unsigned long conn_id, + char *db_name, + char *user, + char *host); + probe query__done(int status); + + /* Fire at the start/end of SQL query parsing */ + probe query__parse__start(char *query); + probe query__parse__done(int status); + + /* Track whether the query hits the query cache or not */ + probe query__cache__hit(char *query, unsigned long rows); + probe query__cache__miss(char *query); + + /* + This probe fires when the actual query execution starts, i.e. after + parsing and checking the query cache, but before privilege checks, + optimizing, etc. + + Query means also all independent queries of a stored procedure and prepared + statements. Also the stored procedure itself is a query. + + exec_type is: + 0: Executed query from sql_parse, top-level query (sql_parse.cc) + 1: Executed prepared statement (sql_prepare.cc) + 2: Executed cursor statement (sql_cursor.cc) + 3: Executed query in stored procedure (sp_head.cc) + */ + probe query__exec__start(char *query, + unsigned long connid, + char *db_name, + char *user, + char *host, + int exec_type); + probe query__exec__done(int status); + + /* These probes fire when performing row operations towards any handler */ + probe insert__row__start(char *db, char *table); + probe insert__row__done(int status); + probe update__row__start(char *db, char *table); + probe update__row__done(int status); + probe delete__row__start(char *db, char *table); + probe delete__row__done(int status); + probe read__row__start(char *db, char *table, int scan_flag); + probe read__row__done(int status); + probe index__read__row__start(char *db, char *table); + probe index__read__row__done(int status); + + /* + These probes fire when calling external_lock for any handler + depending on the lock type being acquired or released. + */ + probe handler__rdlock__start(char *db, char *table); + probe handler__wrlock__start(char *db, char *table); + probe handler__unlock__start(char *db, char *table); + probe handler__rdlock__done(int status); + probe handler__wrlock__done(int status); + probe handler__unlock__done(int status); + + /* + These probes fire when a filesort activity happens in a query. + */ + probe filesort__start(char *db, char *table); + probe filesort__done(int status, unsigned long rows); + /* + The query types SELECT, INSERT, INSERT AS SELECT, UPDATE, UPDATE with + multiple tables, DELETE, DELETE with multiple tables are all probed. + The start probe always contains the query text. + */ + probe select__start(char *query); + probe select__done(int status, unsigned long rows); + probe insert__start(char *query); + probe insert__done(int status, unsigned long rows); + probe insert__select__start(char *query); + probe insert__select__done(int status, unsigned long rows); + probe update__start(char *query); + probe update__done(int status, + unsigned long rowsmatches, unsigned long rowschanged); + probe multi__update__start(char *query); + probe multi__update__done(int status, + unsigned long rowsmatches, + unsigned long rowschanged); + probe delete__start(char *query); + probe delete__done(int status, unsigned long rows); + probe multi__delete__start(char *query); + probe multi__delete__done(int status, unsigned long rows); + + /* + These probes can be used to measure the time waiting for network traffic + or identify network-related problems. + */ + probe net__read__start(); + probe net__read__done(int status, unsigned long bytes); + probe net__write__start(unsigned long bytes); + probe net__write__done(int status); + + /* MyISAM Key cache probes */ + probe keycache__read__start(char *filepath, unsigned long bytes, + unsigned long mem_used, unsigned long mem_free); + probe keycache__read__block(unsigned long bytes); + probe keycache__read__hit(); + probe keycache__read__miss(); + probe keycache__read__done(unsigned long mem_used, unsigned long mem_free); + probe keycache__write__start(char *filepath, unsigned long bytes, + unsigned long mem_used, unsigned long mem_free); + probe keycache__write__block(unsigned long bytes); + probe keycache__write__done(unsigned long mem_used, unsigned long mem_free); +}; + +#pragma D attributes Evolving/Evolving/Common provider mysql provider +#pragma D attributes Evolving/Evolving/Common provider mysql module +#pragma D attributes Evolving/Evolving/Common provider mysql function +#pragma D attributes Evolving/Evolving/Common provider mysql name +#pragma D attributes Evolving/Evolving/Common provider mysql args diff --git a/sql/sp_head.cc b/sql/sp_head.cc index d1f920fd3a5..edb5b9863a6 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -14,6 +14,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mysql_priv.h" +#include "probes_mysql.h" #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation #endif @@ -2889,7 +2890,14 @@ sp_instr_stmt::print(String *str) int sp_instr_stmt::exec_core(THD *thd, uint *nextp) { + MYSQL_QUERY_EXEC_START(thd->query, + thd->thread_id, + (char *) (thd->db ? thd->db : ""), + thd->security_ctx->priv_user, + thd->security_ctx->host_or_ip, + 3); int res= mysql_execute_command(thd); + MYSQL_QUERY_EXEC_DONE(res); *nextp= m_ip+1; return res; } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index ec65ba66fa5..42afe885c3d 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -333,6 +333,7 @@ TODO list: #include <hash.h> #include "../storage/myisammrg/ha_myisammrg.h" #include "../storage/myisammrg/myrg_def.h" +#include "probes_mysql.h" #ifdef EMBEDDED_LIBRARY #include "emb_qcache.h" @@ -1476,11 +1477,13 @@ def_week_frmt: %lu", thd->main_da.disable_status(); BLOCK_UNLOCK_RD(query_block); + MYSQL_QUERY_CACHE_HIT(thd->query, (ulong) thd->limit_found_rows); DBUG_RETURN(1); // Result sent to client err_unlock: STRUCT_UNLOCK(&structure_guard_mutex); err: + MYSQL_QUERY_CACHE_MISS(thd->query); DBUG_RETURN(0); // Query was not cached } diff --git a/sql/sql_class.h b/sql/sql_class.h index 019699dff5a..21c36cfc09a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2788,6 +2788,10 @@ public: void send_error(uint errcode,const char *err); int do_deletes(); bool send_eof(); + inline ha_rows num_deleted() + { + return deleted; + } virtual void abort(); }; @@ -2831,6 +2835,14 @@ public: void send_error(uint errcode,const char *err); int do_updates(); bool send_eof(); + inline ha_rows num_found() + { + return found; + } + inline ha_rows num_updated() + { + return updated; + } virtual void abort(); }; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index d9fb586eb77..02c8297d019 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -19,6 +19,7 @@ */ #include "mysql_priv.h" +#include "probes_mysql.h" #ifdef HAVE_OPENSSL /* @@ -1107,6 +1108,9 @@ pthread_handler_t handle_one_connection(void *arg) if (login_connection(thd)) goto end_thread; + MYSQL_CONNECTION_START(thd->thread_id, thd->security_ctx->priv_user, + (char *) thd->security_ctx->host_or_ip); + prepare_new_connection_state(thd); while (!net->error && net->vio != 0 && diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 7c530cb9013..1f6c9fdee53 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -19,6 +19,7 @@ #include "mysql_priv.h" #include "sql_cursor.h" #include "sql_select.h" +#include "probes_mysql.h" /**************************************************************************** Declarations. @@ -167,8 +168,14 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result, thd->lock_id= sensitive_cursor->get_lock_id(); thd->cursor= sensitive_cursor; } - + MYSQL_QUERY_EXEC_START(thd->query, + thd->thread_id, + (char *) (thd->db ? thd->db : ""), + thd->security_ctx->priv_user, + (char *) thd->security_ctx->host_or_ip, + 2); rc= mysql_execute_command(thd); + MYSQL_QUERY_EXEC_DONE(rc); lex->result= save_result; thd->lock_id= &thd->main_lock_id; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9f94893ffe3..4bd6640d3e0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -27,6 +27,7 @@ #include "sp_cache.h" #include "events.h" #include "sql_trigger.h" +#include "probes_mysql.h" /** @defgroup Runtime_Environment Runtime Environment @@ -913,6 +914,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, DBUG_ENTER("dispatch_command"); DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command)); + MYSQL_COMMAND_START(thd->thread_id, command, + thd->security_ctx->priv_user, + (char *) thd->security_ctx->host_or_ip); + thd->command=command; /* Commands which always take a long time are logged into @@ -1136,6 +1141,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { if (alloc_query(thd, packet, packet_length)) break; // fatal error is set + MYSQL_QUERY_START(thd->query, thd->thread_id, + (char *) (thd->db ? thd->db : ""), + thd->security_ctx->priv_user, + (char *) thd->security_ctx->host_or_ip); char *packet_end= thd->query + thd->query_length; /* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */ const char* end_of_stmt= NULL; @@ -1172,12 +1181,22 @@ bool dispatch_command(enum enum_server_command command, THD *thd, length--; } + if (MYSQL_QUERY_DONE_ENABLED()) + { + MYSQL_QUERY_DONE(thd->is_error()); + } + #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) thd->profiling.finish_current_query(); thd->profiling.start_new_query("continuing"); thd->profiling.set_query_source(beginning_of_next_stmt, length); #endif + MYSQL_QUERY_START(thd->query, thd->thread_id, + (char *) (thd->db ? thd->db : ""), + thd->security_ctx->priv_user, + (char *) thd->security_ctx->host_or_ip); + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_length= length; thd->query= beginning_of_next_stmt; @@ -1534,6 +1553,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd, VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); + + if (MYSQL_QUERY_DONE_ENABLED() || MYSQL_COMMAND_DONE_ENABLED()) + { + int res; + res= (int) thd->is_error(); + if (command == COM_QUERY) + { + MYSQL_QUERY_DONE(res); + } + MYSQL_COMMAND_DONE(res); + } DBUG_RETURN(error); } @@ -2896,11 +2926,14 @@ end_with_restore_list: break; } case SQLCOM_UPDATE: + { + ha_rows found= 0, updated= 0; DBUG_ASSERT(first_table == all_tables && first_table != 0); if (update_precheck(thd, all_tables)) break; DBUG_ASSERT(select_lex->offset_limit == 0); unit->set_limit(select_lex); + MYSQL_UPDATE_START(thd->query); res= (up_result= mysql_update(thd, all_tables, select_lex->item_list, lex->value_list, @@ -2908,11 +2941,14 @@ end_with_restore_list: select_lex->order_list.elements, (ORDER *) select_lex->order_list.first, unit->select_limit_cnt, - lex->duplicates, lex->ignore)); + lex->duplicates, lex->ignore, + &found, &updated)); + MYSQL_UPDATE_DONE(res, found, updated); /* mysql_update return 2 if we need to switch to multi-update */ if (up_result != 2) break; /* Fall through */ + } case SQLCOM_UPDATE_MULTI: { DBUG_ASSERT(first_table == all_tables && first_table != 0); @@ -2960,7 +2996,7 @@ end_with_restore_list: #ifdef HAVE_REPLICATION } /* unlikely */ #endif - + MYSQL_MULTI_UPDATE_START(thd->query); res= mysql_multi_update(thd, all_tables, &select_lex->item_list, &lex->value_list, @@ -3012,11 +3048,11 @@ end_with_restore_list: res= 1; break; } - + MYSQL_INSERT_START(thd->query); res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values, lex->update_list, lex->value_list, lex->duplicates, lex->ignore); - + MYSQL_INSERT_DONE(res, (ulong) thd->row_count_func); /* If we have inserted into a VIEW, and the base table has AUTO_INCREMENT column, but this column is not accessible through @@ -3052,9 +3088,9 @@ end_with_restore_list: res= 1; break; } - if (!(res= open_and_lock_tables(thd, all_tables))) { + MYSQL_INSERT_SELECT_START(thd->query); /* Skip first table, which is the table we are inserting in */ TABLE_LIST *second_table= first_table->next_local; select_lex->table_list.first= (uchar*) second_table; @@ -3088,9 +3124,9 @@ end_with_restore_list: delete sel_result; } /* revert changes for SP */ + MYSQL_INSERT_SELECT_DONE(res, (ulong) thd->row_count_func); select_lex->table_list.first= (uchar*) first_table; } - /* If we have inserted into a VIEW, and the base table has AUTO_INCREMENT column, but this column is not accessible through @@ -3139,11 +3175,12 @@ end_with_restore_list: res= 1; break; } - + MYSQL_DELETE_START(thd->query); res = mysql_delete(thd, all_tables, select_lex->where, &select_lex->order_list, unit->select_limit_cnt, select_lex->options, FALSE); + MYSQL_DELETE_DONE(res, (ulong) thd->row_count_func); break; } case SQLCOM_DELETE_MULTI: @@ -3173,8 +3210,12 @@ end_with_restore_list: if ((res= open_and_lock_tables(thd, all_tables))) break; + MYSQL_MULTI_DELETE_START(thd->query); if ((res= mysql_multi_delete_prepare(thd))) + { + MYSQL_MULTI_DELETE_DONE(1, 0); goto error; + } if (!thd->is_fatal_error && (del_result= new multi_delete(aux_tables, lex->table_count))) @@ -3191,12 +3232,16 @@ end_with_restore_list: OPTION_SETUP_TABLES_DONE, del_result, unit, select_lex); res|= thd->is_error(); + MYSQL_MULTI_DELETE_DONE(res, del_result->num_deleted()); if (res) del_result->abort(); delete del_result; } else + { res= TRUE; // Error + MYSQL_MULTI_DELETE_DONE(1, 0); + } break; } case SQLCOM_DROP_TABLE: @@ -5652,6 +5697,7 @@ void mysql_init_multi_delete(LEX *lex) void mysql_parse(THD *thd, const char *inBuf, uint length, const char ** found_semicolon) { + int error; DBUG_ENTER("mysql_parse"); DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on();); @@ -5720,7 +5766,15 @@ void mysql_parse(THD *thd, const char *inBuf, uint length, thd->server_status|= SERVER_MORE_RESULTS_EXISTS; } lex->set_trg_event_type_for_tables(); - mysql_execute_command(thd); + MYSQL_QUERY_EXEC_START(thd->query, + thd->thread_id, + (char *) (thd->db ? thd->db : ""), + thd->security_ctx->priv_user, + (char *) thd->security_ctx->host_or_ip, + 0); + + error= mysql_execute_command(thd); + MYSQL_QUERY_EXEC_DONE(error); } } } @@ -7523,8 +7577,10 @@ bool parse_sql(THD *thd, Parser_state *parser_state, Object_creation_ctx *creation_ctx) { + bool ret_value; DBUG_ASSERT(thd->m_parser_state == NULL); + MYSQL_QUERY_PARSE_START(thd->query); /* Backup creation context. */ Object_creation_ctx *backup_ctx= NULL; @@ -7556,7 +7612,9 @@ bool parse_sql(THD *thd, /* That's it. */ - return mysql_parse_status || thd->is_fatal_error; + ret_value= mysql_parse_status || thd->is_fatal_error; + MYSQL_QUERY_PARSE_DONE(ret_value); + return ret_value; } /** diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 7fcc374e3f3..0ae902bcd0a 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -89,6 +89,7 @@ When one supplies long data for a placeholder: #include "sp_head.h" #include "sp.h" #include "sp_cache.h" +#include "probes_mysql.h" #ifdef EMBEDDED_LIBRARY /* include MYSQL_BIND headers */ #include <mysql.h> @@ -3565,7 +3566,14 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) if (query_cache_send_result_to_client(thd, thd->query, thd->query_length) <= 0) { + MYSQL_QUERY_EXEC_START(thd->query, + thd->thread_id, + (char *) (thd->db ? thd->db : ""), + thd->security_ctx->priv_user, + (char *) thd->security_ctx->host_or_ip, + 1); error= mysql_execute_command(thd); + MYSQL_QUERY_EXEC_DONE(error); } } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6510d2428db..27298419c40 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -31,6 +31,7 @@ #include "mysql_priv.h" #include "sql_select.h" #include "sql_cursor.h" +#include "probes_mysql.h" #include <m_ctype.h> #include <my_bit.h> @@ -241,6 +242,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result, bool res; register SELECT_LEX *select_lex = &lex->select_lex; DBUG_ENTER("handle_select"); + MYSQL_SELECT_START(thd->query); if (select_lex->master_unit()->is_union() || select_lex->master_unit()->fake_select_lex) @@ -274,6 +276,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result, if (unlikely(res)) result->abort(); + MYSQL_SELECT_DONE((int) res, (ulong) thd->limit_found_rows); DBUG_RETURN(res); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index b9ad88ee663..bfa774a75b1 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -23,6 +23,7 @@ #include "sql_select.h" #include "sp_head.h" #include "sql_trigger.h" +#include "probes_mysql.h" /* Return 0 if row hasn't changed */ @@ -180,7 +181,8 @@ int mysql_update(THD *thd, COND *conds, uint order_num, ORDER *order, ha_rows limit, - enum enum_duplicates handle_duplicates, bool ignore) + enum enum_duplicates handle_duplicates, bool ignore, + ha_rows *found_return, ha_rows *updated_return) { bool using_limit= limit != HA_POS_ERROR; bool safe_update= test(thd->options & OPTION_SAFE_UPDATES); @@ -820,6 +822,8 @@ int mysql_update(THD *thd, } thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */ thd->abort_on_warning= 0; + *found_return= found; + *updated_return= updated; DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0); err: @@ -1164,7 +1168,10 @@ bool mysql_multi_update(THD *thd, thd->lex->select_lex.leaf_tables, fields, values, handle_duplicates, ignore))) + { + MYSQL_MULTI_UPDATE_DONE(1, 0, 0); DBUG_RETURN(TRUE); + } thd->abort_on_warning= test(thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | @@ -1188,6 +1195,7 @@ bool mysql_multi_update(THD *thd, result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR)); result->abort(); } + MYSQL_MULTI_UPDATE_DONE(res, result->found(), result->updated()); delete result; thd->abort_on_warning= 0; DBUG_RETURN(FALSE); diff --git a/storage/archive/Makefile.am b/storage/archive/Makefile.am index d092f091798..aa2ba58ce25 100644 --- a/storage/archive/Makefile.am +++ b/storage/archive/Makefile.am @@ -66,5 +66,22 @@ archive_reader_LDFLAGS = @NOINST_LDFLAGS@ EXTRA_DIST = CMakeLists.txt plug.in + +if HAVE_DTRACE_DASH_G +abs_top_srcdir = @abs_top_srcdir@ +libarchive_a_LIBADD = probes_mysql.o +libarchive_a_DEPENDENCIES = probes_mysql.o dtrace_files dtrace_providers +CLEANFILES = probes_mysql.o dtrace_files dtrace_providers +DTRACEFILES = libarchive_a-ha_archive.o +DTRACEPROVIDER = $(abs_top_srcdir)/sql/probes_mysql.d + +dtrace_files: + echo $(DTRACEFILES) > $@ +dtrace_providers: + echo $(DTRACEPROVIDER) > $@ +probes_mysql.o: $(DTRACEPROVIDER) $(DTRACEFILES) + $(DTRACE) $(DTRACEFLAGS) -G -s $< $(DTRACEFILES) -o $@ +endif + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 967e315d4a4..7dc02e95c62 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -18,6 +18,7 @@ #endif #include "mysql_priv.h" +#include "probes_mysql.h" #include <myisam.h> #include "ha_archive.h" @@ -917,7 +918,9 @@ int ha_archive::index_read(uchar *buf, const uchar *key, { int rc; DBUG_ENTER("ha_archive::index_read"); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); rc= index_read_idx(buf, active_index, key, key_len, find_flag); + MYSQL_INDEX_READ_ROW_DONE(rc); DBUG_RETURN(rc); } @@ -960,8 +963,10 @@ error: int ha_archive::index_next(uchar * buf) { bool found= 0; + int rc; DBUG_ENTER("ha_archive::index_next"); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); while (!(get_row(&archive, buf))) { @@ -972,7 +977,9 @@ int ha_archive::index_next(uchar * buf) } } - DBUG_RETURN(found ? 0 : HA_ERR_END_OF_FILE); + rc= found ? 0 : HA_ERR_END_OF_FILE; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } /* @@ -1196,12 +1203,17 @@ int ha_archive::rnd_next(uchar *buf) { int rc; DBUG_ENTER("ha_archive::rnd_next"); + MYSQL_READ_ROW_START(table_share->db.str, + table_share->table_name.str, TRUE); if (share->crashed) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); if (!scan_rows) - DBUG_RETURN(HA_ERR_END_OF_FILE); + { + rc= HA_ERR_END_OF_FILE; + goto end; + } scan_rows--; ha_statistic_increment(&SSV::ha_read_rnd_next_count); @@ -1210,6 +1222,8 @@ int ha_archive::rnd_next(uchar *buf) table->status=rc ? STATUS_NOT_FOUND: 0; +end: + MYSQL_READ_ROW_DONE(rc); DBUG_RETURN(rc); } @@ -1237,12 +1251,21 @@ void ha_archive::position(const uchar *record) int ha_archive::rnd_pos(uchar * buf, uchar *pos) { + int rc; DBUG_ENTER("ha_archive::rnd_pos"); + MYSQL_READ_ROW_START(table_share->db.str, + table_share->table_name.str, FALSE); ha_statistic_increment(&SSV::ha_read_rnd_next_count); current_position= (my_off_t)my_get_ptr(pos, ref_length); if (azseek(&archive, current_position, SEEK_SET) == (my_off_t)(-1L)) - DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); - DBUG_RETURN(get_row(&archive, buf)); + { + rc= HA_ERR_CRASHED_ON_USAGE; + goto end; + } + rc= get_row(&archive, buf); +end: + MYSQL_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } /* diff --git a/storage/blackhole/Makefile.am b/storage/blackhole/Makefile.am index db4f67cf847..71776b01639 100644 --- a/storage/blackhole/Makefile.am +++ b/storage/blackhole/Makefile.am @@ -48,5 +48,22 @@ libblackhole_a_SOURCES= ha_blackhole.cc EXTRA_DIST = CMakeLists.txt plug.in + +if HAVE_DTRACE_DASH_G +abs_top_srcdir = @abs_top_srcdir@ +libblackhole_a_LIBADD = probes_mysql.o +libblackhole_a_DEPENDENCIES = probes_mysql.o dtrace_files dtrace_providers +CLEANFILES = probes_mysql.o dtrace_files dtrace_providers +DTRACEFILES = libblackhole_a-ha_blackhole.o +DTRACEPROVIDER = $(abs_top_srcdir)/sql/probes_mysql.d + +dtrace_files: + echo $(DTRACEFILES) > $@ +dtrace_providers: + echo $(DTRACEPROVIDER) > $@ +probes_mysql.o: $(DTRACEPROVIDER) $(DTRACEFILES) + $(DTRACE) $(DTRACEFLAGS) -G -s $< $(DTRACEFILES) -o $@ +endif + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index 85b8117e501..6ca3b8d3ab0 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -19,6 +19,7 @@ #endif #include "mysql_priv.h" +#include "probes_mysql.h" #include "ha_blackhole.h" /* Static declarations for handlerton */ @@ -109,15 +110,23 @@ int ha_blackhole::rnd_init(bool scan) int ha_blackhole::rnd_next(uchar *buf) { + int rc; DBUG_ENTER("ha_blackhole::rnd_next"); - DBUG_RETURN(HA_ERR_END_OF_FILE); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + TRUE); + rc= HA_ERR_END_OF_FILE; + MYSQL_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_blackhole::rnd_pos(uchar * buf, uchar *pos) { DBUG_ENTER("ha_blackhole::rnd_pos"); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + FALSE); DBUG_ASSERT(0); + MYSQL_READ_ROW_DONE(0); DBUG_RETURN(0); } @@ -188,8 +197,12 @@ int ha_blackhole::index_read_map(uchar * buf, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) { + int rc; DBUG_ENTER("ha_blackhole::index_read"); - DBUG_RETURN(HA_ERR_END_OF_FILE); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_END_OF_FILE; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } @@ -197,44 +210,69 @@ int ha_blackhole::index_read_idx_map(uchar * buf, uint idx, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) { + int rc; DBUG_ENTER("ha_blackhole::index_read_idx"); - DBUG_RETURN(HA_ERR_END_OF_FILE); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_END_OF_FILE; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_blackhole::index_read_last_map(uchar * buf, const uchar * key, key_part_map keypart_map) { + int rc; DBUG_ENTER("ha_blackhole::index_read_last"); - DBUG_RETURN(HA_ERR_END_OF_FILE); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_END_OF_FILE; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_blackhole::index_next(uchar * buf) { + int rc; DBUG_ENTER("ha_blackhole::index_next"); - DBUG_RETURN(HA_ERR_END_OF_FILE); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_END_OF_FILE; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_blackhole::index_prev(uchar * buf) { + int rc; DBUG_ENTER("ha_blackhole::index_prev"); - DBUG_RETURN(HA_ERR_END_OF_FILE); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_END_OF_FILE; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } int ha_blackhole::index_first(uchar * buf) { + int rc; DBUG_ENTER("ha_blackhole::index_first"); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_END_OF_FILE; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); DBUG_RETURN(HA_ERR_END_OF_FILE); } int ha_blackhole::index_last(uchar * buf) { + int rc; DBUG_ENTER("ha_blackhole::index_last"); - DBUG_RETURN(HA_ERR_END_OF_FILE); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_END_OF_FILE; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } diff --git a/storage/csv/Makefile.am b/storage/csv/Makefile.am index 07ffac88a96..e4d90334d64 100644 --- a/storage/csv/Makefile.am +++ b/storage/csv/Makefile.am @@ -41,5 +41,22 @@ libcsv_a_CXXFLAGS = $(AM_CFLAGS) libcsv_a_SOURCES = transparent_file.cc ha_tina.cc EXTRA_DIST = CMakeLists.txt plug.in + +if HAVE_DTRACE_DASH_G +abs_top_srcdir = @abs_top_srcdir@ +libcsv_a_LIBADD = probes_mysql.o +libcsv_a_DEPENDENCIES = probes_mysql.o dtrace_files dtrace_providers +CLEANFILES = probes_mysql.o dtrace_files dtrace_providers +DTRACEFILES = libcsv_a-ha_tina.o +DTRACEPROVIDER = $(abs_top_srcdir)/sql/probes_mysql.d + +dtrace_files: + echo $(DTRACEFILES) > $@ +dtrace_providers: + echo $(DTRACEPROVIDER) > $@ +probes_mysql.o: $(DTRACEPROVIDER) $(DTRACEFILES) + $(DTRACE) $(DTRACEFLAGS) -G -s $< $(DTRACEFILES) -o $@ +endif + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index a1ff0e29ad1..cc801b33955 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -48,6 +48,7 @@ TODO: #include "mysql_priv.h" #include <mysql/plugin.h> #include "ha_tina.h" +#include "probes_mysql.h" /* @@ -1095,9 +1096,14 @@ int ha_tina::rnd_next(uchar *buf) { int rc; DBUG_ENTER("ha_tina::rnd_next"); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + TRUE); if (share->crashed) - DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + { + rc= HA_ERR_CRASHED_ON_USAGE; + goto end; + } ha_statistic_increment(&SSV::ha_read_rnd_next_count); @@ -1105,13 +1111,19 @@ int ha_tina::rnd_next(uchar *buf) /* don't scan an empty file */ if (!local_saved_data_file_length) - DBUG_RETURN(HA_ERR_END_OF_FILE); + { + rc= HA_ERR_END_OF_FILE; + goto end; + } if ((rc= find_current_row(buf))) - DBUG_RETURN(rc); + goto end; stats.records++; - DBUG_RETURN(0); + rc= 0; +end: + MYSQL_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } /* @@ -1138,10 +1150,15 @@ void ha_tina::position(const uchar *record) int ha_tina::rnd_pos(uchar * buf, uchar *pos) { + int rc; DBUG_ENTER("ha_tina::rnd_pos"); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + FALSE); ha_statistic_increment(&SSV::ha_read_rnd_count); current_position= (off_t)my_get_ptr(pos,ref_length); - DBUG_RETURN(find_current_row(buf)); + rc= find_current_row(buf); + MYSQL_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } /* diff --git a/storage/example/Makefile.am b/storage/example/Makefile.am index 4b2f165377c..bb350dc3639 100644 --- a/storage/example/Makefile.am +++ b/storage/example/Makefile.am @@ -48,5 +48,22 @@ libexample_a_SOURCES= ha_example.cc EXTRA_DIST = CMakeLists.txt plug.in + +if HAVE_DTRACE_DASH_G +libexample_a_LIBADD = probes_mysql.o +libexample_a_DEPENDENCIES = probes_mysql.o +CLEANFILES = +BUILT_SOURCES = +DTRACEFILES = libexample_a-ha_example.o +DTRACEPROVIDER = $(abs_top_srcdir)/sql/probes_mysql.d + +dtrace_files: + echo $(DTRACEFILES) > $@ +dtrace_providers: + echo $(DTRACEPROVIDER) > $@ +probes_mysql.o: $(DTRACEPROVIDER) $(DTRACEFILES) + $(DTRACE) $(DTRACEFLAGS) -G -s $< $(DTRACEFILES) -o $@ +endif + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index 604722c3c8c..30fc82c82d2 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -94,6 +94,7 @@ #define MYSQL_SERVER 1 #include "mysql_priv.h" #include "ha_example.h" +#include "probes_mysql.h" #include <mysql/plugin.h> static handler *example_create_handler(handlerton *hton, @@ -428,8 +429,12 @@ int ha_example::index_read_map(uchar *buf, const uchar *key, enum ha_rkey_function find_flag __attribute__((unused))) { + int rc; DBUG_ENTER("ha_example::index_read"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_WRONG_COMMAND; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } @@ -440,8 +445,12 @@ int ha_example::index_read_map(uchar *buf, const uchar *key, int ha_example::index_next(uchar *buf) { + int rc; DBUG_ENTER("ha_example::index_next"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_WRONG_COMMAND; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } @@ -452,8 +461,12 @@ int ha_example::index_next(uchar *buf) int ha_example::index_prev(uchar *buf) { + int rc; DBUG_ENTER("ha_example::index_prev"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_WRONG_COMMAND; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } @@ -469,8 +482,12 @@ int ha_example::index_prev(uchar *buf) */ int ha_example::index_first(uchar *buf) { + int rc; DBUG_ENTER("ha_example::index_first"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_WRONG_COMMAND; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } @@ -486,8 +503,12 @@ int ha_example::index_first(uchar *buf) */ int ha_example::index_last(uchar *buf) { + int rc; DBUG_ENTER("ha_example::index_last"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + rc= HA_ERR_WRONG_COMMAND; + MYSQL_INDEX_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } @@ -533,8 +554,13 @@ int ha_example::rnd_end() */ int ha_example::rnd_next(uchar *buf) { + int rc; DBUG_ENTER("ha_example::rnd_next"); - DBUG_RETURN(HA_ERR_END_OF_FILE); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + TRUE); + rc= HA_ERR_END_OF_FILE; + MYSQL_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } @@ -581,8 +607,13 @@ void ha_example::position(const uchar *record) */ int ha_example::rnd_pos(uchar *buf, uchar *pos) { + int rc; DBUG_ENTER("ha_example::rnd_pos"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + TRUE); + rc= HA_ERR_WRONG_COMMAND; + MYSQL_READ_ROW_DONE(rc); + DBUG_RETURN(rc); } diff --git a/storage/federated/Makefile.am b/storage/federated/Makefile.am index 64ea0207017..221b30092d2 100644 --- a/storage/federated/Makefile.am +++ b/storage/federated/Makefile.am @@ -48,5 +48,22 @@ libfederated_a_SOURCES= ha_federated.cc EXTRA_DIST = CMakeLists.txt plug.in + +if HAVE_DTRACE_DASH_G +abs_top_srcdir = @abs_top_srcdir@ +libfederated_a_LIBADD = probes_mysql.o +libfederated_a_DEPENDENCIES = probes_mysql.o dtrace_files dtrace_providers +CLEANFILES = probes_mysql.o dtrace_files dtrace_providers +DTRACEFILES = libfederated_a-ha_federated.o +DTRACEPROVIDER = $(abs_top_srcdir)/sql/probes_mysql.d + +dtrace_files: + echo $(DTRACEFILES) > $@ +dtrace_providers: + echo $(DTRACEPROVIDER) > $@ +probes_mysql.o: $(DTRACEPROVIDER) $(DTRACEFILES) + $(DTRACE) $(DTRACEFLAGS) -G -s $< $(DTRACEFILES) -o $@ +endif + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 2f1c5e51caa..69cb2599740 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -380,6 +380,7 @@ #endif #include "ha_federated.h" +#include "probes_mysql.h" #include "m_string.h" @@ -2324,13 +2325,17 @@ int ha_federated::delete_row(const uchar *buf) int ha_federated::index_read(uchar *buf, const uchar *key, uint key_len, ha_rkey_function find_flag) { + int rc; DBUG_ENTER("ha_federated::index_read"); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); if (stored_result) mysql_free_result(stored_result); - DBUG_RETURN(index_read_idx_with_result_set(buf, active_index, key, - key_len, find_flag, - &stored_result)); + rc= index_read_idx_with_result_set(buf, active_index, key, + key_len, find_flag, + &stored_result); + MYSQL_INDEX_READ_ROW_DONE(retval); + DBUG_RETURN(rc); } @@ -2478,6 +2483,7 @@ int ha_federated::read_range_first(const key_range *start_key, sizeof(sql_query_buffer), &my_charset_bin); DBUG_ENTER("ha_federated::read_range_first"); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(!(start_key == NULL && end_key == NULL)); @@ -2506,10 +2512,12 @@ int ha_federated::read_range_first(const key_range *start_key, } retval= read_next(table->record[0], stored_result); + MYSQL_INDEX_READ_ROW_DONE(retval); DBUG_RETURN(retval); error: table->status= STATUS_NOT_FOUND; + MYSQL_INDEX_READ_ROW_DONE(retval); DBUG_RETURN(retval); } @@ -2518,7 +2526,9 @@ int ha_federated::read_range_next() { int retval; DBUG_ENTER("ha_federated::read_range_next"); - retval= rnd_next(table->record[0]); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); + retval= rnd_next_int(table->record[0]); + MYSQL_INDEX_READ_ROW_DONE(retval); DBUG_RETURN(retval); } @@ -2526,9 +2536,13 @@ int ha_federated::read_range_next() /* Used to read forward through the index. */ int ha_federated::index_next(uchar *buf) { + int retval; DBUG_ENTER("ha_federated::index_next"); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_next_count); - DBUG_RETURN(read_next(buf, stored_result)); + retval= read_next(buf, stored_result); + MYSQL_INDEX_READ_ROW_DONE(retval); + DBUG_RETURN(retval); } @@ -2637,7 +2651,18 @@ int ha_federated::index_end(void) int ha_federated::rnd_next(uchar *buf) { + int rc; DBUG_ENTER("ha_federated::rnd_next"); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + TRUE); + rc= rnd_next_int(buf); + MYSQL_READ_ROW_DONE(rc); + DBUG_RETURN(rc); +} + +int ha_federated::rnd_next_int(uchar *buf) +{ + DBUG_ENTER("ha_federated::rnd_next_int"); if (stored_result == 0) { @@ -2726,6 +2751,8 @@ int ha_federated::rnd_pos(uchar *buf, uchar *pos) { int result; DBUG_ENTER("ha_federated::rnd_pos"); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + FALSE); ha_statistic_increment(&SSV::ha_read_rnd_count); if (table->s->primary_key != MAX_KEY) { @@ -2740,6 +2767,7 @@ int ha_federated::rnd_pos(uchar *buf, uchar *pos) result= 0; } table->status= result ? STATUS_NOT_FOUND : 0; + MYSQL_READ_ROW_DONE(result); DBUG_RETURN(result); } diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h index 1974f9936fc..552676b6ae8 100644 --- a/storage/federated/ha_federated.h +++ b/storage/federated/ha_federated.h @@ -232,6 +232,7 @@ public: int rnd_init(bool scan); //required int rnd_end(); int rnd_next(uchar *buf); //required + int rnd_next_int(uchar *buf); int rnd_pos(uchar *buf, uchar *pos); //required void position(const uchar *record); //required int info(uint); //required diff --git a/storage/heap/Makefile.am b/storage/heap/Makefile.am index ec1445dea67..d5fd952b4bd 100644 --- a/storage/heap/Makefile.am +++ b/storage/heap/Makefile.am @@ -51,5 +51,21 @@ libheap_a_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \ EXTRA_DIST = CMakeLists.txt plug.in +if HAVE_DTRACE_DASH_G +abs_top_srcdir = @abs_top_srcdir@ +libheap_a_LIBADD = probes_mysql.o +libheap_a_DEPENDENCIES = probes_mysql.o dtrace_files dtrace_providers +CLEANFILES = probes_mysql.o dtrace_files dtrace_providers +DTRACEFILES = ha_heap.o +DTRACEPROVIDER = $(abs_top_srcdir)/sql/probes_mysql.d + +dtrace_files: + echo $(DTRACEFILES) > $@ +dtrace_providers: + echo $(DTRACEPROVIDER) > $@ +probes_mysql.o: $(DTRACEPROVIDER) $(DTRACEFILES) + $(DTRACE) $(DTRACEFLAGS) -G -s $< $(DTRACEFILES) -o $@ +endif + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index be2914adac4..2cadfa1c24d 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -20,6 +20,7 @@ #define MYSQL_SERVER 1 #include "mysql_priv.h" +#include "probes_mysql.h" #include <mysql/plugin.h> #include "ha_heap.h" #include "heapdef.h" @@ -274,21 +275,25 @@ int ha_heap::index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_key_count); int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag); table->status = error ? STATUS_NOT_FOUND : 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_heap::index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_key_count); int error= heap_rkey(file, buf, active_index, key, keypart_map, HA_READ_PREFIX_LAST); table->status= error ? STATUS_NOT_FOUND : 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -296,45 +301,55 @@ int ha_heap::index_read_idx_map(uchar *buf, uint index, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_key_count); int error = heap_rkey(file, buf, index, key, keypart_map, find_flag); table->status = error ? STATUS_NOT_FOUND : 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_heap::index_next(uchar * buf) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_next_count); int error=heap_rnext(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_heap::index_prev(uchar * buf) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_prev_count); int error=heap_rprev(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_heap::index_first(uchar * buf) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_first_count); int error=heap_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_heap::index_last(uchar * buf) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_last_count); int error=heap_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -345,9 +360,12 @@ int ha_heap::rnd_init(bool scan) int ha_heap::rnd_next(uchar *buf) { + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + TRUE); ha_statistic_increment(&SSV::ha_read_rnd_next_count); int error=heap_scan(file, buf); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_READ_ROW_DONE(error); return error; } @@ -355,10 +373,13 @@ int ha_heap::rnd_pos(uchar * buf, uchar *pos) { int error; HEAP_PTR heap_position; + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + FALSE); ha_statistic_increment(&SSV::ha_read_rnd_count); memcpy_fixed((char*) &heap_position, pos, sizeof(HEAP_PTR)); error=heap_rrnd(file, buf, heap_position); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_READ_ROW_DONE(error); return error; } diff --git a/storage/myisam/Makefile.am b/storage/myisam/Makefile.am index f50c312b8e4..c79fc2e0f03 100644 --- a/storage/myisam/Makefile.am +++ b/storage/myisam/Makefile.am @@ -150,5 +150,21 @@ SUFFIXES = .sh @CHMOD@ +x $@-t @MV@ $@-t $@ +if HAVE_DTRACE_DASH_G +abs_top_srcdir = @abs_top_srcdir@ +libmyisam_a_LIBADD = probes_mysql.o +libmyisam_a_DEPENDENCIES = probes_mysql.o dtrace_files dtrace_providers +CLEANFILES += probes_mysql.o dtrace_files dtrace_providers +DTRACEFILES = ha_myisam.o +DTRACEPROVIDER = $(abs_top_srcdir)/sql/probes_mysql.d + +dtrace_files: + echo $(DTRACEFILES) > $@ +dtrace_providers: + echo $(DTRACEPROVIDER) > $@ +probes_mysql.o: $(DTRACEPROVIDER) $(DTRACEFILES) + $(DTRACE) $(DTRACEFLAGS) -G -s $< $(DTRACEFILES) -o $@ +endif + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index b8d5a9af8d2..a32519653ef 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -20,6 +20,7 @@ #define MYSQL_SERVER 1 #include "mysql_priv.h" +#include "probes_mysql.h" #include <mysql/plugin.h> #include <m_ctype.h> #include <my_bit.h> @@ -1602,10 +1603,12 @@ int ha_myisam::index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_key_count); int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -1613,57 +1616,69 @@ int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_key_count); int error=mi_rkey(file, buf, index, key, keypart_map, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_myisam::index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ENTER("ha_myisam::index_read_last"); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_key_count); int error=mi_rkey(file, buf, active_index, key, keypart_map, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); DBUG_RETURN(error); } int ha_myisam::index_next(uchar *buf) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_next_count); int error=mi_rnext(file,buf,active_index); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_myisam::index_prev(uchar *buf) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_prev_count); int error=mi_rprev(file,buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_myisam::index_first(uchar *buf) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_first_count); int error=mi_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_myisam::index_last(uchar *buf) { + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); DBUG_ASSERT(inited==INDEX); ha_statistic_increment(&SSV::ha_read_last_count); int error=mi_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -1673,12 +1688,14 @@ int ha_myisam::index_next_same(uchar *buf, { int error; DBUG_ASSERT(inited==INDEX); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_next_count); do { error= mi_rnext_same(file,buf); } while (error == HA_ERR_RECORD_DELETED); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -1692,9 +1709,12 @@ int ha_myisam::rnd_init(bool scan) int ha_myisam::rnd_next(uchar *buf) { + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + TRUE); ha_statistic_increment(&SSV::ha_read_rnd_next_count); int error=mi_scan(file, buf); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_READ_ROW_DONE(error); return error; } @@ -1705,9 +1725,12 @@ int ha_myisam::restart_rnd_next(uchar *buf, uchar *pos) int ha_myisam::rnd_pos(uchar *buf, uchar *pos) { + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + FALSE); ha_statistic_increment(&SSV::ha_read_rnd_count); int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_READ_ROW_DONE(error); return error; } diff --git a/storage/myisammrg/Makefile.am b/storage/myisammrg/Makefile.am index 1ca51bc9d03..267ce71f8d1 100644 --- a/storage/myisammrg/Makefile.am +++ b/storage/myisammrg/Makefile.am @@ -40,5 +40,21 @@ libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \ EXTRA_DIST = CMakeLists.txt plug.in +if HAVE_DTRACE_DASH_G +abs_top_srcdir = @abs_top_srcdir@ +libmyisammrg_a_LIBADD = probes_mysql.o +libmyisammrg_a_DEPENDENCIES = probes_mysql.o dtrace_files dtrace_providers +CLEANFILES = probes_mysql.o dtrace_files dtrace_providers +DTRACEFILES = ha_myisammrg.o +DTRACEPROVIDER = $(abs_top_srcdir)/sql/probes_mysql.d + +dtrace_files: + echo $(DTRACEFILES) > $@ +dtrace_providers: + echo $(DTRACEPROVIDER) > $@ +probes_mysql.o: $(DTRACEPROVIDER) $(DTRACEFILES) + $(DTRACE) $(DTRACEFLAGS) -G -s $< $(DTRACEFILES) -o $@ +endif + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 956f0e421cc..999dcf00b93 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -96,6 +96,7 @@ #define MYSQL_SERVER 1 #include "mysql_priv.h" +#include "probes_mysql.h" #include <mysql/plugin.h> #include <m_ctype.h> #include "../myisam/ha_myisam.h" @@ -662,9 +663,11 @@ int ha_myisammrg::index_read_map(uchar * buf, const uchar * key, enum ha_rkey_function find_flag) { DBUG_ASSERT(this->file->children_attached); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_key_count); int error=myrg_rkey(file,buf,active_index, key, keypart_map, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -673,9 +676,11 @@ int ha_myisammrg::index_read_idx_map(uchar * buf, uint index, const uchar * key, enum ha_rkey_function find_flag) { DBUG_ASSERT(this->file->children_attached); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_key_count); int error=myrg_rkey(file,buf,index, key, keypart_map, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -683,46 +688,56 @@ int ha_myisammrg::index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map) { DBUG_ASSERT(this->file->children_attached); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_key_count); int error=myrg_rkey(file,buf,active_index, key, keypart_map, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_myisammrg::index_next(uchar * buf) { DBUG_ASSERT(this->file->children_attached); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_next_count); int error=myrg_rnext(file,buf,active_index); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_myisammrg::index_prev(uchar * buf) { DBUG_ASSERT(this->file->children_attached); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_prev_count); int error=myrg_rprev(file,buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_myisammrg::index_first(uchar * buf) { DBUG_ASSERT(this->file->children_attached); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_first_count); int error=myrg_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } int ha_myisammrg::index_last(uchar * buf) { DBUG_ASSERT(this->file->children_attached); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_last_count); int error=myrg_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -732,12 +747,14 @@ int ha_myisammrg::index_next_same(uchar * buf, { int error; DBUG_ASSERT(this->file->children_attached); + MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); ha_statistic_increment(&SSV::ha_read_next_count); do { error= myrg_rnext_same(file,buf); } while (error == HA_ERR_RECORD_DELETED); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_INDEX_READ_ROW_DONE(error); return error; } @@ -752,9 +769,12 @@ int ha_myisammrg::rnd_init(bool scan) int ha_myisammrg::rnd_next(uchar *buf) { DBUG_ASSERT(this->file->children_attached); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + TRUE); ha_statistic_increment(&SSV::ha_read_rnd_next_count); int error=myrg_rrnd(file, buf, HA_OFFSET_ERROR); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_READ_ROW_DONE(error); return error; } @@ -762,9 +782,12 @@ int ha_myisammrg::rnd_next(uchar *buf) int ha_myisammrg::rnd_pos(uchar * buf, uchar *pos) { DBUG_ASSERT(this->file->children_attached); + MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, + TRUE); ha_statistic_increment(&SSV::ha_read_rnd_count); int error=myrg_rrnd(file, buf, my_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; + MYSQL_READ_ROW_DONE(error); return error; } |