sysbench-1.0.18/0000700000175000017500000000000013553247311011215 5ustar jpjpsysbench-1.0.18/missing0000700000175000017500000002403213553247311012615 0ustar jpjp#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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; either version 2, or (at your option) # any later version. # 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. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 sysbench-1.0.18/install-sh0000700000175000017500000001572213553247311013230 0ustar jpjp#!/bin/sh # # install - install a program, script, or datafile # # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "$0: no input file specified" >&2 exit 1 else : fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d "$dst" ]; then instcmd=: chmodcmd="" else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f "$src" ] || [ -d "$src" ] then : else echo "$0: $src does not exist" >&2 exit 1 fi if [ x"$dst" = x ] then echo "$0: no destination specified" >&2 exit 1 else : fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d "$dst" ] then dst=$dst/`basename "$src"` else : fi fi ## this sed command emulates the dirname command dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp='' while [ $# -ne 0 ] ; do pathcomp=$pathcomp$1 shift if [ ! -d "$pathcomp" ] ; then $mkdirprog "$pathcomp" else : fi pathcomp=$pathcomp/ done fi if [ x"$dir_arg" != x ] then $doit $instcmd "$dst" && if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename "$dst"` else : fi # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && # Now remove or move aside any old file at destination location. We try this # two ways since rm can't unlink itself on some systems and the destination # file might be busy for other reasons. In this case, the final cleanup # might fail but the new file should still install successfully. { if [ -f "$dstdir/$dstfile" ] then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi && # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } sysbench-1.0.18/src/0000700000175000017500000000000013553247311012004 5ustar jpjpsysbench-1.0.18/src/sb_logger.c0000600000175000017500000002500413553247311014116 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 #include "sb_win.h" #endif #ifdef STDC_HEADERS # include # include # include #endif #ifdef HAVE_ERRNO_H # include #endif #ifdef HAVE_MATH_H # include #endif #include "sysbench.h" #include "sb_list.h" #include "sb_logger.h" #include "sb_histogram.h" #include "ck_cc.h" #define TEXT_BUFFER_SIZE 4096 #define ERROR_BUFFER_SIZE 256 /* Use 1024-element array for latency histogram tracking values between 0.001 milliseconds and 100 seconds. */ #define OPER_LOG_GRANULARITY 1024 #define OPER_LOG_MIN_VALUE 1e-3 #define OPER_LOG_MAX_VALUE 1E5 /* Array of message handlers (one chain per message type) */ static sb_list_t handlers[LOG_MSG_TYPE_MAX]; /* set after logger initialization */ static unsigned char initialized; static pthread_mutex_t text_mutex; static unsigned int text_cnt; static char text_buf[TEXT_BUFFER_SIZE]; static int text_handler_init(void); static int text_handler_process(log_msg_t *msg); static int oper_handler_init(void); static int oper_handler_done(void); /* Built-in log handlers */ /* Text messages handler */ static sb_arg_t text_handler_args[] = { SB_OPT("verbosity", "verbosity level {5 - debug, 0 - only critical messages}", "3", INT), SB_OPT_END }; static log_handler_t text_handler = { { &text_handler_init, &text_handler_process, NULL, }, text_handler_args, {0,0} }; /* Operation start/stop messages handler */ static sb_arg_t oper_handler_args[] = { SB_OPT("percentile", "percentile to calculate in latency statistics (1-100). " "Use the special value of 0 to disable percentile calculations", "95", INT), SB_OPT("histogram", "print latency histogram in report", "off", BOOL), SB_OPT_END }; static log_handler_t oper_handler = { { oper_handler_init, NULL, oper_handler_done, }, oper_handler_args, {0,0} }; /* Register logger and all handlers */ int log_register(void) { unsigned int i; for (i = 0; i < LOG_MSG_TYPE_MAX; i++) SB_LIST_INIT(handlers + i); log_add_handler(LOG_MSG_TYPE_TEXT, &text_handler); log_add_handler(LOG_MSG_TYPE_OPER, &oper_handler); return 0; } /* Display command line options for registered log handlers */ void log_print_help(void) { unsigned int i; sb_list_item_t *pos; log_handler_t *handler; printf("Log options:\n"); for (i = 0; i < LOG_MSG_TYPE_MAX; i++) { SB_LIST_FOR_EACH(pos, handlers + i) { handler = SB_LIST_ENTRY(pos, log_handler_t, listitem); if (handler->args != NULL) sb_print_options(handler->args); } } } /* Initialize logger and all handlers */ int log_init(void) { unsigned int i; sb_list_item_t *pos; log_handler_t *handler; for (i = 0; i < LOG_MSG_TYPE_MAX; i++) { SB_LIST_FOR_EACH(pos, handlers + i) { handler = SB_LIST_ENTRY(pos, log_handler_t, listitem); if (handler->ops.init != NULL && handler->ops.init()) return 1; } } /* required to let log_text() pass messages to handlers */ initialized = 1; return 0; } /* Uninitialize logger and all handlers */ void log_done(void) { unsigned int i; sb_list_item_t *pos; log_handler_t *handler; for (i = 0; i < LOG_MSG_TYPE_MAX; i++) { SB_LIST_FOR_EACH(pos, handlers + i) { handler = SB_LIST_ENTRY(pos, log_handler_t, listitem); if (handler->ops.done != NULL) handler->ops.done(); } } initialized = 0; } /* Add handler for a specified type of messages */ int log_add_handler(log_msg_type_t type, log_handler_t *handler) { if (type <= LOG_MSG_TYPE_MIN || type >= LOG_MSG_TYPE_MAX) return 1; if (handler->args != NULL) sb_register_arg_set(handler->args); SB_LIST_ADD_TAIL(&handler->listitem, handlers + type); return 0; } /* Main function to dispatch log messages */ void log_msg(log_msg_t *msg) { sb_list_item_t *pos; log_handler_t *handler; SB_LIST_FOR_EACH(pos, handlers + msg->type) { handler = SB_LIST_ENTRY(pos, log_handler_t, listitem); if (handler->ops.process != NULL) handler->ops.process(msg); } } static const char *get_msg_prefix(log_msg_priority_t priority) { const char * prefix; switch (priority) { case LOG_FATAL: prefix = "FATAL: "; break; case LOG_ALERT: prefix = "ALERT: "; break; case LOG_WARNING: prefix = "WARNING: "; break; case LOG_DEBUG: prefix = "DEBUG: "; break; default: prefix = ""; break; } return prefix; } /* printf-like wrapper to log text messages */ void log_text(log_msg_priority_t priority, const char *fmt, ...) { log_msg_t msg; log_msg_text_t text_msg; char buf[TEXT_BUFFER_SIZE]; va_list ap; int n, clen, maxlen; maxlen = TEXT_BUFFER_SIZE; clen = 0; va_start(ap, fmt); n = vsnprintf(buf + clen, maxlen, fmt, ap); va_end(ap); if (n < 0 || n >= maxlen) n = maxlen; clen += n; maxlen -= n; snprintf(buf + clen, maxlen, "\n"); /* No race condition here because log_init() is supposed to be called in a single-threaded stage */ if (!initialized) { printf("%s%s", get_msg_prefix(priority), buf); return; } msg.type = LOG_MSG_TYPE_TEXT; msg.data = (void *)&text_msg; text_msg.priority = priority; text_msg.text = buf; text_msg.flags = 0; log_msg(&msg); } /* variant of log_text() which prepends log lines with the elapsed time of a specified timer. */ void log_timestamp(log_msg_priority_t priority, double seconds, const char *fmt, ...) { log_msg_t msg; log_msg_text_t text_msg; char buf[TEXT_BUFFER_SIZE]; va_list ap; int n, clen, maxlen; maxlen = TEXT_BUFFER_SIZE; clen = 0; n = snprintf(buf, maxlen, "[ %.0fs ] ", seconds); clen += n; maxlen -= n; va_start(ap, fmt); n = vsnprintf(buf + clen, maxlen, fmt, ap); va_end(ap); if (n < 0 || n >= maxlen) n = maxlen; clen += n; maxlen -= n; snprintf(buf + clen, maxlen, "\n"); /* No race condition here because log_init() is supposed to be called in a single-threaded stage */ if (!initialized) { printf("%s%s", get_msg_prefix(priority), buf); return; } msg.type = LOG_MSG_TYPE_TEXT; msg.data = (void *)&text_msg; text_msg.priority = priority; text_msg.text = buf; /* Skip duplicate checks */ text_msg.flags = LOG_MSG_TEXT_ALLOW_DUPLICATES; log_msg(&msg); } /* printf-like wrapper to log system error messages */ void log_errno(log_msg_priority_t priority, const char *fmt, ...) { char buf[TEXT_BUFFER_SIZE]; char errbuf[ERROR_BUFFER_SIZE]; va_list ap; int n; int old_errno; char *tmp; #ifdef _WIN32 LPVOID lpMsgBuf; old_errno = GetLastError(); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, old_errno, 0, (LPTSTR)&lpMsgBuf, 0, NULL); tmp = (char *)lpMsgBuf; #else old_errno = errno; #ifdef HAVE_STRERROR_R #ifdef STRERROR_R_CHAR_P tmp = strerror_r(old_errno, errbuf, sizeof(errbuf)); #else strerror_r(old_errno, errbuf, sizeof(errbuf)); tmp = errbuf; #endif /* STRERROR_R_CHAR_P */ #else /* !HAVE_STRERROR_P */ strncpy(errbuf, strerror(old_errno), sizeof(errbuf)); tmp = errbuf; #endif /* HAVE_STRERROR_P */ #endif /* WIN32 */ va_start(ap, fmt); n = vsnprintf(buf, TEXT_BUFFER_SIZE, fmt, ap); va_end(ap); if (n < 0 || n == TEXT_BUFFER_SIZE) return; snprintf(buf + n, TEXT_BUFFER_SIZE - n, " errno = %d (%s)", old_errno, tmp); #ifdef _WIN32 LocalFree(lpMsgBuf); #endif log_text(priority, "%s", buf); } /* Initialize text handler */ int text_handler_init(void) { #ifdef HAVE_SETVBUF /* Set stdout to unbuffered mode */ setvbuf(stdout, NULL, _IONBF, 0); #endif sb_globals.verbosity = sb_get_value_int("verbosity"); if (sb_globals.verbosity > LOG_DEBUG) { printf("Invalid value for verbosity: %d\n", sb_globals.verbosity); return 1; } pthread_mutex_init(&text_mutex, NULL); text_cnt = 0; text_buf[0] = '\0'; return 0; } /* Print text message to the log */ int text_handler_process(log_msg_t *msg) { log_msg_text_t *text_msg = (log_msg_text_t *)msg->data; if (text_msg->priority > sb_globals.verbosity) return 0; if (!(text_msg->flags & LOG_MSG_TEXT_ALLOW_DUPLICATES)) { pthread_mutex_lock(&text_mutex); if (!strcmp(text_buf, text_msg->text)) { text_cnt++; pthread_mutex_unlock(&text_mutex); return 0; } else { if (text_cnt > 0) printf("(last message repeated %u times)\n", text_cnt); text_cnt = 0; strncpy(text_buf, text_msg->text, TEXT_BUFFER_SIZE); } pthread_mutex_unlock(&text_mutex); } printf("%s%s", get_msg_prefix(text_msg->priority), text_msg->text); return 0; } /* Initialize operation messages handler */ int oper_handler_init(void) { int tmp; tmp = sb_get_value_int("percentile"); if (tmp < 0 || tmp > 100) { log_text(LOG_FATAL, "Invalid value for --percentile: %d", tmp); return 1; } sb_globals.percentile = tmp; sb_globals.histogram = sb_get_value_flag("histogram"); if (sb_globals.percentile == 0 && sb_globals.histogram != 0) { log_text(LOG_FATAL, "--histogram cannot be used with --percentile=0"); return 1; } if (sb_histogram_init(&sb_latency_histogram, OPER_LOG_GRANULARITY, OPER_LOG_MIN_VALUE, OPER_LOG_MAX_VALUE)) return 1; return 0; } /* Uninitialize operations messages handler */ int oper_handler_done(void) { sb_histogram_done(&sb_latency_histogram); return 0; } sysbench-1.0.18/src/sb_util.h0000600000175000017500000000626313553247311013627 0ustar jpjp/* Copyright (C) 2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_UTIL_H #define SB_UTIL_H /* General utility macros and functions. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_UNISTD_H # include #endif #include "ck_md.h" #include "ck_cc.h" #ifdef HAVE_FUNC_ATTRIBUTE_FORMAT # define SB_ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n))) #else # define SB_ATTRIBUTE_FORMAT(style, m, n) #endif #ifdef HAVE_FUNC_ATTRIBUTE_UNUSED # define SB_ATTRIBUTE_UNUSED __attribute__((unused)) #else # define SB_ATTRIBUTE_UNUSED #endif #if defined(__MACH__) # define DLEXT ".dylib" #else # define DLEXT ".so" #endif /* Calculate the smallest multiple of m that is not smaller than n, when m is a power of 2. */ #define SB_ALIGN(n, m) (((n) + ((m) - 1)) & ~((m) - 1)) /* Calculate padding, i.e. distance from n to SB_ALIGN(n, m), where m is a power of 2. */ #define SB_PAD(n, m) (SB_ALIGN((n),(m)) - (n)) /* Calculate padding to cache line size. */ #define SB_CACHELINE_PAD(n) (SB_PAD((n), CK_MD_CACHELINE)) /* Minimum/maximum values */ #ifdef __GNUC__ # define SB_MIN(a,b) \ ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ _a < _b ? _a : _b; }) # define SB_MAX(a,b) \ ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ _a > _b ? _a : _b; }) #else # define SB_MIN(a,b) (((a) < (b)) ? (a) : (b)) # define SB_MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif /* __GNUC__ */ #define SB_LIKELY(x) CK_CC_LIKELY(x) #define SB_UNLIKELY(x) CK_CC_UNLIKELY(x) /* SB_CONTAINER_OF */ #ifdef __GNUC__ # define SB_MEMBER_TYPE(type, member) __typeof__ (((type *)0)->member) #else # define SB_MEMBER_TYPE(type, member) const void #endif /* __GNUC__ */ #define SB_CONTAINER_OF(ptr, type, member) ((type *)(void *)( \ (char *)(SB_MEMBER_TYPE(type, member) *){ ptr } - offsetof(type, member))) /* Compile-time assertion */ #define SB_COMPILE_TIME_ASSERT(expr) \ do { \ typedef char cta[(expr) ? 1 : -1] SB_ATTRIBUTE_UNUSED; \ } while(0) #ifdef HAVE_ISATTY # define SB_ISATTY() isatty(0) #else # error No isatty() implementation for this platform! #endif /* Allocate a buffer of a specified size such that the address is a multiple of a specified alignment. */ void *sb_memalign(size_t size, size_t alignment); /* Get OS page size */ size_t sb_getpagesize(void); #endif /* SB_UTIL_H */ sysbench-1.0.18/src/sb_lua.c0000600000175000017500000011105513553247311013422 0ustar jpjp/* Copyright (C) 2006 MySQL AB Copyright (C) 2006-2018 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_LIBGEN_H # include #endif #include "sb_lua.h" #include "lua.h" #include "lualib.h" #include "lauxlib.h" #define SB_LUA_EXPORT #include "sb_counter.h" #undef SB_LUA_EXPORT #include "db_driver.h" #include "sb_rand.h" #include "sb_thread.h" #include "sb_ck_pr.h" /* Auto-generated headers for internal scripts. If you add a new header here, make sure it is also added to the internal_scripts array below. */ #include "lua/internal/sysbench.lua.h" #include "lua/internal/sysbench.cmdline.lua.h" #include "lua/internal/sysbench.compat.lua.h" #include "lua/internal/sysbench.rand.lua.h" #include "lua/internal/sysbench.sql.lua.h" #include "lua/internal/sysbench.histogram.lua.h" #define EVENT_FUNC "event" #define PREPARE_FUNC "prepare" #define CLEANUP_FUNC "cleanup" #define HELP_FUNC "help" #define THREAD_INIT_FUNC "thread_init" #define THREAD_DONE_FUNC "thread_done" #define THREAD_RUN_FUNC "thread_run" #define INIT_FUNC "init" #define DONE_FUNC "done" #define REPORT_INTERMEDIATE_HOOK "report_intermediate" #define REPORT_CUMULATIVE_HOOK "report_cumulative" #define xfree(ptr) ({ if ((ptr) != NULL) free((void *) ptr); ptr = NULL; }) /* Interpreter context */ typedef struct { db_conn_t *con; /* Database connection */ db_driver_t *driver; lua_State *L; } sb_lua_ctxt_t; typedef struct { int id; db_bind_type_t type; void *buf; unsigned long buflen; char is_null; } sb_lua_bind_t; typedef struct { db_result_t *ptr; } sb_lua_db_rs_t; typedef struct { db_stmt_t *ptr; sb_lua_bind_t *params; unsigned int nparams; sb_lua_bind_t *results; unsigned int nresults; int param_ref; int result_ref; sb_lua_db_rs_t *rs; } sb_lua_db_stmt_t; typedef struct { const char *name; const unsigned char *source; /* Use a pointer, since _len variables are not compile-time constants */ size_t *source_len; } internal_script_t; typedef enum { SB_LUA_ERROR_NONE, SB_LUA_ERROR_RESTART_EVENT } sb_lua_error_t; bool sb_lua_more_events(int); int sb_lua_set_test_args(sb_arg_t *, size_t); /* Lua interpreter states */ static lua_State **states CK_CC_CACHELINE; static sb_test_t sbtest CK_CC_CACHELINE; static TLS sb_lua_ctxt_t tls_lua_ctxt CK_CC_CACHELINE; /* List of pre-loaded internal scripts */ static internal_script_t internal_scripts[] = { {"sysbench.rand.lua", sysbench_rand_lua, &sysbench_rand_lua_len}, {"sysbench.lua", sysbench_lua, &sysbench_lua_len}, {"sysbench.compat.lua", sysbench_compat_lua, &sysbench_compat_lua_len}, {"sysbench.cmdline.lua", sysbench_cmdline_lua, &sysbench_cmdline_lua_len}, {"sysbench.sql.lua", sysbench_sql_lua, &sysbench_sql_lua_len}, {"sysbench.histogram.lua", sysbench_histogram_lua, &sysbench_histogram_lua_len}, {NULL, NULL, 0} }; /* Main (global) interpreter state */ static lua_State *gstate; /* Custom command name */ static const char * sb_lua_custom_command; /* Lua test operations */ static int sb_lua_op_init(void); static int sb_lua_op_done(void); static int sb_lua_op_thread_init(int); static int sb_lua_op_thread_run(int); static int sb_lua_op_thread_done(int); static sb_operations_t lua_ops = { .init = sb_lua_op_init, .thread_init = sb_lua_op_thread_init, .thread_done = sb_lua_op_thread_done, .report_intermediate = db_report_intermediate, .report_cumulative = db_report_cumulative, .done = sb_lua_op_done }; /* Lua test commands */ static int sb_lua_cmd_prepare(void); static int sb_lua_cmd_cleanup(void); static int sb_lua_cmd_help(void); /* Initialize interpreter state */ static lua_State *sb_lua_new_state(void); /* Close interpretet state */ static int sb_lua_close_state(lua_State *); /* Exported C functions for legacy Lua API */ static int sb_lua_db_connect(lua_State *); static int sb_lua_db_disconnect(lua_State *); static int sb_lua_db_query(lua_State *); static int sb_lua_db_bulk_insert_init(lua_State *); static int sb_lua_db_bulk_insert_next(lua_State *); static int sb_lua_db_bulk_insert_done(lua_State *); static int sb_lua_db_prepare(lua_State *); static int sb_lua_db_bind_param(lua_State *); static int sb_lua_db_bind_result(lua_State *); static int sb_lua_db_execute(lua_State *); static int sb_lua_db_close(lua_State *); static int sb_lua_db_store_results(lua_State *); static int sb_lua_db_free_results(lua_State *); static unsigned int sb_lua_table_size(lua_State *, int); static int read_cmdline_options(lua_State *L); static bool sb_lua_hook_defined(lua_State *, const char *); static bool sb_lua_hook_push(lua_State *, const char *); static void sb_lua_report_intermediate(sb_stat_t *); static void sb_lua_report_cumulative(sb_stat_t *); static void call_error(lua_State *L, const char *name) { const char * const err = lua_tostring(L, -1); log_text(LOG_FATAL, "`%s' function failed: %s", name, err ? err : "(not a string)"); lua_pop(L, 1); } static void report_error(lua_State *L) { const char * const err = lua_tostring(L, -1); log_text(LOG_FATAL, "%s", err ? err : "(not a string)"); lua_pop(L, 1); } static void check_connection(lua_State *L, sb_lua_ctxt_t *ctxt) { if (ctxt->con == NULL) luaL_error(L, "Uninitialized database connection"); } static bool func_available(lua_State *L, const char *func) { lua_getglobal(L, func); bool rc = lua_isfunction(L, -1); lua_pop(L, 1); return rc; } /* Export command line options */ static int do_export_options(lua_State *L, bool global) { sb_list_item_t *pos; option_t *opt; char *tmp; if (!global) { lua_getglobal(L, "sysbench"); lua_pushliteral(L, "opt"); lua_newtable(L); } pos = sb_options_enum_start(); while ((pos = sb_options_enum_next(pos, &opt)) != NULL) { /* The only purpose of the following check if to keep compatibility with legacy scripts where options were exported to the global namespace. In which case name collisions with user-defined functions and variables might occur. For example, the --help option might redefine the help() function. */ if (global) { lua_getglobal(L, opt->name); if (lua_isfunction(L, -1)) { lua_pop(L, 1); continue; } lua_pop(L, 1); } else { lua_pushstring(L, opt->name); } switch (opt->type) { case SB_ARG_TYPE_BOOL: lua_pushboolean(L, sb_opt_to_flag(opt)); break; case SB_ARG_TYPE_INT: lua_pushnumber(L, sb_opt_to_int(opt)); break; case SB_ARG_TYPE_DOUBLE: lua_pushnumber(L, sb_opt_to_double(opt)); break; case SB_ARG_TYPE_SIZE: lua_pushnumber(L, sb_opt_to_size(opt)); break; case SB_ARG_TYPE_STRING: tmp = sb_opt_to_string(opt); lua_pushstring(L, tmp ? tmp : ""); break; case SB_ARG_TYPE_LIST: lua_newtable(L); sb_list_item_t *val; int count = 1; SB_LIST_FOR_EACH(val, sb_opt_to_list(opt)) { lua_pushstring(L, SB_LIST_ENTRY(val, value_t, listitem)->data); lua_rawseti(L, -2, count++); } break; case SB_ARG_TYPE_FILE: /* no need to export anything */ lua_pushnil(L); break; default: log_text(LOG_WARNING, "Global option '%s' will not be exported, because" " the type is unknown", opt->name); lua_pushnil(L); break; } /* set var = value */ if (global) lua_setglobal(L, opt->name); else lua_settable(L, -3); } if (!global) lua_settable(L, -3); /* set sysbench.opt */ return 0; } /* Export option values to the 'sysbench.opt' table. If the script does not declare supported options with sysbench.cmdline.options also export to the global namespace for compatibility with the legacy API. */ static int export_options(lua_State *L) { if (do_export_options(L, false)) return 1; if (sbtest.args == NULL && do_export_options(L, true)) return 1; return 0; } /* Load a specified Lua script */ sb_test_t *sb_load_lua(const char *testname) { if (testname != NULL) { char *tmp = strdup(testname); sbtest.sname = strdup(basename(tmp)); sbtest.lname = tmp; } else { sbtest.sname = strdup(""); sbtest.lname = NULL; } /* Initialize global interpreter state */ gstate = sb_lua_new_state(); if (gstate == NULL) goto error; if (read_cmdline_options(gstate)) goto error; /* Test commands */ if (func_available(gstate, PREPARE_FUNC)) sbtest.builtin_cmds.prepare = &sb_lua_cmd_prepare; if (func_available(gstate, CLEANUP_FUNC)) sbtest.builtin_cmds.cleanup = &sb_lua_cmd_cleanup; if (func_available(gstate, HELP_FUNC)) sbtest.builtin_cmds.help = &sb_lua_cmd_help; /* Test operations */ sbtest.ops = lua_ops; if (func_available(gstate, THREAD_RUN_FUNC)) sbtest.ops.thread_run = &sb_lua_op_thread_run; if (sb_lua_hook_defined(gstate, REPORT_INTERMEDIATE_HOOK)) sbtest.ops.report_intermediate = sb_lua_report_intermediate; if (sb_lua_hook_defined(gstate, REPORT_CUMULATIVE_HOOK)) sbtest.ops.report_cumulative = sb_lua_report_cumulative; /* Allocate per-thread interpreters array */ states = (lua_State **)calloc(sb_globals.threads, sizeof(lua_State *)); if (states == NULL) goto error; return &sbtest; error: sb_lua_done(); return NULL; } void sb_lua_done(void) { sb_lua_close_state(gstate); gstate = NULL; xfree(states); if (sbtest.args != NULL) { for (size_t i = 0; sbtest.args[i].name != NULL; i++) { xfree(sbtest.args[i].name); xfree(sbtest.args[i].desc); xfree(sbtest.args[i].value); } xfree(sbtest.args); } xfree(sbtest.sname); xfree(sbtest.lname); } /* Initialize Lua script */ int sb_lua_op_init(void) { if (export_options(gstate)) return 1; lua_getglobal(gstate, INIT_FUNC); if (!lua_isnil(gstate, -1)) { if (lua_pcall(gstate, 0, 0, 0)) { call_error(gstate, INIT_FUNC); return 1; } } if (!func_available(gstate, EVENT_FUNC)) { log_text(LOG_FATAL, "cannot find the event() function in %s", sbtest.sname); return 1; } return 0; } int sb_lua_op_thread_init(int thread_id) { lua_State * L; L = sb_lua_new_state(); if (L == NULL) return 1; states[thread_id] = L; if (export_options(L)) return 1; lua_getglobal(L, THREAD_INIT_FUNC); if (!lua_isnil(L, -1)) { lua_pushnumber(L, thread_id); if (lua_pcall(L, 1, 1, 0)) { call_error(L, THREAD_INIT_FUNC); return 1; } } return 0; } int sb_lua_op_thread_run(int thread_id) { lua_State * const L = states[thread_id]; lua_getglobal(L, THREAD_RUN_FUNC); lua_pushnumber(L, thread_id); if (lua_pcall(L, 1, 1, 0)) { call_error(L, THREAD_RUN_FUNC); return 1; } return 0; } int sb_lua_op_thread_done(int thread_id) { lua_State * const L = states[thread_id]; int rc = 0; lua_getglobal(L, THREAD_DONE_FUNC); if (!lua_isnil(L, -1)) { lua_pushnumber(L, thread_id); if (lua_pcall(L, 1, 1, 0)) { call_error(L, THREAD_DONE_FUNC); rc = 1; } } sb_lua_close_state(L); return rc; } int sb_lua_op_done(void) { lua_getglobal(gstate, DONE_FUNC); if (!lua_isnil(gstate, -1)) { if (lua_pcall(gstate, 0, 0, 0)) { call_error(gstate, DONE_FUNC); return 1; } } sb_lua_done(); return 0; } /* Pre-load internal scripts */ static int load_internal_scripts(lua_State *L) { for (internal_script_t *s = internal_scripts; s->name != NULL; s++) { if (luaL_loadbuffer(L, (const char *) s->source, s->source_len[0], s->name)) { log_text(LOG_FATAL, "failed to load internal module '%s': %s", s->name, lua_tostring(L, -1)); lua_pop(L, 1); return 1; } lua_call(L, 0, 0); } return 0; } static void sb_lua_var_number(lua_State *L, const char *name, lua_Number n) { lua_pushstring(L, name); lua_pushnumber(L, n); lua_settable(L, -3); } static void sb_lua_var_func(lua_State *L, const char *name, lua_CFunction f) { lua_pushstring(L, name); lua_pushcfunction(L, f); lua_settable(L, -3); } static void sb_lua_var_string(lua_State *L, const char *name, const char *s) { lua_pushstring(L, name); lua_pushstring(L, s); lua_settable(L, -3); } /* Set package.path and package.cpath in a given environment. Also honor LUA_PATH/LUA_CPATH to mimic the default Lua behavior. */ static void sb_lua_set_paths(lua_State *L) { lua_getglobal(L, "package"); int top = lua_gettop(L); lua_pushliteral(L, "./?.lua;"); lua_pushliteral(L, "./?/init.lua;"); lua_pushliteral(L, "./src/lua/?.lua;"); const char *home = getenv("HOME"); if (home != NULL) { lua_pushstring(L, home); lua_pushliteral(L, "/.luarocks/share/lua/5.1/?.lua;"); lua_pushstring(L, home); lua_pushliteral(L, "/.luarocks/share/lua/5.1/?/init.lua;"); lua_pushstring(L, home); lua_pushliteral(L, "/.luarocks/share/lua/?.lua;"); lua_pushstring(L, home); lua_pushliteral(L, "/.luarocks/share/lua/?/init.lua;"); } lua_pushliteral(L, "/usr/local/share/lua/5.1/?.lua;"); lua_pushliteral(L, "/usr/share/lua/5.1/?.lua;"); lua_pushliteral(L, DATADIR "/?.lua;"); lua_concat(L, lua_gettop(L) - top); /* Mimic the default Lua behavior with respect to LUA_PATH and ';;' */ const char *path = getenv("LUA_PATH"); if (path != NULL) { const char *def = lua_tostring(L, -1); path = luaL_gsub(L, path, ";;", ";\1;"); luaL_gsub(L, path, "\1", def); lua_remove(L, -2); lua_remove(L, -2); } lua_setfield(L, top, "path"); lua_pushliteral(L, "./?" DLEXT ";"); if (home != NULL) { lua_pushstring(L, home); lua_pushliteral(L, "/.luarocks/lib/lua/5.1/?" DLEXT ";"); lua_pushstring(L, home); lua_pushliteral(L, "/.luarocks/lib/lua/?" DLEXT ";"); } lua_pushliteral(L, "/usr/local/lib/lua/5.1/?" DLEXT ";"); lua_pushliteral(L, "/usr/lib/lua/5.1/?" DLEXT ";"); lua_pushliteral(L, LIBDIR ";"); lua_concat(L, lua_gettop(L) - top); /* Mimic the default Lua behavior with respect to LUA_CPATH and ';;' */ path = getenv("LUA_CPATH"); if (path != NULL) { const char *def = lua_tostring(L, -1); path = luaL_gsub(L, path, ";;", ";\1;"); luaL_gsub(L, path, "\1", def); lua_remove(L, -2); lua_remove(L, -2); } lua_setfield(L, top, "cpath"); lua_pop(L, 1); /* package */ } /* Create a deep copy of the 'args' array and store it in sbtest.args */ int sb_lua_set_test_args(sb_arg_t *args, size_t len) { sbtest.args = malloc((len + 1) * sizeof(sb_arg_t)); for (size_t i = 0; i < len; i++) { sbtest.args[i].name = strdup(args[i].name); sbtest.args[i].desc = strdup(args[i].desc); sbtest.args[i].type = args[i].type; sbtest.args[i].value = args[i].value != NULL ? strdup(args[i].value) : NULL; sbtest.args[i].validate = args[i].validate; } sbtest.args[len] = (sb_arg_t) {.name = NULL}; return 0; } /* Parse command line options definitions, if present in the script as a sysbench.cmdline.options table. If there was a parsing error, return 1. Return 0 on success. */ static int read_cmdline_options(lua_State *L) { lua_getglobal(L, "sysbench"); lua_getfield(L, -1, "cmdline"); lua_getfield(L, -1, "read_cmdline_options"); if (!lua_isfunction(L, -1)) { log_text(LOG_WARNING, "Cannot find sysbench.cmdline.read_cmdline_options()"); lua_pop(L, 3); return 1; } if (lua_pcall(L, 0, 1, 0) != 0) { call_error(L, "sysbench.cmdline.read_cmdline_options"); lua_pop(L, 2); return 1; } int rc = lua_toboolean(L, -1) == 0; lua_pop(L, 3); return rc; } /* Allocate and initialize new interpreter state */ static lua_State *sb_lua_new_state(void) { lua_State *L; L = luaL_newstate(); luaL_openlibs(L); sb_lua_set_paths(L); /* Export variables into per-state 'sysbench' table */ lua_newtable(L); /* sysbench.tid */ sb_lua_var_number(L, "tid", sb_tls_thread_id); /* Export functions into per-state 'sysbench.db' table */ lua_pushliteral(L, "db"); lua_newtable(L); sb_lua_var_func(L, "connect", sb_lua_db_connect); sb_lua_var_func(L, "disconnect", sb_lua_db_disconnect); sb_lua_var_func(L, "query", sb_lua_db_query); sb_lua_var_func(L, "bulk_insert_init", sb_lua_db_bulk_insert_init); sb_lua_var_func(L, "bulk_insert_next", sb_lua_db_bulk_insert_next); sb_lua_var_func(L, "bulk_insert_done", sb_lua_db_bulk_insert_done); sb_lua_var_func(L, "prepare", sb_lua_db_prepare); sb_lua_var_func(L, "bind_param", sb_lua_db_bind_param); sb_lua_var_func(L, "bind_result", sb_lua_db_bind_result); sb_lua_var_func(L, "execute", sb_lua_db_execute); sb_lua_var_func(L, "close", sb_lua_db_close); sb_lua_var_func(L, "store_results", sb_lua_db_store_results); sb_lua_var_func(L, "free_results", sb_lua_db_free_results); sb_lua_var_number(L, "DB_ERROR_NONE", DB_ERROR_NONE); sb_lua_var_number(L, "DB_ERROR_RESTART_TRANSACTION", DB_ERROR_IGNORABLE); sb_lua_var_number(L, "DB_ERROR_FAILED", DB_ERROR_FATAL); lua_settable(L, -3); /* sysbench.db */ lua_pushliteral(L, "error"); lua_newtable(L); sb_lua_var_number(L, "NONE", SB_LUA_ERROR_NONE); sb_lua_var_number(L, "RESTART_EVENT", SB_LUA_ERROR_RESTART_EVENT); lua_settable(L, -3); /* sysbench.error */ /* sysbench.version */ sb_lua_var_string(L, "version", PACKAGE_VERSION); /* sysbench.version_string */ sb_lua_var_string(L, "version_string", PACKAGE_NAME " " PACKAGE_VERSION SB_GIT_SHA); lua_pushliteral(L, "cmdline"); lua_newtable(L); lua_pushliteral(L, "argv"); lua_createtable(L, sb_globals.argc, 0); for (int i = 0; i < sb_globals.argc; i++) { lua_pushstring(L, sb_globals.argv[i]); lua_rawseti(L, -2, i); } lua_settable(L, -3); /* sysbench.cmdline.argv */ /* Export command name as sysbench.cmdline.command */ if (sb_globals.cmdname) { lua_pushliteral(L, "command"); lua_pushstring(L, sb_globals.cmdname); lua_settable(L, -3); } /* Export script path as sysbench.cmdline.script_path */ sb_lua_var_string(L, "script_path", sbtest.lname); lua_settable(L, -3); /* sysbench.cmdline */ lua_setglobal(L, "sysbench"); luaL_newmetatable(L, "sysbench.stmt"); luaL_newmetatable(L, "sysbench.rs"); if (load_internal_scripts(L)) return NULL; int rc; if ((rc = luaL_loadfile(L, sbtest.lname)) != 0) { if (rc != LUA_ERRFILE) goto loaderr; /* Try to handle the given string as a module name */ lua_getglobal(L, "require"); lua_pushstring(L, sbtest.lname); if (lua_pcall(L, 1, 1, 0)) { const char *msg = lua_tostring(L, -1); if (msg && strncmp(msg, "module ", 7)) goto loaderr; log_text(LOG_FATAL, "Cannot find benchmark '%s': no such built-in test, " "file or module", sbtest.lname); return NULL; } } else if (lua_pcall(L, 0, 0, 0)) goto loaderr; /* Create new L context */ tls_lua_ctxt.L = L; return L; loaderr: report_error(L); return NULL; } /* Close interpreter state */ int sb_lua_close_state(lua_State *state) { sb_lua_ctxt_t * const ctxt = &tls_lua_ctxt; if (ctxt != NULL) { sb_lua_db_disconnect(state); if (ctxt->driver != NULL) { db_destroy(ctxt->driver); ctxt->driver = NULL; } } if (state != NULL) lua_close(state); ctxt->L = NULL; return 0; } /* Execute a given command */ static int execute_command(const char *cmd) { if (export_options(gstate)) return 1; lua_getglobal(gstate, cmd); if (lua_pcall(gstate, 0, 1, 0) != 0) { call_error(gstate, cmd); return 1; } lua_pop(gstate, 1); return 0; } /* Prepare command */ int sb_lua_cmd_prepare(void) { return execute_command(PREPARE_FUNC); } /* Cleanup command */ int sb_lua_cmd_cleanup(void) { return execute_command(CLEANUP_FUNC); } /* Help command */ int sb_lua_cmd_help(void) { return execute_command(HELP_FUNC); } int sb_lua_db_connect(lua_State *L) { sb_lua_ctxt_t * const ctxt = &tls_lua_ctxt; ctxt->driver = db_create(NULL); if (ctxt->driver == NULL) { luaL_error(L, "DB initialization failed"); } lua_pushstring(L, ctxt->driver->sname); lua_setglobal(L, "db_driver"); if (ctxt->con != NULL) return 0; ctxt->con = db_connection_create(ctxt->driver); if (ctxt->con == NULL) luaL_error(L, "Failed to connect to the database"); return 0; } int sb_lua_db_disconnect(lua_State *L) { (void) L; /* unused */ if (tls_lua_ctxt.con) { db_connection_close(tls_lua_ctxt.con); db_connection_free(tls_lua_ctxt.con); tls_lua_ctxt.con = NULL; } return 0; } /* Throw an error with the { errcode = RESTART_EVENT } table. This will make thread_run() restart the event. */ static void throw_restart_event(lua_State *L) { log_text(LOG_DEBUG, "Ignored error encountered, restarting transaction"); lua_createtable(L, 0, 1); lua_pushliteral(L, "errcode"); lua_pushnumber(L, SB_LUA_ERROR_RESTART_EVENT); lua_settable(L, -3); lua_error(L); /* this call never returns */ } int sb_lua_db_query(lua_State *L) { const char *query; db_result_t *rs; size_t len; if (tls_lua_ctxt.con == NULL) sb_lua_db_connect(L); db_conn_t * const con = tls_lua_ctxt.con; query = luaL_checklstring(L, 1, &len); rs = db_query(con, query, len); if (rs == NULL) { if (con->error == DB_ERROR_IGNORABLE) throw_restart_event(L); else if (con->error == DB_ERROR_FATAL) luaL_error(L, "db_query() failed"); } if (rs != NULL) db_free_results(rs); return 0; } int sb_lua_db_bulk_insert_init(lua_State *L) { const char *query; size_t len; if (tls_lua_ctxt.con == NULL) sb_lua_db_connect(L); query = luaL_checklstring(L, 1, &len); if (db_bulk_insert_init(tls_lua_ctxt.con, query, len)) luaL_error(L, "db_bulk_insert_init() failed"); return 0; } int sb_lua_db_bulk_insert_next(lua_State *L) { const char *query; size_t len; check_connection(L, &tls_lua_ctxt); query = luaL_checklstring(L, 1, &len); if (db_bulk_insert_next(tls_lua_ctxt.con, query, len)) luaL_error(L, "db_bulk_insert_next() failed"); return 0; } int sb_lua_db_bulk_insert_done(lua_State *L) { check_connection(L, &tls_lua_ctxt); db_bulk_insert_done(tls_lua_ctxt.con); return 0; } int sb_lua_db_prepare(lua_State *L) { sb_lua_db_stmt_t *stmt; const char *query; size_t len; if (tls_lua_ctxt.con == NULL) sb_lua_db_connect(L); query = luaL_checklstring(L, 1, &len); stmt = (sb_lua_db_stmt_t *)lua_newuserdata(L, sizeof(sb_lua_db_stmt_t)); luaL_getmetatable(L, "sysbench.stmt"); lua_setmetatable(L, -2); memset(stmt, 0, sizeof(sb_lua_db_stmt_t)); stmt->ptr = db_prepare(tls_lua_ctxt.con, query, len); if (stmt->ptr == NULL) luaL_error(L, "db_prepare() failed"); stmt->param_ref = LUA_REFNIL; return 1; } int sb_lua_db_bind_param(lua_State *L) { sb_lua_db_stmt_t *stmt; unsigned int i, n; db_bind_t *binds; char needs_rebind = 0; check_connection(L, &tls_lua_ctxt); stmt = (sb_lua_db_stmt_t *)luaL_checkudata(L, 1, "sysbench.stmt"); luaL_argcheck(L, stmt != NULL, 1, "prepared statement expected"); if (!lua_istable(L, 2)) luaL_error(L, "table was expected"); /* Get table size */ n = sb_lua_table_size(L, 2); if (!n) luaL_error(L, "table is empty"); binds = (db_bind_t *)calloc(n, sizeof(db_bind_t)); stmt->params = (sb_lua_bind_t *)calloc(n, sizeof(sb_lua_bind_t)); if (binds == NULL || stmt->params == NULL) luaL_error(L, "memory allocation failure"); lua_pushnil(L); for (i = 0; i < n; i++) { lua_next(L, 2); switch(lua_type(L, -1)) { case LUA_TNUMBER: stmt->params[i].buf = malloc(sizeof(int)); stmt->params[i].id = luaL_checknumber(L, -2); binds[i].type = DB_TYPE_INT; binds[i].buffer = stmt->params[i].buf; break; case LUA_TSTRING: stmt->params[i].id = luaL_checknumber(L, -2); stmt->params[i].buflen = 0; binds[i].type = DB_TYPE_CHAR; needs_rebind = 1; break; default: lua_pushfstring(L, "Unsupported variable type: %s", lua_typename(L, lua_type(L, -1))); goto error; } binds[i].is_null = &stmt->params[i].is_null; stmt->params[i].type = binds[i].type; lua_pop(L, 1); } if (!needs_rebind && db_bind_param(stmt->ptr, binds, n)) goto error; stmt->nparams = n; /* Create reference for the params table */ lua_pushvalue(L, 2); stmt->param_ref = luaL_ref(L, LUA_REGISTRYINDEX); free(binds); return 0; error: free(binds); lua_error(L); return 0; } int sb_lua_db_bind_result(lua_State *L) { sb_lua_db_stmt_t *stmt; unsigned int i, n; db_bind_t *binds; char needs_rebind = 0; check_connection(L, &tls_lua_ctxt); stmt = (sb_lua_db_stmt_t *)luaL_checkudata(L, 1, "sysbench.stmt"); luaL_argcheck(L, stmt != NULL, 1, "prepared statement expected"); if (!lua_istable(L, 2)) luaL_error(L, "table was expected"); /* Get table size */ n = sb_lua_table_size(L, 2); if (!n) luaL_error(L, "table is empty"); binds = (db_bind_t *)calloc(n, sizeof(db_bind_t)); stmt->results = (sb_lua_bind_t *)calloc(n, sizeof(sb_lua_bind_t)); if (binds == NULL || stmt->results == NULL) luaL_error(L, "memory allocation failure"); lua_pushnil(L); for (i = 0; i < n; i++) { lua_next(L, 2); switch(lua_type(L, -1)) { case LUA_TNUMBER: stmt->results[i].buf = malloc(sizeof(int)); stmt->results[i].id = luaL_checknumber(L, -2); binds[i].type = DB_TYPE_BIGINT; binds[i].buffer = stmt->results[i].buf; break; case LUA_TSTRING: stmt->results[i].id = luaL_checknumber(L, -2); binds[i].type = DB_TYPE_CHAR; needs_rebind = 1; break; default: lua_pushfstring(L, "Unsupported variable type: %s", lua_typename(L, lua_type(L, -1))); goto error; } binds[i].is_null = &stmt->results[i].is_null; stmt->results[i].type = binds[i].type; lua_pop(L, 1); } if (!needs_rebind && db_bind_result(stmt->ptr, binds, n)) goto error; stmt->nresults = n; /* Create reference for the params table */ lua_pushvalue(L, 2); stmt->result_ref = luaL_ref(L, LUA_REGISTRYINDEX); // free(binds); return 0; error: free(binds); lua_error(L); return 0; } int sb_lua_db_execute(lua_State *L) { sb_lua_db_stmt_t *stmt; db_result_t *ptr; sb_lua_db_rs_t *rs; unsigned int i; char needs_rebind = 0; db_bind_t *binds; size_t length; const char *str; sb_lua_bind_t *param; check_connection(L, &tls_lua_ctxt); stmt = (sb_lua_db_stmt_t *)luaL_checkudata(L, 1, "sysbench.stmt"); luaL_argcheck(L, stmt != NULL, 1, "prepared statement expected"); /* Get params table */ lua_rawgeti(L, LUA_REGISTRYINDEX, stmt->param_ref); if (!lua_isnil(L, -1) && !lua_istable(L, -1)) luaL_error(L, "table expected"); for (i = 0; i < stmt->nparams; lua_pop(L, 1), i++) { param = stmt->params + i; lua_pushnumber(L, param->id); lua_gettable(L, -2); if (lua_isnil(L, -1)) { param->is_null = 1; continue; } param->is_null = 0; switch (param->type) { case DB_TYPE_INT: *((int *)param->buf) = luaL_checknumber(L, -1); break; case DB_TYPE_CHAR: str = luaL_checkstring(L, -1); length = lua_objlen(L, -1); if (length > param->buflen) { param->buf = realloc(param->buf, length); needs_rebind = 1; } strncpy(param->buf, str, length); param->buflen = length; break; default: luaL_error(L, "Unsupported variable type: %s", lua_typename(L, lua_type(L, -1))); } } /* Rebind if needed */ if (needs_rebind) { binds = (db_bind_t *)calloc(stmt->nparams, sizeof(db_bind_t)); if (binds == NULL) luaL_error(L, "Memory allocation failure"); for (i = 0; i < stmt->nparams; i++) { param = stmt->params + i; binds[i].type = param->type; binds[i].is_null = ¶m->is_null; if (*binds[i].is_null != 0) continue; switch (param->type) { case DB_TYPE_INT: binds[i].buffer = param->buf; break; case DB_TYPE_CHAR: binds[i].buffer = param->buf; binds[i].data_len = &stmt->params[i].buflen; binds[i].is_null = 0; break; default: luaL_error(L, "Unsupported variable type"); } } if (db_bind_param(stmt->ptr, binds, stmt->nparams)) luaL_error(L, "db_bind_param() failed"); free(binds); } ptr = db_execute(stmt->ptr); if (ptr == NULL && tls_lua_ctxt.con->error == DB_ERROR_IGNORABLE) { stmt->rs = NULL; throw_restart_event(L); } else { rs = (sb_lua_db_rs_t *)lua_newuserdata(L, sizeof(sb_lua_db_rs_t)); rs->ptr = ptr; luaL_getmetatable(L, "sysbench.rs"); lua_setmetatable(L, -2); stmt->rs = rs; } return 1; } int sb_lua_db_close(lua_State *L) { sb_lua_db_stmt_t *stmt; unsigned int i; check_connection(L, &tls_lua_ctxt); stmt = (sb_lua_db_stmt_t *)luaL_checkudata(L, 1, "sysbench.stmt"); luaL_argcheck(L, stmt != NULL, 1, "prepared statement expected"); for (i = 0; i < stmt->nparams; i++) { if (stmt->params[i].buf != NULL) free(stmt->params[i].buf); } free(stmt->params); stmt->params = NULL; luaL_unref(L, LUA_REGISTRYINDEX, stmt->param_ref); luaL_unref(L, LUA_REGISTRYINDEX, stmt->result_ref); db_close(stmt->ptr); return 0; } int sb_lua_db_store_results(lua_State *L) { sb_lua_db_rs_t *rs; check_connection(L, &tls_lua_ctxt); rs = (sb_lua_db_rs_t *)luaL_checkudata(L, 1, "sysbench.rs"); luaL_argcheck(L, rs != NULL, 1, "result set expected"); /* noop as db_store_results() is now performed automatically by db_query() */ return 0; } int sb_lua_db_free_results(lua_State *L) { sb_lua_db_rs_t *rs; check_connection(L, &tls_lua_ctxt); rs = (sb_lua_db_rs_t *)luaL_checkudata(L, 1, "sysbench.rs"); luaL_argcheck(L, rs != NULL, 1, "result set expected"); if (rs->ptr != NULL) { db_free_results(rs->ptr); rs->ptr = NULL; } return 0; } unsigned int sb_lua_table_size(lua_State *L, int index) { unsigned int i; lua_pushnil(L); for (i = 0; lua_next(L, index); i++) { lua_pop(L, 1); } return i; } /* Check if a specified hook exists */ static bool sb_lua_hook_defined(lua_State *L, const char *name) { if (L == NULL) return false; lua_getglobal(L, "sysbench"); lua_getfield(L, -1, "hooks"); lua_getfield(L, -1, name); bool rc = lua_isfunction(L, -1); lua_pop(L, 3); return rc; } /* Push a specified hook on stack */ static bool sb_lua_hook_push(lua_State *L, const char *name) { if (L == NULL) return false; lua_getglobal(L, "sysbench"); lua_getfield(L, -1, "hooks"); lua_getfield(L, -1, name); if (!lua_isfunction(L, -1)) { lua_pop(L, 3); return false; } lua_remove(L, -2); /* hooks */ lua_remove(L, -2); /* sysbench */ return true; } bool sb_lua_loaded(void) { return gstate != NULL; } /* Check if a specified custom command exists */ bool sb_lua_custom_command_defined(const char *name) { lua_State * const L = gstate; lua_getglobal(L, "sysbench"); lua_getfield(L, -1, "cmdline"); lua_getfield(L, -1, "command_defined"); if (!lua_isfunction(L, -1)) { log_text(LOG_WARNING, "Cannot find the sysbench.cmdline.command_defined function"); lua_pop(L, 3); return 1; } lua_pushstring(L, name); if (lua_pcall(L, 1, 1, 0) != 0) { call_error(L, "sysbench.cmdline.command_defined"); lua_pop(L, 2); return 1; } bool rc = lua_toboolean(L, -1); lua_pop(L, 3); return rc; } /* Check if a specified custom command supports parallel execution */ static bool sb_lua_custom_command_parallel(const char *name) { lua_State * const L = gstate; lua_getglobal(L, "sysbench"); lua_getfield(L, -1, "cmdline"); lua_getfield(L, -1, "command_parallel"); if (!lua_isfunction(L, -1)) { log_text(LOG_WARNING, "Cannot find the sysbench.cmdline.command_parallel function"); lua_pop(L, 3); return 1; } lua_pushstring(L, name); if (lua_pcall(L, 1, 1, 0) != 0) { call_error(L, "sysbench.cmdline.command_parallel"); lua_pop(L, 2); return 1; } bool rc = lua_toboolean(L, -1); lua_pop(L, 3); return rc; } static int call_custom_command(lua_State *L) { if (export_options(L)) return 1; lua_getglobal(L, "sysbench"); lua_getfield(L, -1, "cmdline"); lua_getfield(L, -1, "call_command"); if (!lua_isfunction(L, -1)) { log_text(LOG_WARNING, "Cannot find the sysbench.cmdline.call_command function"); lua_pop(L, 3); return 1; } lua_pushstring(L, sb_lua_custom_command); if (lua_pcall(L, 1, 1, 0) != 0) { call_error(L, "sysbench.cmdline.call_command"); lua_pop(L, 2); return 1; } bool rc = lua_toboolean(L, -1); lua_pop(L, 3); return rc ? EXIT_SUCCESS : EXIT_FAILURE; } static void *cmd_worker_thread(void *arg) { sb_thread_ctxt_t *ctxt= (sb_thread_ctxt_t *)arg; sb_tls_thread_id = ctxt->id; /* Initialize thread-local RNG state */ sb_rand_thread_init(); lua_State * const L = sb_lua_new_state(); if (L == NULL) { log_text(LOG_FATAL, "failed to create a thread to execute command"); return NULL; } call_custom_command(L); sb_lua_close_state(L); return NULL; } /* Call a specified custom command */ int sb_lua_call_custom_command(const char *name) { sb_lua_custom_command = name; if (sb_lua_custom_command_parallel(name) && sb_globals.threads > 1) { int err; if ((err = sb_thread_create_workers(cmd_worker_thread))) return err; return sb_thread_join_workers(); } return call_custom_command(gstate); } #define stat_to_number(name) sb_lua_var_number(L, #name, stat->name) static void stat_to_lua_table(lua_State *L, sb_stat_t *stat) { lua_newtable(L); stat_to_number(threads_running); stat_to_number(time_interval); stat_to_number(time_total); stat_to_number(latency_pct); stat_to_number(events); stat_to_number(reads); stat_to_number(writes); stat_to_number(other); stat_to_number(errors); stat_to_number(reconnects); } /* Call sysbench.hooks.report_intermediate */ static void sb_lua_report_intermediate(sb_stat_t *stat) { lua_State * const L = tls_lua_ctxt.L; if (!sb_lua_hook_push(L, REPORT_INTERMEDIATE_HOOK)) return; stat_to_lua_table(L, stat); /* The following is only available for intermediate reports with tx_rate > 0 */ stat_to_number(queue_length); stat_to_number(concurrency); if (lua_pcall(L, 1, 0, 0)) { call_error(L, REPORT_INTERMEDIATE_HOOK); } } /* Call sysbench.hooks.report_cumulative */ static void sb_lua_report_cumulative(sb_stat_t *stat) { lua_State * const L = tls_lua_ctxt.L; /* This may be called either from a separate checkpoint thread (in which case options are exported by sb_lua_report_thread_init(), or from the master thread on benchmark exit. In the latter case, options must be exported, as we don't normally do that for the global Lua state. */ if (L == gstate) export_options(L); if (!sb_lua_hook_push(L, REPORT_CUMULATIVE_HOOK)) return; stat_to_lua_table(L, stat); /* The following stats are only available for cumulative reports */ stat_to_number(latency_min); stat_to_number(latency_max); stat_to_number(latency_avg); stat_to_number(latency_sum); if (lua_pcall(L, 1, 0, 0)) { call_error(L, REPORT_CUMULATIVE_HOOK); } } #undef stat_to_number int sb_lua_report_thread_init(void) { if (tls_lua_ctxt.L == NULL) { sb_lua_new_state(); export_options(tls_lua_ctxt.L); } return 0; } void sb_lua_report_thread_done(void *arg) { (void) arg; /* unused */ if (sb_lua_loaded()) sb_lua_close_state(tls_lua_ctxt.L); } sysbench-1.0.18/src/sb_win.h0000600000175000017500000000506413553247311013445 0ustar jpjp#ifndef SB_WINPORT_H #define SB_WINPORT_H #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0500 #endif #define _CRT_SECURE_NO_WARNINGS #include #include #include #include #if (_MSC_VER < 1400) #error "need Visual Studio 2005 or higher" #endif #ifndef PACKAGE #define PACKAGE "sysbench" #endif #ifndef PACKAGE_VERSION #define PACKAGE_VERSION "1.0" #endif #define strcasecmp _stricmp #define strncasecmp _strnicmp #define srandom(seed) srand(seed) typedef intptr_t ssize_t; #ifdef _WIN64 #define SIZEOF_SIZE_T 8 #else #define SIZEOF_SIZE_T 4 #endif #ifndef __cplusplus #ifndef inline #define inline __inline #endif #endif typedef HANDLE pthread_t; typedef CRITICAL_SECTION pthread_mutex_t; #define SIGNAL 0 #define BROADCAST 1 #define MAX_EVENTS 2 typedef struct _pthread_cond_t { int waiting; CRITICAL_SECTION lock_waiting; HANDLE events[MAX_EVENTS]; HANDLE broadcast_block_event; }pthread_cond_t; typedef struct { char unused; }pthread_condattr_t; typedef struct { DWORD stacksize; }pthread_attr_t; typedef struct { char unused; }pthread_mutexattr_t; typedef volatile LONG pthread_once_t; extern int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); #define PTHREAD_ONCE_INIT 0 #define PTHREAD_ONCE_INPROGRESS 1 #define PTHREAD_ONCE_DONE 2 extern int pthread_attr_init(pthread_attr_t *attr); extern int pthread_cond_destroy(pthread_cond_t *cond); extern int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime); extern int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); extern int pthread_cond_signal(pthread_cond_t *cond); extern int pthread_mutex_lock(pthread_mutex_t *mutex); extern int pthread_mutex_unlock(pthread_mutex_t *mutex); extern int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); extern int pthread_mutex_destroy(pthread_mutex_t *mutex); extern int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); extern int pthread_cancel(pthread_t thread); extern int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize); extern int pthread_join(pthread_t thread, void **value_ptr); extern pthread_t pthread_self(void); extern int gettimeofday(struct timeval * tp, void * tzp); extern int random(); #define ETIMEDOUT 2204 static __inline int usleep(int micros) { Sleep(micros/1000); return 0; } #define gmtime_r(a,b) gmtime_s(b,a) #endif sysbench-1.0.18/src/sb_win.c0000600000175000017500000001552013553247311013436 0ustar jpjp/* Copyright (C) 2008 MySQL AB Copyright (C) 2008-2010 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* This file contains Windows port of Posix functionality used in sysbench (partial implementation of pthreads, gettimeofday() and random() */ #define _CRT_RAND_S /* for rand_s */ #include #include #include #include "sb_win.h" int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { cond->waiting= 0; InitializeCriticalSection(&cond->lock_waiting); cond->events[SIGNAL]= CreateEvent(NULL, FALSE, FALSE, NULL); cond->events[BROADCAST]= CreateEvent(NULL, TRUE, FALSE, NULL); cond->broadcast_block_event= CreateEvent(NULL, TRUE, TRUE, NULL); if( cond->events[SIGNAL] == NULL || cond->events[BROADCAST] == NULL || cond->broadcast_block_event == NULL ) return ENOMEM; return 0; } int pthread_cond_destroy(pthread_cond_t *cond) { DeleteCriticalSection(&cond->lock_waiting); if (CloseHandle(cond->events[SIGNAL]) == 0 || CloseHandle(cond->events[BROADCAST]) == 0 || CloseHandle(cond->broadcast_block_event) == 0) return EINVAL; return 0; } int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { return pthread_cond_timedwait(cond,mutex,NULL); } int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime) { int result; long timeout; union { FILETIME ft; long long i64; }now; if( abstime != NULL ) { long long stoptime_nanos = (abstime->tv_sec*1000000000 + abstime->tv_nsec); long long now_nanos; long long timeout_nanos; GetSystemTimeAsFileTime(&now.ft); now_nanos = now.i64 *100; timeout_nanos = stoptime_nanos - now_nanos; timeout = (long)(timeout_nanos /1000000); } else { /* No time specified; don't expire */ timeout= INFINITE; } /* Block access if previous broadcast hasn't finished. This is just for safety and should normally not affect the total time spent in this function. */ WaitForSingleObject(cond->broadcast_block_event, INFINITE); EnterCriticalSection(&cond->lock_waiting); cond->waiting++; LeaveCriticalSection(&cond->lock_waiting); LeaveCriticalSection(mutex); result= WaitForMultipleObjects(2, cond->events, FALSE, timeout); EnterCriticalSection(&cond->lock_waiting); cond->waiting--; if (cond->waiting == 0 && result == (WAIT_OBJECT_0+BROADCAST)) { /* We're the last waiter to be notified or to stop waiting, so reset the manual event. */ /* Close broadcast gate */ ResetEvent(cond->events[BROADCAST]); /* Open block gate */ SetEvent(cond->broadcast_block_event); } LeaveCriticalSection(&cond->lock_waiting); EnterCriticalSection(mutex); return result == WAIT_TIMEOUT ? ETIMEDOUT : 0; } int pthread_cond_signal(pthread_cond_t *cond) { EnterCriticalSection(&cond->lock_waiting); if(cond->waiting > 0) SetEvent(cond->events[SIGNAL]); LeaveCriticalSection(&cond->lock_waiting); return 0; } int pthread_cond_broadcast(pthread_cond_t *cond) { EnterCriticalSection(&cond->lock_waiting); /* The mutex protect us from broadcasting if there isn't any thread waiting to open the block gate after this call has closed it. */ if(cond->waiting > 0) { /* Close block gate */ ResetEvent(cond->broadcast_block_event); /* Open broadcast gate */ SetEvent(cond->events[BROADCAST]); } LeaveCriticalSection(&cond->lock_waiting); return 0; } int pthread_attr_init(pthread_attr_t *attr) { attr->stacksize = 0; return 0; } int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { InitializeCriticalSection(mutex); return 0; } int pthread_mutex_lock(pthread_mutex_t *mutex) { EnterCriticalSection(mutex); return 0; } int pthread_mutex_unlock(pthread_mutex_t *mutex) { LeaveCriticalSection(mutex); return 0; } int pthread_mutex_destroy(pthread_mutex_t *mutex) { DeleteCriticalSection(mutex); return 0; } int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg) { DWORD tid; *thread = CreateThread(NULL, attr->stacksize, (LPTHREAD_START_ROUTINE) start_routine, arg, STACK_SIZE_PARAM_IS_A_RESERVATION, &tid); if (*thread != NULL) return 0; return -1; } int pthread_cancel(pthread_t thread) { return !TerminateThread(thread, 0); } /* Minimal size of thread stack on Windows*/ #define PTHREAD_STACK_MIN 65536*2 int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize) { if(stacksize) attr->stacksize = max(stacksize, PTHREAD_STACK_MIN); return 0; } int pthread_join(pthread_t pthread, void **value_ptr) { if (WaitForSingleObject(pthread, INFINITE) != WAIT_OBJECT_0) return -1; if (value_ptr) *value_ptr = 0; return 0; } pthread_t pthread_self(void) { return GetCurrentThreadId(); } /* One time initialization. For simplicity, we assume initializer thread does not exit within init_routine(). */ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { LONG state = InterlockedCompareExchange(once_control, PTHREAD_ONCE_INPROGRESS, PTHREAD_ONCE_INIT); switch(state) { case PTHREAD_ONCE_INIT: /* This is initializer thread */ (*init_routine)(); *once_control = PTHREAD_ONCE_DONE; break; case PTHREAD_ONCE_INPROGRESS: /* init_routine in progress. Wait for its completion */ while(*once_control == PTHREAD_ONCE_INPROGRESS) { Sleep(1); } break; case PTHREAD_ONCE_DONE: /* Nothing to do */ break; } return 0; } #include int gettimeofday(struct timeval * tp, void * tzp) { static long long qpf = 0, startup_time = 0; long long qpc; if(qpf == 0) { QueryPerformanceFrequency((LARGE_INTEGER *)&qpf); } if(startup_time == 0) { QueryPerformanceCounter((LARGE_INTEGER *)&qpc); startup_time = time(NULL) - (qpc/qpf); } QueryPerformanceCounter((LARGE_INTEGER *)&qpc); tp->tv_sec = (long)(startup_time + qpc/qpf); tp->tv_usec = (long)((qpc%qpf)*1000000/qpf); return 0; } int random() { int ret; rand_s(&ret); return ret; } sysbench-1.0.18/src/sb_timer.h0000600000175000017500000001203213553247311013761 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_TIMER_H #define SB_TIMER_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 #include "sb_win.h" #endif #ifdef TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #include #include #include "sb_util.h" #include "ck_spinlock.h" #define NS_PER_SEC 1000000000 #define US_PER_SEC 1000000 #define MS_PER_SEC 1000 #define NS_PER_MS (NS_PER_SEC / MS_PER_SEC) /* Convert nanoseconds to seconds and vice versa */ #define NS2SEC(nsec) ((nsec) / (double) NS_PER_SEC) #define SEC2NS(sec) ((uint64_t) (sec) * NS_PER_SEC) /* Convert nanoseconds to milliseconds and vice versa */ #define NS2MS(nsec) ((nsec) / (double) NS_PER_MS) #define MS2NS(sec) ((sec) * (uint64_t) NS_PER_MS) /* Convert milliseconds to seconds and vice versa */ #define MS2SEC(msec) ((msec) / (double) MS_PER_SEC) #define SEC2MS(sec) ((sec) * MS_PER_SEC) /* Difference between two 'timespec' values in nanoseconds */ #define TIMESPEC_DIFF(a,b) (SEC2NS(a.tv_sec - b.tv_sec) + \ (a.tv_nsec - b.tv_nsec)) /* Wrapper over various *gettime* functions */ #ifdef HAVE_CLOCK_GETTIME # define SB_GETTIME(tsp) clock_gettime(CLOCK_MONOTONIC, tsp) #else # define SB_GETTIME(tsp) \ do { \ struct timeval tv; \ gettimeofday(&tv, NULL); \ (tsp)->tv_sec = tv.tv_sec; \ (tsp)->tv_nsec = tv.tv_usec * 1000; \ } while (0) #endif typedef enum {TIMER_UNINITIALIZED, TIMER_INITIALIZED, TIMER_STOPPED, \ TIMER_RUNNING} timer_state_t; /* Timer structure definition */ typedef struct { struct timespec time_start; struct timespec time_end; uint64_t events; uint64_t queue_time; uint64_t min_time; uint64_t max_time; uint64_t sum_time; ck_spinlock_t lock; char pad[SB_CACHELINE_PAD(sizeof(struct timespec)*2 + sizeof(uint64_t)*5 + sizeof(ck_spinlock_t))]; } sb_timer_t; static inline int sb_nanosleep(uint64_t ns) { struct timespec ts = { ns / NS_PER_SEC, ns % NS_PER_SEC }; return nanosleep(&ts, NULL); } /* timer control functions */ /* Initialize timer */ void sb_timer_init(sb_timer_t *); /* Reset timer counters, but leave the current state intact */ void sb_timer_reset(sb_timer_t *t); /* check whether the timer is running */ bool sb_timer_running(sb_timer_t *t); /* start timer */ static inline void sb_timer_start(sb_timer_t *t) { ck_spinlock_lock(&t->lock); SB_GETTIME(&t->time_start); ck_spinlock_unlock(&t->lock); } /* stop timer */ static inline uint64_t sb_timer_stop(sb_timer_t *t) { ck_spinlock_lock(&t->lock); SB_GETTIME(&t->time_end); uint64_t elapsed = TIMESPEC_DIFF(t->time_end, t->time_start) + t->queue_time; t->events++; t->sum_time += elapsed; if (SB_UNLIKELY(elapsed < t->min_time)) t->min_time = elapsed; if (SB_UNLIKELY(elapsed > t->max_time)) t->max_time = elapsed; ck_spinlock_unlock(&t->lock); return elapsed; } /* get the current timer value in nanoseconds without affecting its state, i.e. is safe to be used concurrently on a shared timer. */ static inline uint64_t sb_timer_value(sb_timer_t *t) { struct timespec ts; SB_GETTIME(&ts); return TIMESPEC_DIFF(ts, t->time_start) + t->queue_time; } /* Clone a timer */ void sb_timer_copy(sb_timer_t *to, sb_timer_t *from); /* get time elapsed since the previous call to sb_timer_checkpoint() for the specified timer without stopping it. The first call returns time elapsed since the timer was started. */ uint64_t sb_timer_current(sb_timer_t *t); /* Atomically reset a given timer after copying its state into the timer pointed to by 'old'. */ void sb_timer_checkpoint(sb_timer_t *t, sb_timer_t *old); /* get average time per event */ uint64_t sb_timer_avg(sb_timer_t *); /* get total time for all events */ uint64_t sb_timer_sum(sb_timer_t *); /* get minimum time */ uint64_t sb_timer_min(sb_timer_t *); /* get maximum time */ uint64_t sb_timer_max(sb_timer_t *); /* sum data from two timers. used in summing data from multiple threads */ sb_timer_t sb_timer_merge(sb_timer_t *, sb_timer_t *); #endif /* SB_TIMER_H */ sysbench-1.0.18/src/sb_barrier.c0000600000175000017500000000524613553247311014273 0ustar jpjp/* Copyright (C) 2016 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Thread barrier implementation. It differs from pthread_barrier_t in two ways: - it's more portable (will also work on OS X and Windows with existing pthread_* wrappers in sb_win.c). - it allows defining a callback function which is called right before signaling the participating threads to continue, i.e. as soon as the required number of threads reach the barrier. The callback can also signal an error to sb_barrier_wait() callers by returning a non-zero value. In which case sb_barrier_wait() returns a negative value to all callers. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "sb_barrier.h" int sb_barrier_init(sb_barrier_t *barrier, unsigned int count, sb_barrier_cb_t callback, void *arg) { if (count == 0) return 1; if (pthread_mutex_init(&barrier->mutex, NULL) || pthread_cond_init(&barrier->cond, NULL)) return 1; barrier->init_count = count; barrier->count = count; barrier->callback = callback; barrier->arg = arg; barrier->serial = 0; barrier->error = 0; return 0; } int sb_barrier_wait(sb_barrier_t *barrier) { int res; pthread_mutex_lock(&barrier->mutex); if (!--barrier->count) { barrier->serial++; barrier->count = barrier->init_count; res = SB_BARRIER_SERIAL_THREAD; pthread_cond_broadcast(&barrier->cond); if (barrier->callback != NULL && barrier->callback(barrier->arg) != 0) { barrier->error = 1; res = -1; } pthread_mutex_unlock(&barrier->mutex); } else { unsigned int serial = barrier->serial; do { pthread_cond_wait(&barrier->cond, &barrier->mutex); } while (serial == barrier->serial); res = barrier->error ? -1 : 0; pthread_mutex_unlock(&barrier->mutex); } return res; } void sb_barrier_destroy(sb_barrier_t *barrier) { pthread_mutex_destroy(&barrier->mutex); pthread_cond_destroy(&barrier->cond); } sysbench-1.0.18/src/sb_rand.c0000600000175000017500000002020213553247311013556 0ustar jpjp/* Copyright (C) 2016-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_MATH_H # include #endif #include "sb_options.h" #include "sb_rand.h" #include "sb_logger.h" #include "sb_ck_pr.h" TLS sb_rng_state_t sb_rng_state CK_CC_CACHELINE; /* Exported variables */ int sb_rand_seed; /* optional seed set on the command line */ /* Random numbers command line options */ static sb_arg_t rand_args[] = { SB_OPT("rand-type", "random numbers distribution {uniform,gaussian,special,pareto}", "special", STRING), SB_OPT("rand-spec-iter", "number of iterations used for numbers generation", "12", INT), SB_OPT("rand-spec-pct", "percentage of values to be treated as 'special' " "(for special distribution)", "1", INT), SB_OPT("rand-spec-res", "percentage of 'special' values to use " "(for special distribution)", "75", INT), SB_OPT("rand-seed", "seed for random number generator. When 0, the current time is " "used as a RNG seed.", "0", INT), SB_OPT("rand-pareto-h", "parameter h for pareto distribution", "0.2", DOUBLE), SB_OPT_END }; static rand_dist_t rand_type; /* pointer to the default PRNG as defined by --rand-type */ static uint32_t (*rand_func)(uint32_t, uint32_t); static unsigned int rand_iter; static unsigned int rand_pct; static unsigned int rand_res; /* Pre-computed FP constants to avoid unnecessary conversions and divisions at runtime. */ static double rand_iter_mult; static double rand_pct_mult; static double rand_pct_2_mult; static double rand_res_mult; /* parameters for Pareto distribution */ static double pareto_h; /* parameter h */ static double pareto_power; /* parameter pre-calculated by h */ /* Unique sequence generator state */ static uint32_t rand_unique_index CK_CC_CACHELINE; static uint32_t rand_unique_offset; extern inline uint64_t sb_rand_uniform_uint64(void); extern inline double sb_rand_uniform_double(void); extern inline uint64_t xoroshiro_rotl(const uint64_t, int); extern inline uint64_t xoroshiro_next(uint64_t s[2]); static void rand_unique_seed(uint32_t index, uint32_t offset); int sb_rand_register(void) { sb_register_arg_set(rand_args); return 0; } /* Initialize random numbers generation */ int sb_rand_init(void) { char *s; sb_rand_seed = sb_get_value_int("rand-seed"); s = sb_get_value_string("rand-type"); if (!strcmp(s, "uniform")) { rand_type = DIST_TYPE_UNIFORM; rand_func = &sb_rand_uniform; } else if (!strcmp(s, "gaussian")) { rand_type = DIST_TYPE_GAUSSIAN; rand_func = &sb_rand_gaussian; } else if (!strcmp(s, "special")) { rand_type = DIST_TYPE_SPECIAL; rand_func = &sb_rand_special; } else if (!strcmp(s, "pareto")) { rand_type = DIST_TYPE_PARETO; rand_func = &sb_rand_pareto; } else { log_text(LOG_FATAL, "Invalid random numbers distribution: %s.", s); return 1; } rand_iter = sb_get_value_int("rand-spec-iter"); rand_iter_mult = 1.0 / rand_iter; rand_pct = sb_get_value_int("rand-spec-pct"); rand_pct_mult = rand_pct / 100.0; rand_pct_2_mult = rand_pct / 200.0; rand_res = sb_get_value_int("rand-spec-res"); rand_res_mult = 100.0 / (100.0 - rand_res); pareto_h = sb_get_value_double("rand-pareto-h"); pareto_power = log(pareto_h) / log(1.0-pareto_h); /* Seed PRNG for the main thread. Worker thread do their own seeding */ sb_rand_thread_init(); /* Seed the unique sequence generator */ rand_unique_seed(random(), random()); return 0; } void sb_rand_print_help(void) { printf("Pseudo-Random Numbers Generator options:\n"); sb_print_options(rand_args); } void sb_rand_done(void) { } /* Initialize thread-local RNG state */ void sb_rand_thread_init(void) { /* We use libc PRNG to seed xoroshiro128+ */ sb_rng_state[0] = (((uint64_t) random()) << 32) | (((uint64_t) random()) & UINT32_MAX); sb_rng_state[1] = (((uint64_t) random()) << 32) | (((uint64_t) random()) & UINT32_MAX); } /* Return random number in the specified range with distribution specified with the --rand-type command line option */ uint32_t sb_rand_default(uint32_t a, uint32_t b) { return rand_func(a,b); } /* uniform distribution */ uint32_t sb_rand_uniform(uint32_t a, uint32_t b) { return a + sb_rand_uniform_double() * (b - a + 1); } /* gaussian distribution */ uint32_t sb_rand_gaussian(uint32_t a, uint32_t b) { double sum; double t; unsigned int i; t = b - a + 1; for(i=0, sum=0; i < rand_iter; i++) sum += sb_rand_uniform_double() * t; return a + (uint32_t) (sum * rand_iter_mult) ; } /* 'special' distribution */ uint32_t sb_rand_special(uint32_t a, uint32_t b) { double sum; double t; double range_size; double res; double d; double rnd; unsigned int i; t = b - a; /* Increase range size for special values. */ range_size = t * rand_res_mult; /* Generate uniformly distributed one at this stage */ rnd = sb_rand_uniform_double(); /* Random double in the [0, 1) interval */ /* Random integer in the [0, range_size) interval */ res = rnd * range_size; /* Use gaussian distribution for (100 - rand_res) percent of all generated values. */ if (res < t) { sum = 0.0; for(i = 0; i < rand_iter; i++) sum += sb_rand_uniform_double(); return a + sum * t * rand_iter_mult; } /* For the remaining rand_res percent of values use the uniform distribution. We map previously generated random double in the [0, 1) interval to the rand_pct percent part of the [a, b] interval. Then we move the resulting value in the [0, (b-a) * (rand_pct / 100)] interval to the center of the original interval [a, b]. */ d = t * rand_pct_mult; res = rnd * (d + 1); res += t / 2 - t * rand_pct_2_mult; return a + (uint32_t) res; } /* Pareto distribution */ uint32_t sb_rand_pareto(uint32_t a, uint32_t b) { return a + (uint32_t) ((b - a + 1) * pow(sb_rand_uniform_double(), pareto_power)); } /* Generate random string */ void sb_rand_str(const char *fmt, char *buf) { unsigned int i; for (i=0; fmt[i] != '\0'; i++) { if (fmt[i] == '#') buf[i] = sb_rand_uniform('0', '9'); else if (fmt[i] == '@') buf[i] = sb_rand_uniform('a', 'z'); else buf[i] = fmt[i]; } } /* Unique random sequence generator. This is based on public domain code from https://github.com/preshing/RandomSequence */ static uint32_t rand_unique_permute(uint32_t x) { static const uint32_t prime = UINT32_C(4294967291); if (x >= prime) return x; /* The 5 integers out of range are mapped to themselves. */ uint32_t residue = ((uint64_t) x * x) % prime; return (x <= prime / 2) ? residue : prime - residue; } static void rand_unique_seed(uint32_t index, uint32_t offset) { rand_unique_index = rand_unique_permute(rand_unique_permute(index) + 0x682f0161); rand_unique_offset = rand_unique_permute(rand_unique_permute(offset) + 0x46790905); } /* This is safe to be called concurrently from multiple threads */ uint32_t sb_rand_unique(void) { uint32_t index = ck_pr_faa_32(&rand_unique_index, 1); return rand_unique_permute((rand_unique_permute(index) + rand_unique_offset) ^ 0x5bf03635); } sysbench-1.0.18/src/sb_counter.c0000600000175000017500000000475713553247311014332 0ustar jpjp/* Copyright (C) 2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "sb_counter.h" #include "sysbench.h" #include "sb_util.h" #include "sb_ck_pr.h" sb_counters_t *sb_counters CK_CC_CACHELINE; static sb_counters_t last_intermediate_counters; static sb_counters_t last_cumulative_counters; /* Initialize per-thread stats */ int sb_counters_init(void) { SB_COMPILE_TIME_ASSERT(sizeof(sb_counters_t) % CK_MD_CACHELINE == 0); sb_counters = sb_alloc_per_thread_array(sizeof(sb_counters_t)); return sb_counters == NULL; } void sb_counters_done(void) { if (sb_counters != NULL) { free(sb_counters); sb_counters = NULL; } } static void sb_counters_merge(sb_counters_t dst) { for (size_t t = 0; t < SB_CNT_MAX; t++) for (size_t i = 0; i < sb_globals.threads; i++) dst[t] += sb_counter_val(i, t); } static void sb_counters_checkpoint(sb_counters_t dst, sb_counters_t cp) { for (size_t i = 0; i < SB_CNT_MAX; i++) { uint64_t tmp = cp[i]; cp[i] = dst[i]; dst[i] = dst[i] - tmp; } } /* Return aggregate counter values since the last intermediate report. This is not thread-safe as it updates the global last report state, so it must be called from a single thread. */ void sb_counters_agg_intermediate(sb_counters_t val) { memset(val, 0, sizeof(sb_counters_t)); sb_counters_merge(val); sb_counters_checkpoint(val, last_intermediate_counters); } /* Return aggregate counter values since the last cumulative report. This is not thread-safe as it updates the global last report state, so it must be called from a single thread. */ void sb_counters_agg_cumulative(sb_counters_t val) { memset(val, 0, sizeof(sb_counters_t)); sb_counters_merge(val); sb_counters_checkpoint(val, last_cumulative_counters); } sysbench-1.0.18/src/lua/0000700000175000017500000000000013553247311012565 5ustar jpjpsysbench-1.0.18/src/lua/oltp_update_index.lua0000700000175000017500000000213613553247311017004 0ustar jpjp#!/usr/bin/env sysbench -- Copyright (C) 2006-2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- Update-Index OLTP benchmark -- ---------------------------------------------------------------------- require("oltp_common") function prepare_statements() prepare_index_updates() end function event() execute_index_updates(con) end sysbench-1.0.18/src/lua/oltp_write_only.lua0000700000175000017500000000264013553247311016526 0ustar jpjp#!/usr/bin/env sysbench -- Copyright (C) 2006-2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- Write-Only OLTP benchmark -- ---------------------------------------------------------------------- require("oltp_common") function prepare_statements() if not sysbench.opt.skip_trx then prepare_begin() prepare_commit() end prepare_index_updates() prepare_non_index_updates() prepare_delete_inserts() end function event() if not sysbench.opt.skip_trx then begin() end execute_index_updates() execute_non_index_updates() execute_delete_inserts() if not sysbench.opt.skip_trx then commit() end end sysbench-1.0.18/src/lua/oltp_common.lua0000600000175000017500000003404113553247311015622 0ustar jpjp-- Copyright (C) 2006-2018 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ----------------------------------------------------------------------------- -- Common code for OLTP benchmarks. -- ----------------------------------------------------------------------------- function init() assert(event ~= nil, "this script is meant to be included by other OLTP scripts and " .. "should not be called directly.") end if sysbench.cmdline.command == nil then error("Command is required. Supported commands: prepare, prewarm, run, " .. "cleanup, help") end -- Command line options sysbench.cmdline.options = { table_size = {"Number of rows per table", 10000}, range_size = {"Range size for range SELECT queries", 100}, tables = {"Number of tables", 1}, point_selects = {"Number of point SELECT queries per transaction", 10}, simple_ranges = {"Number of simple range SELECT queries per transaction", 1}, sum_ranges = {"Number of SELECT SUM() queries per transaction", 1}, order_ranges = {"Number of SELECT ORDER BY queries per transaction", 1}, distinct_ranges = {"Number of SELECT DISTINCT queries per transaction", 1}, index_updates = {"Number of UPDATE index queries per transaction", 1}, non_index_updates = {"Number of UPDATE non-index queries per transaction", 1}, delete_inserts = {"Number of DELETE/INSERT combinations per transaction", 1}, range_selects = {"Enable/disable all range SELECT queries", true}, auto_inc = {"Use AUTO_INCREMENT column as Primary Key (for MySQL), " .. "or its alternatives in other DBMS. When disabled, use " .. "client-generated IDs", true}, skip_trx = {"Don't start explicit transactions and execute all queries " .. "in the AUTOCOMMIT mode", false}, secondary = {"Use a secondary index in place of the PRIMARY KEY", false}, create_secondary = {"Create a secondary index in addition to the PRIMARY KEY", true}, mysql_storage_engine = {"Storage engine, if MySQL is used", "innodb"}, pgsql_variant = {"Use this PostgreSQL variant when running with the " .. "PostgreSQL driver. The only currently supported " .. "variant is 'redshift'. When enabled, " .. "create_secondary is automatically disabled, and " .. "delete_inserts is set to 0"} } -- Prepare the dataset. This command supports parallel execution, i.e. will -- benefit from executing with --threads > 1 as long as --tables > 1 function cmd_prepare() local drv = sysbench.sql.driver() local con = drv:connect() for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables, sysbench.opt.threads do create_table(drv, con, i) end end -- Preload the dataset into the server cache. This command supports parallel -- execution, i.e. will benefit from executing with --threads > 1 as long as -- --tables > 1 -- -- PS. Currently, this command is only meaningful for MySQL/InnoDB benchmarks function cmd_prewarm() local drv = sysbench.sql.driver() local con = drv:connect() assert(drv:name() == "mysql", "prewarm is currently MySQL only") -- Do not create on disk tables for subsequent queries con:query("SET tmp_table_size=2*1024*1024*1024") con:query("SET max_heap_table_size=2*1024*1024*1024") for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables, sysbench.opt.threads do local t = "sbtest" .. i print("Prewarming table " .. t) con:query("ANALYZE TABLE sbtest" .. i) con:query(string.format( "SELECT AVG(id) FROM " .. "(SELECT * FROM %s FORCE KEY (PRIMARY) " .. "LIMIT %u) t", t, sysbench.opt.table_size)) con:query(string.format( "SELECT COUNT(*) FROM " .. "(SELECT * FROM %s WHERE k LIKE '%%0%%' LIMIT %u) t", t, sysbench.opt.table_size)) end end -- Implement parallel prepare and prewarm commands sysbench.cmdline.commands = { prepare = {cmd_prepare, sysbench.cmdline.PARALLEL_COMMAND}, prewarm = {cmd_prewarm, sysbench.cmdline.PARALLEL_COMMAND} } -- Template strings of random digits with 11-digit groups separated by dashes -- 10 groups, 119 characters local c_value_template = "###########-###########-###########-" .. "###########-###########-###########-" .. "###########-###########-###########-" .. "###########" -- 5 groups, 59 characters local pad_value_template = "###########-###########-###########-" .. "###########-###########" function get_c_value() return sysbench.rand.string(c_value_template) end function get_pad_value() return sysbench.rand.string(pad_value_template) end function create_table(drv, con, table_num) local id_index_def, id_def local engine_def = "" local extra_table_options = "" local query if sysbench.opt.secondary then id_index_def = "KEY xid" else id_index_def = "PRIMARY KEY" end if drv:name() == "mysql" or drv:name() == "attachsql" or drv:name() == "drizzle" then if sysbench.opt.auto_inc then id_def = "INTEGER NOT NULL AUTO_INCREMENT" else id_def = "INTEGER NOT NULL" end engine_def = "/*! ENGINE = " .. sysbench.opt.mysql_storage_engine .. " */" extra_table_options = mysql_table_options or "" elseif drv:name() == "pgsql" then if not sysbench.opt.auto_inc then id_def = "INTEGER NOT NULL" elseif pgsql_variant == 'redshift' then id_def = "INTEGER IDENTITY(1,1)" else id_def = "SERIAL" end else error("Unsupported database driver:" .. drv:name()) end print(string.format("Creating table 'sbtest%d'...", table_num)) query = string.format([[ CREATE TABLE sbtest%d( id %s, k INTEGER DEFAULT '0' NOT NULL, c CHAR(120) DEFAULT '' NOT NULL, pad CHAR(60) DEFAULT '' NOT NULL, %s (id) ) %s %s]], table_num, id_def, id_index_def, engine_def, extra_table_options) con:query(query) if (sysbench.opt.table_size > 0) then print(string.format("Inserting %d records into 'sbtest%d'", sysbench.opt.table_size, table_num)) end if sysbench.opt.auto_inc then query = "INSERT INTO sbtest" .. table_num .. "(k, c, pad) VALUES" else query = "INSERT INTO sbtest" .. table_num .. "(id, k, c, pad) VALUES" end con:bulk_insert_init(query) local c_val local pad_val for i = 1, sysbench.opt.table_size do c_val = get_c_value() pad_val = get_pad_value() if (sysbench.opt.auto_inc) then query = string.format("(%d, '%s', '%s')", sb_rand(1, sysbench.opt.table_size), c_val, pad_val) else query = string.format("(%d, %d, '%s', '%s')", i, sb_rand(1, sysbench.opt.table_size), c_val, pad_val) end con:bulk_insert_next(query) end con:bulk_insert_done() if sysbench.opt.create_secondary then print(string.format("Creating a secondary index on 'sbtest%d'...", table_num)) con:query(string.format("CREATE INDEX k_%d ON sbtest%d(k)", table_num, table_num)) end end local t = sysbench.sql.type local stmt_defs = { point_selects = { "SELECT c FROM sbtest%u WHERE id=?", t.INT}, simple_ranges = { "SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ?", t.INT, t.INT}, sum_ranges = { "SELECT SUM(k) FROM sbtest%u WHERE id BETWEEN ? AND ?", t.INT, t.INT}, order_ranges = { "SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c", t.INT, t.INT}, distinct_ranges = { "SELECT DISTINCT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c", t.INT, t.INT}, index_updates = { "UPDATE sbtest%u SET k=k+1 WHERE id=?", t.INT}, non_index_updates = { "UPDATE sbtest%u SET c=? WHERE id=?", {t.CHAR, 120}, t.INT}, deletes = { "DELETE FROM sbtest%u WHERE id=?", t.INT}, inserts = { "INSERT INTO sbtest%u (id, k, c, pad) VALUES (?, ?, ?, ?)", t.INT, t.INT, {t.CHAR, 120}, {t.CHAR, 60}}, } function prepare_begin() stmt.begin = con:prepare("BEGIN") end function prepare_commit() stmt.commit = con:prepare("COMMIT") end function prepare_for_each_table(key) for t = 1, sysbench.opt.tables do stmt[t][key] = con:prepare(string.format(stmt_defs[key][1], t)) local nparam = #stmt_defs[key] - 1 if nparam > 0 then param[t][key] = {} end for p = 1, nparam do local btype = stmt_defs[key][p+1] local len if type(btype) == "table" then len = btype[2] btype = btype[1] end if btype == sysbench.sql.type.VARCHAR or btype == sysbench.sql.type.CHAR then param[t][key][p] = stmt[t][key]:bind_create(btype, len) else param[t][key][p] = stmt[t][key]:bind_create(btype) end end if nparam > 0 then stmt[t][key]:bind_param(unpack(param[t][key])) end end end function prepare_point_selects() prepare_for_each_table("point_selects") end function prepare_simple_ranges() prepare_for_each_table("simple_ranges") end function prepare_sum_ranges() prepare_for_each_table("sum_ranges") end function prepare_order_ranges() prepare_for_each_table("order_ranges") end function prepare_distinct_ranges() prepare_for_each_table("distinct_ranges") end function prepare_index_updates() prepare_for_each_table("index_updates") end function prepare_non_index_updates() prepare_for_each_table("non_index_updates") end function prepare_delete_inserts() prepare_for_each_table("deletes") prepare_for_each_table("inserts") end function thread_init() drv = sysbench.sql.driver() con = drv:connect() -- Create global nested tables for prepared statements and their -- parameters. We need a statement and a parameter set for each combination -- of connection/table/query stmt = {} param = {} for t = 1, sysbench.opt.tables do stmt[t] = {} param[t] = {} end -- This function is a 'callback' defined by individual benchmark scripts prepare_statements() end -- Close prepared statements function close_statements() for t = 1, sysbench.opt.tables do for k, s in pairs(stmt[t]) do stmt[t][k]:close() end end if (stmt.begin ~= nil) then stmt.begin:close() end if (stmt.commit ~= nil) then stmt.commit:close() end end function thread_done() close_statements() con:disconnect() end function cleanup() local drv = sysbench.sql.driver() local con = drv:connect() for i = 1, sysbench.opt.tables do print(string.format("Dropping table 'sbtest%d'...", i)) con:query("DROP TABLE IF EXISTS sbtest" .. i ) end end local function get_table_num() return sysbench.rand.uniform(1, sysbench.opt.tables) end local function get_id() return sysbench.rand.default(1, sysbench.opt.table_size) end function begin() stmt.begin:execute() end function commit() stmt.commit:execute() end function execute_point_selects() local tnum = get_table_num() local i for i = 1, sysbench.opt.point_selects do param[tnum].point_selects[1]:set(get_id()) stmt[tnum].point_selects:execute() end end local function execute_range(key) local tnum = get_table_num() for i = 1, sysbench.opt[key] do local id = get_id() param[tnum][key][1]:set(id) param[tnum][key][2]:set(id + sysbench.opt.range_size - 1) stmt[tnum][key]:execute() end end function execute_simple_ranges() execute_range("simple_ranges") end function execute_sum_ranges() execute_range("sum_ranges") end function execute_order_ranges() execute_range("order_ranges") end function execute_distinct_ranges() execute_range("distinct_ranges") end function execute_index_updates() local tnum = get_table_num() for i = 1, sysbench.opt.index_updates do param[tnum].index_updates[1]:set(get_id()) stmt[tnum].index_updates:execute() end end function execute_non_index_updates() local tnum = get_table_num() for i = 1, sysbench.opt.non_index_updates do param[tnum].non_index_updates[1]:set_rand_str(c_value_template) param[tnum].non_index_updates[2]:set(get_id()) stmt[tnum].non_index_updates:execute() end end function execute_delete_inserts() local tnum = get_table_num() for i = 1, sysbench.opt.delete_inserts do local id = get_id() local k = get_id() param[tnum].deletes[1]:set(id) param[tnum].inserts[1]:set(id) param[tnum].inserts[2]:set(k) param[tnum].inserts[3]:set_rand_str(c_value_template) param[tnum].inserts[4]:set_rand_str(pad_value_template) stmt[tnum].deletes:execute() stmt[tnum].inserts:execute() end end -- Re-prepare statements if we have reconnected, which is possible when some of -- the listed error codes are in the --mysql-ignore-errors list function sysbench.hooks.before_restart_event(errdesc) if errdesc.sql_errno == 2013 or -- CR_SERVER_LOST errdesc.sql_errno == 2055 or -- CR_SERVER_LOST_EXTENDED errdesc.sql_errno == 2006 or -- CR_SERVER_GONE_ERROR errdesc.sql_errno == 2011 -- CR_TCP_CONNECTION then close_statements() prepare_statements() end end sysbench-1.0.18/src/lua/oltp_update_non_index.lua0000700000175000017500000000214713553247311017660 0ustar jpjp#!/usr/bin/env sysbench -- Copyright (C) 2006-2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- Update-Non-Index OLTP benchmark -- ---------------------------------------------------------------------- require("oltp_common") function prepare_statements() prepare_non_index_updates() end function event() execute_non_index_updates() end sysbench-1.0.18/src/lua/select_random_points.lua0000700000175000017500000000357713553247311017522 0ustar jpjp#!/usr/bin/env sysbench -- This test is designed for testing MariaDB's key_cache_segments for MyISAM, -- and should work with other storage engines as well. -- -- For details about key_cache_segments please refer to: -- http://kb.askmonty.org/v/segmented-key-cache -- require("oltp_common") -- Add random_points to the list of standard OLTP options sysbench.cmdline.options.random_points = {"Number of random points in the IN() clause in generated SELECTs", 10} -- Override standard prepare/cleanup OLTP functions, as this benchmark does not -- support multiple tables oltp_prepare = prepare oltp_cleanup = cleanup function prepare() assert(sysbench.opt.tables == 1, "this benchmark does not support " .. "--tables > 1") oltp_prepare() end function cleanup() assert(sysbench.opt.tables == 1, "this benchmark does not support " .. "--tables > 1") oltp_cleanup() end function thread_init() drv = sysbench.sql.driver() con = drv:connect() local points = string.rep("?, ", sysbench.opt.random_points - 1) .. "?" stmt = con:prepare(string.format([[ SELECT id, k, c, pad FROM sbtest1 WHERE k IN (%s) ]], points)) params = {} for j = 1, sysbench.opt.random_points do params[j] = stmt:bind_create(sysbench.sql.type.INT) end stmt:bind_param(unpack(params)) rlen = sysbench.opt.table_size / sysbench.opt.threads thread_id = sysbench.tid % sysbench.opt.threads end function thread_done() stmt:close() con:disconnect() end function event() -- To prevent overlapping of our range queries we need to partition the whole -- table into 'threads' segments and then make each thread work with its -- own segment. for i = 1, sysbench.opt.random_points do local rmin = rlen * thread_id local rmax = rmin + rlen params[i]:set(sb_rand(rmin, rmax)) end stmt:execute() end sysbench-1.0.18/src/lua/oltp_delete.lua0000700000175000017500000000241213553247311015572 0ustar jpjp#!/usr/bin/env sysbench -- Copyright (C) 2006-2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- Delete-Only OLTP benchmark -- ---------------------------------------------------------------------- require("oltp_common") function prepare_statements() prepare_for_each_table("deletes") end function event() local tnum = sysbench.rand.uniform(1, sysbench.opt.tables) local id = sysbench.rand.default(1, sysbench.opt.table_size) param[tnum].deletes[1]:set(id) stmt[tnum].deletes:execute() end sysbench-1.0.18/src/lua/internal/0000700000175000017500000000000013553247311014401 5ustar jpjpsysbench-1.0.18/src/lua/internal/sysbench.cmdline.lua0000600000175000017500000001424613553247311020345 0ustar jpjp-- Copyright (C) 2017-2018 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- Command line option handling -- ---------------------------------------------------------------------- ffi = require("ffi") ffi.cdef[[ /* The following has been copied from sb_option.h */ typedef enum { SB_ARG_TYPE_NULL, SB_ARG_TYPE_BOOL, SB_ARG_TYPE_INT, SB_ARG_TYPE_SIZE, SB_ARG_TYPE_DOUBLE, SB_ARG_TYPE_STRING, SB_ARG_TYPE_LIST, SB_ARG_TYPE_FILE, SB_ARG_TYPE_MAX } sb_arg_type_t; /* Option validation function */ typedef bool sb_opt_validate_t(const char *, const char *); /* Test option definition */ typedef struct { const char *name; const char *desc; const char *value; sb_arg_type_t type; sb_opt_validate_t *validate; } sb_arg_t; int sb_lua_set_test_args(sb_arg_t *args, size_t len); ]] sysbench.cmdline.ARG_NULL = ffi.C.SB_ARG_TYPE_NULL sysbench.cmdline.ARG_BOOL = ffi.C.SB_ARG_TYPE_BOOL sysbench.cmdline.ARG_INT = ffi.C.SB_ARG_TYPE_INT sysbench.cmdline.ARG_SIZE = ffi.C.SB_ARG_TYPE_SIZE sysbench.cmdline.ARG_DOUBLE = ffi.C.SB_ARG_TYPE_DOUBLE sysbench.cmdline.ARG_STRING = ffi.C.SB_ARG_TYPE_STRING sysbench.cmdline.ARG_LIST = ffi.C.SB_ARG_TYPE_LIST sysbench.cmdline.ARG_FILE = ffi.C.SB_ARG_TYPE_FILE sysbench.cmdline.ARG_MAX = ffi.C.SB_ARG_TYPE_MAX -- Attribute indicating that a custom command can be executed in parallel sysbench.cmdline.PARALLEL_COMMAND = true local arg_types = { boolean = sysbench.cmdline.ARG_BOOL, string = sysbench.cmdline.ARG_STRING, number = sysbench.cmdline.ARG_DOUBLE, table = sysbench.cmdline.ARG_LIST } local function __genOrderedIndex( t ) local orderedIndex = {} for key in pairs(t) do table.insert( orderedIndex, key ) end table.sort( orderedIndex ) return orderedIndex end local function orderedNext(t, state) local key = nil if state == nil then t.__orderedIndex = __genOrderedIndex( t ) key = t.__orderedIndex[1] else for i = 1,table.getn(t.__orderedIndex) do if t.__orderedIndex[i] == state then key = t.__orderedIndex[i+1] end end end if key then return key, t[key] end t.__orderedIndex = nil return end local function orderedPairs(t) return orderedNext, t, nil end -- Parse command line options definitions, if present in the script as a -- 'sysbench.cmdline.options' table. If no such table exists, or if there a -- parsing error, return false. Return true on success. After parsing the -- command line arguments, option values are available as the sysbench.opt -- table. function sysbench.cmdline.read_cmdline_options() if sysbench.cmdline.options == nil then return true end local t = type(sysbench.cmdline.options) assert(t == "table", "wrong type for sysbench.cmdline.options: " .. t) local i = 0 for name, def in pairs(sysbench.cmdline.options) do i = i+1 end local args = ffi.new('sb_arg_t[?]', i) i = 0 for name, def in orderedPairs(sysbench.cmdline.options) do -- name assert(type(name) == "string" and type(def) == "table", "wrong table structure in sysbench.cmdline.options") args[i].name = name -- description assert(def[1] ~= nil, "nil description for option " .. name) args[i].desc = def[1] if type(def[2]) == "table" then assert(type(def[3]) == "nil" or type(def[3]) == sysbench.cmdline.ARG_LIST, "wrong type for list option " .. name) args[i].value = table.concat(def[2], ',') else if type(def[2]) == "boolean" then args[i].value = def[2] and 'on' or 'off' elseif type(def[2]) == "number" then args[i].value = tostring(def[2]) else args[i].value = def[2] end end -- type local t = def[3] if t == nil then if def[2] ~= nil then -- Try to determine the type by the default value t = arg_types[type(def[2])] else t = sysbench.cmdline.ARG_STRING end end assert(t ~= nil, "cannot determine type for option " .. name) args[i].type = t -- validation function args[i].validate = def[4] i = i + 1 end return ffi.C.sb_lua_set_test_args(args, i) == 0 end function sysbench.cmdline.command_defined(name) return type(sysbench.cmdline.commands) == "table" and sysbench.cmdline.commands[name] ~= nil and sysbench.cmdline.commands[name][1] ~= nil end function sysbench.cmdline.command_parallel(name) return sysbench.cmdline.command_defined(name) and sysbench.cmdline.commands[name][2] == sysbench.cmdline.PARALLEL_COMMAND end function sysbench.cmdline.call_command(name) if not sysbench.cmdline.command_defined(name) then return false end local rc = sysbench.cmdline.commands[name][1]() if rc == nil then -- handle the case when the command does not return and value as success return true else -- otherwise return success for any returned value other than false return rc and true or false end end ffi.cdef[[ void sb_print_test_options(void); ]] -- ---------------------------------------------------------------------- -- Print descriptions of command line options, if defined by -- sysbench.cmdline.options -- ---------------------------------------------------------------------- function sysbench.cmdline.print_test_options() ffi.C.sb_print_test_options() end sysbench-1.0.18/src/lua/internal/sysbench.sql.lua0000600000175000017500000003357313553247311017535 0ustar jpjp-- Copyright (C) 2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- SQL API -- ---------------------------------------------------------------------- ffi = require("ffi") sysbench.sql = {} ffi.cdef[[ /* The following definitions have been copied with modifications from db_driver.h */ typedef enum { DB_ERROR_NONE, /* no error(s) */ DB_ERROR_IGNORABLE, /* error should be ignored as defined by command line arguments or a custom error handler */ DB_ERROR_FATAL /* non-ignorable error */ } sql_error_t; typedef struct { const char *sname; /* short name */ const char *lname; /* long name */ const char opaque[?]; } sql_driver; typedef struct { uint32_t len; /* Value length */ const char *ptr; /* Value string */ } sql_value; /* Result set row definition */ typedef struct { void *ptr; /* Driver-specific row data */ sql_value *values; /* Array of column values */ } sql_row; /* Query type for statistics */ typedef enum { SB_CNT_OTHER, SB_CNT_READ, SB_CNT_WRITE, SB_CNT_TRX, SB_CNT_ERROR, SB_CNT_RECONNECT, SB_CNT_MAX } sb_counter_type; typedef struct { sql_error_t error; /* Driver-independent error code */ int sql_errno; /* Driver-specific error code */ const char *sql_state; /* Database-specific SQL state */ const char *sql_errmsg; /* Database-specific error message */ sql_driver *driver; /* DB driver for this connection */ const char opaque[?]; } sql_connection; typedef struct { sql_connection *connection; const char opaque[?]; } sql_statement; /* Result set definition */ typedef struct { sb_counter_type counter; /* Statistical counter type */ uint32_t nrows; /* Number of affected rows */ uint32_t nfields; /* Number of fields */ sql_statement *statement; /* Pointer to prepared statement (if used) */ void *ptr; /* Pointer to driver-specific data */ sql_row row; /* Last fetched row */ } sql_result; typedef enum { SQL_TYPE_NONE, SQL_TYPE_TINYINT, SQL_TYPE_SMALLINT, SQL_TYPE_INT, SQL_TYPE_BIGINT, SQL_TYPE_FLOAT, SQL_TYPE_DOUBLE, SQL_TYPE_TIME, SQL_TYPE_DATE, SQL_TYPE_DATETIME, SQL_TYPE_TIMESTAMP, SQL_TYPE_CHAR, SQL_TYPE_VARCHAR } sql_bind_type_t; typedef struct { sql_bind_type_t type; void *buffer; unsigned long *data_len; unsigned long max_len; char *is_null; } sql_bind; sql_driver *db_create(const char *); int db_destroy(sql_driver *drv); sql_connection *db_connection_create(sql_driver * drv); int db_connection_close(sql_connection *con); int db_connection_reconnect(sql_connection *con); void db_connection_free(sql_connection *con); int db_bulk_insert_init(sql_connection *, const char *, size_t); int db_bulk_insert_next(sql_connection *, const char *, size_t); int db_bulk_insert_done(sql_connection *); sql_result *db_query(sql_connection *con, const char *query, size_t len); sql_row *db_fetch_row(sql_result *rs); sql_statement *db_prepare(sql_connection *con, const char *query, size_t len); int db_bind_param(sql_statement *stmt, sql_bind *params, size_t len); int db_bind_result(sql_statement *stmt, sql_bind *results, size_t len); sql_result *db_execute(sql_statement *stmt); int db_close(sql_statement *stmt); int db_free_results(sql_result *); ]] local sql_driver = ffi.typeof('sql_driver *') local sql_connection = ffi.typeof('sql_connection *') local sql_statement = ffi.typeof('sql_statement *') local sql_bind = ffi.typeof('sql_bind'); local sql_result = ffi.typeof('sql_result'); local sql_value = ffi.typeof('sql_value'); local sql_row = ffi.typeof('sql_row'); sysbench.sql.type = { NONE = ffi.C.SQL_TYPE_NONE, TINYINT = ffi.C.SQL_TYPE_TINYINT, SMALLINT = ffi.C.SQL_TYPE_SMALLINT, INT = ffi.C.SQL_TYPE_INT, BIGINT = ffi.C.SQL_TYPE_BIGINT, FLOAT = ffi.C.SQL_TYPE_FLOAT, DOUBLE = ffi.C.SQL_TYPE_DOUBLE, TIME = ffi.C.SQL_TYPE_TIME, DATE = ffi.C.SQL_TYPE_DATE, DATETIME = ffi.C.SQL_TYPE_DATETIME, TIMESTAMP = ffi.C.SQL_TYPE_TIMESTAMP, CHAR = ffi.C.SQL_TYPE_CHAR, VARCHAR = ffi.C.SQL_TYPE_VARCHAR } -- Initialize a given SQL driver and return a handle to it to create -- connections. A nil driver name (i.e. no function argument) initializes the -- default driver, i.e. the one specified with --db-driver on the command line. function sysbench.sql.driver(driver_name) local drv = ffi.C.db_create(driver_name) if (drv == nil) then error("failed to initialize the DB driver", 2) end return ffi.gc(drv, ffi.C.db_destroy) end -- sql_driver methods local driver_methods = {} function driver_methods.connect(self) local con = ffi.C.db_connection_create(self) if con == nil then error("connection creation failed", 2) end return ffi.gc(con, ffi.C.db_connection_free) end function driver_methods.name(self) return ffi.string(self.sname) end -- sql_driver metatable local driver_mt = { __index = driver_methods, __gc = ffi.C.db_destroy, __tostring = function() return '' end, } ffi.metatype("sql_driver", driver_mt) -- sql_connection methods local connection_methods = {} function connection_methods.disconnect(self) return assert(ffi.C.db_connection_close(self) == 0) end function connection_methods.reconnect(self) return assert(ffi.C.db_connection_reconnect(self) == 0) end function connection_methods.check_error(self, rs, query) if rs ~= nil or self.error == sysbench.sql.error.NONE then return rs end if self.sql_state == nil or self.sql_errmsg == nil then -- It must be an API error, don't bother trying to downgrade it an -- ignorable error error("SQL API error", 3) end local sql_state = ffi.string(self.sql_state) local sql_errmsg = ffi.string(self.sql_errmsg) -- Create an error descriptor containing connection, failed query, SQL error -- number, state and error message provided by the SQL driver errdesc = { connection = self, query = query, sql_errno = self.sql_errno, sql_state = sql_state, sql_errmsg = sql_errmsg } -- Check if the error has already been marked as ignorable by the driver, or -- there is an error hook that allows downgrading it to IGNORABLE if (self.error == sysbench.sql.error.FATAL and type(sysbench.hooks.sql_error_ignorable) == "function" and sysbench.hooks.sql_error_ignorable(errdesc)) or self.error == sysbench.sql.error.IGNORABLE then -- Throw a 'restart event' exception that can be caught by the user script -- to do some extra steps to restart a transaction (e.g. reprepare -- statements after a reconnect). Otherwise it will be caught by -- thread_run() in sysbench.lua, in which case the entire current event -- will be restarted without extra processing. errdesc.errcode = sysbench.error.RESTART_EVENT error(errdesc, 3) end -- Just throw a regular error message on a fatal error error(string.format("SQL error, errno = %d, state = '%s': %s", self.sql_errno, sql_state, sql_errmsg), 2) end function connection_methods.query(self, query) local rs = ffi.C.db_query(self, query, #query) return self:check_error(rs, query) end function connection_methods.bulk_insert_init(self, query) return assert(ffi.C.db_bulk_insert_init(self, query, #query) == 0, "db_bulk_insert_init() failed") end function connection_methods.bulk_insert_next(self, val) return assert(ffi.C.db_bulk_insert_next(self, val, #val) == 0, "db_bulk_insert_next() failed") end function connection_methods.bulk_insert_done(self) return assert(ffi.C.db_bulk_insert_done(self) == 0, "db_bulk_insert_done() failed") end function connection_methods.prepare(self, query) local stmt = ffi.C.db_prepare(self, query, #query) if stmt == nil then self:check_error(nil, query) end return stmt end -- A convenience wrapper around sql_connection:query() and -- sql_result:fetch_row(). Executes the specified query and returns the first -- row from the result set, if available, or nil otherwise function connection_methods.query_row(self, query) local rs = self:query(query) if rs == nil or rs.nrows == 0 then return nil end return unpack(rs:fetch_row(), 1, rs.nfields) end -- sql_connection metatable local connection_mt = { __index = connection_methods, __tostring = function() return '' end, __gc = ffi.C.db_connection_free, } ffi.metatype("sql_connection", connection_mt) -- sql_param local sql_param = {} function sql_param.set(self, value) local sql_type = sysbench.sql.type local btype = self.type if (value == nil) then self.is_null[0] = true return end self.is_null[0] = false if btype == sql_type.TINYINT or btype == sql_type.SMALLINT or btype == sql_type.INT or btype == sql_type.BIGINT then self.buffer[0] = value elseif btype == sql_type.FLOAT or btype == sql_type.DOUBLE then self.buffer[1] = value elseif btype == sql_type.CHAR or btype == sql_type.VARCHAR then local len = #value len = self.max_len < len and self.max_len or len ffi.copy(self.buffer, value, len) self.data_len[0] = len else error("Unsupported argument type: " .. btype, 2) end end function sql_param.set_rand_str(self, fmt) local sql_type = sysbench.sql.type local btype = self.type self.is_null[0] = false if btype == sql_type.CHAR or btype == sql_type.VARCHAR then local len = #fmt len = self.max_len < len and self.max_len or len ffi.C.sb_rand_str(fmt, self.buffer) self.data_len[0] = len else error("Unsupported argument type: " .. btype, 2) end end sql_param.__index = sql_param sql_param.__tostring = function () return '' end -- sql_statement methods local statement_methods = {} function statement_methods.bind_create(self, btype, max_len) local sql_type = sysbench.sql.type local param = setmetatable({}, sql_param) if btype == sql_type.TINYINT or btype == sql_type.SMALLINT or btype == sql_type.INT or btype == sql_type.BIGINT then param.type = sql_type.BIGINT param.buffer = ffi.new('int64_t[1]') param.max_len = 8 elseif btype == sql_type.FLOAT or btype == sql_type.DOUBLE then param.type = sql_type.DOUBLE param.buffer = ffi.new('double[1]') param.max_len = 8 elseif btype == sql_type.CHAR or btype == sql_type.VARCHAR then param.type = sql_type.VARCHAR param.buffer = ffi.new('char[?]', max_len) param.max_len = max_len else error("Unsupported argument type: " .. btype, 2) end param.data_len = ffi.new('unsigned long[1]') param.is_null = ffi.new('char[1]') return param end function statement_methods.bind_param(self, ...) local len = select('#', ...) if len < 1 then return nil end local binds = ffi.new("sql_bind[?]", len) local i, param for i, param in ipairs({...}) do binds[i-1].type = param.type binds[i-1].buffer = param.buffer binds[i-1].data_len = param.data_len binds[i-1].max_len = param.max_len binds[i-1].is_null = param.is_null end return ffi.C.db_bind_param(self, binds, len) end function statement_methods.execute(self) local rs = ffi.C.db_execute(self) return self.connection:check_error(rs, '') end function statement_methods.close(self) return ffi.C.db_close(self) end -- sql_statement metatable local statement_mt = { __index = statement_methods, __tostring = function() return '' end, __gc = ffi.C.db_close, } ffi.metatype("sql_statement", statement_mt) local bind_mt = { __tostring = function() return '' end, } ffi.metatype("sql_bind", bind_mt) -- sql_result methods local result_methods = {} -- Returns the next row of values from a result set, or nil if there are no more -- rows to fetch. Values are returned as an array, i.e. a table with numeric -- indexes starting from 1. The total number of values (i.e. fields in a result -- set) can be obtained from sql_result.nfields. function result_methods.fetch_row(self) local res = {} local row = ffi.C.db_fetch_row(self) if row == nil then return nil end local i for i = 0, self.nfields-1 do if row.values[i].ptr ~= nil then -- not a NULL value res[i+1] = ffi.string(row.values[i].ptr, tonumber(row.values[i].len)) end end return res end function result_methods.free(self) return assert(ffi.C.db_free_results(self) == 0, "db_free_results() failed") end -- sql_results metatable local result_mt = { __index = result_methods, __tostring = function() return '' end, __gc = ffi.C.db_free_results } ffi.metatype("sql_result", result_mt) -- error codes sysbench.sql.error = {} sysbench.sql.error.NONE = ffi.C.DB_ERROR_NONE sysbench.sql.error.IGNORABLE = ffi.C.DB_ERROR_IGNORABLE sysbench.sql.error.FATAL = ffi.C.DB_ERROR_FATAL sysbench-1.0.18/src/lua/internal/sysbench.lua0000600000175000017500000001252713553247311016733 0ustar jpjp-- Copyright (C) 2016-2018 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ffi = require("ffi") ffi.cdef[[ void sb_event_start(int thread_id); void sb_event_stop(int thread_id); bool sb_more_events(int thread_id); ]] -- ---------------------------------------------------------------------- -- Main event loop. This is a Lua version of sysbench.c:thread_run() -- ---------------------------------------------------------------------- function thread_run(thread_id) while ffi.C.sb_more_events(thread_id) do ffi.C.sb_event_start(thread_id) local success, ret repeat success, ret = pcall(event, thread_id) if not success then if type(ret) == "table" and ret.errcode == sysbench.error.RESTART_EVENT then if sysbench.hooks.before_restart_event then sysbench.hooks.before_restart_event(ret) end else error(ret, 2) -- propagate unknown errors end end until success -- Stop the benchmark if event() returns a value other than nil or false if ret then break end ffi.C.sb_event_stop(thread_id) end end -- ---------------------------------------------------------------------- -- Hooks -- ---------------------------------------------------------------------- sysbench.hooks = { -- sql_error_ignorable = , -- report_intermediate = , -- report_cumulative = } -- Report statistics in the CSV format. Add the following to your -- script to replace the default human-readable reports -- -- sysbench.hooks.report_intermediate = sysbench.report_csv function sysbench.report_csv(stat) local seconds = stat.time_interval print(string.format("%.0f,%u,%4.2f," .. "%4.2f,%4.2f,%4.2f,%4.2f," .. "%4.2f,%4.2f," .. "%4.2f", stat.time_total, stat.threads_running, stat.events / seconds, (stat.reads + stat.writes + stat.other) / seconds, stat.reads / seconds, stat.writes / seconds, stat.other / seconds, stat.latency_pct * 1000, stat.errors / seconds, stat.reconnects / seconds )) end -- Report statistics in the JSON format. Add the following to your -- script to replace the default human-readable reports -- -- sysbench.hooks.report_intermediate = sysbench.report_json function sysbench.report_json(stat) if not gobj then io.write('[\n') -- hack to print the closing bracket when the Lua state of the reporting -- thread is closed gobj = newproxy(true) getmetatable(gobj).__gc = function () io.write('\n]\n') end else io.write(',\n') end local seconds = stat.time_interval io.write(([[ { "time": %4.0f, "threads": %u, "tps": %4.2f, "qps": { "total": %4.2f, "reads": %4.2f, "writes": %4.2f, "other": %4.2f }, "latency": %4.2f, "errors": %4.2f, "reconnects": %4.2f }]]):format( stat.time_total, stat.threads_running, stat.events / seconds, (stat.reads + stat.writes + stat.other) / seconds, stat.reads / seconds, stat.writes / seconds, stat.other / seconds, stat.latency_pct * 1000, stat.errors / seconds, stat.reconnects / seconds )) end -- Report statistics in the default human-readable format. You can use it if you -- want to augment default reports with your own statistics. Call it from your -- own report hook, e.g.: -- -- function sysbench.hooks.report_intermediate(stat) -- print("my stat: ", val) -- sysbench.report_default(stat) -- end function sysbench.report_default(stat) local seconds = stat.time_interval print(string.format("[ %.0fs ] thds: %u tps: %4.2f qps: %4.2f " .. "(r/w/o: %4.2f/%4.2f/%4.2f) lat (ms,%u%%): %4.2f " .. "err/s %4.2f reconn/s: %4.2f", stat.time_total, stat.threads_running, stat.events / seconds, (stat.reads + stat.writes + stat.other) / seconds, stat.reads / seconds, stat.writes / seconds, stat.other / seconds, sysbench.opt.percentile, stat.latency_pct * 1000, stat.errors / seconds, stat.reconnects / seconds )) end sysbench-1.0.18/src/lua/internal/sysbench.rand.lua0000600000175000017500000000424513553247311017654 0ustar jpjp-- Copyright (C) 2016-2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ffi = require("ffi") -- ---------------------------------------------------------------------- -- Pseudo-random number generation API -- ---------------------------------------------------------------------- sysbench.rand = {} ffi.cdef[[ uint64_t sb_rand_uniform_uint64(void); uint32_t sb_rand_default(uint32_t, uint32_t); uint32_t sb_rand_uniform(uint32_t, uint32_t); uint32_t sb_rand_gaussian(uint32_t, uint32_t); uint32_t sb_rand_special(uint32_t, uint32_t); uint32_t sb_rand_pareto(uint32_t, uint32_t); uint32_t sb_rand_unique(void); void sb_rand_str(const char *, char *); double sb_rand_uniform_double(void); ]] function sysbench.rand.uniform_uint64() return ffi.C.sb_rand_uniform_uint64() end function sysbench.rand.default(a, b) return ffi.C.sb_rand_default(a, b) end function sysbench.rand.uniform(a, b) return ffi.C.sb_rand_uniform(a, b) end function sysbench.rand.gaussian(a, b) return ffi.C.sb_rand_gaussian(a, b) end function sysbench.rand.special(a, b) return ffi.C.sb_rand_special(a, b) end function sysbench.rand.pareto(a, b) return ffi.C.sb_rand_pareto(a, b) end function sysbench.rand.unique() return ffi.C.sb_rand_unique() end function sysbench.rand.string(fmt) local buflen = #fmt local buf = ffi.new("uint8_t[?]", buflen) ffi.C.sb_rand_str(fmt, buf) return ffi.string(buf, buflen) end function sysbench.rand.uniform_double() return ffi.C.sb_rand_uniform_double() end sysbench-1.0.18/src/lua/internal/sysbench.histogram.lua0000600000175000017500000000374213553247311020726 0ustar jpjp-- Copyright (C) 2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- Bounded histograms API -- ---------------------------------------------------------------------- ffi = require("ffi") sysbench.histogram = {} ffi.cdef[[ typedef struct histogram sb_histogram_t; /* Allocate a new histogram and initialize it with sb_histogram_init(). */ sb_histogram_t *sb_histogram_new(size_t size, double range_min, double range_max); /* Deallocate a histogram allocated with sb_histogram_new(). */ void sb_histogram_delete(sb_histogram_t *h); /* Update histogram with a given value. */ void sb_histogram_update(sb_histogram_t *h, double value); /* Print a given histogram to stdout */ void sb_histogram_print(sb_histogram_t *h); ]] local histogram = {} function histogram:update(value) ffi.C.sb_histogram_update(self, value) end function histogram:print() ffi.C.sb_histogram_print(self) end local histogram_mt = { __index = histogram, __tostring = '' } ffi.metatype('sb_histogram_t', histogram_mt) function sysbench.histogram.new(size, range_min, range_max) local h = ffi.C.sb_histogram_new(size, range_min, range_max) return ffi.gc(h, ffi.C.sb_histogram_delete) end sysbench-1.0.18/src/lua/internal/sysbench.compat.lua0000600000175000017500000000461113553247311020210 0ustar jpjp-- Copyright (C) 2016-2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- Compatibility wrappers/aliases. These may be removed in later versions -- ---------------------------------------------------------------------- thread_id = sysbench.tid test = sysbench.cmdline.script_path function sb_rnd() -- Keep lower 32 bits from sysbench.rand.uniform_uint64() and convert them to -- a Lua number return tonumber(sysbench.rand.uniform_uint64() % 4294967296) end sb_rand = sysbench.rand.default sb_rand_str = sysbench.rand.string sb_rand_uniform = sysbench.rand.uniform sb_rand_gaussian = sysbench.rand.gaussian sb_rand_special = sysbench.rand.special function sb_rand_uniq(a, b) local res if type(a) == "nil" then a = 0 end if type(b) == "nil" then b = 4294967295 end repeat res = sysbench.rand.unique() until res >= a and res <= b return res end db_connect = sysbench.db.connect db_disconnect = sysbench.db.disconnect db_query = sysbench.db.query db_bulk_insert_init = sysbench.db.bulk_insert_init db_bulk_insert_next = sysbench.db.bulk_insert_next db_bulk_insert_done = sysbench.db.bulk_insert_done db_prepare = sysbench.db.prepare db_bind_param = sysbench.db.bind_param db_bind_result = sysbench.db.bind_result db_execute = sysbench.db.execute db_store_results = sysbench.db.store_results db_free_results = sysbench.db.free_results db_close = sysbench.db.close DB_ERROR_NONE = sysbench.db.DB_ERROR_NONE DB_ERROR_RESTART_TRANSACTION = sysbench.db.DB_ERROR_RESTART_TRANSACTION DB_ERROR_FAILED = sysbench.db.DB_ERROR_FAILED mysql_table_engine = mysql_table_engine or "innodb" myisam_max_rows = 1000000 sysbench-1.0.18/src/lua/internal/Makefile.am0000600000175000017500000000247313553247311016445 0ustar jpjp# Copyright (C) 2016-2018 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA BUILT_SOURCES = sysbench.lua.h sysbench.rand.lua.h sysbench.sql.lua.h \ sysbench.compat.lua.h sysbench.cmdline.lua.h \ sysbench.histogram.lua.h CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = $(BUILT_SOURCES:.h=) SUFFIXES = .lua .lua.h .lua.lua.h: @echo "Creating $@ from $<" @var=$$(echo $< | sed 's/\./_/g') && \ ( echo "unsigned char $${var}[] =" && \ sed -e 's/\\/\\\\/g' \ -e 's/"/\\"/g' \ -e 's/^/ "/g' \ -e 's/$$/\\n"/g' $< && \ echo ";" && \ echo "size_t $${var}_len = sizeof($${var}) - 1;" ) > $@ sysbench-1.0.18/src/lua/oltp_insert.lua0000700000175000017500000000455713553247311015650 0ustar jpjp#!/usr/bin/env sysbench -- Copyright (C) 2006-2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- Insert-Only OLTP benchmark -- ---------------------------------------------------------------------- require("oltp_common") sysbench.cmdline.commands.prepare = { function () if (not sysbench.opt.auto_inc) then -- Create empty tables on prepare when --auto-inc is off, since IDs -- generated on prepare may collide later with values generated by -- sysbench.rand.unique() sysbench.opt.table_size=0 end cmd_prepare() end, sysbench.cmdline.PARALLEL_COMMAND } function prepare_statements() -- We do not use prepared statements here, but oltp_common.sh expects this -- function to be defined end function event() local table_name = "sbtest" .. sysbench.rand.uniform(1, sysbench.opt.tables) local k_val = sysbench.rand.default(1, sysbench.opt.table_size) local c_val = get_c_value() local pad_val = get_pad_value() if (drv:name() == "pgsql" and sysbench.opt.auto_inc) then con:query(string.format("INSERT INTO %s (k, c, pad) VALUES " .. "(%d, '%s', '%s')", table_name, k_val, c_val, pad_val)) else if (sysbench.opt.auto_inc) then i = 0 else -- Convert a uint32_t value to SQL INT i = sysbench.rand.unique() - 2147483648 end con:query(string.format("INSERT INTO %s (id, k, c, pad) VALUES " .. "(%d, %d, '%s', '%s')", table_name, i, k_val, c_val, pad_val)) end end sysbench-1.0.18/src/lua/oltp_read_write.lua0000700000175000017500000000344013553247311016457 0ustar jpjp#!/usr/bin/env sysbench -- Copyright (C) 2006-2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- Read/Write OLTP benchmark -- ---------------------------------------------------------------------- require("oltp_common") function prepare_statements() if not sysbench.opt.skip_trx then prepare_begin() prepare_commit() end prepare_point_selects() if sysbench.opt.range_selects then prepare_simple_ranges() prepare_sum_ranges() prepare_order_ranges() prepare_distinct_ranges() end prepare_index_updates() prepare_non_index_updates() prepare_delete_inserts() end function event() if not sysbench.opt.skip_trx then begin() end execute_point_selects() if sysbench.opt.range_selects then execute_simple_ranges() execute_sum_ranges() execute_order_ranges() execute_distinct_ranges() end execute_index_updates() execute_non_index_updates() execute_delete_inserts() if not sysbench.opt.skip_trx then commit() end end sysbench-1.0.18/src/lua/select_random_ranges.lua0000700000175000017500000000410613553247311017452 0ustar jpjp#!/usr/bin/env sysbench -- This test is designed for testing MariaDB's key_cache_segments for MyISAM, -- and should work with other storage engines as well. -- -- For details about key_cache_segments please refer to: -- http://kb.askmonty.org/v/segmented-key-cache -- require("oltp_common") -- Add --number-of-ranges and --delta to the list of standard OLTP options sysbench.cmdline.options.number_of_ranges = {"Number of random BETWEEN ranges per SELECT", 10} sysbench.cmdline.options.delta = {"Size of BETWEEN ranges", 5} -- Override standard prepare/cleanup OLTP functions, as this benchmark does not -- support multiple tables oltp_prepare = prepare oltp_cleanup = cleanup function prepare() assert(sysbench.opt.tables == 1, "this benchmark does not support " .. "--tables > 1") oltp_prepare() end function cleanup() assert(sysbench.opt.tables == 1, "this benchmark does not support " .. "--tables > 1") oltp_cleanup() end function thread_init() drv = sysbench.sql.driver() con = drv:connect() local ranges = string.rep("k BETWEEN ? AND ? OR ", sysbench.opt.number_of_ranges - 1) .. "k BETWEEN ? AND ?" stmt = con:prepare(string.format([[ SELECT count(k) FROM sbtest1 WHERE %s]], ranges)) params = {} for j = 1, sysbench.opt.number_of_ranges*2 do params[j] = stmt:bind_create(sysbench.sql.type.INT) end stmt:bind_param(unpack(params)) rlen = sysbench.opt.table_size / sysbench.opt.threads thread_id = sysbench.tid % sysbench.opt.threads end function thread_done() stmt:close() con:disconnect() end function event() -- To prevent overlapping of our range queries we need to partition the whole -- table into 'threads' segments and then make each thread work with its -- own segment. for i = 1, sysbench.opt.number_of_ranges*2, 2 do local rmin = rlen * thread_id local rmax = rmin + rlen local val = sb_rand(rmin, rmax) params[i]:set(val) params[i+1]:set(val + sysbench.opt.delta) end stmt:execute() end sysbench-1.0.18/src/lua/Makefile.am0000600000175000017500000000230313553247311014621 0ustar jpjp# Copyright (C) 2016 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA SUBDIRS = internal dist_pkgdata_SCRIPTS = bulk_insert.lua \ oltp_delete.lua \ oltp_insert.lua \ oltp_read_only.lua \ oltp_read_write.lua \ oltp_point_select.lua \ oltp_update_index.lua \ oltp_update_non_index.lua \ oltp_write_only.lua\ select_random_points.lua \ select_random_ranges.lua dist_pkgdata_DATA = oltp_common.lua sysbench-1.0.18/src/lua/oltp_read_only.lua0000700000175000017500000000316113553247311016306 0ustar jpjp#!/usr/bin/env sysbench -- Copyright (C) 2006-2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- Read-Only OLTP benchmark -- ---------------------------------------------------------------------- require("oltp_common") function prepare_statements() prepare_point_selects() if not sysbench.opt.skip_trx then prepare_begin() prepare_commit() end if sysbench.opt.range_selects then prepare_simple_ranges() prepare_sum_ranges() prepare_order_ranges() prepare_distinct_ranges() end end function event() if not sysbench.opt.skip_trx then begin() end execute_point_selects() if sysbench.opt.range_selects then execute_simple_ranges() execute_sum_ranges() execute_order_ranges() execute_distinct_ranges() end if not sysbench.opt.skip_trx then commit() end end sysbench-1.0.18/src/lua/oltp_point_select.lua0000700000175000017500000000236113553247311017023 0ustar jpjp#!/usr/bin/env sysbench -- Copyright (C) 2006-2017 Alexey Kopytov -- 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; either version 2 of the License, or -- (at your option) any later version. -- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -- ---------------------------------------------------------------------- -- OLTP Point Select benchmark -- ---------------------------------------------------------------------- require("oltp_common") function prepare_statements() -- use 1 query per event, rather than sysbench.opt.point_selects which -- defaults to 10 in other OLTP scripts sysbench.opt.point_selects=1 prepare_point_selects() end function event() execute_point_selects() end sysbench-1.0.18/src/lua/bulk_insert.lua0000700000175000017500000000265413553247311015623 0ustar jpjp#!/usr/bin/env sysbench -- -------------------------------------------------------------------------- -- -- Bulk insert benchmark: do multi-row INSERTs concurrently in --threads -- threads with each thread inserting into its own table. The number of INSERTs -- executed by each thread is controlled by either --time or --events. -- -------------------------------------------------------------------------- -- cursize=0 function thread_init() drv = sysbench.sql.driver() con = drv:connect() end function prepare() local i local drv = sysbench.sql.driver() local con = drv:connect() for i = 1, sysbench.opt.threads do print("Creating table 'sbtest" .. i .. "'...") con:query(string.format([[ CREATE TABLE IF NOT EXISTS sbtest%d ( id INTEGER NOT NULL, k INTEGER DEFAULT '0' NOT NULL, PRIMARY KEY (id))]], i)) end end function event() if (cursize == 0) then con:bulk_insert_init("INSERT INTO sbtest" .. thread_id+1 .. " VALUES") end cursize = cursize + 1 con:bulk_insert_next("(" .. cursize .. "," .. cursize .. ")") end function thread_done(thread_9d) con:bulk_insert_done() con:disconnect() end function cleanup() local i local drv = sysbench.sql.driver() local con = drv:connect() for i = 1, sysbench.opt.threads do print("Dropping table 'sbtest" .. i .. "'...") con:query("DROP TABLE IF EXISTS sbtest" .. i ) end end sysbench-1.0.18/src/drivers/0000700000175000017500000000000013553247311013462 5ustar jpjpsysbench-1.0.18/src/drivers/drizzle/0000700000175000017500000000000013553247311015145 5ustar jpjpsysbench-1.0.18/src/drivers/drizzle/drv_drizzle.c0000600000175000017500000004374413553247311017665 0ustar jpjp/* Copyright (C) 2009 Sun Microsystems, Inc. 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include #include #include "sb_options.h" #include "db_driver.h" #define DEBUG(format, ...) do { if (db_globals.debug) log_text(LOG_DEBUG, format, __VA_ARGS__); } while (0) /* Drizzle driver arguments */ static sb_arg_t drizzle_drv_args[] = { {"drizzle-host", "Drizzle server host", SB_ARG_TYPE_LIST, "localhost"}, {"drizzle-port", "Drizzle server port", SB_ARG_TYPE_INT, "4427"}, {"drizzle-socket", "Drizzle socket", SB_ARG_TYPE_STRING, NULL}, {"drizzle-user", "Drizzle user", SB_ARG_TYPE_STRING, ""}, {"drizzle-password", "Drizzle password", SB_ARG_TYPE_STRING, ""}, {"drizzle-db", "Drizzle database name", SB_ARG_TYPE_STRING, "sbtest"}, {"drizzle-buffer", "Level of library buffering (none, field, row, all)", SB_ARG_TYPE_STRING, "none"}, {"drizzle-mysql", "Use MySQL Protocol", SB_ARG_TYPE_BOOL, "off"}, {NULL, NULL, SB_ARG_TYPE_NULL, NULL} }; typedef enum { BUFFER_NONE, BUFFER_FIELD, BUFFER_ROW, BUFFER_ALL } buffer_level; typedef struct { sb_list_t *hosts; unsigned int port; char *socket; char *user; char *password; char *db; buffer_level buffer; int mysql; } drizzle_drv_args_t; /* Drizzle driver capabilities */ static drv_caps_t drizzle_drv_caps = { .multi_rows_insert = 1, .prepared_statements = 0, .auto_increment = 1, .serial = 0, .unsigned_int = 0, }; static drizzle_drv_args_t args; /* driver args */ static sb_list_item_t *hosts_pos; static pthread_mutex_t hosts_mutex; static void column_info(drizzle_column_st *column); /* Drizzle driver operations */ static int drizzle_drv_init(void); static int drizzle_drv_describe(drv_caps_t *); static int drizzle_drv_connect(db_conn_t *); static int drizzle_drv_disconnect(db_conn_t *); static int drizzle_drv_prepare(db_stmt_t *, const char *, size_t); static int drizzle_drv_bind_param(db_stmt_t *, db_bind_t *, size_t); static int drizzle_drv_bind_result(db_stmt_t *, db_bind_t *, size_t); static db_error_t drizzle_drv_execute(db_stmt_t *, db_result_t *); static int drizzle_drv_fetch(db_result_t *); static int drizzle_drv_fetch_row(db_result_t *, db_row_t *); static db_error_t drizzle_drv_query(db_conn_t *, const char *, size_t, db_result_t *); static int drizzle_drv_free_results(db_result_t *); static int drizzle_drv_close(db_stmt_t *); static int drizzle_drv_store_results(db_result_t *); static int drizzle_drv_done(void); /* Drizzle driver definition */ static db_driver_t drizzle_driver = { .sname = "drizzle", .lname = "Drizzle driver", .args = drizzle_drv_args, .ops = { .init = drizzle_drv_init, .describe = drizzle_drv_describe, .connect = drizzle_drv_connect, .disconnect = drizzle_drv_disconnect, .prepare = drizzle_drv_prepare, .bind_param = drizzle_drv_bind_param, .bind_result = drizzle_drv_bind_result, .execute = drizzle_drv_execute, .fetch = drizzle_drv_fetch, .fetch_row = drizzle_drv_fetch_row, .free_results = drizzle_drv_free_results, .close = drizzle_drv_close, .query = drizzle_drv_query, .store_results = drizzle_drv_store_results, .done = drizzle_drv_done }, }; /* Local functions */ /* Register Drizzle driver */ int register_driver_drizzle(sb_list_t *drivers) { SB_LIST_ADD_TAIL(&drizzle_driver.listitem, drivers); return 0; } /* Drizzle driver initialization */ int drizzle_drv_init(void) { char *s; args.hosts = sb_get_value_list("drizzle-host"); if (SB_LIST_IS_EMPTY(args.hosts)) { log_text(LOG_FATAL, "No Drizzle hosts specified, aborting"); return 1; } hosts_pos = args.hosts; pthread_mutex_init(&hosts_mutex, NULL); args.port = (unsigned int)sb_get_value_int("drizzle-port"); args.socket = sb_get_value_string("drizzle-socket"); args.user = sb_get_value_string("drizzle-user"); args.password = sb_get_value_string("drizzle-password"); args.db = sb_get_value_string("drizzle-db"); s= sb_get_value_string("drizzle-buffer"); if (!strcasecmp(s, "none")) args.buffer= BUFFER_NONE; else if (!strcasecmp(s, "field")) args.buffer= BUFFER_FIELD; else if (!strcasecmp(s, "row")) args.buffer= BUFFER_ROW; else if (!strcasecmp(s, "all")) args.buffer= BUFFER_ALL; args.mysql= sb_get_value_flag("drizzle-mysql"); return 0; } /* Describe database capabilities (possibly depending on table type) */ int drizzle_drv_describe(drv_caps_t *caps ) { *caps = drizzle_drv_caps; return 0; } /* Connect to Drizzle database */ int drizzle_drv_connect(db_conn_t *sb_conn) { drizzle_st *drizzle_lib= NULL; drizzle_con_st *con= NULL; const char *host; drizzle_return_t ret; drizzle_lib= drizzle_create(drizzle_lib); if (args.socket) { DEBUG("drizzle_con_add_uds(%p, %p \"%s\", \"%s\", \"%s\", \"%s\", %d)", drizzle_lib, con, args.socket, args.user, args.password, args.db, args.mysql ? DRIZZLE_CON_MYSQL : 0); con= drizzle_con_add_uds(drizzle_lib, con, args.socket, args.user, args.password, args.db, args.mysql ? DRIZZLE_CON_MYSQL : 0); } else { pthread_mutex_lock(&hosts_mutex); hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos); if (hosts_pos == args.hosts) hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos); host = SB_LIST_ENTRY(hosts_pos, value_t, listitem)->data; pthread_mutex_unlock(&hosts_mutex); DEBUG("drizzle_con_add_tcp(%p, %p \"%s\", %u, \"%s\", \"%s\", \"%s\", %d)", drizzle_lib, con, host, args.port, args.user, args.password, args.db, args.mysql ? DRIZZLE_CON_MYSQL : 0); con= drizzle_con_add_tcp(drizzle_lib, con, host, args.port, args.user, args.password, args.db, args.mysql ? DRIZZLE_CON_MYSQL : 0); } if (con == NULL) { log_text(LOG_FATAL, "unable to Add Drizzle Connection, aborting..."); log_text(LOG_FATAL, "error %d: %s", drizzle_errno(drizzle_lib), drizzle_error(drizzle_lib)); return 1; } if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK) { log_text(LOG_FATAL, "unable to connect to Drizzle server: %d", ret); log_text(LOG_FATAL, "error %d: %s", drizzle_errno(drizzle_lib), drizzle_error(drizzle_lib)); free(con); return 1; } sb_conn->ptr = con; return 0; } /* Disconnect from Drizzle database */ int drizzle_drv_disconnect(db_conn_t *sb_conn) { drizzle_con_st *con = (drizzle_con_st *)sb_conn->ptr; if (con != NULL) { DEBUG("drizzle_close(%p)", con); drizzle_con_close(con); free(con); } return 0; } /* Prepare statement */ int drizzle_drv_prepare(db_stmt_t *stmt, const char *query, size_t len) { (void) len; /* unused */ /* Use client-side PS */ stmt->emulated = 1; stmt->query = strdup(query); return 0; } /* Bind parameters for prepared statement */ int drizzle_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len) { drizzle_con_st *con = (drizzle_con_st *)stmt->connection->ptr; if (con == NULL) return 1; /* Use emulation */ if (stmt->bound_param != NULL) free(stmt->bound_param); stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t)); if (stmt->bound_param == NULL) return 1; memcpy(stmt->bound_param, params, len * sizeof(db_bind_t)); stmt->bound_param_len = len; return 0; } /* Bind results for prepared statement */ int drizzle_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, size_t len) { (void)stmt; (void)params; (void)len; return 0; } /* Execute prepared statement */ db_error_t drizzle_drv_execute(db_stmt_t *stmt, db_result_t *rs) { db_conn_t *con = stmt->connection; char *buf = NULL; unsigned int buflen = 0; unsigned int i, j, vcnt; char need_realloc; int n; /* Use emulation */ /* Build the actual query string from parameters list */ need_realloc = 1; vcnt = 0; for (i = 0, j = 0; stmt->query[i] != '\0'; i++) { again: if (j+1 >= buflen || need_realloc) { buflen = (buflen > 0) ? buflen * 2 : 256; buf = realloc(buf, buflen); if (buf == NULL) { log_text(LOG_DEBUG, "ERROR: exiting drizzle_drv_execute(), memory allocation failure"); return DB_ERROR_FATAL; } need_realloc = 0; } if (stmt->query[i] != '?') { buf[j++] = stmt->query[i]; continue; } n = db_print_value(stmt->bound_param + vcnt, buf + j, (int)(buflen - j)); if (n < 0) { need_realloc = 1; goto again; } j += (unsigned int)n; vcnt++; } buf[j] = '\0'; con->error = drizzle_drv_query(con, buf, j, rs); free(buf); if (con->error != DB_ERROR_NONE) { log_text(LOG_DEBUG, "ERROR: exiting drizzle_drv_execute(), database error"); return con->error; } return DB_ERROR_NONE; } /* Execute SQL query */ db_error_t drizzle_drv_query(db_conn_t *sb_conn, const char *query, size_t len, db_result_t *rs) { drizzle_con_st *con = sb_conn->ptr; unsigned int rc; drizzle_return_t ret; drizzle_result_st *result= NULL; DEBUG("drizzle_query(%p, %p, \"%s\", %u, %p)", con, result, query, len, &ret); result= drizzle_query(con, NULL, query, len, &ret); DEBUG("drizzle_query(%p) == %d", con, ret); if (ret == DRIZZLE_RETURN_ERROR_CODE) { rc= drizzle_result_error_code(result); /* Error code constants haven't been added yet to libdrizzle ER_LOCK_DEADLOCK==1213 ER_LOCK_WAIT_TIMEOUT==1205 ER_CHECKREAD==1020 */ if (rc == 1213 || rc == 1205 || rc == 1020) return DB_ERROR_IGNORABLE; log_text(LOG_ALERT, "Drizzle Query Failed: %u:%s", drizzle_result_error_code(result), drizzle_result_error(result)); return DB_ERROR_FATAL; } else if (ret != DRIZZLE_RETURN_OK) { rc = drizzle_con_errno(con); DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc); log_text(LOG_ALERT, "failed to execute Drizzle query: len==%d `%s`:", strlen(query), query); log_text(LOG_ALERT, "Error %d %s", drizzle_con_errno(con), drizzle_con_error(con)); return DB_ERROR_FATAL; } DEBUG("drizzle_query \"%s\" returned %d", query, ret); if (result == NULL) { DEBUG("drizzle_query(%p, \"%s\") == NULL",con,query); return DB_ERROR_FATAL; } rs->ptr= result; rs->nrows= drizzle_result_row_count(result); DEBUG("drizzle_result_row_count(%p) == %d",result,rs->nrows); return DB_ERROR_NONE; } /* Fetch row from result set of a prepared statement */ int drizzle_drv_fetch(db_result_t *rs) { /* NYI */ (void)rs; printf("in drizzle_drv_fetch_row!\n"); return 1; } /* Fetch row from result set of a query */ int drizzle_drv_fetch_row(db_result_t *rs, db_row_t *row) { /* NYI */ printf("in drizzle_drv_fetch_row!\n"); (void)rs; /* unused */ (void)row; /* unused */ return 1; } /* Store results from the last query */ int drizzle_drv_store_results(db_result_t *rs) { drizzle_con_st *con = rs->connection->ptr; drizzle_result_st *res = rs->ptr; drizzle_return_t ret; drizzle_column_st *column= NULL; unsigned int rc; if (con == NULL || res == NULL) return DB_ERROR_FATAL; if (args.buffer == BUFFER_ALL) { ret= drizzle_result_buffer(res); DEBUG("drizzle_result_buffer(%p) = %d", res, ret); if (ret != DRIZZLE_RETURN_OK) { rc = drizzle_con_errno(con); DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc); log_text(LOG_ALERT, "drizzle_result_buffer failed: `%p`:", res); log_text(LOG_ALERT, "Error %d %s", drizzle_con_errno(con), drizzle_con_error(con)); return DB_ERROR_FATAL; } while ((column = drizzle_column_next(res)) != NULL) column_info(column); } else if (drizzle_result_column_count(res) > 0) { drizzle_row_t row; drizzle_field_t field; uint64_t row_num; size_t offset= 0; size_t length; size_t total; /* Read column meta-info */ while (1) { column= drizzle_column_read(res, column, &ret); DEBUG("drizzle_column_read(%p,%p,%p) == %d",res, column, &ret, ret); if (ret != DRIZZLE_RETURN_OK) { rc = drizzle_con_errno(con); DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc); log_text(LOG_ALERT, "drizzle_column_read failed: `%p`:", res); log_text(LOG_ALERT, "Error %d %s", drizzle_con_errno(con), drizzle_con_error(con)); return DB_ERROR_FATAL; } if (column == NULL) break; column_info(column); drizzle_column_free(column); } /* Actually fetch rows */ while (1) /* Loop for rows */ { if (args.buffer == BUFFER_ROW) { row= drizzle_row_buffer(res, &ret); DEBUG("drizzle_row_buffer(%p, %p) == %p, %d",res, &ret, row, ret); if (ret != DRIZZLE_RETURN_OK) { rc = drizzle_con_errno(con); DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc); log_text(LOG_ALERT, "drizzle_row_buffer failed: `%p`:", res); log_text(LOG_ALERT, "Error %d %s", drizzle_con_errno(con), drizzle_con_error(con)); return DB_ERROR_FATAL; } if (row == NULL) break; DEBUG("drizzle_row_free(%p, %p)",res,row); drizzle_row_free(res, row); } else if (args.buffer == BUFFER_NONE || args.buffer == BUFFER_FIELD) { row_num= drizzle_row_read(res, &ret); DEBUG("drizzle_row_read(%p, %p) == %"PRIu64", %d", res, &ret, row_num, ret); if (ret != DRIZZLE_RETURN_OK) { rc = drizzle_con_errno(con); DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc); log_text(LOG_ALERT, "drizzle_row_read failed: `%p`:", res); log_text(LOG_ALERT, "Error %d %s", drizzle_con_errno(con), drizzle_con_error(con)); return DB_ERROR_FATAL; } if (row_num == 0) break; while (1) /* Loop for fields */ { if (args.buffer == BUFFER_FIELD) { /* Since an entire field is buffered, we don't need to worry about partial reads. */ field= drizzle_field_buffer(res, &total, &ret); DEBUG("drizzle_field_buffer(%p, &p, %p) == %p, %x, %d", res, &total, &ret, field, total, ret); length= total; } else { field= drizzle_field_read(res, &offset, &length, &total, &ret); DEBUG("drizzle_field_read(%p, %p, %p, %p, %p) == " "%p, %x, %x, %x, %d", res, &offset, &length, &total, &ret, field, offset, length, total, ret); } if (ret == DRIZZLE_RETURN_ROW_END) break; else if (ret != DRIZZLE_RETURN_OK) { rc = drizzle_con_errno(con); DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc); log_text(LOG_ALERT, "drizzle_field_(buffer|read) failed: `%p`:", res); log_text(LOG_ALERT, "Error %d %s", drizzle_con_errno(con), drizzle_con_error(con)); return DB_ERROR_FATAL; } if (args.buffer == BUFFER_FIELD) drizzle_field_free(field); } /* while (1) Loop for fields */ } /* if (args.buffer) */ } /* while (1) */ } return DB_ERROR_NONE; } /* Free result set */ int drizzle_drv_free_results(db_result_t *rs) { if (rs->ptr != NULL) { DEBUG("drizzle_result_free(%p)", rs->ptr); drizzle_result_free(rs->ptr); rs->ptr = NULL; return 0; } return 1; } /* Close prepared statement */ int drizzle_drv_close(db_stmt_t *stmt) { (void)stmt; return 0; } /* Uninitialize driver */ int drizzle_drv_done(void) { return 0; } void column_info(drizzle_column_st *column) { DEBUG("Field: catalog=%s\n" " db=%s\n" " table=%s\n" " org_table=%s\n" " name=%s\n" " org_name=%s\n" " charset=%u\n" " size=%u\n" " type=%u\n" " flags=%u\n", drizzle_column_catalog(column), drizzle_column_db(column), drizzle_column_table(column), drizzle_column_orig_table(column), drizzle_column_name(column), drizzle_column_orig_name(column), drizzle_column_charset(column), drizzle_column_size(column), drizzle_column_type(column), drizzle_column_flags(column)); } sysbench-1.0.18/src/drivers/drizzle/Makefile.am0000600000175000017500000000147213553247311017207 0ustar jpjp# Copyright (C) 2009 Sun Microsystems, Inc. # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA noinst_LIBRARIES = libsbdrizzle.a libsbdrizzle_a_SOURCES = drv_drizzle.c sysbench-1.0.18/src/drivers/pgsql/0000700000175000017500000000000013553247311014610 5ustar jpjpsysbench-1.0.18/src/drivers/pgsql/drv_pgsql.c0000600000175000017500000004433313553247311016766 0ustar jpjp/* Copyright (C) 2005 MySQL AB Copyright (C) 2005-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include #include "sb_options.h" #include "db_driver.h" #include "sb_rand.h" #define xfree(ptr) ({ if (ptr) free((void *)ptr); ptr = NULL; }) /* Maximum length of text representation of bind parameters */ #define MAX_PARAM_LENGTH 256UL /* PostgreSQL driver arguments */ static sb_arg_t pgsql_drv_args[] = { SB_OPT("pgsql-host", "PostgreSQL server host", "localhost", STRING), SB_OPT("pgsql-port", "PostgreSQL server port", "5432", INT), SB_OPT("pgsql-user", "PostgreSQL user", "sbtest", STRING), SB_OPT("pgsql-password", "PostgreSQL password", "", STRING), SB_OPT("pgsql-db", "PostgreSQL database name", "sbtest", STRING), SB_OPT_END }; typedef struct { char *host; char *port; char *user; char *password; char *db; } pgsql_drv_args_t; /* Structure used for DB-to-PgSQL bind types map */ typedef struct { db_bind_type_t db_type; int pg_type; } db_pgsql_bind_map_t; /* DB-to-PgSQL bind types map */ db_pgsql_bind_map_t db_pgsql_bind_map[] = { {DB_TYPE_TINYINT, 0}, {DB_TYPE_SMALLINT, 21}, {DB_TYPE_INT, 23}, {DB_TYPE_BIGINT, 20}, {DB_TYPE_FLOAT, 700}, {DB_TYPE_DOUBLE, 701}, {DB_TYPE_DATETIME, 0}, {DB_TYPE_TIMESTAMP, 1114}, {DB_TYPE_CHAR, 18}, {DB_TYPE_VARCHAR, 1043}, {DB_TYPE_NONE, 0} }; /* PgSQL driver capabilities */ static drv_caps_t pgsql_drv_caps = { 1, /* multi_rows_insert */ 1, /* prepared_statements */ 0, /* auto_increment */ 0, /* needs_commit */ 1, /* serial */ 0, /* unsigned int */ }; /* Describes the PostgreSQL prepared statement */ typedef struct pg_stmt { char *name; int prepared; int nparams; Oid *ptypes; char **pvalues; } pg_stmt_t; static pgsql_drv_args_t args; /* driver args */ static char use_ps; /* whether server-side prepared statemens should be used */ /* PgSQL driver operations */ static int pgsql_drv_init(void); static int pgsql_drv_describe(drv_caps_t *); static int pgsql_drv_connect(db_conn_t *); static int pgsql_drv_disconnect(db_conn_t *); static int pgsql_drv_prepare(db_stmt_t *, const char *, size_t); static int pgsql_drv_bind_param(db_stmt_t *, db_bind_t *, size_t); static int pgsql_drv_bind_result(db_stmt_t *, db_bind_t *, size_t); static db_error_t pgsql_drv_execute(db_stmt_t *, db_result_t *); static int pgsql_drv_fetch(db_result_t *); static int pgsql_drv_fetch_row(db_result_t *, db_row_t *); static db_error_t pgsql_drv_query(db_conn_t *, const char *, size_t, db_result_t *); static int pgsql_drv_free_results(db_result_t *); static int pgsql_drv_close(db_stmt_t *); static int pgsql_drv_done(void); /* PgSQL driver definition */ static db_driver_t pgsql_driver = { .sname = "pgsql", .lname = "PostgreSQL driver", .args = pgsql_drv_args, .ops = { .init = pgsql_drv_init, .describe = pgsql_drv_describe, .connect = pgsql_drv_connect, .disconnect = pgsql_drv_disconnect, .prepare = pgsql_drv_prepare, .bind_param = pgsql_drv_bind_param, .bind_result = pgsql_drv_bind_result, .execute = pgsql_drv_execute, .fetch = pgsql_drv_fetch, .fetch_row = pgsql_drv_fetch_row, .free_results = pgsql_drv_free_results, .close = pgsql_drv_close, .query = pgsql_drv_query, .done = pgsql_drv_done } }; /* Local functions */ static int get_pgsql_bind_type(db_bind_type_t); static int get_unique_stmt_name(char *, int); /* Register PgSQL driver */ int register_driver_pgsql(sb_list_t *drivers) { SB_LIST_ADD_TAIL(&pgsql_driver.listitem, drivers); return 0; } /* PgSQL driver initialization */ int pgsql_drv_init(void) { args.host = sb_get_value_string("pgsql-host"); args.port = sb_get_value_string("pgsql-port"); args.user = sb_get_value_string("pgsql-user"); args.password = sb_get_value_string("pgsql-password"); args.db = sb_get_value_string("pgsql-db"); use_ps = 0; pgsql_drv_caps.prepared_statements = 1; if (db_globals.ps_mode != DB_PS_MODE_DISABLE) use_ps = 1; return 0; } /* Describe database capabilities */ int pgsql_drv_describe(drv_caps_t *caps) { PGconn *con; *caps = pgsql_drv_caps; /* Determine the server version */ con = PQsetdbLogin(args.host, args.port, NULL, NULL, args.db, args.user, args.password); if (PQstatus(con) != CONNECTION_OK) { log_text(LOG_FATAL, "Connection to database failed: %s", PQerrorMessage(con)); PQfinish(con); return 1; } /* Support for multi-row INSERTs is not available before 8.2 */ if (PQserverVersion(con) < 80200) caps->multi_rows_insert = 0; PQfinish(con); return 0; } static void empty_notice_processor(void *arg, const char *msg) { (void) arg; /* unused */ (void) msg; /* unused */ } /* Connect to database */ int pgsql_drv_connect(db_conn_t *sb_conn) { PGconn *con; con = PQsetdbLogin(args.host, args.port, NULL, NULL, args.db, args.user, args.password); if (PQstatus(con) != CONNECTION_OK) { log_text(LOG_FATAL, "Connection to database failed: %s", PQerrorMessage(con)); PQfinish(con); return 1; } /* Silence the default notice receiver spitting NOTICE message to stderr */ PQsetNoticeProcessor(con, empty_notice_processor, NULL); sb_conn->ptr = con; return 0; } /* Disconnect from database */ int pgsql_drv_disconnect(db_conn_t *sb_conn) { PGconn *con = (PGconn *)sb_conn->ptr; /* These might be allocated in pgsql_check_status() */ xfree(sb_conn->sql_state); xfree(sb_conn->sql_errmsg); if (con != NULL) PQfinish(con); return 0; } /* Prepare statement */ int pgsql_drv_prepare(db_stmt_t *stmt, const char *query, size_t len) { PGconn *con = (PGconn *)stmt->connection->ptr; PGresult *pgres; pg_stmt_t *pgstmt; char *buf = NULL; unsigned int vcnt; unsigned int need_realloc; unsigned int i,j; unsigned int buflen; int n; char name[32]; (void) len; /* unused */ if (con == NULL) return 1; if (!use_ps) { /* Use client-side PS */ stmt->emulated = 1; stmt->query = strdup(query); return 0; } /* Convert query to PgSQL-style named placeholders */ need_realloc = 1; vcnt = 1; buflen = 0; for (i = 0, j = 0; query[i] != '\0'; i++) { again: if (j+1 >= buflen || need_realloc) { buflen = (buflen > 0) ? buflen * 2 : 256; buf = realloc(buf, buflen); if (buf == NULL) goto error; need_realloc = 0; } if (query[i] != '?') { buf[j++] = query[i]; continue; } n = snprintf(buf + j, buflen - j, "$%d", vcnt); if (n < 0 || n >= (int)(buflen - j)) { need_realloc = 1; goto again; } j += n; vcnt++; } buf[j] = '\0'; /* Store the query to be prepared later on the first bind_param call */ stmt->query = strdup(buf); free(buf); pgstmt = (pg_stmt_t *)calloc(1, sizeof(pg_stmt_t)); if (pgstmt == NULL) goto error; /* Generate random statement name */ get_unique_stmt_name(name, sizeof(name)); pgstmt->name = strdup(name); pgstmt->nparams = vcnt - 1; /* Special keys for statements without parameters, since we don't need to know the types of arguments, and no calls to bind_param() will be made */ if (pgstmt->nparams == 0) { /* Do prepare */ pgres = PQprepare(con, pgstmt->name, stmt->query, pgstmt->nparams, NULL); if (PQresultStatus(pgres) != PGRES_COMMAND_OK) { log_text(LOG_FATAL, "PQprepare() failed: %s", PQerrorMessage(con)); PQclear(pgres); free(stmt->query); free(pgstmt->name); free(pgstmt); return 1; } PQclear(pgres); pgstmt->prepared = 1; } stmt->ptr = pgstmt; return 0; error: return 1; } /* Bind parameters for prepared statement */ int pgsql_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len) { PGconn *con = (PGconn *)stmt->connection->ptr; PGresult *pgres; pg_stmt_t *pgstmt; unsigned int i; if (con == NULL) return 1; if (stmt->bound_param != NULL) free(stmt->bound_param); stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t)); if (stmt->bound_param == NULL) return 1; memcpy(stmt->bound_param, params, len * sizeof(db_bind_t)); stmt->bound_param_len = len; if (stmt->emulated) return 0; pgstmt = stmt->ptr; if (pgstmt->prepared) return 0; /* Prepare statement here, since we need to know types of parameters */ /* Validate parameters count */ if ((unsigned)pgstmt->nparams != len) { log_text(LOG_ALERT, "wrong number of parameters in prepared statement"); log_text(LOG_DEBUG, "counted: %d, passed to bind_param(): %zd", pgstmt->nparams, len); return 1; } pgstmt->ptypes = (Oid *)malloc(len * sizeof(int)); if (pgstmt->ptypes == NULL) return 1; /* Convert sysbench data types to PgSQL ones */ for (i = 0; i < len; i++) pgstmt->ptypes[i] = get_pgsql_bind_type(params[i].type); /* Do prepare */ pgres = PQprepare(con, pgstmt->name, stmt->query, pgstmt->nparams, pgstmt->ptypes); if (PQresultStatus(pgres) != PGRES_COMMAND_OK) { log_text(LOG_FATAL, "PQprepare() failed: %s", PQerrorMessage(con)); return 1; } PQclear(pgres); pgstmt->pvalues = (char **)calloc(len, sizeof(char *)); if (pgstmt->pvalues == NULL) return 1; /* Allocate buffers for bind parameters */ for (i = 0; i < len; i++) { if (pgstmt->pvalues[i] != NULL) { free(pgstmt->pvalues[i]); } pgstmt->pvalues[i] = (char *)malloc(MAX_PARAM_LENGTH); if (pgstmt->pvalues[i] == NULL) return 1; } pgstmt->prepared = 1; return 0; } /* Bind results for prepared statement */ int pgsql_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, size_t len) { /* unused */ (void)stmt; (void)params; (void)len; return 0; } /* Check query execution status */ static db_error_t pgsql_check_status(db_conn_t *con, PGresult *pgres, const char *funcname, const char *query, db_result_t *rs) { ExecStatusType status; db_error_t rc; PGconn * const pgcon = con->ptr; status = PQresultStatus(pgres); switch(status) { case PGRES_TUPLES_OK: rs->nrows = PQntuples(pgres); rs->nfields = PQnfields(pgres); rs->counter = SB_CNT_READ; rc = DB_ERROR_NONE; break; case PGRES_COMMAND_OK: rs->nrows = strtoul(PQcmdTuples(pgres), NULL, 10);; rs->counter = (rs->nrows > 0) ? SB_CNT_WRITE : SB_CNT_OTHER; rc = DB_ERROR_NONE; /* Since we are not returning a result set, the SQL layer will never call pgsql_drv_free_results(). So we must call PQclear() here. */ PQclear(pgres); break; case PGRES_FATAL_ERROR: rs->nrows = 0; rs->counter = SB_CNT_ERROR; /* Duplicate strings here, because PostgreSQL will deallocate them on PQclear() call below. They will be deallocated either on subsequent calls to pgsql_check_status() or in pgsql_drv_disconnect(). */ xfree(con->sql_state); xfree(con->sql_errmsg); con->sql_state = strdup(PQresultErrorField(pgres, PG_DIAG_SQLSTATE)); con->sql_errmsg = strdup(PQresultErrorField(pgres, PG_DIAG_MESSAGE_PRIMARY)); if (!strcmp(con->sql_state, "40P01") /* deadlock_detected */ || !strcmp(con->sql_state, "23505") /* unique violation */ || !strcmp(con->sql_state, "40001"))/* serialization_failure */ { PGresult *tmp; tmp = PQexec(pgcon, "ROLLBACK"); PQclear(tmp); rc = DB_ERROR_IGNORABLE; } else { log_text(LOG_FATAL, "%s() failed: %d %s", funcname, status, con->sql_errmsg); if (query != NULL) log_text(LOG_FATAL, "failed query was: %s", query); rc = DB_ERROR_FATAL; } PQclear(pgres); break; default: rs->nrows = 0; rs->counter = SB_CNT_ERROR; rc = DB_ERROR_FATAL; } return rc; } /* Execute prepared statement */ db_error_t pgsql_drv_execute(db_stmt_t *stmt, db_result_t *rs) { db_conn_t *con = stmt->connection; PGconn *pgcon = (PGconn *)con->ptr; PGresult *pgres; pg_stmt_t *pgstmt; char *buf = NULL; unsigned int buflen = 0; unsigned int i, j, vcnt; char need_realloc; int n; db_error_t rc; unsigned long len; con->sql_errno = 0; xfree(con->sql_state); xfree(con->sql_errmsg); if (!stmt->emulated) { pgstmt = stmt->ptr; if (pgstmt == NULL) { log_text(LOG_DEBUG, "ERROR: exiting mysql_drv_execute(), uninitialized statement"); return DB_ERROR_FATAL; } /* Convert sysbench bind structures to PgSQL data */ for (i = 0; i < (unsigned)pgstmt->nparams; i++) { if (stmt->bound_param[i].is_null && *(stmt->bound_param[i].is_null)) continue; switch (stmt->bound_param[i].type) { case DB_TYPE_CHAR: case DB_TYPE_VARCHAR: len = stmt->bound_param[i].data_len[0]; memcpy(pgstmt->pvalues[i], stmt->bound_param[i].buffer, SB_MIN(MAX_PARAM_LENGTH, len)); /* PostgreSQL requires a zero-terminated string */ pgstmt->pvalues[i][len] = '\0'; break; default: db_print_value(stmt->bound_param + i, pgstmt->pvalues[i], MAX_PARAM_LENGTH); } } pgres = PQexecPrepared(pgcon, pgstmt->name, pgstmt->nparams, (const char **)pgstmt->pvalues, NULL, NULL, 1); rc = pgsql_check_status(con, pgres, "PQexecPrepared", NULL, rs); rs->ptr = (rs->counter == SB_CNT_READ) ? (void *) pgres : NULL; return rc; } /* Use emulation */ /* Build the actual query string from parameters list */ need_realloc = 1; vcnt = 0; for (i = 0, j = 0; stmt->query[i] != '\0'; i++) { again: if (j+1 >= buflen || need_realloc) { buflen = (buflen > 0) ? buflen * 2 : 256; buf = realloc(buf, buflen); if (buf == NULL) return DB_ERROR_FATAL; need_realloc = 0; } if (stmt->query[i] != '?') { buf[j++] = stmt->query[i]; continue; } n = db_print_value(stmt->bound_param + vcnt, buf + j, buflen - j); if (n < 0) { need_realloc = 1; goto again; } j += n; vcnt++; } buf[j] = '\0'; rc = pgsql_drv_query(con, buf, j, rs); free(buf); return rc; } /* Execute SQL query */ db_error_t pgsql_drv_query(db_conn_t *sb_conn, const char *query, size_t len, db_result_t *rs) { PGconn *pgcon = sb_conn->ptr; PGresult *pgres; db_error_t rc; (void)len; /* unused */ sb_conn->sql_errno = 0; xfree(sb_conn->sql_state); xfree(sb_conn->sql_errmsg); pgres = PQexec(pgcon, query); rc = pgsql_check_status(sb_conn, pgres, "PQexec", query, rs); rs->ptr = (rs->counter == SB_CNT_READ) ? (void *) pgres : NULL; return rc; } /* Fetch row from result set of a prepared statement */ int pgsql_drv_fetch(db_result_t *rs) { /* NYI */ (void)rs; return 1; } /* Fetch row from result set of a query */ int pgsql_drv_fetch_row(db_result_t *rs, db_row_t *row) { intptr_t rownum; int i; /* Use row->ptr as a row number, rather than a pointer to avoid dynamic memory management. */ rownum = (intptr_t) row->ptr; if (rownum >= (int) rs->nrows) return DB_ERROR_IGNORABLE; for (i = 0; i < (int) rs->nfields; i++) { /* PQgetvalue() returns an empty string, not a NULL value for a NULL field. Callers of this function expect a NULL pointer in this case. */ if (PQgetisnull(rs->ptr, rownum, i)) row->values[i].ptr = NULL; else { row->values[i].len = PQgetlength(rs->ptr, rownum, i); row->values[i].ptr = PQgetvalue(rs->ptr, rownum, i); } } row->ptr = (void *) (rownum + 1); return DB_ERROR_NONE; } /* Free result set */ int pgsql_drv_free_results(db_result_t *rs) { if (rs->ptr != NULL) { PQclear((PGresult *)rs->ptr); rs->ptr = NULL; rs->row.ptr = 0; return 0; } return 1; } /* Close prepared statement */ int pgsql_drv_close(db_stmt_t *stmt) { pg_stmt_t *pgstmt = stmt->ptr; int i; if (pgstmt == NULL) return 1; if (pgstmt->name != NULL) free(pgstmt->name); if (pgstmt->ptypes != NULL) free(pgstmt->ptypes); if (pgstmt->pvalues != NULL) { for (i = 0; i < pgstmt->nparams; i++) if (pgstmt->pvalues[i] != NULL) free(pgstmt->pvalues[i]); free(pgstmt->pvalues); } xfree(stmt->ptr); return 0; } /* Uninitialize driver */ int pgsql_drv_done(void) { return 0; } /* Map SQL data type to bind_type value in MYSQL_BIND */ int get_pgsql_bind_type(db_bind_type_t type) { unsigned int i; for (i = 0; db_pgsql_bind_map[i].db_type != DB_TYPE_NONE; i++) if (db_pgsql_bind_map[i].db_type == type) return db_pgsql_bind_map[i].pg_type; return -1; } int get_unique_stmt_name(char *name, int len) { return snprintf(name, len, "sbstmt%d%d", (int) sb_rand_uniform_uint64(), (int) sb_rand_uniform_uint64()); } sysbench-1.0.18/src/drivers/pgsql/Makefile.am0000600000175000017500000000163613553247311016654 0ustar jpjp# Copyright (C) 2005 MySQL AB # Copyright (C) 2005-2015 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA noinst_LIBRARIES = libsbpgsql.a libsbpgsql_a_SOURCES = drv_pgsql.c libsbpgsql_a_CPPFLAGS = -g $(PGSQL_CFLAGS) $(AM_CPPFLAGS) sysbench-1.0.18/src/drivers/attachsql/0000700000175000017500000000000013553247311015446 5ustar jpjpsysbench-1.0.18/src/drivers/attachsql/drv_attachsql.c0000600000175000017500000004016613553247311020462 0ustar jpjp/* Copyright 2014 Hewlett-Packard Development Company, L.P. based on the Drizzle driver: Copyright (C) 2009 Sun Microsystems, Inc. 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include #include #include #include "sb_options.h" #include "db_driver.h" #define DEBUG(format, ...) do { if (db_globals.debug) log_text(LOG_DEBUG, format, __VA_ARGS__); } while (0) /* Drizzle driver arguments */ static sb_arg_t attachsql_drv_args[] = { {"attachsql-host", "libAttachSQL server host", SB_ARG_TYPE_LIST, "localhost"}, {"attachsql-port", "libAttachSQL server port", SB_ARG_TYPE_INT, "4427"}, {"attachsql-socket", "libAttachSQL socket", SB_ARG_TYPE_STRING, NULL}, {"attachsql-user", "libAttachSQL user", SB_ARG_TYPE_STRING, ""}, {"attachsql-password", "libAttachSQL password", SB_ARG_TYPE_STRING, ""}, {"attachsql-db", "libAttachSQL database name", SB_ARG_TYPE_STRING, "sbtest"}, {NULL, NULL, SB_ARG_TYPE_NULL, NULL} }; typedef struct { sb_list_t *hosts; unsigned int port; char *socket; char *user; char *password; char *db; } attachsql_drv_args_t; /* AttachSQL driver capabilities * At a later date we will add prepared statements to this */ static drv_caps_t attachsql_drv_caps = { .multi_rows_insert = 1, .prepared_statements = 1, .auto_increment = 1, .serial = 0, .unsigned_int = 0, }; static attachsql_drv_args_t args; /* driver args */ static sb_list_item_t *hosts_pos; static pthread_mutex_t hosts_mutex; /* libAttachSQL driver operations */ static int attachsql_drv_init(void); static int attachsql_drv_describe(drv_caps_t *); static int attachsql_drv_connect(db_conn_t *); static int attachsql_drv_disconnect(db_conn_t *); static int attachsql_drv_prepare(db_stmt_t *, const char *, size_t); static int attachsql_drv_bind_param(db_stmt_t *, db_bind_t *, size_t); static int attachsql_drv_bind_result(db_stmt_t *, db_bind_t *, size_t); static db_error_t attachsql_drv_execute(db_stmt_t *, db_result_t *); static int attachsql_drv_fetch(db_result_t *); static int attachsql_drv_fetch_row(db_result_t *, db_row_t *); static db_error_t attachsql_drv_query(db_conn_t *, const char *, size_t, db_result_t *); static int attachsql_drv_free_results(db_result_t *); static int attachsql_drv_close(db_stmt_t *); static int attachsql_drv_store_results(db_result_t *); static int attachsql_drv_done(void); /* libAttachSQL driver definition */ static db_driver_t attachsql_driver = { .sname = "attachsql", .lname = "libAttachSQL driver", .args = attachsql_drv_args, .ops = { .init = attachsql_drv_init, .describe = attachsql_drv_describe, .connect = attachsql_drv_connect, .disconnect = attachsql_drv_disconnect, .prepare = attachsql_drv_prepare, .bind_param = attachsql_drv_bind_param, .bind_result = attachsql_drv_bind_result, .execute = attachsql_drv_execute, .fetch = attachsql_drv_fetch, .fetch_row = attachsql_drv_fetch_row, .free_results = attachsql_drv_free_results, .close = attachsql_drv_close, .query = attachsql_drv_query, .store_results = attachsql_drv_store_results, .done = attachsql_drv_done } }; /* Local functions */ /* Register libAttachSQL driver */ int register_driver_attachsql(sb_list_t *drivers) { SB_LIST_ADD_TAIL(&attachsql_driver.listitem, drivers); return 0; } /* libAttachSQL driver initialization */ int attachsql_drv_init(void) { args.hosts = sb_get_value_list("attachsql-host"); if (SB_LIST_IS_EMPTY(args.hosts)) { log_text(LOG_FATAL, "No libAttachSQL hosts specified, aborting"); return 1; } hosts_pos = args.hosts; pthread_mutex_init(&hosts_mutex, NULL); args.port = (unsigned int)sb_get_value_int("attachsql-port"); args.socket = sb_get_value_string("attachsql-socket"); args.user = sb_get_value_string("attachsql-user"); args.password = sb_get_value_string("attachsql-password"); args.db = sb_get_value_string("attachsql-db"); attachsql_library_init(); return 0; } /* Describe database capabilities (possibly depending on table type) */ int attachsql_drv_describe(drv_caps_t *caps ) { *caps = attachsql_drv_caps; return 0; } /* Connect to libAttachSQL database */ int attachsql_drv_connect(db_conn_t *sb_conn) { attachsql_connect_t *con= NULL; const char *host; attachsql_error_t *error= NULL; attachsql_return_t aret= ATTACHSQL_RETURN_NONE; if (args.socket) { DEBUG("attachsql_connect_create(\"%s\", \"%s\", \"%s\", \"%s\")", args.socket, args.user, args.password, args.db); con= attachsql_connect_create(args.socket, 0, args.user, args.password, args.db, &error); } else { pthread_mutex_lock(&hosts_mutex); hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos); if (hosts_pos == args.hosts) hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos); host = SB_LIST_ENTRY(hosts_pos, value_t, listitem)->data; pthread_mutex_unlock(&hosts_mutex); DEBUG("attachsql_connect_create(\"%s\", %u, \"%s\", \"%s\", \"%s\")", host, args.port, args.user, args.password, args.db); con= attachsql_connect_create(host, args.port, args.user, args.password, args.db, &error); } if (con == NULL) { log_text(LOG_FATAL, "unable to Add libAttachSQL Connection, aborting..."); log_text(LOG_FATAL, "error %d: %s", attachsql_error_code(error), attachsql_error_message(error)); attachsql_error_free(error); return 1; } attachsql_connect_set_option(con, ATTACHSQL_OPTION_SEMI_BLOCKING, NULL); if (!attachsql_connect(con, &error)) { log_text(LOG_FATAL, "unable to connect to libAttachSQL server"); log_text(LOG_FATAL, "error %d: %s", attachsql_error_code(error), attachsql_error_message(error)); attachsql_error_free(error); attachsql_connect_destroy(con); return 1; } while (aret != ATTACHSQL_RETURN_IDLE) { aret = attachsql_connect_poll(con, &error); if (error) { log_text(LOG_FATAL, "unable to connect to libAttachSQL server"); log_text(LOG_FATAL, "error %d: %s", attachsql_error_code(error), attachsql_error_message(error)); attachsql_error_free(error); attachsql_connect_destroy(con); return 1; } } sb_conn->ptr = con; return 0; } /* Disconnect from libAttachSQL database */ int attachsql_drv_disconnect(db_conn_t *sb_conn) { attachsql_connect_t *con = (attachsql_connect_t *)sb_conn->ptr; if (con != NULL) { DEBUG("attachsql_connect_destroy(%p)", con); attachsql_connect_destroy(con); } return 0; } /* Prepare statement */ int attachsql_drv_prepare(db_stmt_t *stmt, const char *query, size_t len) { attachsql_connect_t *con= (attachsql_connect_t *)stmt->connection->ptr; attachsql_error_t *error= NULL; attachsql_return_t aret= ATTACHSQL_RETURN_NONE; attachsql_statement_prepare(con, len, query, &error); while(aret != ATTACHSQL_RETURN_EOF) { aret= attachsql_connect_poll(con, &error); if (error) { log_text(LOG_ALERT, "libAttachSQL Prepare Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error)); attachsql_error_free(error); return DB_ERROR_FATAL; } } return 0; } /* Bind parameters for prepared statement */ int attachsql_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len) { /* libAttachSQL doesn't do this, you do this during execute * this is because sysbench doesn't set the values until that time */ if (stmt->bound_param != NULL) free(stmt->bound_param); stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t)); if (stmt->bound_param == NULL) return 1; memcpy(stmt->bound_param, params, len * sizeof(db_bind_t)); stmt->bound_param_len = len; return 0; } /* Bind results for prepared statement */ int attachsql_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, size_t len) { (void)stmt; (void)params; (void)len; /* libAttachSQL doesn't do this, you get after execute */ return 0; } /* Execute prepared statement */ db_error_t attachsql_drv_execute(db_stmt_t *stmt, db_result_t *rs) { (void) rs; attachsql_connect_t *con= (attachsql_connect_t *)stmt->connection->ptr; attachsql_return_t aret= ATTACHSQL_RETURN_NONE; attachsql_error_t *error= NULL; uint16_t i; int8_t tinyint; int16_t smallint; int32_t normalint; int64_t bigint; float float_type; double double_type; db_time_t *time_data; if (con == NULL) return 1; for (i= 0; i < stmt->bound_param_len; i++) { db_bind_t *param= &stmt->bound_param[i]; switch(param->type) { case DB_TYPE_TINYINT: tinyint= *(int8_t*)param->buffer; attachsql_statement_set_int(con, i, tinyint, NULL); break; case DB_TYPE_SMALLINT: smallint= *(int16_t*)param->buffer; attachsql_statement_set_int(con, i, smallint, NULL); break; case DB_TYPE_INT: normalint= *(int32_t*)param->buffer; attachsql_statement_set_int(con, i, normalint, NULL); break; case DB_TYPE_BIGINT: bigint= *(int64_t*)param->buffer; attachsql_statement_set_bigint(con, i, bigint, NULL); break; case DB_TYPE_FLOAT: float_type= *(float*)param->buffer; attachsql_statement_set_float(con, i, float_type, NULL); break; case DB_TYPE_DOUBLE: double_type= *(double*)param->buffer; attachsql_statement_set_double(con, i, double_type, NULL); break; case DB_TYPE_TIME: time_data= (db_time_t*)param->buffer; attachsql_statement_set_time(con, i, time_data->hour, time_data->minute, time_data->second, 0, false, NULL); break; case DB_TYPE_DATE: case DB_TYPE_DATETIME: case DB_TYPE_TIMESTAMP: time_data= (db_time_t*)param->buffer; attachsql_statement_set_datetime(con, i, time_data->year, time_data->month, time_data->day, time_data->hour, time_data->minute, time_data->second, 0, NULL); break; case DB_TYPE_CHAR: case DB_TYPE_VARCHAR: attachsql_statement_set_string(con, i, param->max_len, param->buffer, NULL); case DB_TYPE_NONE: default: attachsql_statement_set_null(con, i, NULL); /* Not supported */ } } attachsql_statement_execute(con, &error); while(aret != ATTACHSQL_RETURN_EOF) { aret= attachsql_connect_poll(con, &error); if (aret == ATTACHSQL_RETURN_ROW_READY) { return 0; } if (error) { log_text(LOG_ALERT, "libAttachSQL Execute Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error)); attachsql_error_free(error); return DB_ERROR_FATAL; } } return DB_ERROR_NONE; } /* Execute SQL query */ db_error_t attachsql_drv_query(db_conn_t *sb_conn, const char *query, size_t len, db_result_t *rs) { (void) rs; attachsql_connect_t *con = sb_conn->ptr; unsigned int rc; attachsql_error_t *error= NULL; attachsql_return_t aret= ATTACHSQL_RETURN_NONE; /* Close any previous query */ attachsql_query_close(con); DEBUG("attachsql_query(%p, \"%s\", %u)", con, query, len); attachsql_query(con, len, query, 0, NULL, &error); while((aret != ATTACHSQL_RETURN_EOF) && (aret != ATTACHSQL_RETURN_ROW_READY)) { aret= attachsql_connect_poll(con, &error); if (error) { rc= attachsql_error_code(error); if (rc == 1213 || rc == 1205 || rc == 1020) { attachsql_error_free(error); return DB_ERROR_IGNORABLE; } log_text(LOG_ALERT, "libAttachSQL Query Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error)); attachsql_error_free(error); return DB_ERROR_FATAL; } } //rs->connection->ptr= con; DEBUG("attachsql_query \"%s\" returned %d", query, aret); return DB_ERROR_NONE; } /* Fetch row from result set of a prepared statement */ int attachsql_drv_fetch(db_result_t *rs) { /* NYI */ attachsql_connect_t *con = rs->connection->ptr; size_t tmp_len; uint16_t columns, col; attachsql_return_t aret= ATTACHSQL_RETURN_NONE; attachsql_error_t *error= NULL; while((aret != ATTACHSQL_RETURN_EOF) && (aret != ATTACHSQL_RETURN_ROW_READY)) { aret= attachsql_connect_poll(con, &error); if (error) { log_text(LOG_ALERT, "libAttachSQL Query Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error)); attachsql_error_free(error); return 1; } } if (aret == ATTACHSQL_RETURN_EOF) { return 1; } attachsql_statement_row_get(con, NULL); columns= attachsql_query_column_count(con); for (col= 0; col < columns; col++) { switch (attachsql_statement_get_column_type(con, col)) { case ATTACHSQL_COLUMN_TYPE_TINY: case ATTACHSQL_COLUMN_TYPE_SHORT: case ATTACHSQL_COLUMN_TYPE_LONG: case ATTACHSQL_COLUMN_TYPE_YEAR: case ATTACHSQL_COLUMN_TYPE_INT24: attachsql_statement_get_int(con, col, &error); break; case ATTACHSQL_COLUMN_TYPE_LONGLONG: attachsql_statement_get_bigint(con, col, &error); break; case ATTACHSQL_COLUMN_TYPE_FLOAT: attachsql_statement_get_float(con, col, &error); break; case ATTACHSQL_COLUMN_TYPE_DOUBLE: attachsql_statement_get_double(con, col, &error); break; default: attachsql_statement_get_char(con, col, &tmp_len, &error); break; } } attachsql_query_row_next(con); return 0; } /* Fetch row from result set of a query */ int attachsql_drv_fetch_row(db_result_t *rs, db_row_t *row) { attachsql_error_t *error= NULL; attachsql_return_t aret= ATTACHSQL_RETURN_NONE; /* NYI */ attachsql_connect_t *con = rs->connection->ptr; while((aret != ATTACHSQL_RETURN_EOF) && (aret != ATTACHSQL_RETURN_ROW_READY)) { aret= attachsql_connect_poll(con, &error); if (error) { log_text(LOG_ALERT, "libAttachSQL Query Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error)); attachsql_error_free(error); return 1; } } if (aret == ATTACHSQL_RETURN_EOF) { return 1; } row->ptr= attachsql_query_row_get(con, NULL); attachsql_query_row_next(con); return 0; } /* Store results from the last query */ int attachsql_drv_store_results(db_result_t *rs) { int ret= 0; db_row_t row; /* libAttachSQL can't do things in this order */ while (ret == 0) { if (rs->statement != NULL) { ret= attachsql_drv_fetch(rs); } else { ret= attachsql_drv_fetch_row(rs, &row); } } return DB_ERROR_NONE; } /* Free result set */ int attachsql_drv_free_results(db_result_t *rs) { if (rs->connection->ptr != NULL) { DEBUG("attachsql_query_close(%p)", rs->connection->ptr); attachsql_query_close(rs->connection->ptr); rs->connection->ptr = NULL; return 0; } return 1; } /* Close prepared statement */ int attachsql_drv_close(db_stmt_t *stmt) { attachsql_connect_t *con= (attachsql_connect_t *)stmt->connection->ptr; attachsql_statement_close(con); return 0; } /* Uninitialize driver */ int attachsql_drv_done(void) { return 0; } sysbench-1.0.18/src/drivers/attachsql/Makefile.am0000600000175000017500000000164113553247311017506 0ustar jpjp# Copyright 2014 Hewlett-Packard Development Company, L.P. # based on the Drizzle driver: # Copyright (C) 2009 Sun Microsystems, Inc. # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA noinst_LIBRARIES = libsbattachsql.a libsbattachsql_a_SOURCES = drv_attachsql.c sysbench-1.0.18/src/drivers/oracle/0000700000175000017500000000000013553247311014727 5ustar jpjpsysbench-1.0.18/src/drivers/oracle/drv_oracle.c0000600000175000017500000006360713553247311017231 0ustar jpjp/* Copyright (C) 2005 MySQL AB Copyright (C) 2005-2008 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include #include "sb_options.h" #include "db_driver.h" /* Number of rows to prefetch for result sets */ #define ORA_DRV_PREFETCH_COUNT 1000 #define CHECKERR(stmt) \ do { \ if (rc != OCI_SUCCESS) \ { \ log_text(LOG_FATAL, "%s failed in %s:%d", stmt, __FILE__, __LINE__); \ checkerr(ora_con->errhp, rc); \ goto error; \ } \ } while(0); static sb_arg_t ora_drv_args[] = { {"oracle-user", "Oracle user", SB_ARG_TYPE_STRING, "sbtest"}, {"oracle-password", "Oracle password", SB_ARG_TYPE_STRING, ""}, {"oracle-db", "Oracle database name", SB_ARG_TYPE_STRING, "sbtest"}, {NULL, NULL, SB_ARG_TYPE_NULL, NULL} }; typedef struct { OCISvcCtx *svchp; OCIServer *srvhp; OCIError *errhp; OCITrans *transhp; OCISession *usrhp; } ora_conn_t; typedef struct { sb2 ind; } ora_bind_t; typedef enum { STMT_TYPE_BEGIN, STMT_TYPE_COMMIT, STMT_TYPE_SELECT, STMT_TYPE_UPDATE } ora_stmt_type_t; typedef struct { OCIStmt *ptr; ora_stmt_type_t type; ora_bind_t *params; ora_bind_t *results; } ora_stmt_t; typedef struct { ub2 type; text *name; ub2 len; OCIDefine *defhp; void *value; sb2 ind; sb_list_item_t listitem; } ora_column_t; typedef struct { void *value; sb2 ind; } ora_data_t; typedef struct { ora_data_t *data; sb_list_item_t listitem; } ora_row_t; typedef struct { ub4 ncolumns; ub4 nrows; sb_list_t columns; sb_list_t rows; } ora_result_set_t; typedef struct { char *user; char *password; unsigned char *db; } ora_drv_args_t; /* Structure used for DB-to-Oracle bind types map */ typedef struct { db_bind_type_t db_type; ub2 ora_type; sb4 ora_len; } db_oracle_bind_map_t; /* DB-to-Oracle bind types map */ db_oracle_bind_map_t db_oracle_bind_map[] = { {DB_TYPE_TINYINT, SQLT_INT, sizeof(char)}, {DB_TYPE_SMALLINT, SQLT_INT, sizeof(short)}, {DB_TYPE_INT, SQLT_INT, sizeof(int)} , {DB_TYPE_BIGINT, SQLT_INT, sizeof(long long)}, {DB_TYPE_FLOAT, SQLT_FLT, sizeof(float)}, {DB_TYPE_DOUBLE, SQLT_FLT, sizeof(double)}, {DB_TYPE_DATETIME, SQLT_DATE, sizeof(void *)}, {DB_TYPE_TIMESTAMP, SQLT_TIMESTAMP, sizeof(void *)}, {DB_TYPE_CHAR, SQLT_AFC, 0}, {DB_TYPE_VARCHAR, SQLT_VCS, 0}, {DB_TYPE_NONE, 0, 0} }; /* Oracle driver capabilities */ static drv_caps_t ora_drv_caps = { .multi_rows_insert = 0, .prepared_statements = 1, .needs_commit = 1, }; static OCIEnv *ora_env; /* OCI environmental handle */ static ora_drv_args_t args; /* driver args */ /* Oracle driver operations */ static int ora_drv_init(void); static int ora_drv_describe(drv_caps_t *); static int ora_drv_connect(db_conn_t *); static int ora_drv_disconnect(db_conn_t *); static int ora_drv_prepare(db_stmt_t *, const char *, size_t); static int ora_drv_bind_param(db_stmt_t *, db_bind_t *, size_t); static int ora_drv_bind_result(db_stmt_t *, db_bind_t *, size_t); static db_error_t ora_drv_execute(db_stmt_t *, db_result_t *); static int ora_drv_fetch(db_result_t *); static int ora_drv_fetch_row(db_result_t *, db_row_t *); static db_error_t ora_drv_query(db_conn_t *, const char *, size_t, db_result_t *); static int ora_drv_free_results(db_result_t *); static int ora_drv_close(db_stmt_t *); static int ora_drv_store_results(db_result_t *); static int ora_drv_done(void); /* Oracle driver definition */ static db_driver_t oracle_driver = { .sname = "oracle", .lname = "Oracle driver", .args = ora_drv_args, .ops = { .init = ora_drv_init, .describe = ora_drv_describe, .connect = ora_drv_connect, .disconnect = ora_drv_disconnect, .prepare = ora_drv_prepare, .bind_param = ora_drv_bind_param, .bind_result = ora_drv_bind_result, .execute = ora_drv_execute, .fetch = ora_drv_fetch, .fetch_row = ora_drv_fetch_row, .free_results = ora_drv_free_results, .close = ora_drv_close, .query = ora_drv_query, .store_results = ora_drv_store_results, .done = ora_drv_done } }; /* Local functions */ static sword get_oracle_bind_type(db_bind_t *, ub2 *, sb4 *, sb2 *); static sb4 get_oracle_type_size(sword); static ora_stmt_type_t get_stmt_type(const char *); static void checkerr(OCIError *, sword); /* Register Oracle driver */ int register_driver_oracle(sb_list_t *drivers) { SB_LIST_ADD_TAIL(&oracle_driver.listitem, drivers); return 0; } /* Oracle driver initialization */ int ora_drv_init(void) { sword rc; args.user = sb_get_value_string("oracle-user"); args.password = sb_get_value_string("oracle-password"); args.db = sb_get_value_string("oracle-db"); /* Initialize the environment */ rc = OCIEnvCreate(&ora_env, OCI_THREADED | OCI_OBJECT, NULL, NULL, NULL, NULL, 0, NULL); if (rc != OCI_SUCCESS || ora_env == NULL) { log_text(LOG_FATAL, "OCIEnvCreate failed!"); return 1; } return 0; } /* Describe database capabilities */ int ora_drv_describe(drv_caps_t *caps) { *caps = ora_drv_caps; return 0; } /* Connect to the database */ int ora_drv_connect(db_conn_t *sb_conn) { sword rc; ora_conn_t *ora_con = NULL; ora_con = (ora_conn_t *)malloc(sizeof(ora_conn_t)); if (ora_con == NULL) goto error; /* Allocate a service handle */ rc = OCIHandleAlloc(ora_env, (dvoid **)&(ora_con->svchp), OCI_HTYPE_SVCCTX, 0, (dvoid **)NULL); if (rc != OCI_SUCCESS) { log_text(LOG_FATAL, "OCIHandleAlloc (OCI_HTYPE_SVCCTX) failed"); goto error; } /* Allocate an error handle */ rc = OCIHandleAlloc(ora_env, (dvoid **)&(ora_con->errhp), OCI_HTYPE_ERROR, 0, (dvoid **)NULL); if (rc != OCI_SUCCESS) { log_text(LOG_FATAL, "OCIHandleAlloc (OCI_HTYPE_ERROR) failed"); goto error; } /* Allocate an server handle */ rc = OCIHandleAlloc(ora_env, (dvoid **)&(ora_con->srvhp), OCI_HTYPE_SERVER, 0, (dvoid **)NULL); CHECKERR("OCIHandleAlloc"); /* Allocate a user session handle */ rc = OCIHandleAlloc(ora_env, (dvoid **)&(ora_con->usrhp), OCI_HTYPE_SESSION, 0, (dvoid **)NULL); CHECKERR("OCIHandleAlloc"); /* Attach to the server */ rc = OCIServerAttach(ora_con->srvhp, ora_con->errhp, args.db, strlen(args.db), OCI_DEFAULT); CHECKERR("OCIServerAttach"); /* Set the server attribute in the service context handler */ rc = OCIAttrSet(ora_con->svchp, OCI_HTYPE_SVCCTX, ora_con->srvhp, 0, OCI_ATTR_SERVER, ora_con->errhp); CHECKERR("OCIAttrSet"); /* Set the user name attribute in the user session handler */ rc = OCIAttrSet(ora_con->usrhp, OCI_HTYPE_SESSION, args.user, strlen(args.user), OCI_ATTR_USERNAME, ora_con->errhp); CHECKERR("OCIAttrSet"); /* Set the password attribute in the user session handler */ rc = OCIAttrSet(ora_con->usrhp, OCI_HTYPE_SESSION, args.password, strlen(args.password), OCI_ATTR_PASSWORD, ora_con->errhp); CHECKERR("OCIAttrSet"); /* Allocate the transaction handle and set it to service context */ rc = OCIHandleAlloc(ora_env, (dvoid **)&(ora_con->transhp), OCI_HTYPE_TRANS, 0, (dvoid **)NULL); CHECKERR("OCIHandleAlloc"); rc = OCIAttrSet(ora_con->svchp, OCI_HTYPE_SVCCTX, ora_con->transhp, 0, OCI_ATTR_TRANS, ora_con->errhp); CHECKERR("OCIAttrSet"); /* Start the session */ rc = OCISessionBegin (ora_con->svchp, ora_con->errhp, ora_con->usrhp, OCI_CRED_RDBMS, OCI_DEFAULT); CHECKERR("OCISessionBegin"); /* Set the user session attribute in the service context handler */ rc = OCIAttrSet(ora_con->svchp, OCI_HTYPE_SVCCTX, ora_con->usrhp, 0, OCI_ATTR_SESSION, ora_con->errhp); CHECKERR("OCIAttrSet"); sb_conn->ptr = ora_con; return 0; error: if (ora_con != NULL) free(ora_con); return 1; } /* Disconnect from database */ int ora_drv_disconnect(db_conn_t *sb_conn) { ora_conn_t *con = sb_conn->ptr; sword rc; int res = 0; if (con == NULL) return 1; rc = OCISessionEnd(con->svchp, con->errhp, con->usrhp, 0); if (rc != OCI_SUCCESS) { log_text(LOG_FATAL, "OCISessionEnd failed"); res = 1; } rc = OCIServerDetach(con->srvhp, con->errhp, OCI_DEFAULT); if (rc != OCI_SUCCESS) { log_text(LOG_FATAL, "OCIServerDetach failed"); res = 1; } /* Free handles */ if (OCIHandleFree(con->usrhp, OCI_HTYPE_SESSION) != OCI_SUCCESS) res = 1; if (OCIHandleFree(con->srvhp, OCI_HTYPE_SERVER) != OCI_SUCCESS) res = 1; if (OCIHandleFree(con->svchp, OCI_HTYPE_SVCCTX) != OCI_SUCCESS) res = 1; if (OCIHandleFree(con->errhp, OCI_HTYPE_ERROR) != OCI_SUCCESS) res = 1; free(con); return res; } /* Prepare statement */ int ora_drv_prepare(db_stmt_t *stmt, const char *query, size_t len) { ora_conn_t *ora_con = (ora_conn_t *)stmt->connection->ptr; sword rc; ora_stmt_t *ora_stmt = NULL; char *buf = NULL; unsigned int vcnt; unsigned int need_realloc; unsigned int i,j; unsigned int buflen; int n; ub4 prefetch_cnt = ORA_DRV_PREFETCH_COUNT; if (ora_con == NULL) return 1; if (db_globals.ps_mode != DB_PS_MODE_DISABLE) { ora_stmt = (ora_stmt_t *)calloc(1, sizeof(ora_stmt_t)); if (ora_stmt == NULL) goto error; rc = OCIHandleAlloc(ora_env, (dvoid **)&(ora_stmt->ptr), OCI_HTYPE_STMT, 0, NULL); if (rc != OCI_SUCCESS) goto error; /* Convert query to Oracle-style named placeholders */ need_realloc = 1; vcnt = 1; buflen = 0; for (i = 0, j = 0; query[i] != '\0'; i++) { again: if (j+1 >= buflen || need_realloc) { buflen = (buflen > 0) ? buflen * 2 : 256; buf = realloc(buf, buflen); if (buf == NULL) goto error; need_realloc = 0; } if (query[i] != '?') { buf[j++] = query[i]; continue; } n = snprintf(buf + j, buflen - j, ":%d", vcnt); if (n < 0 || n >= (int)(buflen - j)) { need_realloc = 1; goto again; } j += n; vcnt++; } buf[j] = '\0'; ora_stmt->type = get_stmt_type(buf); if (ora_stmt->type != STMT_TYPE_BEGIN && ora_stmt->type != STMT_TYPE_COMMIT) { rc = OCIStmtPrepare(ora_stmt->ptr, ora_con->errhp, buf, j, OCI_NTV_SYNTAX, OCI_DEFAULT); CHECKERR("OCIStmtPrepare"); rc = OCIAttrSet(ora_stmt->ptr, OCI_HTYPE_STMT, &prefetch_cnt, 0, OCI_ATTR_PREFETCH_ROWS, ora_con->errhp); CHECKERR("OCIAttrSet"); } free(buf); stmt->ptr = (void *)ora_stmt; } else { /* Use client-side PS */ stmt->emulated = 1; } stmt->query = strdup(query); return 0; error: if (ora_stmt != NULL) { if (ora_stmt->ptr != NULL) OCIHandleFree(ora_stmt->ptr, OCI_HTYPE_STMT); free(ora_stmt); } log_text(LOG_FATAL, "Failed to prepare statement: '%s'", query); return 1; } /* Bind parameters for prepared statement */ int ora_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len) { ora_conn_t *con = (ora_conn_t *)stmt->connection->ptr; ora_stmt_t *ora_stmt = (ora_stmt_t *)stmt->ptr; OCIBind * bindp; unsigned int i; sword rc; ub2 dtype; sb4 dlen; if (con == NULL) return 1; if (!stmt->emulated) { if (ora_stmt == NULL || ora_stmt->ptr == NULL) return 1; if (ora_stmt->params != NULL) free(ora_stmt->params); ora_stmt->params = (ora_bind_t *)malloc(len * sizeof(ora_bind_t)); if (ora_stmt->params == NULL) return 1; /* Convert sysbench bind structures to Oracle ones */ bindp = NULL; for (i = 0; i < len; i++) { if (get_oracle_bind_type(params+i, &dtype, &dlen, &ora_stmt->params[i].ind)) { free(ora_stmt->params); ora_stmt->params = NULL; return 1; } rc = OCIBindByPos(ora_stmt->ptr, &bindp, con->errhp, i+1, params[i].buffer, dlen, dtype, (dvoid *)&ora_stmt->params[i].ind, NULL, NULL, 0, NULL, OCI_DEFAULT); if (rc != OCI_SUCCESS) { log_text(LOG_FATAL, "OCIBindByPos failed"); free(ora_stmt->params); ora_stmt->params = NULL; return 1; } } return 0; } /* Use emulation */ if (stmt->bound_param != NULL) free(stmt->bound_param); stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t)); if (stmt->bound_param == NULL) return 1; memcpy(stmt->bound_param, params, len * sizeof(db_bind_t)); stmt->bound_param_len = len; return 0; } /* Bind results for prepared statement */ int ora_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, size_t len) { /* NYI */ (void)stmt; (void)params; (void)len; return 1; } /* Execute prepared statement */ db_error_t ora_drv_execute(db_stmt_t *stmt, db_result_t *rs) { db_conn_t *db_con = stmt->connection; ora_stmt_t *ora_stmt = stmt->ptr; ora_conn_t *ora_con; ub4 iters; char *buf = NULL; unsigned int buflen = 0; unsigned int i, j, vcnt; char need_realloc; int n; sword rc; (void)rs; /* unused */ if (db_con == NULL) return DB_ERROR_FATAL; ora_con = db_con->ptr; if (ora_con == NULL) return DB_ERROR_FATAL; if (!stmt->emulated) { if (stmt->ptr == NULL) return DB_ERROR_FATAL; if (ora_stmt->type == STMT_TYPE_BEGIN) { rc = OCITransStart(ora_con->svchp, ora_con->errhp, 3600, OCI_TRANS_NEW); CHECKERR("OCITransStart"); return DB_ERROR_NONE; } else if (ora_stmt->type == STMT_TYPE_COMMIT) { rc = OCITransCommit(ora_con->svchp, ora_con->errhp, OCI_DEFAULT); CHECKERR("OCITransCommit"); return DB_ERROR_NONE; } else if (ora_stmt->type == STMT_TYPE_SELECT) iters = 0; else iters = 1; rc = OCIStmtExecute(ora_con->svchp, ora_stmt->ptr, ora_con->errhp, iters, 0, NULL, NULL, OCI_DEFAULT); CHECKERR("OCIStmtExecute"); return DB_ERROR_NONE; } /* Build the actual query string from parameters list */ need_realloc = 1; vcnt = 0; for (i = 0, j = 0; stmt->query[i] != '\0'; i++) { again: if (j+1 >= buflen || need_realloc) { buflen = (buflen > 0) ? buflen * 2 : 256; buf = realloc(buf, buflen); if (buf == NULL) { return DB_ERROR_FATAL; } need_realloc = 0; } if (stmt->query[i] != '?') { buf[j++] = stmt->query[i]; continue; } n = db_print_value(stmt->bound_param + vcnt, buf + j, buflen - j); if (n < 0) { need_realloc = 1; goto again; } j += n; vcnt++; } buf[j] = '\0'; db_con->error = ora_drv_query(db_con, buf, j, rs); free(buf); return DB_ERROR_NONE; error: log_text(LOG_FATAL, "failed query was: '%s'", stmt->query); return DB_ERROR_FATAL; } /* Execute SQL query */ db_error_t ora_drv_query(db_conn_t *sb_conn, const char *query, size_t len, db_result_t *rs) { ora_conn_t *ora_con = sb_conn->ptr; sword rc = 0; void *tmp = NULL; ub4 iters; ora_stmt_type_t type; OCIStmt *stmt = NULL; (void)rs; /* unused */ type = get_stmt_type(query); if (type == STMT_TYPE_BEGIN) { rc = OCITransStart(ora_con->svchp, ora_con->errhp, 3600, OCI_TRANS_NEW); CHECKERR("OCITransStart"); return DB_ERROR_NONE; } else if (type == STMT_TYPE_COMMIT) { rc = OCITransCommit(ora_con->svchp, ora_con->errhp, OCI_DEFAULT); CHECKERR("OCITransCommit"); return DB_ERROR_NONE; } else if (type == STMT_TYPE_SELECT) iters = 0; else iters = 1; rc = OCIHandleAlloc(ora_env, (dvoid **)&tmp, OCI_HTYPE_STMT, 0, (dvoid **)NULL); CHECKERR("OCIHandleAlloc"); stmt = (OCIStmt *)tmp; rc = OCIStmtPrepare(stmt, ora_con->errhp, (OraText *)query, len, OCI_NTV_SYNTAX, OCI_DEFAULT); CHECKERR("OCIStmtPrepare"); rc = OCIStmtExecute(ora_con->svchp, stmt, ora_con->errhp, iters, 0, NULL, NULL, OCI_DEFAULT); CHECKERR("OCIStmtExecute"); OCIHandleFree(stmt, OCI_HTYPE_STMT); return DB_ERROR_NONE; error: log_text(LOG_FATAL, "failed query was: '%s'", query); if (stmt != NULL) OCIHandleFree(stmt, OCI_HTYPE_STMT); return DB_ERROR_FATAL; } /* Fetch row from result set of a prepared statement */ int ora_drv_fetch(db_result_t *rs) { /* NYI */ (void)rs; return 1; } /* Fetch row from result set of a query */ int ora_drv_fetch_row(db_result_t *rs, db_row_t *row) { /* NYI */ (void)rs; /* unused */ (void)row; /* unused */ return 1; } /* Store results from the last query */ int ora_drv_store_results(db_result_t *rs) { unsigned int i; sword rc; db_stmt_t *db_stmt = rs->statement; db_conn_t *db_conn = rs->connection; ora_stmt_t *ora_stmt; ora_conn_t *ora_con; ora_result_set_t *ora_rs; ora_column_t *column; ora_row_t *row; OCIParam *parm; void *tmp = NULL; unsigned int col_len; ub4 semantics; sb_list_item_t *pos; text *fnamep; if (db_stmt == NULL || db_conn == NULL) return 1; ora_stmt = (ora_stmt_t *)db_stmt->ptr; ora_con = (ora_conn_t *)db_conn->ptr; if (ora_stmt == NULL || ora_con == NULL) return 1; if (rs->ptr != NULL) return 1; ora_rs = (ora_result_set_t *)calloc(1, sizeof(ora_result_set_t)); if (ora_rs == NULL) return 1; rs->ptr = ora_rs; SB_LIST_INIT(&ora_rs->columns); SB_LIST_INIT(&ora_rs->rows); i = 1; rc = OCIParamGet((dvoid *)ora_stmt->ptr, OCI_HTYPE_STMT, ora_con->errhp, (dvoid **)&tmp, i); parm = (OCIParam *)tmp; /* Loop to get description of all columns */ while (rc == OCI_SUCCESS) { column = (ora_column_t *)calloc(1, sizeof(ora_column_t)); if (column == NULL) goto error; SB_LIST_ADD_TAIL(&column->listitem, &ora_rs->columns); /* Get the column type attribute */ rc = OCIAttrGet((dvoid *)parm, OCI_DTYPE_PARAM, (dvoid *)&column->type, NULL, OCI_ATTR_DATA_TYPE, ora_con->errhp); CHECKERR("OCIAttrGet"); /* Get the column name attribute */ rc = OCIAttrGet((dvoid *)parm, OCI_DTYPE_PARAM, &fnamep, (ub4 *)&col_len, OCI_ATTR_NAME, ora_con->errhp); CHECKERR("OCIAttrGet"); column->name = (char *)malloc(col_len + 1); if (column->name == NULL) goto error; strncpy(column->name, fnamep, col_len + 1); /* Get the length semantics */ rc = OCIAttrGet((dvoid *)parm, OCI_DTYPE_PARAM, (dvoid *)&semantics, NULL, OCI_ATTR_CHAR_USED, ora_con->errhp); CHECKERR("OCIAttrGet"); if (semantics) { /* Get the column width in characters */ rc = OCIAttrGet((dvoid *)parm, OCI_DTYPE_PARAM, (dvoid *)&column->len, NULL, OCI_ATTR_CHAR_SIZE, ora_con->errhp); if (column->len == 0) column->len = get_oracle_type_size(column->type); } else { /* Get the column width in bytes */ rc = OCIAttrGet((dvoid *)parm, OCI_DTYPE_PARAM, (dvoid *)&column->len, NULL, OCI_ATTR_DATA_SIZE, ora_con->errhp); if (column->len == 0) column->len = get_oracle_type_size(column->type); } CHECKERR("OCIAttrGet"); OCIDescriptorFree(parm, OCI_DTYPE_PARAM); /* Describe the column */ column->value = malloc(column->len); if (column->value == NULL) goto error; rc = OCIDefineByPos(ora_stmt->ptr, &column->defhp, ora_con->errhp, i, column->value, column->len, column->type, &column->ind, NULL, NULL, OCI_DEFAULT); CHECKERR("OCIDefineByPos"); i++; rc = OCIParamGet(ora_stmt->ptr, OCI_HTYPE_STMT, ora_con->errhp, (dvoid **)&tmp, i); parm = (OCIParam *)tmp; } ora_rs->ncolumns = i-1; /* Now fetch the actual data */ while(1) { rc = OCIStmtFetch2(ora_stmt->ptr, ora_con->errhp, 1, OCI_FETCH_NEXT, 0, OCI_DEFAULT); if (rc == OCI_NO_DATA) break; CHECKERR("OCIStmtFetch"); row = (ora_row_t *)calloc(1, sizeof(ora_row_t)); if (row == NULL) goto error; row->data = (ora_data_t *)calloc(ora_rs->ncolumns, sizeof(ora_data_t)); i = 0; SB_LIST_FOR_EACH(pos, &ora_rs->columns) { column = SB_LIST_ENTRY(pos, ora_column_t, listitem); row->data[i].value = (void *)malloc(column->len); if (row->data[i].value == NULL) goto error; memcpy(row->data[i].value, column->value, column->len); row->data[i].ind = column->ind; i++; } SB_LIST_ADD_TAIL(&row->listitem, &ora_rs->rows); ora_rs->nrows++; } return 0; error: return 1; } /* Free result set */ int ora_drv_free_results(db_result_t *rs) { ora_result_set_t *ora_rs = (ora_result_set_t *)rs->ptr; ora_row_t *row; ora_column_t *column; sb_list_item_t *cur; sb_list_item_t *next; unsigned int i; if (ora_rs == NULL) return 1; SB_LIST_FOR_EACH_SAFE(cur, next, &ora_rs->rows) { row = SB_LIST_ENTRY(cur, ora_row_t, listitem); if (row->data != NULL) { for (i = 0; i < ora_rs->ncolumns; i++) { if (row->data[i].value != NULL) free(row->data[i].value); } free(row->data); } SB_LIST_DELETE(cur); free(row); } SB_LIST_FOR_EACH_SAFE(cur, next, &ora_rs->columns) { column = SB_LIST_ENTRY(cur, ora_column_t, listitem); if (column->name != NULL) free(column->name); if (column->value != NULL) free(column->value); SB_LIST_DELETE(cur); free(column); } free(ora_rs); rs->ptr = NULL; return 0; } /* Close prepared statement */ int ora_drv_close(db_stmt_t *stmt) { ora_stmt_t *ora_stmt = stmt->ptr; if (ora_stmt == NULL) return 1; OCIHandleFree(stmt, OCI_HTYPE_STMT); return 0; } /* Uninitialize driver */ int ora_drv_done(void) { sword rc; if (ora_env == NULL) return 1; rc = OCIHandleFree(ora_env, OCI_HTYPE_ENV); if (rc != OCI_SUCCESS) { log_text(LOG_FATAL, "OCIHandleFree failed"); return 1; } return 0; } /* Get Oracle type, type length and indicator values from sysbench parameter */ sword get_oracle_bind_type(db_bind_t *param, ub2 *type, sb4 *len, sb2 *ind) { unsigned int i; for (i = 0; db_oracle_bind_map[i].db_type != DB_TYPE_NONE; i++) if (db_oracle_bind_map[i].db_type == param->type) { *type = db_oracle_bind_map[i].ora_type; *len = db_oracle_bind_map[i].ora_len; if (param->type == DB_TYPE_CHAR || param->type == DB_TYPE_VARCHAR) *len = strlen(param->buffer); *ind = (param->is_null) ? -1 : 0; return 0; } return 1; } /* Get Oracle type size in bytes */ sb4 get_oracle_type_size(sword type) { unsigned int i; sb4 size = 0; if (type == SQLT_NUM) return 21; for (i = 0; db_oracle_bind_map[i].db_type != DB_TYPE_NONE; i++) if (db_oracle_bind_map[i].ora_type == type && size < db_oracle_bind_map[i].ora_len) size = db_oracle_bind_map[i].ora_len; return size; } ora_stmt_type_t get_stmt_type(const char *query) { if (!strncmp(query, "BEGIN", 5)) return STMT_TYPE_BEGIN; else if (!strncmp(query, "COMMIT", 6)) return STMT_TYPE_COMMIT; else if (!strncmp(query, "SELECT", 6)) return STMT_TYPE_SELECT; return STMT_TYPE_UPDATE; } db_bind_type_t get_db_bind_type(sword type) { unsigned int i; for (i = 0; db_oracle_bind_map[i].db_type != DB_TYPE_NONE; i++) if (db_oracle_bind_map[i].ora_type == type) return db_oracle_bind_map[i].db_type; return DB_TYPE_NONE; } /* Check and display Oracle error */ void checkerr(OCIError *errhp, sword status) { text errbuf[512]; sword errcode; switch (status) { case OCI_SUCCESS: break; case OCI_SUCCESS_WITH_INFO: log_text(LOG_ALERT, "Error - OCI_SUCCESS_WITH_INFO"); break; case OCI_NEED_DATA: log_text(LOG_ALERT, "Error - OCI_NEED_DATA"); break; case OCI_NO_DATA: log_text(LOG_ALERT, "Error - OCI_NO_DATA"); break; case OCI_ERROR: OCIErrorGet((dvoid *) errhp, (ub4) 1, (text *) NULL, (sb4 *) &errcode, errbuf, (ub4) sizeof(errbuf), (ub4) OCI_HTYPE_ERROR); log_text(LOG_ALERT, "Error - %s", errbuf); break; case OCI_INVALID_HANDLE: log_text(LOG_ALERT, "Error - OCI_INVALID_HANDLE"); break; case OCI_STILL_EXECUTING: log_text(LOG_ALERT, "Error - OCI_STILL_EXECUTE"); break; case OCI_CONTINUE: log_text(LOG_ALERT, "Error - OCI_CONTINUE"); break; default: break; } } sysbench-1.0.18/src/drivers/oracle/Makefile.am0000600000175000017500000000163513553247311016772 0ustar jpjp# Copyright (C) 2005 MySQL AB # Copyright (C) 2005-2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA noinst_LIBRARIES = libsboracle.a libsboracle_a_SOURCES = drv_oracle.c libsboracle_a_CPPFLAGS = $(ORA_CFLAGS) $(AM_CPPFLAGS) sysbench-1.0.18/src/drivers/mysql/0000700000175000017500000000000013553247311014627 5ustar jpjpsysbench-1.0.18/src/drivers/mysql/CMakeLists.txt0000600000175000017500000000011213553247311017363 0ustar jpjpINCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) ADD_LIBRARY(sbmysql drv_mysql.c) sysbench-1.0.18/src/drivers/mysql/Makefile.am0000600000175000017500000000163313553247311016670 0ustar jpjp# Copyright (C) 2004 MySQL AB # Copyright (C) 2004-2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA noinst_LIBRARIES = libsbmysql.a libsbmysql_a_SOURCES = drv_mysql.c libsbmysql_a_CPPFLAGS = $(MYSQL_CFLAGS) $(AM_CPPFLAGS) sysbench-1.0.18/src/drivers/mysql/drv_mysql.c0000600000175000017500000006350713553247311017030 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef STDC_HEADERS # include #endif #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 #include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include #include #include #include #include "sb_options.h" #include "db_driver.h" #define DEBUG(format, ...) \ do { \ if (SB_UNLIKELY(args.debug != 0)) \ log_text(LOG_DEBUG, format, __VA_ARGS__); \ } while (0) #define SAFESTR(s) ((s != NULL) ? (s) : "(null)") #if !defined(MARIADB_BASE_VERSION) && !defined(MARIADB_VERSION_ID) && \ MYSQL_VERSION_ID >= 80001 && MYSQL_VERSION_ID != 80002 /* see https://bugs.mysql.com/?id=87337 */ typedef bool my_bool; #endif /* MySQL driver arguments */ static sb_arg_t mysql_drv_args[] = { SB_OPT("mysql-host", "MySQL server host", "localhost", LIST), SB_OPT("mysql-port", "MySQL server port", "3306", LIST), SB_OPT("mysql-socket", "MySQL socket", NULL, LIST), SB_OPT("mysql-user", "MySQL user", "sbtest", STRING), SB_OPT("mysql-password", "MySQL password", "", STRING), SB_OPT("mysql-db", "MySQL database name", "sbtest", STRING), SB_OPT("mysql-ssl", "use SSL connections, if available in the client " "library", "off", BOOL), SB_OPT("mysql-ssl-cipher", "use specific cipher for SSL connections", "", STRING), SB_OPT("mysql-compression", "use compression, if available in the " "client library", "off", BOOL), SB_OPT("mysql-debug", "trace all client library calls", "off", BOOL), SB_OPT("mysql-ignore-errors", "list of errors to ignore, or \"all\"", "1213,1020,1205", LIST), SB_OPT("mysql-dry-run", "Dry run, pretend that all MySQL client API " "calls are successful without executing them", "off", BOOL), SB_OPT_END }; typedef struct { sb_list_t *hosts; sb_list_t *ports; sb_list_t *sockets; char *user; char *password; char *db; unsigned char use_ssl; char *ssl_cipher; unsigned char use_compression; unsigned char debug; sb_list_t *ignored_errors; unsigned int dry_run; } mysql_drv_args_t; typedef struct { MYSQL *mysql; char *host; char *user; char *password; char *db; unsigned int port; char *socket; } db_mysql_conn_t; /* Structure used for DB-to-MySQL bind types map */ typedef struct { db_bind_type_t db_type; int my_type; } db_mysql_bind_map_t; /* DB-to-MySQL bind types map */ db_mysql_bind_map_t db_mysql_bind_map[] = { {DB_TYPE_TINYINT, MYSQL_TYPE_TINY}, {DB_TYPE_SMALLINT, MYSQL_TYPE_SHORT}, {DB_TYPE_INT, MYSQL_TYPE_LONG}, {DB_TYPE_BIGINT, MYSQL_TYPE_LONGLONG}, {DB_TYPE_FLOAT, MYSQL_TYPE_FLOAT}, {DB_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE}, {DB_TYPE_DATETIME, MYSQL_TYPE_DATETIME}, {DB_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP}, {DB_TYPE_CHAR, MYSQL_TYPE_STRING}, {DB_TYPE_VARCHAR, MYSQL_TYPE_VAR_STRING}, {DB_TYPE_NONE, 0} }; /* MySQL driver capabilities */ static drv_caps_t mysql_drv_caps = { 1, 0, 1, 0, 0, 1 }; static mysql_drv_args_t args; /* driver args */ static char use_ps; /* whether server-side prepared statemens should be used */ /* Positions in the list of hosts/ports/sockets. Protected by pos_mutex */ static sb_list_item_t *hosts_pos; static sb_list_item_t *ports_pos; static sb_list_item_t *sockets_pos; static pthread_mutex_t pos_mutex; /* MySQL driver operations */ static int mysql_drv_init(void); static int mysql_drv_thread_init(int); static int mysql_drv_describe(drv_caps_t *); static int mysql_drv_connect(db_conn_t *); static int mysql_drv_reconnect(db_conn_t *); static int mysql_drv_disconnect(db_conn_t *); static int mysql_drv_prepare(db_stmt_t *, const char *, size_t); static int mysql_drv_bind_param(db_stmt_t *, db_bind_t *, size_t); static int mysql_drv_bind_result(db_stmt_t *, db_bind_t *, size_t); static db_error_t mysql_drv_execute(db_stmt_t *, db_result_t *); static int mysql_drv_fetch(db_result_t *); static int mysql_drv_fetch_row(db_result_t *, db_row_t *); static db_error_t mysql_drv_query(db_conn_t *, const char *, size_t, db_result_t *); static int mysql_drv_free_results(db_result_t *); static int mysql_drv_close(db_stmt_t *); static int mysql_drv_thread_done(int); static int mysql_drv_done(void); /* MySQL driver definition */ static db_driver_t mysql_driver = { .sname = "mysql", .lname = "MySQL driver", .args = mysql_drv_args, .ops = { .init = mysql_drv_init, .thread_init = mysql_drv_thread_init, .describe = mysql_drv_describe, .connect = mysql_drv_connect, .disconnect = mysql_drv_disconnect, .reconnect = mysql_drv_reconnect, .prepare = mysql_drv_prepare, .bind_param = mysql_drv_bind_param, .bind_result = mysql_drv_bind_result, .execute = mysql_drv_execute, .fetch = mysql_drv_fetch, .fetch_row = mysql_drv_fetch_row, .free_results = mysql_drv_free_results, .close = mysql_drv_close, .query = mysql_drv_query, .thread_done = mysql_drv_thread_done, .done = mysql_drv_done } }; /* Local functions */ static int get_mysql_bind_type(db_bind_type_t); /* Register MySQL driver */ int register_driver_mysql(sb_list_t *drivers) { SB_LIST_ADD_TAIL(&mysql_driver.listitem, drivers); return 0; } /* MySQL driver initialization */ int mysql_drv_init(void) { pthread_mutex_init(&pos_mutex, NULL); args.hosts = sb_get_value_list("mysql-host"); if (SB_LIST_IS_EMPTY(args.hosts)) { log_text(LOG_FATAL, "No MySQL hosts specified, aborting"); return 1; } hosts_pos = SB_LIST_ITEM_NEXT(args.hosts); args.ports = sb_get_value_list("mysql-port"); if (SB_LIST_IS_EMPTY(args.ports)) { log_text(LOG_FATAL, "No MySQL ports specified, aborting"); return 1; } ports_pos = SB_LIST_ITEM_NEXT(args.ports); args.sockets = sb_get_value_list("mysql-socket"); sockets_pos = args.sockets; args.user = sb_get_value_string("mysql-user"); args.password = sb_get_value_string("mysql-password"); args.db = sb_get_value_string("mysql-db"); args.use_ssl = sb_get_value_flag("mysql-ssl"); args.ssl_cipher = sb_get_value_string("mysql-ssl-cipher"); args.use_compression = sb_get_value_flag("mysql-compression"); args.debug = sb_get_value_flag("mysql-debug"); if (args.debug) sb_globals.verbosity = LOG_DEBUG; args.ignored_errors = sb_get_value_list("mysql-ignore-errors"); args.dry_run = sb_get_value_flag("mysql-dry-run"); use_ps = 0; mysql_drv_caps.prepared_statements = 1; if (db_globals.ps_mode != DB_PS_MODE_DISABLE) use_ps = 1; DEBUG("mysql_library_init(%d, %p, %p)", 0, NULL, NULL); mysql_library_init(0, NULL, NULL); return 0; } /* Thread-local driver initialization */ int mysql_drv_thread_init(int thread_id) { (void) thread_id; /* unused */ const my_bool rc = mysql_thread_init(); DEBUG("mysql_thread_init() = %d", (int) rc); return rc != 0; } /* Thread-local driver deinitialization */ int mysql_drv_thread_done(int thread_id) { (void) thread_id; /* unused */ DEBUG("mysql_thread_end(%s)", ""); mysql_thread_end(); return 0; } /* Describe database capabilities */ int mysql_drv_describe(drv_caps_t *caps) { *caps = mysql_drv_caps; return 0; } static int mysql_drv_real_connect(db_mysql_conn_t *db_mysql_con) { MYSQL *con = db_mysql_con->mysql; const char *ssl_key; const char *ssl_cert; const char *ssl_ca; if (args.use_ssl) { ssl_key= "client-key.pem"; ssl_cert= "client-cert.pem"; ssl_ca= "cacert.pem"; DEBUG("mysql_ssl_set(%p, \"%s\", \"%s\", \"%s\", NULL, \"%s\")", con, ssl_key, ssl_cert, ssl_ca, args.ssl_cipher); mysql_ssl_set(con, ssl_key, ssl_cert, ssl_ca, NULL, args.ssl_cipher); #ifdef HAVE_MYSQL_OPT_SSL_MODE unsigned int opt_ssl_mode = SSL_MODE_REQUIRED; DEBUG("mysql_options(%p, %s, %u)", con, "MYSQL_OPT_SSL_MODE", opt_ssl_mode); mysql_options(con, MYSQL_OPT_SSL_MODE, &opt_ssl_mode); #endif } if (args.use_compression) { DEBUG("mysql_options(%p, %s, %s)",con, "MYSQL_OPT_COMPRESS", "NULL"); mysql_options(con, MYSQL_OPT_COMPRESS, NULL); } DEBUG("mysql_real_connect(%p, \"%s\", \"%s\", \"%s\", \"%s\", %u, \"%s\", %s)", con, SAFESTR(db_mysql_con->host), SAFESTR(db_mysql_con->user), SAFESTR(db_mysql_con->password), SAFESTR(db_mysql_con->db), db_mysql_con->port, SAFESTR(db_mysql_con->socket), (MYSQL_VERSION_ID >= 50000) ? "CLIENT_MULTI_STATEMENTS" : "0" ); return mysql_real_connect(con, db_mysql_con->host, db_mysql_con->user, db_mysql_con->password, db_mysql_con->db, db_mysql_con->port, db_mysql_con->socket, #if MYSQL_VERSION_ID >= 50000 CLIENT_MULTI_STATEMENTS #else 0 #endif ) == NULL; } /* Connect to MySQL database */ int mysql_drv_connect(db_conn_t *sb_conn) { MYSQL *con; db_mysql_conn_t *db_mysql_con; if (args.dry_run) return 0; db_mysql_con = (db_mysql_conn_t *) calloc(1, sizeof(db_mysql_conn_t)); if (db_mysql_con == NULL) return 1; con = (MYSQL *) malloc(sizeof(MYSQL)); if (con == NULL) return 1; db_mysql_con->mysql = con; DEBUG("mysql_init(%p)", con); mysql_init(con); pthread_mutex_lock(&pos_mutex); if (SB_LIST_IS_EMPTY(args.sockets)) { db_mysql_con->socket = NULL; db_mysql_con->host = SB_LIST_ENTRY(hosts_pos, value_t, listitem)->data; db_mysql_con->port = atoi(SB_LIST_ENTRY(ports_pos, value_t, listitem)->data); /* Pick the next port in args.ports. If there are no more ports in the list, move to the next available host and get the first port again. */ ports_pos = SB_LIST_ITEM_NEXT(ports_pos); if (ports_pos == args.ports) { hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos); if (hosts_pos == args.hosts) hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos); ports_pos = SB_LIST_ITEM_NEXT(ports_pos); } } else { db_mysql_con->host = "localhost"; /* The sockets list may be empty. So unlike hosts/ports the loop invariant here is that sockets_pos points to the previous one and should be advanced before using it, not after. */ sockets_pos = SB_LIST_ITEM_NEXT(sockets_pos); if (sockets_pos == args.sockets) sockets_pos = SB_LIST_ITEM_NEXT(sockets_pos); db_mysql_con->socket = SB_LIST_ENTRY(sockets_pos, value_t, listitem)->data; } pthread_mutex_unlock(&pos_mutex); db_mysql_con->user = args.user; db_mysql_con->password = args.password; db_mysql_con->db = args.db; if (mysql_drv_real_connect(db_mysql_con)) { if (!SB_LIST_IS_EMPTY(args.sockets)) log_text(LOG_FATAL, "unable to connect to MySQL server on socket '%s', " "aborting...", db_mysql_con->socket); else log_text(LOG_FATAL, "unable to connect to MySQL server on host '%s', " "port %u, aborting...", db_mysql_con->host, db_mysql_con->port); log_text(LOG_FATAL, "error %d: %s", mysql_errno(con), mysql_error(con)); free(db_mysql_con); free(con); return 1; } if (args.use_ssl) { DEBUG("mysql_get_ssl_cipher(con): \"%s\"", mysql_get_ssl_cipher(con)); } sb_conn->ptr = db_mysql_con; return 0; } /* Disconnect from MySQL database */ int mysql_drv_disconnect(db_conn_t *sb_conn) { db_mysql_conn_t *db_mysql_con = sb_conn->ptr; if (args.dry_run) return 0; if (db_mysql_con != NULL && db_mysql_con->mysql != NULL) { DEBUG("mysql_close(%p)", db_mysql_con->mysql); mysql_close(db_mysql_con->mysql); free(db_mysql_con->mysql); free(db_mysql_con); } return 0; } /* Prepare statement */ int mysql_drv_prepare(db_stmt_t *stmt, const char *query, size_t len) { MYSQL_STMT *mystmt; unsigned int rc; if (args.dry_run) return 0; db_mysql_conn_t *db_mysql_con = (db_mysql_conn_t *) stmt->connection->ptr; MYSQL *con = db_mysql_con->mysql; if (con == NULL) return 1; if (use_ps) { mystmt = mysql_stmt_init(con); DEBUG("mysql_stmt_init(%p) = %p", con, mystmt); if (mystmt == NULL) { log_text(LOG_FATAL, "mysql_stmt_init() failed"); return 1; } stmt->ptr = (void *)mystmt; DEBUG("mysql_stmt_prepare(%p, \"%s\", %u) = %p", mystmt, query, (unsigned int) len, stmt->ptr); if (mysql_stmt_prepare(mystmt, query, len)) { /* Check if this statement in not supported */ rc = mysql_errno(con); DEBUG("mysql_errno(%p) = %u", con, rc); if (rc == ER_UNSUPPORTED_PS) { log_text(LOG_INFO, "Failed to prepare query \"%s\" (%d: %s), using emulation", query, rc, mysql_error(con)); goto emulate; } else { log_text(LOG_FATAL, "mysql_stmt_prepare() failed"); log_text(LOG_FATAL, "MySQL error: %d \"%s\"", rc, mysql_error(con)); DEBUG("mysql_stmt_close(%p)", mystmt); mysql_stmt_close(mystmt); return 1; } } stmt->query = strdup(query); stmt->counter = (mysql_stmt_field_count(mystmt) > 0) ? SB_CNT_READ : SB_CNT_WRITE; return 0; } emulate: /* Use client-side PS */ stmt->emulated = 1; stmt->query = strdup(query); return 0; } static void convert_to_mysql_bind(MYSQL_BIND *mybind, db_bind_t *bind) { mybind->buffer_type = get_mysql_bind_type(bind->type); mybind->buffer = bind->buffer; mybind->buffer_length = bind->max_len; mybind->length = bind->data_len; /* Reuse the buffer passed by the caller to avoid conversions. This is only valid if sizeof(char) == sizeof(mybind->is_null[0]). Depending on the version of the MySQL client library, the type of MYSQL_BIND::is_null[0] can be either my_bool or bool, but sizeof(bool) is not defined by the C standard. We assume it to be 1 on most platforms to simplify code and Lua API. */ #if SIZEOF_BOOL > 1 # error This code assumes sizeof(bool) == 1! #endif mybind->is_null = (my_bool *) bind->is_null; } /* Bind parameters for prepared statement */ int mysql_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len) { MYSQL_BIND *bind; unsigned int i; my_bool rc; unsigned long param_count; if (args.dry_run) return 0; db_mysql_conn_t *db_mysql_con = (db_mysql_conn_t *) stmt->connection->ptr; MYSQL *con = db_mysql_con->mysql; if (con == NULL) return 1; if (!stmt->emulated) { if (stmt->ptr == NULL) return 1; /* Validate parameters count */ param_count = mysql_stmt_param_count(stmt->ptr); DEBUG("mysql_stmt_param_count(%p) = %lu", stmt->ptr, param_count); if (param_count != len) { log_text(LOG_FATAL, "Wrong number of parameters to mysql_stmt_bind_param"); return 1; } /* Convert sysbench bind structures to MySQL ones */ bind = (MYSQL_BIND *)calloc(len, sizeof(MYSQL_BIND)); if (bind == NULL) return 1; for (i = 0; i < len; i++) convert_to_mysql_bind(&bind[i], ¶ms[i]); rc = mysql_stmt_bind_param(stmt->ptr, bind); DEBUG("mysql_stmt_bind_param(%p, %p) = %d", stmt->ptr, bind, rc); if (rc) { log_text(LOG_FATAL, "mysql_stmt_bind_param() failed"); log_text(LOG_FATAL, "MySQL error: %d \"%s\"", mysql_errno(con), mysql_error(con)); free(bind); return 1; } free(bind); return 0; } /* Use emulation */ if (stmt->bound_param != NULL) free(stmt->bound_param); stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t)); if (stmt->bound_param == NULL) return 1; memcpy(stmt->bound_param, params, len * sizeof(db_bind_t)); stmt->bound_param_len = len; return 0; } /* Bind results for prepared statement */ int mysql_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, size_t len) { MYSQL_BIND *bind; unsigned int i; my_bool rc; if (args.dry_run) return 0; db_mysql_conn_t *db_mysql_con =(db_mysql_conn_t *) stmt->connection->ptr; MYSQL *con = db_mysql_con->mysql; if (con == NULL || stmt->ptr == NULL) return 1; /* Convert sysbench bind structures to MySQL ones */ bind = (MYSQL_BIND *)calloc(len, sizeof(MYSQL_BIND)); if (bind == NULL) return 1; for (i = 0; i < len; i++) convert_to_mysql_bind(&bind[i], ¶ms[i]); rc = mysql_stmt_bind_result(stmt->ptr, bind); DEBUG("mysql_stmt_bind_result(%p, %p) = %d", stmt->ptr, bind, rc); if (rc) { free(bind); return 1; } free(bind); return 0; } /* Reset connection to the server by reconnecting with the same parameters. */ static int mysql_drv_reconnect(db_conn_t *sb_con) { db_mysql_conn_t *db_mysql_con = (db_mysql_conn_t *) sb_con->ptr; MYSQL *con = db_mysql_con->mysql; log_text(LOG_DEBUG, "Reconnecting"); DEBUG("mysql_close(%p)", con); mysql_close(con); while (mysql_drv_real_connect(db_mysql_con)) { if (sb_globals.error) return DB_ERROR_FATAL; usleep(1000); } log_text(LOG_DEBUG, "Reconnected"); return DB_ERROR_IGNORABLE; } /* Check if the error in a given connection should be fatal or ignored according to the list of errors in --mysql-ignore-errors. */ static db_error_t check_error(db_conn_t *sb_con, const char *func, const char *query, sb_counter_type_t *counter) { sb_list_item_t *pos; unsigned int tmp; db_mysql_conn_t *db_mysql_con = (db_mysql_conn_t *) sb_con->ptr; MYSQL *con = db_mysql_con->mysql; const unsigned int error = mysql_errno(con); DEBUG("mysql_errno(%p) = %u", con, sb_con->sql_errno); sb_con->sql_errno = (int) error; sb_con->sql_state = mysql_sqlstate(con); DEBUG("mysql_state(%p) = %s", con, sb_con->sql_state); sb_con->sql_errmsg = mysql_error(con); DEBUG("mysql_error(%p) = %s", con, sb_con->sql_errmsg); /* Check if the error code is specified in --mysql-ignore-errors, and return DB_ERROR_IGNORABLE if so, or DB_ERROR_FATAL otherwise */ SB_LIST_FOR_EACH(pos, args.ignored_errors) { const char *val = SB_LIST_ENTRY(pos, value_t, listitem)->data; tmp = (unsigned int) atoi(val); if (error == tmp || !strcmp(val, "all")) { log_text(LOG_DEBUG, "Ignoring error %u %s, ", error, sb_con->sql_errmsg); /* Check if we should reconnect */ switch (error) { case CR_SERVER_LOST: case CR_SERVER_GONE_ERROR: case CR_TCP_CONNECTION: case CR_SERVER_LOST_EXTENDED: *counter = SB_CNT_RECONNECT; return mysql_drv_reconnect(sb_con); default: break; } *counter = SB_CNT_ERROR; return DB_ERROR_IGNORABLE; } } if (query) log_text(LOG_FATAL, "%s returned error %u (%s) for query '%s'", func, error, sb_con->sql_errmsg, query); else log_text(LOG_FATAL, "%s returned error %u (%s)", func, error, sb_con->sql_errmsg); *counter = SB_CNT_ERROR; return DB_ERROR_FATAL; } /* Execute prepared statement */ db_error_t mysql_drv_execute(db_stmt_t *stmt, db_result_t *rs) { db_conn_t *con = stmt->connection; char *buf = NULL; unsigned int buflen = 0; unsigned int i, j, vcnt; char need_realloc; int n; if (args.dry_run) return DB_ERROR_NONE; con->sql_errno = 0; con->sql_state = NULL; con->sql_errmsg = NULL; if (!stmt->emulated) { if (stmt->ptr == NULL) { log_text(LOG_DEBUG, "ERROR: exiting mysql_drv_execute(), uninitialized statement"); return DB_ERROR_FATAL; } int err = mysql_stmt_execute(stmt->ptr); DEBUG("mysql_stmt_execute(%p) = %d", stmt->ptr, err); if (err) return check_error(con, "mysql_stmt_execute()", stmt->query, &rs->counter); if (stmt->counter != SB_CNT_READ) { rs->nrows = (uint32_t) mysql_stmt_affected_rows(stmt->ptr); DEBUG("mysql_stmt_affected_rows(%p) = %u", stmt->ptr, (unsigned) rs->nrows); rs->counter = (rs->nrows > 0) ? SB_CNT_WRITE : SB_CNT_OTHER; return DB_ERROR_NONE; } err = mysql_stmt_store_result(stmt->ptr); DEBUG("mysql_stmt_store_result(%p) = %d", stmt->ptr, err); if (err) { return check_error(con, "mysql_stmt_store_result()", NULL, &rs->counter); } rs->counter = stmt->counter; rs->nrows = (uint32_t) mysql_stmt_num_rows(stmt->ptr); DEBUG("mysql_stmt_num_rows(%p) = %u", rs->statement->ptr, (unsigned) (rs->nrows)); return DB_ERROR_NONE; } /* Use emulation */ /* Build the actual query string from parameters list */ need_realloc = 1; vcnt = 0; for (i = 0, j = 0; stmt->query[i] != '\0'; i++) { again: if (j+1 >= buflen || need_realloc) { buflen = (buflen > 0) ? buflen * 2 : 256; buf = realloc(buf, buflen); if (buf == NULL) { log_text(LOG_DEBUG, "ERROR: exiting mysql_drv_execute(), memory allocation failure"); return DB_ERROR_FATAL; } need_realloc = 0; } if (stmt->query[i] != '?') { buf[j++] = stmt->query[i]; continue; } n = db_print_value(stmt->bound_param + vcnt, buf + j, (int)(buflen - j)); if (n < 0) { need_realloc = 1; goto again; } j += (unsigned int)n; vcnt++; } buf[j] = '\0'; db_error_t rc = mysql_drv_query(con, buf, j, rs); free(buf); return rc; } /* Execute SQL query */ db_error_t mysql_drv_query(db_conn_t *sb_conn, const char *query, size_t len, db_result_t *rs) { db_mysql_conn_t *db_mysql_con; MYSQL *con; if (args.dry_run) return DB_ERROR_NONE; sb_conn->sql_errno = 0; sb_conn->sql_state = NULL; sb_conn->sql_errmsg = NULL; db_mysql_con = (db_mysql_conn_t *)sb_conn->ptr; con = db_mysql_con->mysql; int err = mysql_real_query(con, query, len); DEBUG("mysql_real_query(%p, \"%s\", %zd) = %d", con, query, len, err); if (SB_UNLIKELY(err != 0)) return check_error(sb_conn, "mysql_drv_query()", query, &rs->counter); /* Store results and get query type */ MYSQL_RES *res = mysql_store_result(con); DEBUG("mysql_store_result(%p) = %p", con, res); if (res == NULL) { if (mysql_errno(con) == 0 && mysql_field_count(con) == 0) { /* Not a select. Check if it was a DML */ uint32_t nrows = (uint32_t) mysql_affected_rows(con); if (nrows > 0) { rs->counter = SB_CNT_WRITE; rs->nrows = nrows; } else rs->counter = SB_CNT_OTHER; return DB_ERROR_NONE; } return check_error(sb_conn, "mysql_store_result()", NULL, &rs->counter); } rs->counter = SB_CNT_READ; rs->ptr = (void *)res; rs->nrows = mysql_num_rows(res); DEBUG("mysql_num_rows(%p) = %u", res, (unsigned int) rs->nrows); rs->nfields = mysql_num_fields(res); DEBUG("mysql_num_fields(%p) = %u", res, (unsigned int) rs->nfields); return DB_ERROR_NONE; } /* Fetch row from result set of a prepared statement */ int mysql_drv_fetch(db_result_t *rs) { /* NYI */ (void)rs; /* unused */ if (args.dry_run) return DB_ERROR_NONE; return 1; } /* Fetch row from result set of a query */ int mysql_drv_fetch_row(db_result_t *rs, db_row_t *row) { MYSQL_ROW my_row; if (args.dry_run) return DB_ERROR_NONE; my_row = mysql_fetch_row(rs->ptr); DEBUG("mysql_fetch_row(%p) = %p", rs->ptr, my_row); unsigned long *lengths = mysql_fetch_lengths(rs->ptr); DEBUG("mysql_fetch_lengths(%p) = %p", rs->ptr, lengths); if (lengths == NULL) return DB_ERROR_IGNORABLE; for (size_t i = 0; i < rs->nfields; i++) { row->values[i].len = lengths[i]; row->values[i].ptr = my_row[i]; } return DB_ERROR_NONE; } /* Free result set */ int mysql_drv_free_results(db_result_t *rs) { if (args.dry_run) return 0; /* Is this a result set of a prepared statement? */ if (rs->statement != NULL && rs->statement->emulated == 0) { DEBUG("mysql_stmt_free_result(%p)", rs->statement->ptr); mysql_stmt_free_result(rs->statement->ptr); rs->ptr = NULL; } if (rs->ptr != NULL) { DEBUG("mysql_free_result(%p)", rs->ptr); mysql_free_result((MYSQL_RES *)rs->ptr); rs->ptr = NULL; } return 0; } /* Close prepared statement */ int mysql_drv_close(db_stmt_t *stmt) { if (args.dry_run) return 0; if (stmt->query) { free(stmt->query); stmt->query = NULL; } if (stmt->ptr == NULL) return 1; int rc = mysql_stmt_close(stmt->ptr); DEBUG("mysql_stmt_close(%p) = %d", stmt->ptr, rc); stmt->ptr = NULL; return rc; } /* Uninitialize driver */ int mysql_drv_done(void) { if (args.dry_run) return 0; mysql_library_end(); return 0; } /* Map SQL data type to bind_type value in MYSQL_BIND */ int get_mysql_bind_type(db_bind_type_t type) { unsigned int i; for (i = 0; db_mysql_bind_map[i].db_type != DB_TYPE_NONE; i++) if (db_mysql_bind_map[i].db_type == type) return db_mysql_bind_map[i].my_type; return -1; } sysbench-1.0.18/src/drivers/Makefile.am0000600000175000017500000000210513553247311015516 0ustar jpjp# Copyright (C) 2004 MySQL AB # Copyright (C) 2004-2014 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA if USE_MYSQL MYSQL_DIR = mysql endif if USE_DRIZZLE DRIZZLE_DIR = drizzle endif if USE_ATTACHSQL ATTACHSQL_DIR = attachsql endif if USE_ORACLE ORACLE_DIR = oracle endif if USE_PGSQL PGSQL_DIR = pgsql endif SUBDIRS = $(MYSQL_DIR) $(ORACLE_DIR) $(PGSQL_DIR) $(DRIZZLE_DIR) $(ATTACHSQL_DIR) sysbench-1.0.18/src/sb_timer.c0000600000175000017500000000704413553247311013763 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef STDC_HEADERS # include #endif #ifdef HAVE_STRING_H # include #endif #include "sb_logger.h" #include "sb_timer.h" #include "sb_util.h" /* Some functions for simple time operations */ /* initialize timer */ void sb_timer_init(sb_timer_t *t) { SB_COMPILE_TIME_ASSERT(sizeof(sb_timer_t) % CK_MD_CACHELINE == 0); memset(&t->time_start, 0, sizeof(struct timespec)); memset(&t->time_end, 0, sizeof(struct timespec)); ck_spinlock_init(&t->lock); sb_timer_reset(t); } /* Reset timer counters, but leave the current state intact */ void sb_timer_reset(sb_timer_t *t) { t->min_time = UINT64_MAX; t->max_time = 0; t->sum_time = 0; t->events = 0; t->queue_time = 0; } /* Clone a timer */ void sb_timer_copy(sb_timer_t *to, sb_timer_t *from) { memcpy(to, from, sizeof(sb_timer_t)); ck_spinlock_init(&to->lock); } /* check whether the timer is running */ bool sb_timer_running(sb_timer_t *t) { return TIMESPEC_DIFF(t->time_start, t->time_end) > 0; } /* get time elapsed since the previous call to sb_timer_current() for the specified timer without stopping it. The first call returns time elapsed since the timer was started. */ uint64_t sb_timer_current(sb_timer_t *t) { struct timespec tmp; uint64_t res; SB_GETTIME(&tmp); res = TIMESPEC_DIFF(tmp, t->time_start); t->time_start = tmp; return res; } /* Atomically reset a given timer after copying its state into the timer pointed to by 'old'. */ void sb_timer_checkpoint(sb_timer_t *t, sb_timer_t *old) { ck_spinlock_lock(&t->lock); memcpy(old, t, sizeof(*old)); ck_spinlock_init(&old->lock); sb_timer_reset(t); ck_spinlock_unlock(&t->lock); } /* get average time per event */ uint64_t sb_timer_avg(sb_timer_t *t) { if(t->events == 0) return 0; /* return zero if there were no events */ return (t->sum_time / t->events); } /* get total time for all events */ uint64_t sb_timer_sum(sb_timer_t *t) { return t->sum_time; } /* get minimum time */ uint64_t sb_timer_min(sb_timer_t *t) { if (t->events == 0) return 0; return t->min_time; } /* get maximum time */ uint64_t sb_timer_max(sb_timer_t *t) { return t->max_time; } /* sum data from several timers. used in summing data from multiple threads */ sb_timer_t sb_timer_merge(sb_timer_t *t1, sb_timer_t *t2) { sb_timer_t t; /* Initialize to avoid warnings */ memset(&t, 0, sizeof(sb_timer_t)); t.sum_time = t1->sum_time+t2->sum_time; t.events = t1->events+t2->events; if (t1->max_time > t2->max_time) t.max_time = t1->max_time; else t.max_time = t2->max_time; if (t1->min_timemin_time) t.min_time = t1->min_time; else t.min_time = t2->min_time; return t; } sysbench-1.0.18/src/sysbench.c0000600000175000017500000012070613553247311013776 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2018 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef STDC_HEADERS # include # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_UNISTD_H # include # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_ERRNO_H # include #endif #ifdef HAVE_FCNTL_H # include #endif #ifdef HAVE_PTHREAD_H # include #endif #ifdef HAVE_THREAD_H # include #endif #ifdef HAVE_MATH_H # include #endif #ifdef HAVE_SCHED_H # include #endif #ifdef HAVE_SIGNAL_H # include #endif #ifdef HAVE_LIMITS_H # include #endif #include #include "sysbench.h" #include "sb_options.h" #include "sb_lua.h" #include "db_driver.h" #include "sb_rand.h" #include "sb_thread.h" #include "sb_barrier.h" #include "ck_cc.h" #include "ck_ring.h" #define VERSION_STRING PACKAGE" "PACKAGE_VERSION SB_GIT_SHA /* Maximum queue length for the tx-rate mode. Must be a power of 2 */ #define MAX_QUEUE_LEN 131072 /* Wait at most this number of seconds for worker threads to initialize */ #define THREAD_INIT_TIMEOUT 30 /* Extra thread ID assigned to background threads. This may be used as an index into per-thread arrays (see comment in sb_alloc_per_thread_array(). */ #define SB_BACKGROUND_THREAD_ID sb_globals.threads /* General options */ sb_arg_t general_args[] = { SB_OPT("threads", "number of threads to use", "1", INT), SB_OPT("events", "limit for total number of events", "0", INT), SB_OPT("time", "limit for total execution time in seconds", "10", INT), SB_OPT("forced-shutdown", "number of seconds to wait after the --time limit before forcing " "shutdown, or 'off' to disable", "off", STRING), SB_OPT("thread-stack-size", "size of stack per thread", "64K", SIZE), SB_OPT("rate", "average transactions rate. 0 for unlimited rate", "0", INT), SB_OPT("report-interval", "periodically report intermediate statistics with " "a specified interval in seconds. 0 disables intermediate reports", "0", INT), SB_OPT("report-checkpoints", "dump full statistics and reset all counters at " "specified points in time. The argument is a list of comma-separated " "values representing the amount of time in seconds elapsed from start " "of test when report checkpoint(s) must be performed. Report " "checkpoints are off by default.", "", LIST), SB_OPT("debug", "print more debugging info", "off", BOOL), SB_OPT("validate", "perform validation checks where possible", "off", BOOL), SB_OPT("help", "print help and exit", "off", BOOL), SB_OPT("version", "print version and exit", "off", BOOL), SB_OPT("config-file", "File containing command line options", NULL, FILE), SB_OPT("tx-rate", "deprecated alias for --rate", "0", INT), SB_OPT("max-requests", "deprecated alias for --events", "0", INT), SB_OPT("max-time", "deprecated alias for --time", "0", INT), SB_OPT("num-threads", "deprecated alias for --threads", "1", INT), SB_OPT_END }; /* List of available tests */ sb_list_t tests; /* Global variables */ sb_globals_t sb_globals; sb_test_t *current_test; /* Barrier to ensure we start the benchmark run when all workers are ready */ static sb_barrier_t thread_start_barrier; /* structures to handle queue of events, needed for tx_rate mode */ static pthread_mutex_t queue_mutex; static pthread_cond_t queue_cond; static uint64_t queue_array[MAX_QUEUE_LEN] CK_CC_CACHELINE; static ck_ring_buffer_t queue_ring_buffer[MAX_QUEUE_LEN] CK_CC_CACHELINE; static ck_ring_t queue_ring CK_CC_CACHELINE; static int report_thread_created CK_CC_CACHELINE; static int checkpoints_thread_created; static int eventgen_thread_created; /* per-thread timers for response time stats */ static sb_timer_t *timers; /* Temporary copy of timers for checkpoint reports */ static sb_timer_t *timers_copy; /* Global execution timer */ sb_timer_t sb_exec_timer CK_CC_CACHELINE; /* timers for intermediate/checkpoint reports */ sb_timer_t sb_intermediate_timer CK_CC_CACHELINE; sb_timer_t sb_checkpoint_timer CK_CC_CACHELINE; TLS int sb_tls_thread_id; static void print_header(void); static void print_help(void); static void print_run_mode(sb_test_t *); #ifdef HAVE_ALARM static void sigalrm_thread_init_timeout_handler(int sig) { if (sig != SIGALRM) return; log_text(LOG_FATAL, "Worker threads failed to initialize within %u seconds!", THREAD_INIT_TIMEOUT); exit(2); } /* Default intermediate reports handler */ void sb_report_intermediate(sb_stat_t *stat) { log_timestamp(LOG_NOTICE, stat->time_total, "thds: %" PRIu32 " eps: %4.2f lat (ms,%u%%): %4.2f", stat->threads_running, stat->events / stat->time_interval, sb_globals.percentile, SEC2MS(stat->latency_pct)); if (sb_globals.tx_rate > 0) log_timestamp(LOG_NOTICE, stat->time_total, "queue length: %" PRIu64 " concurrency: %" PRIu64, stat->queue_length, stat->concurrency); } static void report_get_common_stat(sb_stat_t *stat, sb_counters_t cnt) { memset(stat, 0, sizeof(sb_stat_t)); stat->threads_running = sb_globals.threads_running; stat->events = cnt[SB_CNT_EVENT]; stat->reads = cnt[SB_CNT_READ]; stat->writes = cnt[SB_CNT_WRITE]; stat->other = cnt[SB_CNT_OTHER]; stat->errors = cnt[SB_CNT_ERROR]; stat->reconnects = cnt[SB_CNT_RECONNECT]; stat->time_total = NS2SEC(sb_timer_value(&sb_exec_timer)); } static void report_intermediate(void) { sb_stat_t stat; sb_counters_t cnt; /* sb_globals.report_interval may be set to 0 by the master thread to silence intermediate reports at the end of the test */ if (ck_pr_load_uint(&sb_globals.report_interval) == 0) return; sb_counters_agg_intermediate(cnt); report_get_common_stat(&stat, cnt); stat.latency_pct = MS2SEC(sb_histogram_get_pct_intermediate(&sb_latency_histogram, sb_globals.percentile)); stat.time_interval = NS2SEC(sb_timer_current(&sb_intermediate_timer)); if (sb_globals.tx_rate > 0) { stat.queue_length = ck_ring_size(&queue_ring); stat.concurrency = ck_pr_load_int(&sb_globals.concurrency); } if (current_test && current_test->ops.report_intermediate) current_test->ops.report_intermediate(&stat); else sb_report_intermediate(&stat); } /* Default cumulative reports handler */ void sb_report_cumulative(sb_stat_t *stat) { const unsigned int nthreads = sb_globals.threads; if (sb_globals.forced_shutdown_in_progress) { /* In case we print statistics on forced shutdown, there may be (potentially long running or hung) transactions which are still in progress. We still want to reflect them in statistics, so stop running timers to consider long transactions as done at the forced shutdown time, and print a counter of still running transactions. */ unsigned unfinished = 0; for (unsigned i = 0; i < nthreads; i++) { if (sb_timer_running(&timers_copy[i])) { unfinished++; sb_timer_stop(&timers_copy[i]); }; } if (unfinished > 0) { log_text(LOG_NOTICE, ""); log_text(LOG_NOTICE, "Number of unfinished transactions on " "forced shutdown: %u", unfinished); } } log_text(LOG_NOTICE, ""); log_text(LOG_NOTICE, "General statistics:"); log_text(LOG_NOTICE, " total time: %.4fs", stat->time_total); log_text(LOG_NOTICE, " total number of events: %" PRIu64, stat->events); log_text(LOG_NOTICE, ""); log_text(LOG_NOTICE, "Latency (ms):"); log_text(LOG_NOTICE, " min: %39.2f", SEC2MS(stat->latency_min)); log_text(LOG_NOTICE, " avg: %39.2f", SEC2MS(stat->latency_avg)); log_text(LOG_NOTICE, " max: %39.2f", SEC2MS(stat->latency_max)); if (sb_globals.percentile > 0) log_text(LOG_NOTICE, " %3dth percentile: %27.2f", sb_globals.percentile, SEC2MS(stat->latency_pct)); else log_text(LOG_NOTICE, " percentile stats: disabled"); log_text(LOG_NOTICE, " sum: %39.2f", SEC2MS(stat->latency_sum)); log_text(LOG_NOTICE, ""); /* Aggregate temporary timers copy */ sb_timer_t t; sb_timer_init(&t); for(unsigned i = 0; i < nthreads; i++) t = sb_timer_merge(&t, &timers_copy[i]); /* Calculate and print events distribution by threads */ const double events_avg = (double) t.events / nthreads; const double time_avg = stat->latency_sum / nthreads; double events_stddev = 0; double time_stddev = 0; for(unsigned i = 0; i < nthreads; i++) { double diff = fabs(events_avg - timers_copy[i].events); events_stddev += diff * diff; diff = fabs(time_avg - NS2SEC(sb_timer_sum(&timers_copy[i]))); time_stddev += diff * diff; } events_stddev = sqrt(events_stddev / nthreads); time_stddev = sqrt(time_stddev / nthreads); log_text(LOG_NOTICE, "Threads fairness:"); log_text(LOG_NOTICE, " events (avg/stddev): %.4f/%3.2f", events_avg, events_stddev); log_text(LOG_NOTICE, " execution time (avg/stddev): %.4f/%3.2f", time_avg, time_stddev); log_text(LOG_NOTICE, ""); if (sb_globals.debug) { log_text(LOG_DEBUG, "Verbose per-thread statistics:\n"); for(unsigned i = 0; i < nthreads; i++) { log_text(LOG_DEBUG, " thread #%3d: min: %.4fs avg: %.4fs max: %.4fs " "events: %" PRIu64, i, NS2SEC(sb_timer_min(&timers_copy[i])), NS2SEC(sb_timer_avg(&timers_copy[i])), NS2SEC(sb_timer_max(&timers_copy[i])), timers_copy[i].events); log_text(LOG_DEBUG, " " "total time taken by event execution: %.4fs", NS2SEC(sb_timer_sum(&timers_copy[i]))); } log_text(LOG_NOTICE, ""); } } static void report_cumulative(void) { sb_stat_t stat; unsigned i; sb_counters_t cnt; sb_counters_agg_cumulative(cnt); report_get_common_stat(&stat, cnt); stat.latency_pct = MS2SEC(sb_histogram_get_pct_checkpoint(&sb_latency_histogram, sb_globals.percentile)); sb_timer_t t; sb_timer_init(&t); const unsigned nthreads = sb_globals.threads; /* Atomically reset each timer after copying into its timers_copy slot */ for (i = 0; i < nthreads; i++) sb_timer_checkpoint(&timers[i], &timers_copy[i]); /* Aggregate temporary timers copy */ for(i = 0; i < nthreads; i++) t = sb_timer_merge(&t, &timers_copy[i]); /* Calculate aggregate latency values */ stat.latency_min = NS2SEC(sb_timer_min(&t)); stat.latency_max = NS2SEC(sb_timer_max(&t)); stat.latency_avg = NS2SEC(sb_timer_avg(&t)); stat.latency_sum = NS2SEC(sb_timer_sum(&t)); stat.time_interval = NS2SEC(sb_timer_current(&sb_checkpoint_timer)); if (current_test && current_test->ops.report_cumulative) current_test->ops.report_cumulative(&stat); else sb_report_cumulative(&stat); } static void sigalrm_forced_shutdown_handler(int sig) { if (sig != SIGALRM) return; sb_globals.forced_shutdown_in_progress = 1; sb_timer_stop(&sb_exec_timer); sb_timer_stop(&sb_intermediate_timer); sb_timer_stop(&sb_checkpoint_timer); log_text(LOG_FATAL, "The --max-time limit has expired, forcing shutdown..."); report_cumulative(); log_done(); exit(2); } #endif static int register_tests(void) { SB_LIST_INIT(&tests); /* Register tests */ return register_test_fileio(&tests) + register_test_cpu(&tests) + register_test_memory(&tests) + register_test_threads(&tests) + register_test_mutex(&tests) + db_register() + sb_rand_register() ; } /* Print program header */ void print_header(void) { log_text(LOG_NOTICE, "%s (using %s %s)\n", VERSION_STRING, SB_WITH_LUAJIT, LUAJIT_VERSION); } /* Print program usage */ void print_help(void) { sb_list_item_t *pos; sb_test_t *test; printf("Usage:\n"); printf(" sysbench [options]... [testname] [command]\n\n"); printf("Commands implemented by most tests: prepare run cleanup help\n\n"); printf("General options:\n"); sb_print_options(general_args); sb_rand_print_help(); log_print_help(); db_print_help(); printf("Compiled-in tests:\n"); SB_LIST_FOR_EACH(pos, &tests) { test = SB_LIST_ENTRY(pos, sb_test_t, listitem); printf(" %s - %s\n", test->sname, test->lname); } printf("\n"); printf("See 'sysbench help' for a list of options for " "each test.\n\n"); } /* Set an option value if a default value has been previously set with sb_register_arg_set(), i.e. if it's a 'known' option, or ignore_unknown is 'true'. In which case return 0, otherwise return 1. */ static int parse_option(char *name, bool ignore_unknown) { const char *value; char *tmp; option_t *opt; char ctmp = 0; int rc; tmp = strchr(name, '='); if (tmp != NULL) { ctmp = *tmp; *tmp = '\0'; value = tmp + 1; } else { value = NULL; } opt = sb_find_option(name); if (opt != NULL || ignore_unknown) rc = set_option(name, value, opt != NULL ? opt->type : SB_ARG_TYPE_STRING) == NULL; else rc = 1; if (tmp != NULL) *tmp = ctmp; return rc; } /* Parse general command line arguments. Test-specific argument are parsed by parse_test_arguments() at a later stage when a builtin test or a Lua script is known. */ static int parse_general_arguments(int argc, char *argv[]) { const char * testname; const char * cmdname; /* Set default values for general options */ if (sb_register_arg_set(general_args)) return 1; /* Parse command line arguments */ testname = NULL; cmdname = NULL; for (int i = 1; i < argc; i++) { if (strncmp(argv[i], "--", 2)) { if (testname == NULL) { testname = argv[i]; continue; } if (cmdname == NULL) { cmdname = argv[i]; continue; } fprintf(stderr, "Unrecognized command line argument: %s\n", argv[i]); return 1; } else if (!strncmp(argv[i] + 2, "test=", 5)) { /* Support the deprecated --test for compatibility reasons */ fprintf(stderr, "WARNING: the --test option is deprecated. You can pass a " "script name or path on the command line without any options.\n"); parse_option(argv[i] + 2, true); testname = sb_get_value_string("test"); } else if (!parse_option(argv[i]+2, false)) { /* An option from general_args. Exclude it from future processing */ argv[i] = NULL; } } sb_globals.testname = testname; sb_globals.cmdname = cmdname; return 0; } /* Parse test-specific arguments */ static int parse_test_arguments(sb_test_t *test, int argc, char *argv[]) { /* Set default values */ if (test->args != NULL && sb_register_arg_set(test->args)) return 1; for (int i = 1; i < argc; i++) { /* Skip already parsed and non-option arguments */ if (argv[i] == NULL || strncmp(argv[i], "--", 2)) continue; /* At this stage an unrecognized option must throw a error, unless the test defines no options (for compatibility with legacy Lua scripts). In the latter case we just export all unrecognized options as strings. */ if (parse_option(argv[i]+2, test->args == NULL)) { fprintf(stderr, "invalid option: %s\n", argv[i]); return 1; } argv[i] = NULL; } return 0; } void print_run_mode(sb_test_t *test) { log_text(LOG_NOTICE, "Running the test with following options:"); log_text(LOG_NOTICE, "Number of threads: %d", sb_globals.threads); if (sb_globals.tx_rate > 0) { log_text(LOG_NOTICE, "Target transaction rate: %d/sec", sb_globals.tx_rate); } if (sb_globals.report_interval) { log_text(LOG_NOTICE, "Report intermediate results every %d second(s)", sb_globals.report_interval); } if (sb_globals.n_checkpoints > 0) { char list_str[MAX_CHECKPOINTS * 12]; char *tmp = list_str; unsigned int i; int n, size = sizeof(list_str); for (i = 0; i < sb_globals.n_checkpoints - 1; i++) { n = snprintf(tmp, size, "%u, ", sb_globals.checkpoints[i]); if (n >= size) break; tmp += n; size -= n; } if (i == sb_globals.n_checkpoints - 1) snprintf(tmp, size, "%u", sb_globals.checkpoints[i]); log_text(LOG_NOTICE, "Report checkpoint(s) at %s seconds", list_str); } if (sb_globals.debug) log_text(LOG_NOTICE, "Debug mode enabled.\n"); if (sb_globals.validate) log_text(LOG_NOTICE, "Validation checks: on.\n"); if (sb_rand_seed) { log_text(LOG_NOTICE, "Initializing random number generator from seed (%d).\n", sb_rand_seed); srandom(sb_rand_seed); } else { log_text(LOG_NOTICE, "Initializing random number generator from current time\n"); srandom(time(NULL)); } if (sb_globals.force_shutdown) log_text(LOG_NOTICE, "Forcing shutdown in %u seconds", (unsigned) NS2SEC(sb_globals.max_time_ns) + sb_globals.timeout); log_text(LOG_NOTICE, ""); if (test->ops.print_mode != NULL) test->ops.print_mode(); } bool sb_more_events(int thread_id) { (void) thread_id; /* unused */ if (sb_globals.error) return false; /* Check if we have a time limit */ if (sb_globals.max_time_ns > 0 && SB_UNLIKELY(sb_timer_value(&sb_exec_timer) >= sb_globals.max_time_ns)) { log_text(LOG_INFO, "Time limit exceeded, exiting..."); return false; } /* Check if we have a limit on the number of events */ if (sb_globals.max_events > 0 && SB_UNLIKELY(ck_pr_faa_64(&sb_globals.nevents, 1) >= sb_globals.max_events)) { log_text(LOG_INFO, "Event limit exceeded, exiting..."); return false; } /* If we are in tx_rate mode, we take events from queue */ if (sb_globals.tx_rate > 0) { void *ptr = NULL; while (!ck_ring_dequeue_spmc(&queue_ring, queue_ring_buffer, &ptr) && !sb_globals.error) { pthread_mutex_lock(&queue_mutex); pthread_cond_wait(&queue_cond, &queue_mutex); pthread_mutex_unlock(&queue_mutex); /* Re-check for global error and time limit after waiting */ if (sb_globals.error) return false; if (sb_globals.max_time_ns > 0 && SB_UNLIKELY(sb_timer_value(&sb_exec_timer) >= sb_globals.max_time_ns)) { log_text(LOG_INFO, "Time limit exceeded, exiting..."); return false; } } ck_pr_inc_int(&sb_globals.concurrency); timers[thread_id].queue_time = sb_timer_value(&sb_exec_timer) - ((uint64_t *) ptr)[0]; } return true; } void sb_event_start(int thread_id) { sb_timer_start(&timers[thread_id]); } void sb_event_stop(int thread_id) { sb_timer_t *timer = &timers[thread_id]; long long value; value = sb_timer_stop(timer); if (sb_globals.percentile > 0) sb_histogram_update(&sb_latency_histogram, NS2MS(value)); sb_counter_inc(thread_id, SB_CNT_EVENT); if (sb_globals.tx_rate > 0) { ck_pr_dec_int(&sb_globals.concurrency); } } /* Main event loop -- the default thread_run implementation */ static int thread_run(sb_test_t *test, int thread_id) { sb_event_t event; int rc = 0; while (sb_more_events(thread_id) && rc == 0) { event = test->ops.next_event(thread_id); if (event.type == SB_REQ_TYPE_NULL) break; sb_event_start(thread_id); rc = test->ops.execute_event(&event, thread_id); sb_event_stop(thread_id); } return rc; } /* Main worker thread */ static void *worker_thread(void *arg) { sb_thread_ctxt_t *ctxt; unsigned int thread_id; int rc; ctxt = (sb_thread_ctxt_t *)arg; sb_test_t * const test = current_test; sb_tls_thread_id = thread_id = ctxt->id; /* Initialize thread-local RNG state */ sb_rand_thread_init(); log_text(LOG_DEBUG, "Worker thread (#%d) started", thread_id); if (test->ops.thread_init != NULL && test->ops.thread_init(thread_id) != 0) { log_text(LOG_DEBUG, "Worker thread (#%d) failed to initialize!", thread_id); sb_globals.error = 1; /* Avoid blocking the main thread */ sb_barrier_wait(&thread_start_barrier); return NULL; } log_text(LOG_DEBUG, "Worker thread (#%d) initialized", thread_id); /* Wait for other threads to initialize */ if (sb_barrier_wait(&thread_start_barrier) < 0) return NULL; if (test->ops.thread_run != NULL) { /* Use benchmark-provided thread_run implementation */ rc = test->ops.thread_run(thread_id); } else { /* Use default thread_run implementation */ rc = thread_run(test, thread_id); } if (rc != 0) sb_globals.error = 1; else if (test->ops.thread_done != NULL) test->ops.thread_done(thread_id); return NULL; } /* Generate exponentially distributed number with a given Lambda */ static inline double sb_rand_exp(double lambda) { return -lambda * log(1 - sb_rand_uniform_double()); } static void *eventgen_thread_proc(void *arg) { (void)arg; /* unused */ sb_tls_thread_id = SB_BACKGROUND_THREAD_ID; /* Initialize thread-local RNG state */ sb_rand_thread_init(); ck_ring_init(&queue_ring, MAX_QUEUE_LEN); if (pthread_mutex_init(&queue_mutex, NULL) || pthread_cond_init(&queue_cond, NULL)) { sb_barrier_wait(&thread_start_barrier); return NULL; } log_text(LOG_DEBUG, "Event generating thread started"); /* Wait for other threads to initialize */ if (sb_barrier_wait(&thread_start_barrier) < 0) return NULL; eventgen_thread_created = 1; /* Get exponentially distributed time intervals in nanoseconds with Lambda = tx_rate. Alternatively, we can use Lambda = tx_rate / 1e9 */ const double lambda = 1e9 / sb_globals.tx_rate; uint64_t curr_ns = sb_timer_value(&sb_exec_timer); uint64_t intr_ns = sb_rand_exp(lambda); uint64_t next_ns = curr_ns + intr_ns; for (int i = 0; ; i = (i+1) % MAX_QUEUE_LEN) { curr_ns = sb_timer_value(&sb_exec_timer); intr_ns = sb_rand_exp(lambda); next_ns += intr_ns; if (sb_globals.max_time_ns > 0 && SB_UNLIKELY(curr_ns >= sb_globals.max_time_ns)) { /* Wake all waiting threads */ pthread_cond_broadcast(&queue_cond); return NULL; } if (next_ns > curr_ns) sb_nanosleep(next_ns - curr_ns); /* Enqueue a new event */ queue_array[i] = sb_timer_value(&sb_exec_timer); if (ck_ring_enqueue_spmc(&queue_ring, queue_ring_buffer, &queue_array[i]) == false) { sb_globals.error = 1; log_text(LOG_FATAL, "The event queue is full. This means the worker threads are " "unable to keep up with the specified event generation rate"); pthread_cond_broadcast(&queue_cond); return NULL; } /* Wake up one waiting thread, if there are any */ pthread_cond_signal(&queue_cond); } return NULL; } /* Intermediate reports thread */ static void *report_thread_proc(void *arg) { unsigned long long pause_ns; unsigned long long prev_ns; unsigned long long next_ns; unsigned long long curr_ns; const unsigned long long interval_ns = SEC2NS(sb_globals.report_interval); (void)arg; /* unused */ sb_tls_thread_id = SB_BACKGROUND_THREAD_ID; /* Initialize thread-local RNG state */ sb_rand_thread_init(); if (sb_lua_loaded() && sb_lua_report_thread_init()) return NULL; pthread_cleanup_push(sb_lua_report_thread_done, NULL); log_text(LOG_DEBUG, "Reporting thread started"); /* Wait for other threads to initialize */ if (sb_barrier_wait(&thread_start_barrier) < 0) return NULL; report_thread_created = 1; pause_ns = interval_ns; prev_ns = sb_timer_value(&sb_exec_timer) + interval_ns; for (;;) { sb_nanosleep(pause_ns); report_intermediate(); curr_ns = sb_timer_value(&sb_exec_timer); do { next_ns = prev_ns + interval_ns; prev_ns = next_ns; } while (curr_ns >= next_ns); pause_ns = next_ns - curr_ns; } pthread_cleanup_pop(1); return NULL; } /* Checkpoints reports thread */ static void *checkpoints_thread_proc(void *arg) { unsigned long long next_ns; unsigned long long curr_ns; unsigned int i; (void)arg; /* unused */ sb_tls_thread_id = SB_BACKGROUND_THREAD_ID; /* Initialize thread-local RNG state */ sb_rand_thread_init(); if (sb_lua_loaded() && sb_lua_report_thread_init()) return NULL; pthread_cleanup_push(sb_lua_report_thread_done, NULL); log_text(LOG_DEBUG, "Checkpoints report thread started"); /* Wait for other threads to initialize */ if (sb_barrier_wait(&thread_start_barrier) < 0) return NULL; checkpoints_thread_created = 1; for (i = 0; i < sb_globals.n_checkpoints; i++) { next_ns = SEC2NS(sb_globals.checkpoints[i]); curr_ns = sb_timer_value(&sb_exec_timer); if (next_ns <= curr_ns) continue; sb_nanosleep(next_ns - curr_ns); log_timestamp(LOG_NOTICE, NS2SEC(sb_timer_value(&sb_exec_timer)), "Checkpoint report:"); report_cumulative(); } pthread_cleanup_pop(1); return NULL; } /* Callback to start timers when all threads are ready */ static int threads_started_callback(void *arg) { (void) arg; /* unused */ /* Report initialization errors to the main thread */ if (sb_globals.error) return 1; sb_globals.threads_running = sb_globals.threads; sb_timer_start(&sb_exec_timer); sb_timer_copy(&sb_intermediate_timer, &sb_exec_timer); sb_timer_copy(&sb_checkpoint_timer, &sb_exec_timer); log_text(LOG_NOTICE, "Threads started!\n"); return 0; } /* Main test function: start threads, wait for them to finish and measure time. */ static int run_test(sb_test_t *test) { int err; pthread_t report_thread; pthread_t checkpoints_thread; pthread_t eventgen_thread; unsigned int barrier_threads; /* initialize test */ if (test->ops.init != NULL && test->ops.init() != 0) return 1; /* print test mode */ print_run_mode(test); /* initialize timers */ sb_timer_init(&sb_exec_timer); sb_timer_init(&sb_intermediate_timer); sb_timer_init(&sb_checkpoint_timer); /* prepare test */ if (test->ops.prepare != NULL && test->ops.prepare() != 0) return 1; pthread_mutex_init(&sb_globals.exec_mutex, NULL); sb_globals.threads_running = 0; /* Calculate the required number of threads for the start barrier */ barrier_threads = 1 + sb_globals.threads + (sb_globals.report_interval > 0) + (sb_globals.tx_rate > 0) + (sb_globals.n_checkpoints > 0); /* Initialize the start barrier */ if (sb_barrier_init(&thread_start_barrier, barrier_threads, threads_started_callback, NULL)) { log_errno(LOG_FATAL, "sb_barrier_init() failed"); return 1; } if (sb_globals.report_interval > 0) { /* Create a thread for intermediate statistic reports */ if ((err = sb_thread_create(&report_thread, &sb_thread_attr, &report_thread_proc, NULL)) != 0) { log_errno(LOG_FATAL, "sb_thread_create() for the reporting thread failed."); return 1; } } if (sb_globals.tx_rate > 0) { if ((err = sb_thread_create(&eventgen_thread, &sb_thread_attr, &eventgen_thread_proc, NULL)) != 0) { log_errno(LOG_FATAL, "sb_thread_create() for the reporting thread failed."); return 1; } } if (sb_globals.n_checkpoints > 0) { /* Create a thread for checkpoint statistic reports */ if ((err = sb_thread_create(&checkpoints_thread, &sb_thread_attr, &checkpoints_thread_proc, NULL)) != 0) { log_errno(LOG_FATAL, "sb_thread_create() for the checkpoint thread failed."); return 1; } } if ((err = sb_thread_create_workers(&worker_thread))) return err; #ifdef HAVE_ALARM /* Exit with an error if thread initialization timeout expires */ signal(SIGALRM, sigalrm_thread_init_timeout_handler); alarm(THREAD_INIT_TIMEOUT); #endif if (sb_barrier_wait(&thread_start_barrier) < 0) { log_text(LOG_FATAL, "Thread initialization failed!"); return 1; } #ifdef HAVE_ALARM alarm(0); if (sb_globals.force_shutdown) { /* Set the alarm to force shutdown */ signal(SIGALRM, sigalrm_forced_shutdown_handler); alarm(NS2SEC(sb_globals.max_time_ns) + sb_globals.timeout); } #endif if ((err = sb_thread_join_workers())) return err; sb_timer_stop(&sb_exec_timer); sb_timer_stop(&sb_intermediate_timer); sb_timer_stop(&sb_checkpoint_timer); /* Silence periodic reports if they were on */ ck_pr_store_uint(&sb_globals.report_interval, 0); #ifdef HAVE_ALARM alarm(0); #endif log_text(LOG_INFO, "Done.\n"); /* cleanup test */ if (test->ops.cleanup != NULL && test->ops.cleanup() != 0) return 1; if (report_thread_created) { if (sb_thread_cancel(report_thread) || sb_thread_join(report_thread, NULL)) log_errno(LOG_FATAL, "Terminating the reporting thread failed."); } if (eventgen_thread_created) { /* When a time limit is used, the event generation thread may terminate itself. */ if ((sb_thread_cancel(eventgen_thread) || sb_thread_join(eventgen_thread, NULL)) && sb_globals.max_time_ns == 0) log_text(LOG_FATAL, "Terminating the event generator thread failed."); } if (checkpoints_thread_created) { if (sb_thread_cancel(checkpoints_thread) || sb_thread_join(checkpoints_thread, NULL)) log_errno(LOG_FATAL, "Terminating the checkpoint thread failed."); } /* print test-specific stats */ if (!sb_globals.error) { if (sb_globals.histogram) { log_text(LOG_NOTICE, "Latency histogram (values are in milliseconds)"); sb_histogram_print(&sb_latency_histogram); log_text(LOG_NOTICE, " "); } report_cumulative(); } pthread_mutex_destroy(&sb_globals.exec_mutex); /* finalize test */ if (test->ops.done != NULL) (*(test->ops.done))(); return sb_globals.error != 0; } static sb_test_t *find_test(const char *name) { sb_list_item_t *pos; sb_test_t *test; SB_LIST_FOR_EACH(pos, &tests) { test = SB_LIST_ENTRY(pos, sb_test_t, listitem); if (!strcmp(test->sname, name)) return test; } return NULL; } static int checkpoint_cmp(const void *a_ptr, const void *b_ptr) { const unsigned int a = *(const unsigned int *) a_ptr; const unsigned int b = *(const unsigned int *) b_ptr; return (int) (a - b); } static int init(void) { option_t *opt; char *tmp; sb_list_t *checkpoints_list; sb_list_item_t *pos_val; value_t *val; sb_globals.threads = sb_get_value_int("num-threads"); if (sb_globals.threads > 1) { log_text(LOG_WARNING, "--num-threads is deprecated, use --threads instead"); sb_opt_copy("threads", "num-threads"); } else sb_globals.threads = sb_get_value_int("threads"); if (sb_globals.threads <= 0) { log_text(LOG_FATAL, "Invalid value for --threads: %d.\n", sb_globals.threads); return 1; } sb_globals.max_events = sb_get_value_int("max-requests"); if (sb_globals.max_events > 0) { log_text(LOG_WARNING, "--max-requests is deprecated, use --events instead"); sb_opt_copy("events", "max-requests"); } else sb_globals.max_events = sb_get_value_int("events"); int max_time = sb_get_value_int("max-time"); if (max_time > 0) { log_text(LOG_WARNING, "--max-time is deprecated, use --time instead"); sb_opt_copy("time", "max-time"); } else max_time = sb_get_value_int("time"); sb_globals.max_time_ns = SEC2NS(max_time); if (!sb_globals.max_events && !sb_globals.max_time_ns) log_text(LOG_WARNING, "Both event and time limits are disabled, " "running an endless test"); if (sb_globals.max_time_ns > 0) { /* Parse the --forced-shutdown value */ tmp = sb_get_value_string("forced-shutdown"); if (tmp == NULL) { sb_globals.force_shutdown = 1; sb_globals.timeout = NS2SEC(sb_globals.max_time_ns) / 20; } else if (strcasecmp(tmp, "off")) { char *endptr; sb_globals.force_shutdown = 1; sb_globals.timeout = (unsigned) strtol(tmp, &endptr, 10); if (*endptr == '%') sb_globals.timeout = (unsigned) (sb_globals.timeout * NS2SEC(sb_globals.max_time_ns) / 100); else if (*tmp == '\0' || *endptr != '\0') { log_text(LOG_FATAL, "Invalid value for --forced-shutdown: '%s'", tmp); return 1; } } else sb_globals.force_shutdown = 0; } int err; if ((err = sb_thread_init())) return err; sb_globals.debug = sb_get_value_flag("debug"); /* Automatically set logger verbosity to 'debug' */ if (sb_globals.debug) { opt = sb_find_option("verbosity"); if (opt != NULL) set_option(opt->name, "5", opt->type); } sb_globals.validate = sb_get_value_flag("validate"); if (sb_rand_init()) { return 1; } sb_globals.tx_rate = sb_get_value_int("tx-rate"); if (sb_globals.tx_rate > 0) { log_text(LOG_WARNING, "--tx-rate is deprecated, use --rate instead"); sb_opt_copy("rate", "tx-rate"); } else sb_globals.tx_rate = sb_get_value_int("rate"); sb_globals.report_interval = sb_get_value_int("report-interval"); sb_globals.n_checkpoints = 0; checkpoints_list = sb_get_value_list("report-checkpoints"); SB_LIST_FOR_EACH(pos_val, checkpoints_list) { char *endptr; long res; val = SB_LIST_ENTRY(pos_val, value_t, listitem); res = strtol(val->data, &endptr, 10); if (*endptr != '\0' || res < 0 || res > INT_MAX) { log_text(LOG_FATAL, "Invalid value for --report-checkpoints: '%s'", val->data); return 1; } if (++sb_globals.n_checkpoints > MAX_CHECKPOINTS) { log_text(LOG_FATAL, "Too many checkpoints in --report-checkpoints " "(up to %d can be defined)", MAX_CHECKPOINTS); return 1; } sb_globals.checkpoints[sb_globals.n_checkpoints-1] = (unsigned int) res; } if (sb_globals.n_checkpoints > 0) { qsort(sb_globals.checkpoints, sb_globals.n_checkpoints, sizeof(unsigned int), checkpoint_cmp); } /* Initialize timers */ timers = sb_alloc_per_thread_array(sizeof(sb_timer_t)); timers_copy = sb_alloc_per_thread_array(sizeof(sb_timer_t)); if (timers == NULL || timers_copy == NULL) { log_text(LOG_FATAL, "Memory allocation failure"); return 1; } for (unsigned i = 0; i < sb_globals.threads; i++) sb_timer_init(&timers[i]); return 0; } int main(int argc, char *argv[]) { sb_test_t *test = NULL; int rc; sb_globals.argc = argc; sb_globals.argv = malloc(argc * sizeof(char *)); memcpy(sb_globals.argv, argv, argc * sizeof(char *)); /* Initialize options library */ sb_options_init(); /* First register the logger */ if (log_register()) return EXIT_FAILURE; /* Register available tests */ if (register_tests()) { fprintf(stderr, "Failed to register tests.\n"); return EXIT_FAILURE; } /* Parse command line arguments */ if (parse_general_arguments(argc, argv)) return EXIT_FAILURE; if (sb_get_value_flag("help")) { print_help(); return EXIT_SUCCESS; } if (sb_get_value_flag("version")) { printf("%s\n", VERSION_STRING); return EXIT_SUCCESS; } /* Initialize global variables and logger */ if (init() || log_init() || sb_counters_init()) return EXIT_FAILURE; print_header(); if (sb_globals.testname != NULL && strcmp(sb_globals.testname, "-")) { /* Is it a built-in test name? */ test = find_test(sb_globals.testname); if (test != NULL && sb_globals.cmdname == NULL) { /* Command is a mandatory argument for built-in tests */ fprintf(stderr, "The '%s' test requires a command argument. " "See 'sysbench %s help'\n", test->sname, test->sname); return EXIT_FAILURE; } if (test == NULL) { if ((test = sb_load_lua(sb_globals.testname)) == NULL) return EXIT_FAILURE; if (sb_globals.cmdname == NULL) { /* No command specified, there's nothing more todo */ return test != NULL ? EXIT_SUCCESS: EXIT_FAILURE; } } } else { sb_globals.testname = NULL; if (SB_ISATTY()) log_text(LOG_NOTICE, "Reading the script from the standard input:\n"); test = sb_load_lua(NULL); return test != NULL ? EXIT_SUCCESS : EXIT_FAILURE; } current_test = test; /* Load and parse test-specific options */ if (parse_test_arguments(test, argc, argv)) return EXIT_FAILURE; if (sb_lua_loaded() && sb_lua_custom_command_defined(sb_globals.cmdname)) { rc = sb_lua_call_custom_command(sb_globals.cmdname); } else if (!strcmp(sb_globals.cmdname, "help")) { if (test->builtin_cmds.help != NULL) { test->builtin_cmds.help(); rc = EXIT_SUCCESS; goto end; } else if (test->args != NULL) { printf("%s options:\n", test->sname); sb_print_test_options(); rc = EXIT_SUCCESS; goto end; } /* We don't know want to print as help text, let the user know */ fprintf(stderr, "'%s' test does not implement the 'help' command.\n", test->sname); return EXIT_FAILURE; } else if (!strcmp(sb_globals.cmdname, "prepare")) { if (test->builtin_cmds.prepare == NULL) { fprintf(stderr, "'%s' test does not implement the 'prepare' command.\n", test->sname); rc = EXIT_FAILURE; goto end; } rc = test->builtin_cmds.prepare(); } else if (!strcmp(sb_globals.cmdname, "cleanup")) { if (test->builtin_cmds.cleanup == NULL) { fprintf(stderr, "'%s' test does not implement the 'cleanup' command.\n", test->sname); rc = EXIT_FAILURE; goto end; } rc = test->builtin_cmds.cleanup(); } else if (!strcmp(sb_globals.cmdname, "run")) { rc = run_test(test) ? EXIT_FAILURE : EXIT_SUCCESS; } else { fprintf(stderr, "Unknown command: %s\n", sb_globals.cmdname); rc = EXIT_FAILURE; } end: if (sb_lua_loaded()) sb_lua_done(); db_done(); sb_counters_done(); log_done(); sb_options_done(); sb_rand_done(); sb_thread_done(); free(timers); free(timers_copy); free(sb_globals.argv); return rc; } /* Print a description of available command line options for the current test */ void sb_print_test_options(void) { if (current_test != NULL) sb_print_options(current_test->args); } /* Allocate an array of objects of the specified size for all threads, both worker and background ones. */ void *sb_alloc_per_thread_array(size_t size) { /* We want to exclude queries executed by background threads from statistics generated for worker threads. To simplify code, we allocate all timers and counters for all worker threads + possible background threads created by sysbench for statistic reports, etc. When executing requests from background threads, extra array slots will be used (it depends on the assigned ID for each thread). When aggregating counters and timers, we only consider slots in the range [0, sb_globals.threads - 1], i.e. ignore statistics generated by background threads. Currently we assign the same single thread ID for all background threads, so they also share the same single slot in each allocated array. */ const size_t bsize = (sb_globals.threads + 1) * size; void *ptr = sb_memalign(bsize, CK_MD_CACHELINE); memset(ptr, 0, bsize); return ptr; } sysbench-1.0.18/src/sb_barrier.h0000600000175000017500000000304313553247311014271 0ustar jpjp/* Copyright (C) 2016 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Thread barrier implementation. */ #ifndef SB_BARRIER_H #define SB_BARRIER_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_PTHREAD_H # include #endif #ifdef _WIN32 #include "sb_win.h" #endif #define SB_BARRIER_SERIAL_THREAD 1 typedef int (*sb_barrier_cb_t)(void *); typedef struct { unsigned int count; unsigned int init_count; unsigned int serial; pthread_mutex_t mutex; pthread_cond_t cond; sb_barrier_cb_t callback; void *arg; int error; } sb_barrier_t; int sb_barrier_init(sb_barrier_t *barrier, unsigned int count, sb_barrier_cb_t callback, void *arg); int sb_barrier_wait(sb_barrier_t *barrier); void sb_barrier_destroy(sb_barrier_t *barrier); #endif /* SB_BARRIER_H */ sysbench-1.0.18/src/xoroshiro128plus.h0000600000175000017500000000515213553247311015355 0ustar jpjp/* Code below is based on the original work with the following copyright notice: */ /* Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org) To the extent possible under law, the author has dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. See . */ #include /* This is the successor to xorshift128+. It is the fastest full-period generator passing BigCrush without systematic failures, but due to the relatively short period it is acceptable only for applications with a mild amount of parallelism; otherwise, use a xorshift1024* generator. Beside passing BigCrush, this generator passes the PractRand test suite up to (and included) 16TB, with the exception of binary rank tests, which fail due to the lowest bit being an LFSR; all other bits pass all tests. We suggest to use a sign test to extract a random Boolean value. Note that the generator uses a simulated rotate operation, which most C compilers will turn into a single instruction. In Java, you can use Long.rotateLeft(). In languages that do not make low-level rotation instructions accessible xorshift128+ could be faster. The state must be seeded so that it is not everywhere zero. If you have a 64-bit seed, we suggest to seed a splitmix64 generator and use its output to fill s. */ inline uint64_t xoroshiro_rotl(const uint64_t x, int k) { return (x << k) | (x >> (64 - k)); } inline uint64_t xoroshiro_next(uint64_t s[2]) { const uint64_t s0 = s[0]; uint64_t s1 = s[1]; const uint64_t result = s0 + s1; s1 ^= s0; s[0] = xoroshiro_rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b s[1] = xoroshiro_rotl(s1, 36); // c return result; } /* This is the jump function for the generator. It is equivalent to 2^64 calls to next(); it can be used to generate 2^64 non-overlapping subsequences for parallel computations. */ static inline void xoroshiro_jump(uint64_t s[2]) { static const uint64_t JUMP[] = { 0xbeac0467eba5facb, 0xd86b048b86aa9922 }; uint64_t s0 = 0; uint64_t s1 = 0; int i, b; for(i = 0; i < (int) (sizeof JUMP / sizeof *JUMP); i++) for(b = 0; b < 64; b++) { if (JUMP[i] & 1ULL << b) { s0 ^= s[0]; s1 ^= s[1]; } xoroshiro_next(s); } s[0] = s0; s[1] = s1; } sysbench-1.0.18/src/sb_list.h0000600000175000017500000000715413553247311013625 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2014 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_LIST_H #define SB_LIST_H typedef struct sb_list_item_t { struct sb_list_item_t *next_p; struct sb_list_item_t *prev_p; } sb_list_item_t; typedef sb_list_item_t sb_list_item; typedef sb_list_item_t sb_list_t ; #ifndef offsetof # define offsetof(type, member) ((size_t) &((type *)0)->member) #endif #define SB_LIST_DECLARE(name) \ SB_LIST_T name = { &(name), &(name) } #define SB_LIST_INIT(head_p) \ do { \ (head_p)->next_p = (head_p); \ (head_p)->prev_p = (head_p); \ } while (0) #define SB_LIST_ITEM_INIT(item_p) \ SB_LIST_INIT(item_p) #define SB_LIST_ADD(item_p, head_p) \ do { \ (item_p)->next_p = (head_p)->next_p; \ (item_p)->prev_p = (head_p); \ (head_p)->next_p = (item_p); \ (item_p)->next_p->prev_p = (item_p); \ } while (0) #define SB_LIST_ADD_TAIL(item_p, head_p) \ do { \ (item_p)->prev_p = (head_p)->prev_p; \ (item_p)->next_p = (head_p); \ (head_p)->prev_p = (item_p); \ (item_p)->prev_p->next_p = (item_p); \ } while (0); #define SB_LIST_DELETE(old_item_p) \ do { \ (old_item_p)->next_p->prev_p = (old_item_p)->prev_p; \ (old_item_p)->prev_p->next_p = (old_item_p)->next_p; \ } while (0) #define SB_LIST_REPLACE(item_p, old_item_p) \ do { \ (item_p)->next_p = (old_item_p)->next_p; \ (item_p)->prev_p = (old_item_p)->prev_p; \ (item_p)->next_p->prev_p = (item_p); \ (item_p)->prev_p->next_p = (item_p); \ } while (0) #define SB_LIST_IS_EMPTY(head_p) \ ((head_p)->next_p == (head_p)) #define SB_LIST_ITEM_IN_LIST(item_p) \ ((item_p)->next_p != (item_p)) #define SB_LIST_ITEM_FIRST(item_p, head_p) \ ((item_p)->prev_p != (head_p)) #define SB_LIST_ITEM_LAST(item_p, head_p) \ ((item_p)->next_p == (head_p)) #define SB_LIST_ITEM_NEXT(item_p) \ ((item_p)->next_p) #define SB_LIST_ITEM_PREV(item_p) \ ((item_p)->prev_p) #define SB_LIST_ENTRY(ptr, type, member) \ ((type *)(void *)(((char *)(ptr) - offsetof(type, member)))) #define SB_LIST_ONCE(pos_p, head_p) \ pos_p= (head_p)->next_p; if (pos_p != (head_p)) #define SB_LIST_FOR_EACH(pos_p, head_p) \ for (pos_p = (head_p)->next_p; pos_p != (head_p); pos_p = pos_p->next_p) #define SB_LIST_ENUM_START(head_p) \ (head_p) #define SB_LIST_ENUM_NEXT(pos_p, head_p) \ ((pos_p->next_p != (head_p)) ? (pos_p->next_p) : NULL) #define SB_LIST_FOR_EACH_SAFE(pos_p, temp_p, head_p) \ for (pos_p = (head_p)->next_p, temp_p = (pos_p)->next_p; pos_p != (head_p); \ pos_p = temp_p, temp_p = (pos_p)->next_p) #define SB_LIST_FOR_EACH_REV_SAFE(pos_p, temp_p, head_p) \ for (pos_p = (head_p)->prev_p, temp_p = (pos_p)->prev_p; pos_p != (head_p); \ pos_p = temp_p, temp_p = (pos_p)->prev_p) #endif /* SB_LIST_H */ sysbench-1.0.18/src/CMakeLists.txt0000600000175000017500000000713013553247311014547 0ustar jpjp# Copyright (C) 2008 MySQL AB # Copyright (C) 2008-2017 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA cmake_minimum_required(VERSION 2.6) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) project(sysbench) add_executable(sysbench sysbench.c sysbench.h sb_timer.c sb_timer.h sb_options.c sb_options.h sb_logger.c sb_logger.h sb_histogram.c sb_histogram.h sb_list.h db_driver.h db_driver.c sb_win.c sb_win.h sb_rand.c sb_rand.h sb_thread.c sb_thread.h sb_barrier.c sb_barrier.h ) if(MSVC) # Link C runtime statically to avoid hassle with CRT dll redistribution. STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE}) STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO}) STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG}) STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG_INIT ${CMAKE_C_FLAGS_DEBUG_INIT}) STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}) STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG_INIT ${CMAKE_CXX_FLAGS_DEBUG_INIT}) #Silence "deprecated API" warnings. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4996") #Look for mysql.h in INCLUDE paths find_path(MYSQLH_PATH mysql.h ENV INCLUDE) message("mysql.h directory = ${MYSQLH_PATH}") #Looks for libmysql.lib in LIB paths find_file(LIBMYSQL_LIB libmysql.lib ENV LIB) message("libmysql.lib = ${LIBMYSQL_LIB}") #Look for libmysql.dll find_file(LIBMYSQL_DLL libmysql.dll ENV LIB ENV PATH) message("libmysql.dll = ${LIBMYSQL_DLL}") #If mysql header file and client library are found, build with mysql if(MYSQLH_PATH AND LIBMYSQL_LIB) set(USE_MYSQL 1) #If libmysql.dll found, copy it next to sysbench.exe in the postbuild step if(LIBMYSQL_DLL) file(TO_NATIVE_PATH ${LIBMYSQL_DLL} LIBMYSQL_DLL) ADD_CUSTOM_COMMAND( TARGET sysbench POST_BUILD COMMAND copy /y ${LIBMYSQL_DLL} $(OutDir) ) endif(LIBMYSQL_DLL) endif(MYSQLH_PATH AND LIBMYSQL_LIB) endif(MSVC) if(USE_MYSQL) message("using mysql driver") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_MYSQL") include_directories(${MYSQLH_PATH}) add_subdirectory(drivers/mysql) target_link_libraries (sysbench sbmysql) target_link_libraries (sysbench ${LIBMYSQL_LIB}) endif(USE_MYSQL) add_subdirectory(tests/cpu) target_link_libraries (sysbench sbcpu) add_subdirectory(tests/fileio) target_link_libraries (sysbench sbfileio) add_subdirectory(tests/mutex) target_link_libraries (sysbench sbmutex) add_subdirectory(tests/threads) target_link_libraries (sysbench sbthreads) add_subdirectory(tests/memory) target_link_libraries (sysbench sbmemory) sysbench-1.0.18/src/sb_global.h0000600000175000017500000000164713553247311014113 0ustar jpjp/* Copyright (C) 2016 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Global and portability-related macros */ #ifndef SB_GLOBAL_H #define SB_GLOBAL_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #endif /* SB_GLOBAL_H */ sysbench-1.0.18/src/sb_histogram.c0000600000175000017500000002062013553247311014633 0ustar jpjp/* Copyright (C) 2011-2017 Alexey Kopytov. 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 #include "sb_win.h" #endif #ifdef STDC_HEADERS # include # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_MATH_H # include #endif #include "sysbench.h" #include "sb_histogram.h" #include "sb_logger.h" #include "sb_rand.h" #include "sb_ck_pr.h" #include "ck_cc.h" #include "sb_util.h" /* Number of slots for current histogram array. TODO: replace this constant with some autodetection code based on the number of available cores or some such. */ #define SB_HISTOGRAM_NSLOTS 128 /* Global latency histogram */ sb_histogram_t sb_latency_histogram CK_CC_CACHELINE; int sb_histogram_init(sb_histogram_t *h, size_t size, double range_min, double range_max) { size_t i; uint64_t *tmp; /* Allocate memory for cumulative_array + temp_array + all slot arrays */ tmp = (uint64_t *) calloc(size * (SB_HISTOGRAM_NSLOTS + 2), sizeof(uint64_t)); h->interm_slots = (uint64_t **) malloc(SB_HISTOGRAM_NSLOTS * sizeof(uint64_t *)); if (tmp == NULL || h->interm_slots == NULL) { log_text(LOG_FATAL, "Failed to allocate memory for a histogram object, size = %zd", size); return 1; } h->cumulative_array = tmp; tmp += size; h->temp_array = tmp; tmp += size; for (i = 0; i < SB_HISTOGRAM_NSLOTS; i++) { h->interm_slots[i] = tmp; tmp += size; } h->range_deduct = log(range_min); h->range_mult = (size - 1) / (log(range_max) - h->range_deduct); h->range_min = range_min; h->range_max = range_max; h->array_size = size; pthread_rwlock_init(&h->lock, NULL); return 0; } void sb_histogram_update(sb_histogram_t *h, double value) { size_t slot; ssize_t i; slot = sb_rand_uniform_uint64() % SB_HISTOGRAM_NSLOTS; i = floor((log(value) - h->range_deduct) * h->range_mult + 0.5); if (SB_UNLIKELY(i < 0)) i = 0; else if (SB_UNLIKELY(i >= (ssize_t) (h->array_size))) i = h->array_size - 1; ck_pr_inc_64(&h->interm_slots[slot][i]); } double sb_histogram_get_pct_intermediate(sb_histogram_t *h, double percentile) { size_t i, s; uint64_t nevents, ncur, nmax; double res; nevents = 0; /* This can be called concurrently with other sb_histogram_get_pct_*() functions, so use the lock to protect shared structures. This will not block sb_histogram_update() calls, but we make sure we don't lose any concurrent increments by atomically fetching each array element and replacing it with 0. */ pthread_rwlock_wrlock(&h->lock); /* Merge intermediate slots into temp_array. */ const size_t size = h->array_size; uint64_t * const array = h->temp_array; for (i = 0; i < size; i++) { array[i] = ck_pr_fas_64(&h->interm_slots[0][i], 0); nevents += array[i]; } for (s = 1; s < SB_HISTOGRAM_NSLOTS; s++) { for (i = 0; i < size; i++) { uint64_t t; t = ck_pr_fas_64(&h->interm_slots[s][i], 0); array[i] += t; nevents += t; } } /* Now that we have an aggregate 'snapshot' of current arrays and the total number of events in it, calculate the current, intermediate percentile value to return. */ nmax = floor(nevents * percentile / 100 + 0.5); ncur = 0; for (i = 0; i < size; i++) { ncur += array[i]; if (ncur >= nmax) break; } res = exp(i / h->range_mult + h->range_deduct); /* Finally, add temp_array into accumulated values in cumulative_array. */ for (i = 0; i < size; i++) { h->cumulative_array[i] += array[i]; } h->cumulative_nevents += nevents; pthread_rwlock_unlock(&h->lock); return res; } /* Aggregate arrays from intermediate slots into cumulative_array. This should be called with the histogram lock write-locked. */ static void merge_intermediate_into_cumulative(sb_histogram_t *h) { size_t i, s; uint64_t nevents; nevents = h->cumulative_nevents; const size_t size = h->array_size; uint64_t * const array = h->cumulative_array; for (s = 0; s < SB_HISTOGRAM_NSLOTS; s++) { for (i = 0; i < size; i++) { uint64_t t = ck_pr_fas_64(&h->interm_slots[s][i], 0); array[i] += t; nevents += t; } } h->cumulative_nevents = nevents; } /* Calculate a given percentile from the cumulative array. This should be called with the histogram lock either read- or write-locked. */ static double get_pct_cumulative(sb_histogram_t *h, double percentile) { size_t i; uint64_t ncur, nmax; nmax = floor(h->cumulative_nevents * percentile / 100 + 0.5); ncur = 0; for (i = 0; i < h->array_size; i++) { ncur += h->cumulative_array[i]; if (ncur >= nmax) break; } return exp(i / h->range_mult + h->range_deduct); } double sb_histogram_get_pct_cumulative(sb_histogram_t *h, double percentile) { double res; /* This can be called concurrently with other sb_histogram_get_pct_*() functions, so use the lock to protect shared structures. This will not block sb_histogram_update() calls, but we make sure we don't lose any concurrent increments by atomically fetching each array element and replacing it with 0. */ pthread_rwlock_wrlock(&h->lock); merge_intermediate_into_cumulative(h); res = get_pct_cumulative(h, percentile); pthread_rwlock_unlock(&h->lock); return res; } double sb_histogram_get_pct_checkpoint(sb_histogram_t *h, double percentile) { double res; /* This can be called concurrently with other sb_histogram_get_pct_*() functions, so use the lock to protect shared structures. This will not block sb_histogram_update() calls, but we make sure we don't lose any concurrent increments by atomically fetching each array element and replacing it with 0. */ pthread_rwlock_wrlock(&h->lock); merge_intermediate_into_cumulative(h); res = get_pct_cumulative(h, percentile); /* Reset the cumulative array */ memset(h->cumulative_array, 0, h->array_size * sizeof(uint64_t)); h->cumulative_nevents = 0; pthread_rwlock_unlock(&h->lock); return res; } void sb_histogram_print(sb_histogram_t *h) { uint64_t maxcnt; int width; size_t i; pthread_rwlock_wrlock(&h->lock); merge_intermediate_into_cumulative(h); uint64_t * const array = h->cumulative_array; maxcnt = 0; for (i = 0; i < h->array_size; i++) { if (array[i] > maxcnt) maxcnt = array[i]; } if (maxcnt == 0) return; printf(" value ------------- distribution ------------- count\n"); for (i = 0; i < h->array_size; i++) { if (array[i] == 0) continue; width = floor(array[i] * (double) 40 / maxcnt + 0.5); printf("%12.3f |%-40.*s %lu\n", exp(i / h->range_mult + h->range_deduct), /* value */ width, "****************************************", /* distribution */ (unsigned long) array[i]); /* count */ } pthread_rwlock_unlock(&h->lock); } void sb_histogram_done(sb_histogram_t *h) { pthread_rwlock_destroy(&h->lock); free(h->cumulative_array); free(h->interm_slots); } /* Allocate a new histogram and initialize it with sb_histogram_init(). */ sb_histogram_t *sb_histogram_new(size_t size, double range_min, double range_max) { sb_histogram_t *h; if ((h = malloc(sizeof(*h))) == NULL) return NULL; if (sb_histogram_init(h, size, range_min, range_max)) { free(h); return NULL; } return h; } /* Deallocate a histogram allocated with sb_histogram_new(). */ void sb_histogram_delete(sb_histogram_t *h) { sb_histogram_done(h); free(h); } sysbench-1.0.18/src/sb_lua.h0000600000175000017500000000237213553247311013430 0ustar jpjp/* Copyright (C) 2006 MySQL AB Copyright (C) 2006-2018 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "sysbench.h" #include "lua.h" /* Load a specified Lua script */ sb_test_t *sb_load_lua(const char *testname); void sb_lua_done(void); int sb_lua_hook_call(lua_State *L, const char *name); bool sb_lua_custom_command_defined(const char *name); int sb_lua_call_custom_command(const char *name); int sb_lua_report_thread_init(void); void sb_lua_report_thread_done(void *); bool sb_lua_loaded(void); sysbench-1.0.18/src/sb_thread.c0000600000175000017500000000654113553247311014113 0ustar jpjp/* Copyright (C) 2016 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Wrappers around pthread_create() and friends to provide necessary (de-)initialization. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 #include "sb_win.h" #endif #ifdef HAVE_PTHREAD_H # include #endif #include "sb_thread.h" #include "sb_rand.h" #include "sb_logger.h" #include "sysbench.h" #include "sb_ck_pr.h" pthread_attr_t sb_thread_attr; /* Thread descriptors */ static sb_thread_ctxt_t *threads; /* Stack size for each thread */ static int thread_stack_size; int sb_thread_init(void) { thread_stack_size = sb_get_value_size("thread-stack-size"); if (thread_stack_size <= 0) { log_text(LOG_FATAL, "Invalid value for thread-stack-size: %d.\n", thread_stack_size); return 1; } /* initialize attr */ pthread_attr_init(&sb_thread_attr); #ifdef PTHREAD_SCOPE_SYSTEM pthread_attr_setscope(&sb_thread_attr,PTHREAD_SCOPE_SYSTEM); #endif pthread_attr_setstacksize(&sb_thread_attr, thread_stack_size); #ifdef HAVE_THR_SETCONCURRENCY /* Set thread concurrency (required on Solaris) */ thr_setconcurrency(sb_globals.threads); #endif threads = malloc(sb_globals.threads * sizeof(sb_thread_ctxt_t)); if (threads == NULL) { log_text(LOG_FATAL, "Memory allocation failure.\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } void sb_thread_done(void) { if (threads != NULL) free(threads); } int sb_thread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) { return pthread_create(thread, attr, start_routine, arg); } int sb_thread_join(pthread_t thread, void **retval) { return pthread_join(thread, retval); } int sb_thread_cancel(pthread_t thread) { return pthread_cancel(thread); } int sb_thread_create_workers(void *(*worker_routine)(void*)) { unsigned int i; log_text(LOG_NOTICE, "Initializing worker threads...\n"); for(i = 0; i < sb_globals.threads; i++) { threads[i].id = i; } for(i = 0; i < sb_globals.threads; i++) { int err; if ((err = sb_thread_create(&(threads[i].thread), &sb_thread_attr, worker_routine, (void*)(threads + i))) != 0) { log_errno(LOG_FATAL, "sb_thread_create() for thread #%d failed.", i); return EXIT_FAILURE; } } return EXIT_SUCCESS; } int sb_thread_join_workers(void) { for(unsigned i = 0; i < sb_globals.threads; i++) { int err; if((err = sb_thread_join(threads[i].thread, NULL)) != 0) log_errno(LOG_FATAL, "sb_thread_join() for thread #%d failed.", i); ck_pr_dec_uint(&sb_globals.threads_running); } return EXIT_SUCCESS; } sysbench-1.0.18/src/sb_options.c0000600000175000017500000003553213553247311014341 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2018 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 # include "sb_win.h" #endif #ifdef STDC_HEADERS # include # include # include # include #endif #ifdef HAVE_LIMITS_H # include #endif #include "sb_options.h" #include "sysbench.h" #define VALUE_DELIMITER '=' #define VALUE_SEPARATOR ',' #define COMMENT_CHAR '#' #define MAXSTRLEN 256 /* Global options list */ static sb_list_t options; /* List of size modifiers (kilo, mega, giga, tera) */ static const char sizemods[] = "KMGT"; /* Convert dashes to underscores in option names */ static void convert_dashes(char *); /* Compare option names */ static int opt_name_cmp(const char *, const char *); /* Array of option formats as displayed by sb_print_options(). The order and number of elements must match sb_arg_type_t! */ static char *opt_formats[] = { NULL, /* SB_ARG_TYPE_NULL */ "[=on|off]", /* SB_ARG_TYPE_FLAG */ "=N", /* SB_ARG_TYPE_INT */ "=SIZE", /* SB_ARG_TYPE_SIZE */ "=N", /* SB_ARG_TYPE_DOUBLE */ "=STRING", /* SB_ARG_TYPE_STRING */ "=[LIST,...]", /* SB_ARG_TYPE_LIST */ "=FILENAME" /* SB_ARG_TYPE_FILE */ }; /* Initialize options library */ int sb_options_init(void) { SB_LIST_INIT(&options); return 0; } /* Release resource allocated by the options library */ int sb_options_done(void) { free_options(&options); return 0; } /* Register set of command line arguments */ int sb_register_arg_set(sb_arg_t *set) { unsigned int i; for (i=0; set[i].name != NULL; i++) { option_t * const opt = set_option(set[i].name, set[i].value, set[i].type); if (opt == NULL) return 1; opt->validate = set->validate; } return 0; } option_t *sb_find_option(const char *name) { return find_option(&options, name); } static void read_config_file(const char *filename) { /* read config options from file */ FILE *fp = fopen(filename, "r"); if (!fp) { perror(filename); } else { read_config(fp, &options); fclose(fp); } } option_t *set_option(const char *name, const char *value, sb_arg_type_t type) { option_t *opt; char *tmpbuf; char *tmp; opt = add_option(&options, name); if (opt == NULL) return NULL; free_values(&opt->values); opt->type = type; if (opt->validate != NULL && !opt->validate(name, value)) return NULL; if (type != SB_ARG_TYPE_BOOL && (value == NULL || value[0] == '\0')) return opt; switch (type) { case SB_ARG_TYPE_BOOL: if (value == NULL || !strcmp(value, "on") || !strcmp(value, "true") || !strcmp(value, "1")) { add_value(&opt->values, "on"); } else if (strcmp(value, "off") && strcmp(value, "false") && strcmp(value, "0")) { return NULL; } break; case SB_ARG_TYPE_INT: case SB_ARG_TYPE_SIZE: case SB_ARG_TYPE_DOUBLE: case SB_ARG_TYPE_STRING: add_value(&opt->values, value); break; case SB_ARG_TYPE_LIST: if (value == NULL) break; tmpbuf = strdup(value); tmp = tmpbuf; for (tmp = strtok(tmp, ","); tmp != NULL; tmp = strtok(NULL, ",")) add_value(&opt->values, tmp); free(tmpbuf); break; case SB_ARG_TYPE_FILE: read_config_file(value); break; default: printf("Unknown argument type: %d", type); return NULL; } return opt; } void sb_print_options(sb_arg_t *opts) { unsigned int i; unsigned int len; unsigned int maxlen; char *fmt; /* Count the maximum name length */ for (i = 0, maxlen = 0; opts[i].name != NULL; i++) { len = strlen(opts[i].name); len += (opts[i].type < SB_ARG_TYPE_MAX) ? strlen(opt_formats[opts[i].type]) : 8 /* =UNKNOWN */; if (len > maxlen) maxlen = len; } for (i = 0; opts[i].name != NULL; i++) { if (opts[i].type < SB_ARG_TYPE_MAX) fmt = opt_formats[opts[i].type]; else fmt = "=UNKNOWN"; printf(" --%s%-*s%s", opts[i].name, (int)(maxlen - strlen(opts[i].name) + 1), fmt, opts[i].desc); if (opts[i].value != NULL) printf(" [%s]", opts[i].value); printf("\n"); } printf("\n"); } int sb_opt_to_flag(option_t *opt) { return !SB_LIST_IS_EMPTY(&opt->values); } int sb_get_value_flag(const char *name) { option_t *opt; opt = find_option(&options, name); if (opt == NULL) return 0; return sb_opt_to_flag(opt); } int sb_opt_to_int(option_t *opt) { value_t *val; sb_list_item_t *pos; long res; char *endptr; SB_LIST_ONCE(pos, &opt->values) { val = SB_LIST_ENTRY(pos, value_t, listitem); res = strtol(val->data, &endptr, 10); if (*endptr != '\0' || res > INT_MAX || res < INT_MIN) { fprintf(stderr, "Invalid value for the '%s' option: '%s'\n", opt->name, val->data); exit(EXIT_FAILURE); } return (int) res; } return 0; } int sb_get_value_int(const char *name) { option_t *opt; opt = find_option(&options, name); if (opt == NULL) return 0; return sb_opt_to_int(opt);; } unsigned long long sb_opt_to_size(option_t *opt) { value_t *val; sb_list_item_t *pos; unsigned long long res = 0; char mult = 0; int rc; unsigned int i, n; char *c; SB_LIST_ONCE(pos, &opt->values) { val = SB_LIST_ENTRY(pos, value_t, listitem); /* * Reimplentation of sscanf(val->data, "%llu%c", &res, &mult), since * there is no standard on how to specify long long values */ res = 0; for (rc = 0, c = val->data; *c != '\0'; c++) { if (*c < '0' || *c > '9') { if (rc == 1) { rc = 2; mult = *c; } break; } rc = 1; res = res * 10 + *c - '0'; } if (rc == 2) { for (n = 0; sizemods[n] != '\0'; n++) if (toupper(mult) == sizemods[n]) break; if (sizemods[n] != '\0') { for (i = 0; i <= n; i++) res *= 1024; } else res = 0; /* Unknown size modifier */ } } return res; } unsigned long long sb_get_value_size(const char *name) { option_t *opt; opt = find_option(&options, name); if (opt == NULL) return 0; return sb_opt_to_size(opt); } double sb_opt_to_double(option_t *opt) { value_t *val; sb_list_item_t *pos; double res = 0; SB_LIST_FOR_EACH(pos, &opt->values) { val = SB_LIST_ENTRY(pos, value_t, listitem); res = strtod(val->data, NULL); } return res; } double sb_get_value_double(const char *name) { option_t *opt; opt = find_option(&options, name); if (opt == NULL) return 0; return sb_opt_to_double(opt); } char *sb_opt_to_string(option_t *opt) { value_t *val; sb_list_item_t *pos; SB_LIST_ONCE(pos, &opt->values) { val = SB_LIST_ENTRY(pos, value_t, listitem); return val->data; } return NULL; } char *sb_get_value_string(const char *name) { option_t *opt; opt = find_option(&options, name); if (opt == NULL) return NULL; return sb_opt_to_string(opt); } bool sb_opt_copy(const char *to, const char *from) { option_t *opt = find_option(&options, from); if (opt == NULL) return false; set_option(to, sb_opt_to_string(opt), opt->type); return true; } sb_list_t *sb_opt_to_list(option_t *opt) { return &opt->values; } sb_list_t *sb_get_value_list(const char *name) { option_t *opt; opt = find_option(&options, name); if (opt == NULL) return NULL; return sb_opt_to_list(opt); } char *sb_print_value_size(char *buf, unsigned int buflen, double value) { unsigned int i; for (i = 0; i < sizeof(sizemods) && value >= 1024; i++, value /= 1024) /* empty */ ; if (i > 0) snprintf(buf, buflen, "%.5g%ci", value, sizemods[i-1]); else snprintf(buf, buflen, "%.5g", value); return buf; } value_t *new_value() { value_t *newval; newval = (value_t *)malloc(sizeof(value_t)); if (newval != NULL) memset(newval, 0, sizeof(value_t)); return newval; } option_t *new_option() { option_t *newopt; newopt = (option_t *)malloc(sizeof(option_t)); if (newopt != NULL) { memset(newopt, 0, sizeof(option_t)); SB_LIST_INIT(&newopt->values); } return newopt; } void free_values(sb_list_t *values) { sb_list_item_t *next; sb_list_item_t *cur; value_t *val; if (values == NULL) return; SB_LIST_FOR_EACH_SAFE(cur, next, values) { val = SB_LIST_ENTRY(cur, value_t, listitem); if (val->data != NULL) free(val->data); SB_LIST_DELETE(cur); free(val); } } void free_options(sb_list_t *options) { sb_list_item_t *next; sb_list_item_t *cur; option_t *opt; if (options == NULL) return; SB_LIST_FOR_EACH_SAFE(cur, next, options) { opt = SB_LIST_ENTRY(cur, option_t, listitem); if (opt->name != NULL) free(opt->name); free_values(&opt->values); free(opt); } } int remove_value(sb_list_t *values, char *valname) { value_t * value; if (values == NULL || valname == NULL) return 1; if ((value = find_value(values, valname)) == NULL) return 1; if (value->data != NULL) { free(value->data); } SB_LIST_DELETE(&value->listitem); free(value); return 0; } int remove_option(sb_list_t * options, char * optname) { option_t * option; if (options == NULL || optname == NULL) return 1; if ((option = find_option(options, optname)) == NULL) return 1; free_values(&option->values); if (option->name != NULL) free(option->name); SB_LIST_DELETE(&option->listitem); free(option); return 0; } value_t *add_value(sb_list_t *values, const char *data) { value_t *newval; if (values == NULL || data == NULL) return NULL; if ((newval = new_value()) == NULL) return NULL; if ((newval->data = strdup(data)) == NULL) { free(newval); return NULL; } SB_LIST_ADD_TAIL(&newval->listitem, values); return newval; } value_t *find_value(sb_list_t *values, const char *data) { sb_list_item_t *pos; value_t *value; if (values == NULL || data == NULL) return NULL; SB_LIST_FOR_EACH(pos, values) { value = SB_LIST_ENTRY(pos, value_t, listitem); if (!strcmp(value->data, data)) return value; } return NULL; } option_t *add_option(sb_list_t *options, const char *name) { option_t *option; if (options == NULL || name == NULL) return NULL; if ((option = find_option(options, name)) != NULL) return option; if ((option = new_option()) == NULL) return NULL; option->name = strdup(name); convert_dashes(option->name); SB_LIST_ADD_TAIL(&option->listitem, options); return option; } void convert_dashes(char *s) { while (*s != '\0') { if (*s == '-') *s = '_'; s++; } } int opt_name_cmp(const char *s1, const char *s2) { for (/* empty */; *s1 != '\0'; s1++, s2++) { if (*s1 == *s2) continue; if ((*s1 != '-' && *s1 != '_') || (*s2 != '-' && *s2 != '_')) break; } return *s1 - *s2; } option_t *find_option(sb_list_t *options, const char *name) { sb_list_item_t *pos; option_t *opt; if (options == NULL || name == NULL) return NULL; SB_LIST_FOR_EACH(pos, options) { opt = SB_LIST_ENTRY(pos, option_t, listitem); if (!opt_name_cmp(opt->name, name)) return opt; } return NULL; } sb_list_item_t *sb_options_enum_start(void) { return SB_LIST_ENUM_START(&options); } sb_list_item_t *sb_options_enum_next(sb_list_item_t *pos, option_t **opt) { pos = SB_LIST_ENUM_NEXT(pos, &options); if (pos == NULL) return NULL; *opt = SB_LIST_ENTRY(pos, option_t, listitem); return pos; } sb_list_t *read_config(FILE *fp, sb_list_t *options) { char buf[MAXSTRLEN]; char *tmp; char qc; option_t *newopt; int optlen; int nline; if (fp == NULL || options == NULL) return NULL; nline = 0; while (fgets(buf, MAXSTRLEN, fp) != NULL) { nline++; tmp = strchr(buf, VALUE_DELIMITER); if (tmp == NULL) continue; if (*tmp != '\0') *tmp++ = '\0'; if ((newopt = add_option(options, buf)) == NULL) return NULL; free_values(&newopt->values); while (*tmp != '\0') { if (isspace((int)*tmp)) { tmp++; continue; } if (*tmp == COMMENT_CHAR) break; else if (*tmp == '\'' || *tmp == '\"') { qc = *tmp; for (tmp++, optlen = 0; tmp[optlen] != '\0' && tmp[optlen] != qc; optlen++) { /* Empty */ } if (tmp[optlen] == '\0') { fprintf(stderr, "unexpected EOL on line %d\n", nline); return NULL; } tmp[optlen++] = '\0'; add_value(&newopt->values, tmp); for (tmp = tmp + optlen; *tmp != '\0' && *tmp != VALUE_SEPARATOR; tmp++) { /* Empty */ } if (*tmp == VALUE_SEPARATOR) tmp++; } else { for (optlen = 0; tmp[optlen] != '\0' && tmp[optlen] != VALUE_SEPARATOR && !isspace(tmp[optlen]); optlen++) { /* Empty */ } if (tmp[optlen] != '\0') tmp[optlen++] = '\0'; add_value(&newopt->values, tmp); tmp += optlen; } } } return options; } int write_config(FILE *fp, sb_list_t *options) { option_t *opt; value_t *val; sb_list_item_t *pos_opt; sb_list_item_t *pos_val; if (fp == NULL || options == NULL) return 1; SB_LIST_FOR_EACH(pos_opt, options) { opt = SB_LIST_ENTRY(pos_opt, option_t, listitem); if (opt->ignore || opt->name == NULL) continue; opt->ignore = 1; fprintf(fp, "%s %c ", opt->name, VALUE_DELIMITER); SB_LIST_FOR_EACH(pos_val, &opt->values) { val = SB_LIST_ENTRY(pos_val, value_t, listitem); if (!val->ignore && val->data != NULL) fprintf(fp, "%s", val->data); if (!SB_LIST_ITEM_LAST(pos_val, &opt->values)) fprintf(fp, "%c ", VALUE_SEPARATOR); } fputc('\n', fp); } return 0; } sysbench-1.0.18/src/sb_logger.h0000600000175000017500000001003413553247311014120 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2016 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_LOGGER_H #define SB_LOGGER_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_PTHREAD_H # include #endif #include "sb_util.h" #include "sb_options.h" #include "sb_timer.h" #include "sb_histogram.h" /* Text message flags (used in the 'flags' field of log_text_msg_t) */ #define LOG_MSG_TEXT_ALLOW_DUPLICATES 1 /* Message types definition */ typedef enum { LOG_MSG_TYPE_MIN, /* used for internal purposes */ LOG_MSG_TYPE_TEXT, /* arbitrary text messages */ LOG_MSG_TYPE_OPER, /* operation start/stop messages */ LOG_MSG_TYPE_MAX /* used for internal purposes */ } log_msg_type_t; /* Message priorities definition */ typedef enum { LOG_FATAL, /* system is unusable */ LOG_ALERT, /* user actions must be taken */ LOG_WARNING, /* warnings */ LOG_NOTICE, /* normal but significant messages */ LOG_INFO, /* informational messages */ LOG_DEBUG, /* debug-level messages */ LOG_MAX /* used for internal purposes */ } log_msg_priority_t; /* Text message definition */ typedef struct { log_msg_priority_t priority; char *text; unsigned int flags; } log_msg_text_t; /* Operation start/stop message definition */ typedef enum { LOG_MSG_OPER_START, LOG_MSG_OPER_STOP } log_msg_oper_action_t; typedef struct { log_msg_oper_action_t action; int thread_id; } log_msg_oper_t; /* General log message definition */ typedef struct { log_msg_type_t type; void *data; } log_msg_t; /* Log handler operations definition */ typedef int log_op_register(void); /* register handler options */ typedef int log_op_init(void); /* initialize log handler */ typedef int log_op_process(log_msg_t *msg); /* process message */ typedef int log_op_done(void); /* uninitialize log handler */ /* Log handler operations structure */ typedef struct { log_op_init *init; log_op_process *process; log_op_done *done; } log_handler_ops_t; /* Log handler definition */ typedef struct { log_handler_ops_t ops; /* handler operations */ sb_arg_t *args; /* handler arguments */ sb_list_item_t listitem; /* can be linked in a list */ } log_handler_t; /* Register logger */ int log_register(void); /* Display command line options for all register log handlers */ void log_print_help(void); /* Initialize logger */ int log_init(void); /* Add handler for a specified type of messages */ int log_add_handler(log_msg_type_t type, log_handler_t *handler); /* Main function to dispatch log messages */ void log_msg(log_msg_t *); /* printf-like wrapper to log text messages */ void log_text(log_msg_priority_t priority, const char *fmt, ...) SB_ATTRIBUTE_FORMAT(printf, 2, 3); /* variant of log_text() which prepends log lines with a elapsed time of the specified timer. */ void log_timestamp(log_msg_priority_t priority, double seconds, const char *fmt, ...) SB_ATTRIBUTE_FORMAT(printf, 3, 4); /* printf-like wrapper to log system error messages */ void log_errno(log_msg_priority_t priority, const char *fmt, ...) SB_ATTRIBUTE_FORMAT(printf, 2, 3); /* Uninitialize logger */ void log_done(void); #endif /* SB_LOGGER_H */ sysbench-1.0.18/src/sb_thread.h0000600000175000017500000000313113553247311014110 0ustar jpjp/* Copyright (C) 2016 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Wrappers around pthread_create() and friends to provide necessary (de-)initialization. */ #ifndef SB_THREAD_H #define SB_THREAD_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 #include "sb_win.h" #endif #ifdef HAVE_PTHREAD_H # include #endif /* Thread context definition */ typedef struct { pthread_t thread; unsigned int id; } sb_thread_ctxt_t; extern pthread_attr_t sb_thread_attr; int sb_thread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); int sb_thread_join(pthread_t thread, void **retval); int sb_thread_cancel(pthread_t thread); int sb_thread_create_workers(void *(*worker_routine)(void*)); int sb_thread_join_workers(void); int sb_thread_init(void); void sb_thread_done(void); #endif /* SB_THREAD_H */ sysbench-1.0.18/src/sb_ck_pr.h0000600000175000017500000001733313553247311013750 0ustar jpjp/* Copyright (C) 2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * This file incorporates work covered by the following copyright and * permission notice: * * Copyright 2010 Samy Al Bahra. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. */ /* Compatibility wrappers for ConcurrencyKit functions. ConcurrencyKit does not implement 64-bit atomic primitives on some 32-bit architectures (e.g. x86, ARMv6) natively. Newer versions support the CK_USE_CC_BUILTINS define which allows resorting to compiler builtins emulating 64-bit atomics on 32-bit architectures. However, one might want to build with an old, distribution-provided CK version where that option is not available. For those versions, define 64-bit atomics as aliases to GCC builtins. A cleaner solution would be to define the corresponding sysbench data structures as 32-bit integers on those architectures, but the amount of extra code to implement and support is not worth it. Code below has been copied with modifications from gcc/ck_pr.h from the ConcurrencyKit distribution. */ #ifndef SB_CK_H #define SB_CK_H #include "ck_pr.h" #if !defined(CK_F_PR_LOAD_64) #ifndef __GNUC__ # error Unsupported platform #endif #include #define CK_PR_ACCESS(x) (*(volatile __typeof__(x) *)&(x)) #define CK_PR_LOAD(S, M, T) \ CK_CC_INLINE static T \ ck_pr_md_load_##S(const M *target) \ { \ T r; \ ck_pr_barrier(); \ r = CK_PR_ACCESS(*(const T *)target); \ ck_pr_barrier(); \ return (r); \ } \ CK_CC_INLINE static void \ ck_pr_md_store_##S(M *target, T v) \ { \ ck_pr_barrier(); \ CK_PR_ACCESS(*(T *)target) = v; \ ck_pr_barrier(); \ return; \ } #define CK_PR_LOAD_S(S, T) CK_PR_LOAD(S, T, T) CK_PR_LOAD_S(64, uint64_t) #undef CK_PR_LOAD_S #undef CK_PR_LOAD #define CK_PR_LOAD_SAFE(SRC, TYPE) ck_pr_md_load_##TYPE((SRC)) #define CK_PR_STORE_SAFE(DST, VAL, TYPE) \ ck_pr_md_store_##TYPE( \ ((void)sizeof(*(DST) = (VAL)), (DST)), \ (VAL)) #define ck_pr_load_64(SRC) CK_PR_LOAD_SAFE((SRC), 64) #define ck_pr_store_64(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 64) /* * Atomic compare and swap. */ #define CK_PR_CAS(S, M, T) \ CK_CC_INLINE static bool \ ck_pr_cas_##S(M *target, T compare, T set) \ { \ bool z; \ z = __sync_bool_compare_and_swap((T *)target, compare, set); \ return z; \ } #define CK_PR_CAS_S(S, T) CK_PR_CAS(S, T, T) CK_PR_CAS_S(64, uint64_t) #undef CK_PR_CAS_S #undef CK_PR_CAS #define CK_PR_CAS_O(S, T) \ CK_CC_INLINE static bool \ ck_pr_cas_##S##_value(T *target, T compare, T set, T *v) \ { \ set = __sync_val_compare_and_swap(target, compare, set);\ *v = set; \ return (set == compare); \ } CK_PR_CAS_O(64, uint64_t) #undef CK_PR_CAS_O /* * Atomic store-only binary operations. */ #define CK_PR_BINARY(K, S, M, T) \ CK_CC_INLINE static void \ ck_pr_##K##_##S(M *target, T d) \ { \ d = __sync_fetch_and_##K((T *)target, d); \ return; \ } #define CK_PR_BINARY_S(K, S, T) CK_PR_BINARY(K, S, T, T) #define CK_PR_GENERATE(K) \ CK_PR_BINARY_S(K, 64, uint64_t) CK_PR_GENERATE(add) CK_PR_GENERATE(sub) CK_PR_GENERATE(and) CK_PR_GENERATE(or) CK_PR_GENERATE(xor) #undef CK_PR_GENERATE #undef CK_PR_BINARY_S #undef CK_PR_BINARY #define CK_PR_UNARY(S, M, T) \ CK_CC_INLINE static void \ ck_pr_inc_##S(M *target) \ { \ ck_pr_add_##S(target, (T)1); \ return; \ } \ CK_CC_INLINE static void \ ck_pr_dec_##S(M *target) \ { \ ck_pr_sub_##S(target, (T)1); \ return; \ } #define CK_PR_UNARY_S(S, M) CK_PR_UNARY(S, M, M) CK_PR_UNARY_S(64, uint64_t) #undef CK_PR_UNARY_S #undef CK_PR_UNARY #define CK_PR_FAA(S, M, T, C) \ CK_CC_INLINE static C \ ck_pr_faa_##S(M *target, T delta) \ { \ T previous; \ C punt; \ punt = (C)ck_pr_md_load_##S(target); \ previous = (T)punt; \ while (ck_pr_cas_##S##_value(target, \ (C)previous, \ (C)(previous + delta), \ &previous) == false) \ ck_pr_stall(); \ \ return ((C)previous); \ } #define CK_PR_FAS(S, M, C) \ CK_CC_INLINE static C \ ck_pr_fas_##S(M *target, C update) \ { \ C previous; \ previous = ck_pr_md_load_##S(target); \ while (ck_pr_cas_##S##_value(target, \ previous, \ update, \ &previous) == false) \ ck_pr_stall(); \ \ return (previous); \ } #define CK_PR_FAA_S(S, M) CK_PR_FAA(S, M, M, M) #define CK_PR_FAS_S(S, M) CK_PR_FAS(S, M, M) CK_PR_FAA_S(64, uint64_t) CK_PR_FAS_S(64, uint64_t) #undef CK_PR_FAA_S #undef CK_PR_FAA #undef CK_PR_FAS_S #undef CK_PR_FAS #endif /* !CK_F_PR_LOAD_64*/ #endif /* SB_CK_H */ sysbench-1.0.18/src/sb_util.c0000600000175000017500000000371713553247311013623 0ustar jpjp/* Copyright (C) 2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 #include "sb_win.h" #endif #ifdef STDC_HEADERS # include # include #endif #ifdef HAVE_UNISTD_H # include #endif #include "sb_util.h" #include "sb_logger.h" /* Allocate a buffer of a specified size such that the address is a multiple of a specified alignment. */ void *sb_memalign(size_t size, size_t alignment) { void *buf; #ifdef HAVE_POSIX_MEMALIGN int ret= posix_memalign(&buf, alignment, size); if (ret != 0) buf = NULL; #elif defined(HAVE_MEMALIGN) buf = memalign(alignment, size); #elif defined(HAVE_VALLOC) /* Allocate on page boundary */ (void) alignment; /* unused */ buffer = valloc(size); #elif defined (_WIN32) /* Allocate on page boundary */ (void) alignment; /* unused */ buffer = VirtualAlloc(NULL, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); #else # error Cannot find an aligned allocation library function! #endif return buf; } /* Get OS page size */ size_t sb_getpagesize(void) { #ifdef _SC_PAGESIZE return sysconf(_SC_PAGESIZE); #elif defined _WIN32 SYSTEM_INFO info; GetSystemInfo(&info); return info.dwPageSize; #else return getpagesize(); #endif } sysbench-1.0.18/src/sb_counter.h0000600000175000017500000000604013553247311014322 0ustar jpjp/* Copyright (C) 2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_COUNTER_H #define SB_COUNTER_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef STDC_HEADERS # include #endif #include "sb_util.h" #include "sb_ck_pr.h" /* Statistic counter types */ typedef enum { SB_CNT_OTHER, /* unknown type of queries */ SB_CNT_READ, /* reads */ SB_CNT_WRITE, /* writes */ SB_CNT_EVENT, /* events */ SB_CNT_ERROR, /* errors */ SB_CNT_RECONNECT, /* reconnects */ SB_CNT_MAX } sb_counter_type_t; /* sizeof(sb_counter_t) must be a multiple of CK_MD_CACHELINE to avoid cache line sharing. */ typedef uint64_t sb_counters_t[SB_ALIGN(SB_CNT_MAX * sizeof(uint64_t), CK_MD_CACHELINE) / sizeof(uint64_t)]; extern sb_counters_t *sb_counters; int sb_counters_init(void); void sb_counters_done(void); /* Cannot use C99 inline here, because CK atomic primitives use static inlines which in turn leads to compiler warnings. So for performance reasons the following functions are defined 'static inline' too everywhere except sb_lua.c where they are declared and defined as external linkage functions to be available from LuaJIT FFI. */ #ifndef SB_LUA_EXPORT # define SB_LUA_INLINE static inline #else # define SB_LUA_INLINE uint64_t sb_counter_val(int thread_id, sb_counter_type_t type); void sb_counter_inc(int thread_id, sb_counter_type_t type); #endif /* Return the current value for a given counter */ SB_LUA_INLINE uint64_t sb_counter_val(int thread_id, sb_counter_type_t type) { return ck_pr_load_64(&sb_counters[thread_id][type]); } /* Increment a given stat counter for a given thread */ SB_LUA_INLINE void sb_counter_inc(int thread_id, sb_counter_type_t type) { ck_pr_store_64(&sb_counters[thread_id][type], sb_counter_val(thread_id, type)+1); } #undef SB_LUA_INLINE /* Return aggregate counter values since the last intermediate report. This is not thread-safe as it updates the global last report state, so it must be called from a single thread. */ void sb_counters_agg_intermediate(sb_counters_t val); /* Return aggregate counter values since the last cumulative report. This is not thread-safe as it updates the global last report state, so it must be called from a single thread. */ void sb_counters_agg_cumulative(sb_counters_t val); #endif sysbench-1.0.18/src/Makefile.am0000600000175000017500000000454513553247311014052 0ustar jpjp# Copyright (C) 2004 MySQL AB # Copyright (C) 2004-2017 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA SUBDIRS = drivers tests lua . AM_CPPFLAGS += -DDATADIR=\"$(pkgdatadir)\" -DLIBDIR=\"$(pkglibdir)\" bin_PROGRAMS = sysbench EXTRA_LDFLAGS = @EXTRA_LDFLAGS@ # The following check will be extended as new database drivers will be added if USE_MYSQL mysql_ldadd = drivers/mysql/libsbmysql.a $(MYSQL_LIBS) endif if USE_DRIZZLE drizzle_ldadd = drivers/drizzle/libsbdrizzle.a $(LIBDRIZZLE) endif if USE_ATTACHSQL attachsql_ldadd = drivers/attachsql/libsbattachsql.a $(LIBATTACHSQL) endif if USE_ORACLE ora_ldadd = drivers/oracle/libsboracle.a $(ORA_LIBS) endif if USE_PGSQL pgsql_ldadd = drivers/pgsql/libsbpgsql.a $(PGSQL_LIBS) endif sysbench_SOURCES = sysbench.c sysbench.h sb_timer.c sb_timer.h \ sb_options.c sb_options.h sb_logger.c sb_logger.h sb_list.h db_driver.h \ db_driver.c sb_histogram.c sb_histogram.h sb_rand.c sb_rand.h \ sb_thread.c sb_thread.h sb_barrier.c sb_barrier.h sb_lua.c \ sb_ck_pr.h \ sb_lua.h sb_util.h sb_util.c sb_counter.h sb_counter.c \ lua/internal/sysbench.lua.h lua/internal/sysbench.sql.lua.h \ lua/internal/sysbench.rand.lua.h lua/internal/sysbench.cmdline.lua.h \ lua/internal/sysbench.compat.lua.h lua/internal/sysbench.histogram.lua.h \ xoroshiro128plus.h sysbench_LDADD = tests/fileio/libsbfileio.a tests/threads/libsbthreads.a \ tests/memory/libsbmemory.a tests/cpu/libsbcpu.a \ tests/mutex/libsbmutex.a \ $(mysql_ldadd) $(drizzle_ldadd) $(attachsql_ldadd) $(pgsql_ldadd) \ $(ora_ldadd) $(LUAJIT_LIBS) $(CK_LIBS) sysbench_LDFLAGS = $(EXTRA_LDFLAGS) $(mysql_ldflags) $(attachsql_ldflags) \ $(pgsql_ldflags) $(ora_ldflags) $(LUAJIT_LDFLAGS) sysbench-1.0.18/src/db_driver.h0000600000175000017500000002565713553247311014136 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef DB_DRIVER_H #define DB_DRIVER_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "sysbench.h" #include "sb_list.h" #include "sb_histogram.h" #include "sb_counter.h" /* Prepared statements usage modes */ typedef enum { DB_PS_MODE_AUTO, DB_PS_MODE_DISABLE, } db_ps_mode_t; /* Global DB API options */ typedef struct { db_ps_mode_t ps_mode; /* Requested prepared statements usage mode */ char *driver; /* Requested database driver */ unsigned char debug; /* debug flag */ } db_globals_t; /* Driver capabilities definition */ typedef struct { char multi_rows_insert; /* 1 if database supports multi-row inserts */ char prepared_statements; /* 1 if database supports prepared statements */ char auto_increment; /* 1 if database supports AUTO_INCREMENT clause */ char needs_commit; /* 1 if database needs explicit commit after INSERTs */ char serial; /* 1 if database supports SERIAL clause */ char unsigned_int; /* 1 if database supports UNSIGNED INTEGER types */ } drv_caps_t; /* Database errors definition */ typedef enum { DB_ERROR_NONE, /* no error(s) */ DB_ERROR_IGNORABLE, /* error should be ignored as defined by command line arguments or a custom error handler */ DB_ERROR_FATAL /* non-ignorable error */ } db_error_t; /* Available buffer types (for parameters binding) */ typedef enum { DB_TYPE_NONE, DB_TYPE_TINYINT, DB_TYPE_SMALLINT, DB_TYPE_INT, DB_TYPE_BIGINT, DB_TYPE_FLOAT, DB_TYPE_DOUBLE, DB_TYPE_TIME, DB_TYPE_DATE, DB_TYPE_DATETIME, DB_TYPE_TIMESTAMP, DB_TYPE_CHAR, DB_TYPE_VARCHAR } db_bind_type_t; /* Structure used to represent DATE, TIME, DATETIME and TIMESTAMP values */ typedef struct { unsigned int year; unsigned int month; unsigned int day; unsigned int hour; unsigned int minute; unsigned int second; } db_time_t; /* Structure used to bind data for prepared statements */ typedef struct { db_bind_type_t type; void *buffer; unsigned long *data_len; unsigned long max_len; char *is_null; } db_bind_t; /* Forward declarations */ struct db_conn; struct db_stmt; struct db_result; struct db_row; /* Driver operations definition */ typedef int drv_op_init(void); typedef int drv_op_thread_init(int); typedef int drv_op_describe(drv_caps_t *); typedef int drv_op_connect(struct db_conn *); typedef int drv_op_reconnect(struct db_conn *); typedef int drv_op_disconnect(struct db_conn *); typedef int drv_op_prepare(struct db_stmt *, const char *, size_t); typedef int drv_op_bind_param(struct db_stmt *, db_bind_t *, size_t); typedef int drv_op_bind_result(struct db_stmt *, db_bind_t *, size_t); typedef db_error_t drv_op_execute(struct db_stmt *, struct db_result *); typedef int drv_op_fetch(struct db_result *); typedef int drv_op_fetch_row(struct db_result *, struct db_row *); typedef db_error_t drv_op_query(struct db_conn *, const char *, size_t, struct db_result *); typedef int drv_op_free_results(struct db_result *); typedef int drv_op_close(struct db_stmt *); typedef int drv_op_thread_done(int); typedef int drv_op_done(void); typedef struct { drv_op_init *init; /* initializate driver */ drv_op_thread_init *thread_init; /* thread-local driver initialization */ drv_op_describe *describe; /* describe database capabilities */ drv_op_connect *connect; /* connect to database */ drv_op_disconnect *disconnect; /* disconnect from database */ drv_op_reconnect *reconnect; /* reconnect with the same parameters */ drv_op_prepare *prepare; /* prepare statement */ drv_op_bind_param *bind_param; /* bind params for prepared statement */ drv_op_bind_result *bind_result; /* bind results for prepared statement */ drv_op_execute *execute; /* execute prepared statement */ drv_op_fetch *fetch; /* fetch row for prepared statement */ drv_op_fetch_row *fetch_row; /* fetch row for queries */ drv_op_free_results *free_results; /* free result set */ drv_op_close *close; /* close prepared statement */ drv_op_query *query; /* execute non-prepared statement */ drv_op_thread_done *thread_done; /* thread-local driver deinitialization */ drv_op_done *done; /* uninitialize driver */ } drv_ops_t; /* Database driver definition */ typedef struct { const char *sname; /* short name */ const char *lname; /* long name */ sb_arg_t *args; /* driver command line arguments */ drv_ops_t ops; /* driver operations */ sb_list_item_t listitem; /* can be linked in a list */ bool initialized; pthread_mutex_t mutex; } db_driver_t; /* Row value definition */ typedef struct { uint32_t len; /* Value length */ const char *ptr; /* Value string */ } db_value_t; /* Result set row definition */ typedef struct db_row { void *ptr; /* Driver-specific row data */ db_value_t *values; /* Array of column values */ } db_row_t; /* Result set definition */ typedef struct db_result { sb_counter_type_t counter; /* Statistical counter type */ uint32_t nrows; /* Number of affected rows */ uint32_t nfields; /* Number of fields */ struct db_stmt *statement; /* Pointer to prepared statement (if used) */ void *ptr; /* Pointer to driver-specific data */ db_row_t row; /* Last fetched row */ } db_result_t; typedef enum { DB_CONN_READY, DB_CONN_RESULT_SET, DB_CONN_INVALID } db_conn_state_t; /* Database connection structure */ typedef struct db_conn { db_error_t error; /* Database-independent error code */ int sql_errno; /* Database-specific error code */ const char *sql_state; /* Database-specific SQL state */ const char *sql_errmsg; /* Database-specific error message */ db_driver_t *driver; /* DB driver for this connection */ void *ptr; /* Driver-specific data */ db_result_t rs; /* Result set */ db_conn_state_t state; /* Connection state */ int thread_id; /* Thread this connection belongs to */ unsigned int bulk_cnt; /* Current number of rows in bulk insert buffer */ unsigned int bulk_buflen; /* Current length of bulk_buffer */ char *bulk_buffer; /* Bulk insert query buffer */ unsigned int bulk_ptr; /* Current position in bulk_buffer */ unsigned int bulk_values; /* Save value of bulk_ptr */ unsigned int bulk_commit_cnt; /* Current value of uncommitted rows */ unsigned int bulk_commit_max; /* Maximum value of uncommitted rows */ char pad[SB_CACHELINE_PAD(sizeof(db_error_t) + sizeof(int) + sizeof(void *) + sizeof(void *) + sizeof(void *) + sizeof(void *) + sizeof(db_result_t) + sizeof(db_conn_state_t) + sizeof(int) + sizeof(int) * 2 + sizeof(void *) + sizeof(int) * 4 )]; } db_conn_t; /* Prepared statement definition */ typedef struct db_stmt { db_conn_t *connection; /* Connection which this statement belongs to */ char *query; /* Query string for emulated PS */ db_bind_t *bound_param; /* Array of bound parameters for emulated PS */ unsigned int bound_param_len; /* Length of the bound_param array */ db_bind_t *bound_res; /* Array of bound results for emulated PS */ db_bind_t *bound_res_len; /* Length of the bound_res array */ char emulated; /* Should this statement be emulated? */ sb_counter_type_t counter; /* Query type */ void *ptr; /* Pointer to driver-specific data structure */ } db_stmt_t; extern db_globals_t db_globals; /* Database abstraction layer calls */ int db_register(void); void db_print_help(void); db_driver_t *db_create(const char *); int db_destroy(db_driver_t *); int db_describe(db_driver_t *, drv_caps_t *); db_conn_t *db_connection_create(db_driver_t *); int db_connection_close(db_conn_t *); int db_connection_reconnect(db_conn_t *con); void db_connection_free(db_conn_t *con); db_stmt_t *db_prepare(db_conn_t *, const char *, size_t); int db_bind_param(db_stmt_t *, db_bind_t *, size_t); int db_bind_result(db_stmt_t *, db_bind_t *, size_t); db_result_t *db_execute(db_stmt_t *); db_row_t *db_fetch_row(db_result_t *); db_result_t *db_query(db_conn_t *, const char *, size_t len); int db_free_results(db_result_t *); int db_store_results(db_result_t *); int db_close(db_stmt_t *); void db_done(void); int db_print_value(db_bind_t *, char *, int); /* Initialize multi-row insert operation */ int db_bulk_insert_init(db_conn_t *, const char *, size_t); /* Add row to multi-row insert operation */ int db_bulk_insert_next(db_conn_t *, const char *, size_t); /* Finish multi-row insert operation */ int db_bulk_insert_done(db_conn_t *); /* Print database-specific test stats */ void db_report_intermediate(sb_stat_t *); void db_report_cumulative(sb_stat_t *); /* DB drivers registrars */ #ifdef USE_MYSQL int register_driver_mysql(sb_list_t *); #endif #ifdef USE_DRIZZLE int register_driver_drizzle(sb_list_t *); #endif #ifdef USE_ATTACHSQL int register_driver_attachsql(sb_list_t *); #endif #ifdef USE_DRIZZLECLIENT int register_driver_drizzleclient(sb_list_t *); #endif #ifdef USE_ORACLE int register_driver_oracle(sb_list_t *); #endif #ifdef USE_PGSQL int register_driver_pgsql(sb_list_t *); #endif #endif /* DB_DRIVER_H */ sysbench-1.0.18/src/sb_rand.h0000600000175000017500000000413213553247311013567 0ustar jpjp/* Copyright (C) 2016-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_RAND_H #define SB_RAND_H #include #include "xoroshiro128plus.h" /* Random numbers distributions */ typedef enum { DIST_TYPE_UNIFORM, DIST_TYPE_GAUSSIAN, DIST_TYPE_SPECIAL, DIST_TYPE_PARETO } rand_dist_t; typedef uint64_t sb_rng_state_t [2]; /* optional seed set on the command line */ extern int sb_rand_seed; /* Thread-local RNG state */ extern TLS sb_rng_state_t sb_rng_state; /* Return a uniformly distributed pseudo-random 64-bit unsigned integer */ inline uint64_t sb_rand_uniform_uint64(void) { return xoroshiro_next(sb_rng_state); } /* Return a uniformly distributed pseudo-random double in the [0, 1) interval */ inline double sb_rand_uniform_double(void) { const uint64_t x = sb_rand_uniform_uint64(); const union { uint64_t i; double d; } u = { .i = UINT64_C(0x3FF) << 52 | x >> 12 }; return u.d - 1.0; } int sb_rand_register(void); void sb_rand_print_help(void); int sb_rand_init(void); void sb_rand_done(void); void sb_rand_thread_init(void); /* Generator functions */ uint32_t sb_rand_default(uint32_t, uint32_t); uint32_t sb_rand_uniform(uint32_t, uint32_t); uint32_t sb_rand_gaussian(uint32_t, uint32_t); uint32_t sb_rand_special(uint32_t, uint32_t); uint32_t sb_rand_pareto(uint32_t, uint32_t); uint32_t sb_rand_unique(void); void sb_rand_str(const char *, char *); #endif /* SB_RAND_H */ sysbench-1.0.18/src/tests/0000700000175000017500000000000013553247311013146 5ustar jpjpsysbench-1.0.18/src/tests/sb_memory.h0000600000175000017500000000216513553247311015321 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2008 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_MEMORY_H #define SB_MEMORY_H /* Memory request type definition */ typedef enum { SB_MEM_OP_NONE, SB_MEM_OP_READ, SB_MEM_OP_WRITE } sb_mem_op_t; /* Memory scope type definition */ typedef enum { SB_MEM_SCOPE_GLOBAL, SB_MEM_SCOPE_LOCAL } sb_mem_scope_t; int register_test_memory(sb_list_t *tests); #endif sysbench-1.0.18/src/tests/mutex/0000700000175000017500000000000013553247311014310 5ustar jpjpsysbench-1.0.18/src/tests/mutex/CMakeLists.txt0000600000175000017500000000157613553247311017063 0ustar jpjp# Copyright (C) 2008 MySQL AB # Copyright (C) 2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/tests) add_library(sbmutex sb_mutex.c) sysbench-1.0.18/src/tests/mutex/Makefile.am0000600000175000017500000000163113553247311016347 0ustar jpjp# Copyright (C) 2004 MySQL AB # Copyright (C) 2004-2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA noinst_LIBRARIES = libsbmutex.a libsbmutex_a_SOURCES = sb_mutex.c ../sb_mutex.h libsbmutex_a_CPPFLAGS = $(AM_CPPFLAGS) sysbench-1.0.18/src/tests/mutex/sb_mutex.c0000600000175000017500000000757513553247311016322 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2016 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 # include "sb_win.h" #endif #ifdef HAVE_PTHREAD_H # include #endif #include "sysbench.h" #include "sb_ck_pr.h" #include "sb_rand.h" typedef struct { pthread_mutex_t mutex; char pad[256]; } thread_lock; /* Mutex test arguments */ static sb_arg_t mutex_args[] = { SB_OPT("mutex-num", "total size of mutex array", "4096", INT), SB_OPT("mutex-locks", "number of mutex locks to do per thread", "50000", INT), SB_OPT("mutex-loops", "number of empty loops to do outside mutex lock", "10000", INT), SB_OPT_END }; /* Mutex test operations */ static int mutex_init(void); static void mutex_print_mode(void); static sb_event_t mutex_next_event(int); static int mutex_execute_event(sb_event_t *, int); static int mutex_done(void); static sb_test_t mutex_test = { .sname = "mutex", .lname = "Mutex performance test", .ops = { .init = mutex_init, .print_mode = mutex_print_mode, .next_event = mutex_next_event, .execute_event = mutex_execute_event, .done = mutex_done }, .args = mutex_args }; static thread_lock *thread_locks; static unsigned int mutex_num; static unsigned int mutex_loops; static unsigned int mutex_locks; static unsigned int global_var; static TLS int tls_counter; int register_test_mutex(sb_list_t *tests) { SB_LIST_ADD_TAIL(&mutex_test.listitem, tests); return 0; } int mutex_init(void) { unsigned int i; mutex_num = sb_get_value_int("mutex-num"); mutex_loops = sb_get_value_int("mutex-loops"); mutex_locks = sb_get_value_int("mutex-locks"); thread_locks = (thread_lock *)malloc(mutex_num * sizeof(thread_lock)); if (thread_locks == NULL) { log_text(LOG_FATAL, "Memory allocation failure!"); return 1; } for (i = 0; i < mutex_num; i++) pthread_mutex_init(&thread_locks[i].mutex, NULL); return 0; } int mutex_done(void) { unsigned int i; for(i=0; i < mutex_num; i++) pthread_mutex_destroy(&thread_locks[i].mutex); free(thread_locks); return 0; } sb_event_t mutex_next_event(int thread_id) { sb_event_t sb_req; sb_mutex_request_t *mutex_req = &sb_req.u.mutex_request; (void) thread_id; /* unused */ /* Perform only one request per thread */ if (tls_counter++ > 0) sb_req.type = SB_REQ_TYPE_NULL; else { sb_req.type = SB_REQ_TYPE_MUTEX; mutex_req->nlocks = mutex_locks; mutex_req->nloops = mutex_loops; } return sb_req; } int mutex_execute_event(sb_event_t *sb_req, int thread_id) { unsigned int i; unsigned int current_lock; sb_mutex_request_t *mutex_req = &sb_req->u.mutex_request; (void) thread_id; /* unused */ do { current_lock = sb_rand_uniform(0, mutex_num - 1); for (i = 0; i < mutex_req->nloops; i++) ck_pr_barrier(); pthread_mutex_lock(&thread_locks[current_lock].mutex); global_var++; pthread_mutex_unlock(&thread_locks[current_lock].mutex); mutex_req->nlocks--; } while (mutex_req->nlocks > 0); return 0; } void mutex_print_mode(void) { log_text(LOG_INFO, "Doing mutex performance test"); } sysbench-1.0.18/src/tests/sb_cpu.h0000600000175000017500000000157213553247311014601 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_CPU_H #define SB_CPU_H int register_test_cpu(sb_list_t *tests); #endif sysbench-1.0.18/src/tests/sb_fileio.h0000600000175000017500000000241013553247311015251 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2008 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_FILEIO_H #define SB_FILEIO_H #ifdef _WIN32 #include "sb_win.h" /* ssize_t defined*/ #endif /* File operation types */ typedef enum { FILE_OP_TYPE_NULL, FILE_OP_TYPE_READ, FILE_OP_TYPE_WRITE, FILE_OP_TYPE_FSYNC } sb_file_op_t; /* File IO request definition */ typedef struct { unsigned int file_id; long long pos; ssize_t size; sb_file_op_t operation; } sb_file_request_t; int register_test_fileio(sb_list_t *tests); #endif sysbench-1.0.18/src/tests/sb_mutex.h0000600000175000017500000000177113553247311015155 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_MUTEX_H #define SB_MUTEX_H /* Threads request definition */ typedef struct { unsigned int nlocks; unsigned int nloops; } sb_mutex_request_t; int register_test_mutex(sb_list_t *tests); #endif sysbench-1.0.18/src/tests/memory/0000700000175000017500000000000013553247311014456 5ustar jpjpsysbench-1.0.18/src/tests/memory/CMakeLists.txt0000600000175000017500000000160013553247311017215 0ustar jpjp# Copyright (C) 2008 MySQL AB # Copyright (C) 2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/tests) add_library(sbmemory sb_memory.c) sysbench-1.0.18/src/tests/memory/sb_memory.c0000600000175000017500000003022613553247311016623 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 #include "sb_win.h" #endif #include "sysbench.h" #include "sb_rand.h" #ifdef HAVE_SYS_IPC_H # include #endif #ifdef HAVE_SYS_SHM_H # include #endif #include #define LARGE_PAGE_SIZE (4UL * 1024 * 1024) /* Memory test arguments */ static sb_arg_t memory_args[] = { SB_OPT("memory-block-size", "size of memory block for test", "1K", SIZE), SB_OPT("memory-total-size", "total size of data to transfer", "100G", SIZE), SB_OPT("memory-scope", "memory access scope {global,local}", "global", STRING), #ifdef HAVE_LARGE_PAGES SB_OPT("memory-hugetlb", "allocate memory from HugeTLB pool", "off", BOOL), #endif SB_OPT("memory-oper", "type of memory operations {read, write, none}", "write", STRING), SB_OPT("memory-access-mode", "memory access mode {seq,rnd}", "seq", STRING), SB_OPT_END }; /* Memory test operations */ static int memory_init(void); static int memory_thread_init(int); static void memory_print_mode(void); static sb_event_t memory_next_event(int); static int event_rnd_none(sb_event_t *, int); static int event_rnd_read(sb_event_t *, int); static int event_rnd_write(sb_event_t *, int); static int event_seq_none(sb_event_t *, int); static int event_seq_read(sb_event_t *, int); static int event_seq_write(sb_event_t *, int); static void memory_report_intermediate(sb_stat_t *); static void memory_report_cumulative(sb_stat_t *); static sb_test_t memory_test = { .sname = "memory", .lname = "Memory functions speed test", .ops = { .init = memory_init, .thread_init = memory_thread_init, .print_mode = memory_print_mode, .next_event = memory_next_event, .report_intermediate = memory_report_intermediate, .report_cumulative = memory_report_cumulative }, .args = memory_args }; /* Test arguments */ static ssize_t memory_block_size; static long long memory_total_size; static unsigned int memory_scope; static unsigned int memory_oper; static unsigned int memory_access_rnd; #ifdef HAVE_LARGE_PAGES static unsigned int memory_hugetlb; #endif static TLS uint64_t tls_total_ops CK_CC_CACHELINE; static TLS size_t *tls_buf; static TLS size_t *tls_buf_end; /* Array of per-thread buffers */ static size_t **buffers; /* Global buffer */ static size_t *buffer; #ifdef HAVE_LARGE_PAGES static void * hugetlb_alloc(size_t size); #endif int register_test_memory(sb_list_t *tests) { SB_LIST_ADD_TAIL(&memory_test.listitem, tests); return 0; } int memory_init(void) { unsigned int i; char *s; memory_block_size = sb_get_value_size("memory-block-size"); if (memory_block_size < SIZEOF_SIZE_T || /* Must be a power of 2 */ (memory_block_size & (memory_block_size - 1)) != 0) { log_text(LOG_FATAL, "Invalid value for memory-block-size: %s", sb_get_value_string("memory-block-size")); return 1; } memory_total_size = sb_get_value_size("memory-total-size"); s = sb_get_value_string("memory-scope"); if (!strcmp(s, "global")) memory_scope = SB_MEM_SCOPE_GLOBAL; else if (!strcmp(s, "local")) memory_scope = SB_MEM_SCOPE_LOCAL; else { log_text(LOG_FATAL, "Invalid value for memory-scope: %s", s); return 1; } #ifdef HAVE_LARGE_PAGES memory_hugetlb = sb_get_value_flag("memory-hugetlb"); #endif s = sb_get_value_string("memory-oper"); if (!strcmp(s, "write")) memory_oper = SB_MEM_OP_WRITE; else if (!strcmp(s, "read")) memory_oper = SB_MEM_OP_READ; else if (!strcmp(s, "none")) memory_oper = SB_MEM_OP_NONE; else { log_text(LOG_FATAL, "Invalid value for memory-oper: %s", s); return 1; } s = sb_get_value_string("memory-access-mode"); if (!strcmp(s, "seq")) memory_access_rnd = 0; else if (!strcmp(s, "rnd")) memory_access_rnd = 1; else { log_text(LOG_FATAL, "Invalid value for memory-access-mode: %s", s); return 1; } if (memory_scope == SB_MEM_SCOPE_GLOBAL) { #ifdef HAVE_LARGE_PAGES if (memory_hugetlb) buffer = hugetlb_alloc(memory_block_size); else #endif buffer = sb_memalign(memory_block_size, sb_getpagesize()); if (buffer == NULL) { log_text(LOG_FATAL, "Failed to allocate buffer!"); return 1; } memset(buffer, 0, memory_block_size); } else { buffers = malloc(sb_globals.threads * sizeof(void *)); if (buffers == NULL) { log_text(LOG_FATAL, "Failed to allocate buffers array!"); return 1; } for (i = 0; i < sb_globals.threads; i++) { #ifdef HAVE_LARGE_PAGES if (memory_hugetlb) buffers[i] = hugetlb_alloc(memory_block_size); else #endif buffers[i] = sb_memalign(memory_block_size, sb_getpagesize()); if (buffers[i] == NULL) { log_text(LOG_FATAL, "Failed to allocate buffer for thread #%d!", i); return 1; } memset(buffers[i], 0, memory_block_size); } } switch (memory_oper) { case SB_MEM_OP_NONE: memory_test.ops.execute_event = memory_access_rnd ? event_rnd_none : event_seq_none; break; case SB_MEM_OP_READ: memory_test.ops.execute_event = memory_access_rnd ? event_rnd_read : event_seq_read; break; case SB_MEM_OP_WRITE: memory_test.ops.execute_event = memory_access_rnd ? event_rnd_write : event_seq_write; break; default: log_text(LOG_FATAL, "Unknown memory request type: %d\n", memory_oper); return 1; } /* Use our own limit on the number of events */ sb_globals.max_events = 0; return 0; } int memory_thread_init(int thread_id) { (void) thread_id; /* unused */ /* Initialize thread-local variables for each thread */ if (memory_total_size > 0) { tls_total_ops = memory_total_size / memory_block_size / sb_globals.threads; } switch (memory_scope) { case SB_MEM_SCOPE_GLOBAL: tls_buf = buffer; break; case SB_MEM_SCOPE_LOCAL: tls_buf = buffers[thread_id]; break; default: log_text(LOG_FATAL, "Invalid memory scope"); return 1; } tls_buf_end = (size_t *) (void *) ((char *) tls_buf + memory_block_size); return 0; } sb_event_t memory_next_event(int thread_id) { sb_event_t req; (void) thread_id; /* unused */ if (memory_total_size > 0 && !tls_total_ops--) { req.type = SB_REQ_TYPE_NULL; return req; } req.type = SB_REQ_TYPE_MEMORY; return req; } /* Use either 32- or 64-bit primitives depending on the native word size. ConcurrencyKit ensures the corresponding loads/stores are not optimized away by the compiler. */ #if SIZEOF_SIZE_T == 4 # define SIZE_T_LOAD(ptr) ck_pr_load_32((uint32_t *)(ptr)) # define SIZE_T_STORE(ptr,val) ck_pr_store_32((uint32_t *)(ptr),(uint32_t)(val)) #elif SIZEOF_SIZE_T == 8 # define SIZE_T_LOAD(ptr) ck_pr_load_64((uint64_t *)(ptr)) # define SIZE_T_STORE(ptr,val) ck_pr_store_64((uint64_t *)(ptr),(uint64_t)(val)) #else # error Unsupported platform. #endif int event_rnd_none(sb_event_t *req, int thread_id) { (void) req; /* unused */ (void) thread_id; /* unused */ for (ssize_t i = 0; i < memory_block_size; i += SIZEOF_SIZE_T) { size_t offset = (volatile size_t) (sb_rand_uniform_double() * (memory_block_size / SIZEOF_SIZE_T)); (void) offset; /* unused */ /* nop */ } return 0; } int event_rnd_read(sb_event_t *req, int thread_id) { (void) req; /* unused */ (void) thread_id; /* unused */ for (ssize_t i = 0; i < memory_block_size; i += SIZEOF_SIZE_T) { size_t offset = (size_t) (sb_rand_uniform_double() * (memory_block_size / SIZEOF_SIZE_T)); size_t val = SIZE_T_LOAD(tls_buf + offset); (void) val; /* unused */ } return 0; } int event_rnd_write(sb_event_t *req, int thread_id) { (void) req; /* unused */ (void) thread_id; /* unused */ for (ssize_t i = 0; i < memory_block_size; i += SIZEOF_SIZE_T) { size_t offset = (size_t) (sb_rand_uniform_double() * (memory_block_size / SIZEOF_SIZE_T)); SIZE_T_STORE(tls_buf + offset, i); } return 0; } int event_seq_none(sb_event_t *req, int thread_id) { (void) req; /* unused */ (void) thread_id; /* unused */ for (size_t *buf = tls_buf, *end = buf + memory_block_size / SIZEOF_SIZE_T; buf < end; buf++) { ck_pr_barrier(); /* nop */ } return 0; } int event_seq_read(sb_event_t *req, int thread_id) { (void) req; /* unused */ (void) thread_id; /* unused */ for (size_t *buf = tls_buf, *end = buf + memory_block_size / SIZEOF_SIZE_T; buf < end; buf++) { size_t val = SIZE_T_LOAD(buf); (void) val; /* unused */ } return 0; } int event_seq_write(sb_event_t *req, int thread_id) { (void) req; /* unused */ (void) thread_id; /* unused */ for (size_t *buf = tls_buf, *end = buf + memory_block_size / SIZEOF_SIZE_T; buf < end; buf++) { SIZE_T_STORE(buf, end - buf); } return 0; } void memory_print_mode(void) { char *str; log_text(LOG_NOTICE, "Running memory speed test with the following options:"); log_text(LOG_NOTICE, " block size: %ldKiB", (long)(memory_block_size / 1024)); log_text(LOG_NOTICE, " total size: %ldMiB", (long)(memory_total_size / 1024 / 1024)); switch (memory_oper) { case SB_MEM_OP_READ: str = "read"; break; case SB_MEM_OP_WRITE: str = "write"; break; case SB_MEM_OP_NONE: str = "none"; break; default: str = "(unknown)"; break; } log_text(LOG_NOTICE, " operation: %s", str); switch (memory_scope) { case SB_MEM_SCOPE_GLOBAL: str = "global"; break; case SB_MEM_SCOPE_LOCAL: str = "local"; break; default: str = "(unknown)"; break; } log_text(LOG_NOTICE, " scope: %s", str); log_text(LOG_NOTICE, ""); } /* Print intermediate test statistics. */ void memory_report_intermediate(sb_stat_t *stat) { const double megabyte = 1024.0 * 1024.0; log_timestamp(LOG_NOTICE, stat->time_total, "%4.2f MiB/sec", stat->events * memory_block_size / megabyte / stat->time_interval); } /* Print cumulative test statistics. */ void memory_report_cumulative(sb_stat_t *stat) { const double megabyte = 1024.0 * 1024.0; log_text(LOG_NOTICE, "Total operations: %" PRIu64 " (%8.2f per second)\n", stat->events, stat->events / stat->time_interval); if (memory_oper != SB_MEM_OP_NONE) { const double mb = stat->events * memory_block_size / megabyte; log_text(LOG_NOTICE, "%4.2f MiB transferred (%4.2f MiB/sec)\n", mb, mb / stat->time_interval); } sb_report_cumulative(stat); } #ifdef HAVE_LARGE_PAGES /* Allocate memory from HugeTLB pool */ void * hugetlb_alloc(size_t size) { int shmid; void *ptr; struct shmid_ds buf; /* Align block size to my_large_page_size */ size = ((size - 1) & ~LARGE_PAGE_SIZE) + LARGE_PAGE_SIZE; shmid = shmget(IPC_PRIVATE, size, SHM_HUGETLB | SHM_R | SHM_W); if (shmid < 0) { log_errno(LOG_FATAL, "Failed to allocate %zd bytes from HugeTLB memory.", size); return NULL; } ptr = shmat(shmid, NULL, 0); if (ptr == (void *)-1) { log_errno(LOG_FATAL, "Failed to attach shared memory segment,"); shmctl(shmid, IPC_RMID, &buf); return NULL; } /* Remove the shared memory segment so that it will be automatically freed after memory is detached or process exits */ shmctl(shmid, IPC_RMID, &buf); return ptr; } #endif sysbench-1.0.18/src/tests/memory/Makefile.am0000600000175000017500000000163613553247311016522 0ustar jpjp# Copyright (C) 2004 MySQL AB # Copyright (C) 2004-2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA noinst_LIBRARIES = libsbmemory.a libsbmemory_a_SOURCES = sb_memory.c ../sb_memory.h libsbmemory_a_CPPFLAGS = $(AM_CPPFLAGS) sysbench-1.0.18/src/tests/fileio/0000700000175000017500000000000013553247311014415 5ustar jpjpsysbench-1.0.18/src/tests/fileio/crc32tbl.h0000600000175000017500000007355013553247311016220 0ustar jpjp/* crc32.h -- tables for rapid CRC calculation * Generated automatically by crc32.c */ local const unsigned long FAR crc_table[TBLS][256] = { { 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, 0x2d02ef8dUL #ifdef BYFOUR }, { 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, 0x9324fd72UL }, { 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, 0xbe9834edUL }, { 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, 0xde0506f1UL }, { 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, 0x8def022dUL }, { 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, 0x72fd2493UL }, { 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, 0xed3498beUL }, { 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, 0xf10605deUL #endif } }; sysbench-1.0.18/src/tests/fileio/CMakeLists.txt0000600000175000017500000000161013553247311017155 0ustar jpjp# Copyright (C) 2008 MySQL AB # Copyright (C) 2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/tests) ADD_LIBRARY(sbfileio sb_fileio.c crc32.c) sysbench-1.0.18/src/tests/fileio/crc32.c0000600000175000017500000002245713553247311015511 0ustar jpjp/* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * Thanks to Rodney Brown for his contribution of faster * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing * tables for updating the shift register in one step with three exclusive-ors * instead of four steps with four exclusive-ors. This results about a factor * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. */ /* @(#) $Id$ */ #ifdef MAKECRCH # include # ifndef DYNAMIC_CRC_TABLE # define DYNAMIC_CRC_TABLE # endif /* !DYNAMIC_CRC_TABLE */ #endif /* MAKECRCH */ #define local static #define STDC #define FAR #define ZEXPORT #define Z_NULL 0 #define OF(args) args #include "crc32.h" #ifndef _WIN32 #define ptrdiff_t long #else #include #endif /* Find a four-byte integer type for crc32_little() and crc32_big(). */ #ifndef NOBYFOUR # ifdef STDC /* need ANSI C limits.h to determine sizes */ # include # define BYFOUR # if (UINT_MAX == 0xffffffffUL) typedef unsigned int u4; # else # if (ULONG_MAX == 0xffffffffUL) typedef unsigned long u4; # else # if (USHRT_MAX == 0xffffffffUL) typedef unsigned short u4; # else # undef BYFOUR /* can't find a four-byte integer type! */ # endif # endif # endif # endif /* STDC */ #endif /* !NOBYFOUR */ /* Definitions for doing the crc four data bytes at a time. */ #ifdef BYFOUR # define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ (((w)&0xff00)<<8)+(((w)&0xff)<<24)) local unsigned long crc32_little OF((unsigned long, const unsigned char FAR *, unsigned)); local unsigned long crc32_big OF((unsigned long, const unsigned char FAR *, unsigned)); # define TBLS 8 #else # define TBLS 1 #endif /* BYFOUR */ #ifdef DYNAMIC_CRC_TABLE local int crc_table_empty = 1; local unsigned long FAR crc_table[TBLS][256]; local void make_crc_table OF((void)); #ifdef MAKECRCH local void write_table OF((FILE *, const unsigned long FAR *)); #endif /* MAKECRCH */ /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. Polynomials over GF(2) are represented in binary, one bit per coefficient, with the lowest powers in the most significant bit. Then adding polynomials is just exclusive-or, and multiplying a polynomial by x is a right shift by one. If we call the above polynomial p, and represent a byte as the polynomial q, also with the lowest power in the most significant bit (so the byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, where a mod b means the remainder after dividing a by b. This calculation is done using the shift-register method of multiplying and taking the remainder. The register is initialized to zero, and for each incoming bit, x^32 is added mod p to the register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x (which is shifting right by one and adding x^32 mod p if the bit shifted out is a one). We start with the highest power (least significant bit) of q and repeat for all eight bits of q. The first table is simply the CRC of all possible eight bit values. This is all the information needed to generate CRCs on data a byte at a time for all combinations of CRC register values and incoming bytes. The remaining tables allow for word-at-a-time CRC calculation for both big-endian and little- endian machines, where a word is four bytes. */ local void make_crc_table() { unsigned long c; int n, k; unsigned long poly; /* polynomial exclusive-or pattern */ /* terms of polynomial defining this crc (except x^32): */ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; /* make exclusive-or pattern from polynomial (0xedb88320UL) */ poly = 0UL; for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) poly |= 1UL << (31 - p[n]); /* generate a crc for every 8-bit value */ for (n = 0; n < 256; n++) { c = (unsigned long)n; for (k = 0; k < 8; k++) c = c & 1 ? poly ^ (c >> 1) : c >> 1; crc_table[0][n] = c; } #ifdef BYFOUR /* generate crc for each value followed by one, two, and three zeros, and then the byte reversal of those as well as the first table */ for (n = 0; n < 256; n++) { c = crc_table[0][n]; crc_table[4][n] = REV(c); for (k = 1; k < 4; k++) { c = crc_table[0][c & 0xff] ^ (c >> 8); crc_table[k][n] = c; crc_table[k + 4][n] = REV(c); } } #endif /* BYFOUR */ crc_table_empty = 0; #ifdef MAKECRCH /* write out CRC tables to crc32.h */ { FILE *out; out = fopen("crc32.h", "w"); if (out == NULL) return; fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); fprintf(out, "local const unsigned long FAR "); fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); write_table(out, crc_table[0]); # ifdef BYFOUR fprintf(out, "#ifdef BYFOUR\n"); for (k = 1; k < 8; k++) { fprintf(out, " },\n {\n"); write_table(out, crc_table[k]); } fprintf(out, "#endif\n"); # endif /* BYFOUR */ fprintf(out, " }\n};\n"); fclose(out); } #endif /* MAKECRCH */ } #ifdef MAKECRCH local void write_table(out, table) FILE *out; const unsigned long FAR *table; { int n; for (n = 0; n < 256; n++) fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); } #endif /* MAKECRCH */ #else /* !DYNAMIC_CRC_TABLE */ /* ======================================================================== * Tables of CRC-32s of all single-byte values, made by make_crc_table(). */ #include "crc32tbl.h" #endif /* DYNAMIC_CRC_TABLE */ /* ========================================================================= */ #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 /* ========================================================================= */ unsigned long ZEXPORT crc32(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { if (buf == Z_NULL) return 0UL; #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ #ifdef BYFOUR if (sizeof(void *) == sizeof(ptrdiff_t)) { u4 endian; endian = 1; if (*((unsigned char *)(&endian))) return crc32_little(crc, buf, len); else return crc32_big(crc, buf, len); } #endif /* BYFOUR */ crc = crc ^ 0xffffffffUL; while (len >= 8) { DO8; len -= 8; } if (len) do { DO1; } while (--len); return crc ^ 0xffffffffUL; } #ifdef BYFOUR /* ========================================================================= */ #define DOLIT4 c ^= *buf4++; \ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 /* ========================================================================= */ local unsigned long crc32_little(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register u4 c; register const u4 FAR *buf4; c = (u4)crc; c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); len--; } buf4 = (const u4 FAR *)(void *)buf; while (len >= 32) { DOLIT32; len -= 32; } while (len >= 4) { DOLIT4; len -= 4; } buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); } while (--len); c = ~c; return (unsigned long)c; } /* ========================================================================= */ #define DOBIG4 c ^= *++buf4; \ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 /* ========================================================================= */ local unsigned long crc32_big(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register u4 c; register const u4 FAR *buf4; c = REV((u4)crc); c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); len--; } buf4 = (const u4 FAR *)(void *)buf; buf4--; while (len >= 32) { DOBIG32; len -= 32; } while (len >= 4) { DOBIG4; len -= 4; } buf4++; buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); } while (--len); c = ~c; return (unsigned long)(REV(c)); } #endif /* BYFOUR */ sysbench-1.0.18/src/tests/fileio/sb_fileio.c0000600000175000017500000014362413553247311016530 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2018 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 #include "sb_win.h" #endif #ifdef STDC_HEADERS # include # include # include #endif #ifdef HAVE_UNISTD_H # include # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_FCNTL_H # include #endif #ifdef HAVE_ERRNO_H # include #endif #ifdef HAVE_LIBAIO # include #endif #ifdef HAVE_SYS_MMAN_H # include #endif #ifdef _WIN32 # include # include # include # define S_IRUSR _S_IREAD # define S_IWUSR _S_IWRITE # define HAVE_MMAP #endif #include "sysbench.h" #include "crc32.h" #include "sb_histogram.h" #include "sb_rand.h" #include "sb_util.h" /* Lengths of the checksum and the offset fields in a block */ #define FILE_CHECKSUM_LENGTH sizeof(int) #define FILE_OFFSET_LENGTH sizeof(long) #ifdef _WIN32 typedef HANDLE FILE_DESCRIPTOR; #define VALID_FILE(fd) (fd != INVALID_HANDLE_VALUE) #define SB_INVALID_FILE INVALID_HANDLE_VALUE #define FD_FMT "%p" #define MAP_SHARED 0 #define PROT_READ 1 #define PROT_WRITE 2 #define MAP_FAILED NULL void *mmap(void *addr, size_t len, int prot, int flags, FILE_DESCRIPTOR fd, long long off); int munmap(void *addr, size_t size); #else typedef int FILE_DESCRIPTOR; #define VALID_FILE(fd) (fd >= 0) #define SB_INVALID_FILE (-1) #define FD_FMT "%d" #endif /* Supported operations in request */ typedef enum { MODE_READ, MODE_WRITE, MODE_REWRITE, MODE_RND_READ, MODE_RND_WRITE, MODE_RND_RW, MODE_MIXED } file_test_mode_t; /* fsync modes */ typedef enum { FSYNC_ALL, FSYNC_DATA } file_fsync_mode_t; /* File I/O modes */ typedef enum { FILE_IO_MODE_SYNC, FILE_IO_MODE_ASYNC, FILE_IO_MODE_MMAP } file_io_mode_t; typedef enum { SB_FILE_FLAG_SYNC = 1, SB_FILE_FLAG_DSYNC = 2, SB_FILE_FLAG_DIRECTIO = 4 } file_flags_t; #ifdef HAVE_LIBAIO /* Per-thread async I/O context */ typedef struct { io_context_t io_ctxt; /* AIO context */ unsigned int nrequests; /* Current number of queued I/O requests */ struct io_event *events; /* Array of events */ } sb_aio_context_t; /* Async I/O operation */ typedef struct { struct iocb iocb; sb_file_op_t type; ssize_t len; } sb_aio_oper_t; static sb_aio_context_t *aio_ctxts; #endif typedef struct { void *buffer; unsigned int buffer_file_id; long long buffer_pos; } sb_per_thread_t; static sb_per_thread_t *per_thread; /* Test options */ static unsigned int num_files; static long long total_size; static long long file_size; static int file_block_size; static file_flags_t file_extra_flags; static int file_fsync_freq; static int file_fsync_all; static int file_fsync_end; static file_fsync_mode_t file_fsync_mode; static float file_rw_ratio; static int file_merged_requests; static long long file_request_size; static file_io_mode_t file_io_mode; #ifdef HAVE_LIBAIO static unsigned int file_async_backlog; #endif /* statistical and other "local" variables */ static long long position; /* current position in file */ static unsigned int current_file; /* current file */ static unsigned int fsynced_file; /* file number to be fsynced (periodic) */ static int is_dirty; /* any writes after last fsync series ? */ static int read_ops; static int write_ops; static int other_ops; static int last_other_ops; static unsigned int req_performed; /* number of requests done */ static unsigned long long bytes_read; static unsigned long long last_bytes_read; static unsigned long long bytes_written; static unsigned long long last_bytes_written; static const double megabyte = 1024.0 * 1024.0; #ifdef HAVE_MMAP /* Array of file mappings */ static void **mmaps; static unsigned long file_page_mask; #endif /* Array of file descriptors */ static FILE_DESCRIPTOR *files; /* test mode type */ static file_test_mode_t test_mode; /* Previous request needed for validation */ static sb_file_request_t prev_req; static sb_arg_t fileio_args[] = { SB_OPT("file-num", "number of files to create", "128", INT), SB_OPT("file-block-size", "block size to use in all IO operations", "16384", INT), SB_OPT("file-total-size", "total size of files to create", "2G", SIZE), SB_OPT("file-test-mode", "test mode {seqwr, seqrewr, seqrd, rndrd, rndwr, rndrw}", NULL, STRING), SB_OPT("file-io-mode", "file operations mode {sync,async,mmap}", "sync", STRING), #ifdef HAVE_LIBAIO SB_OPT("file-async-backlog", "number of asynchronous operatons to queue per thread", "128", INT), #endif SB_OPT("file-extra-flags", "list of additional flags to use to open files {sync,dsync,direct}", "", LIST), SB_OPT("file-fsync-freq", "do fsync() after this number of requests " "(0 - don't use fsync())", "100", INT), SB_OPT("file-fsync-all", "do fsync() after each write operation", "off", BOOL), SB_OPT("file-fsync-end", "do fsync() at the end of test", "on", BOOL), SB_OPT("file-fsync-mode", "which method to use for synchronization {fsync, fdatasync}", "fsync", STRING), SB_OPT("file-merged-requests", "merge at most this number of IO requests " "if possible (0 - don't merge)", "0", INT), SB_OPT("file-rw-ratio", "reads/writes ratio for combined test", "1.5", DOUBLE), SB_OPT_END }; /* fileio test commands */ static int file_cmd_prepare(void); static int file_cmd_cleanup(void); /* fileio test operations */ static int file_init(void); static void file_print_mode(void); static int file_prepare(void); static sb_event_t file_next_event(int thread_id); static int file_execute_event(sb_event_t *, int); static int file_thread_done(int); static int file_done(void); static void file_report_intermediate(sb_stat_t *); static void file_report_cumulative(sb_stat_t *); static sb_test_t fileio_test = { .sname = "fileio", .lname = "File I/O test", .ops = { .init = file_init, .prepare = file_prepare, .print_mode = file_print_mode, .next_event = file_next_event, .execute_event = file_execute_event, .report_intermediate = file_report_intermediate, .report_cumulative = file_report_cumulative, .thread_done = file_thread_done, .done = file_done }, .builtin_cmds = { .prepare = file_cmd_prepare, .cleanup = file_cmd_cleanup }, .args = fileio_args }; static int create_files(void); static int remove_files(void); static int parse_arguments(void); static void clear_stats(void); static void init_vars(void); static sb_event_t file_get_seq_request(void); static sb_event_t file_get_rnd_request(int thread_id); static void check_seq_req(sb_file_request_t *, sb_file_request_t *); static const char *get_io_mode_str(file_io_mode_t mode); static const char *get_test_mode_str(file_test_mode_t mode); static void file_fill_buffer(unsigned char *, unsigned int, size_t); static int file_validate_buffer(unsigned char *, unsigned int, size_t); /* File operation wrappers */ static int file_do_fsync(unsigned int, int); static int file_fsync(unsigned int, int); static ssize_t file_pread(unsigned int, void *, ssize_t, long long, int); static ssize_t file_pwrite(unsigned int, void *, ssize_t, long long, int); #ifdef HAVE_LIBAIO static int file_async_init(void); static int file_async_done(void); static int file_submit_or_wait(struct iocb *, sb_file_op_t, ssize_t, int); static int file_wait(int, long); #endif #ifdef HAVE_MMAP static int file_mmap_prepare(void); static int file_mmap_done(void); #endif /* Portability wrappers */ static unsigned long sb_get_allocation_granularity(void); static void sb_free_memaligned(void *buf); static FILE_DESCRIPTOR sb_open(const char *); static int sb_create(const char *); int register_test_fileio(sb_list_t *tests) { SB_LIST_ADD_TAIL(&fileio_test.listitem, tests); return 0; } int file_init(void) { if (parse_arguments()) return 1; files = (FILE_DESCRIPTOR *)malloc(num_files * sizeof(FILE_DESCRIPTOR)); if (files == NULL) { log_text(LOG_FATAL, "Memory allocation failure."); return 1; } #ifdef HAVE_LIBAIO if (file_async_init()) return 1; #endif init_vars(); clear_stats(); return 0; } int file_prepare(void) { unsigned int i; char file_name[512]; for (i=0; i < num_files; i++) { snprintf(file_name, sizeof(file_name), "test_file.%d",i); /* remove test files for creation test if they exist */ if (test_mode == MODE_WRITE) { unlink(file_name); if (sb_create(file_name)) { log_errno(LOG_FATAL, "Cannot create file '%s'", file_name); return 1; } } log_text(LOG_DEBUG, "Opening file: %s", file_name); files[i] = sb_open(file_name); if (!VALID_FILE(files[i])) { log_errno(LOG_FATAL, "Cannot open file '%s'", file_name); log_text(LOG_WARNING, "Did you forget to run the prepare step?"); return 1; } if (test_mode == MODE_WRITE) continue; /* Validate file size */ struct stat buf; if (fstat(files[i], &buf)) { log_errno(LOG_FATAL, "fstat() failed on file '%s'", file_name); return 1; } if (buf.st_size < file_size) { char ss1[16], ss2[16]; log_text(LOG_FATAL, "Size of file '%s' is %sB, but at least %sB is expected.", file_name, sb_print_value_size(ss1, sizeof(ss1), buf.st_size), sb_print_value_size(ss2, sizeof(ss2), file_size)); log_text(LOG_WARNING, "Did you run 'prepare' with different --file-total-size or " "--file-num values?"); return 1; } } #ifdef HAVE_MMAP if (file_mmap_prepare()) return 1; #endif return 0; } int file_done(void) { unsigned int i; for (i = 0; i < num_files; i++) #ifndef _WIN32 close(files[i]); #else CloseHandle(files[i]); #endif #ifdef HAVE_LIBAIO if (file_async_done()) return 1; #endif #ifdef HAVE_MMAP if (file_mmap_done()) return 1; #endif for (i = 0; i < sb_globals.threads; i++) { if (per_thread[i].buffer != NULL) sb_free_memaligned(per_thread[i].buffer); } free(per_thread); return 0; } sb_event_t file_next_event(int thread_id) { if (test_mode == MODE_WRITE || test_mode == MODE_REWRITE || test_mode == MODE_READ) return file_get_seq_request(); return file_get_rnd_request(thread_id); } /* Get sequential read or write request */ sb_event_t file_get_seq_request(void) { sb_event_t sb_req; sb_file_request_t *file_req = &sb_req.u.file_request; sb_req.type = SB_REQ_TYPE_FILE; SB_THREAD_MUTEX_LOCK(); /* assume function is called with correct mode always */ if (test_mode == MODE_WRITE || test_mode == MODE_REWRITE) file_req->operation = FILE_OP_TYPE_WRITE; else file_req->operation = FILE_OP_TYPE_READ; /* See whether it's time to fsync file(s) */ if (file_fsync_freq != 0 && file_req->operation == FILE_OP_TYPE_WRITE && is_dirty && req_performed % file_fsync_freq == 0) { file_req->operation = FILE_OP_TYPE_FSYNC; file_req->file_id = fsynced_file; file_req->pos = 0; file_req->size = 0; fsynced_file++; if (fsynced_file == num_files) { fsynced_file = 0; is_dirty = 0; } SB_THREAD_MUTEX_UNLOCK(); return sb_req; } req_performed++; if (file_req->operation == FILE_OP_TYPE_WRITE) is_dirty = 1; /* Rewind to the first file if all files are processed */ if (current_file == num_files) { position= 0; current_file= 0; } file_req->file_id = current_file; file_req->pos = position; file_req->size = SB_MIN(file_request_size, file_size - position); position += file_req->size; /* scroll to the next file if not already out of bound */ if (position == file_size) { current_file++; position=0; } if (sb_globals.validate) { check_seq_req(&prev_req, file_req); prev_req = *file_req; } SB_THREAD_MUTEX_UNLOCK(); return sb_req; } /* Request generatior for random tests */ sb_event_t file_get_rnd_request(int thread_id) { sb_event_t sb_req; sb_file_request_t *file_req = &sb_req.u.file_request; unsigned long long tmppos; int mode = test_mode; unsigned int i; sb_req.type = SB_REQ_TYPE_FILE; SB_THREAD_MUTEX_LOCK(); /* Convert mode for combined tests. Locking to get consistent values We have to use "real" values for mixed test */ if (test_mode==MODE_RND_RW) { if ((double)(read_ops + 1) / (write_ops + 1) < file_rw_ratio) mode=MODE_RND_READ; else mode=MODE_RND_WRITE; } /* is_dirty is only set if writes are done and cleared after all files are synced */ if (file_fsync_freq != 0 && is_dirty) { if (req_performed % file_fsync_freq == 0) { file_req->operation = FILE_OP_TYPE_FSYNC; file_req->file_id = fsynced_file; file_req->pos = 0; file_req->size = 0; fsynced_file++; if (fsynced_file == num_files) { fsynced_file = 0; is_dirty = 0; } SB_THREAD_MUTEX_UNLOCK(); return sb_req; } } if (mode==MODE_RND_WRITE) /* mode shall be WRITE or RND_WRITE only */ file_req->operation = FILE_OP_TYPE_WRITE; else file_req->operation = FILE_OP_TYPE_READ; retry: tmppos = (long long) (sb_rand_uniform_double() * total_size); tmppos = tmppos - (tmppos % (long long) file_block_size); file_req->file_id = (int) (tmppos / (long long) file_size); file_req->pos = (long long) (tmppos % (long long) file_size); file_req->size = SB_MIN(file_block_size, file_size - file_req->pos); if (sb_globals.validate) { /* For the multi-threaded validation test we have to make sure the block is not being used by another thread */ for (i = 0; i < sb_globals.threads; i++) { if (i != (unsigned) thread_id && per_thread[i].buffer_file_id == file_req->file_id && per_thread[i].buffer_pos == file_req->pos) goto retry; } } per_thread[thread_id].buffer_file_id = file_req->file_id; per_thread[thread_id].buffer_pos = file_req->pos; req_performed++; if (file_req->operation == FILE_OP_TYPE_WRITE) is_dirty = 1; SB_THREAD_MUTEX_UNLOCK(); return sb_req; } int file_execute_event(sb_event_t *sb_req, int thread_id) { FILE_DESCRIPTOR fd; sb_file_request_t *file_req = &sb_req->u.file_request; if (sb_globals.debug) { log_text(LOG_DEBUG, "Executing request, operation: %d, file_id: %d, pos: %d, " "size: %d", file_req->operation, file_req->file_id, (int)file_req->pos, (int)file_req->size); } /* Check request parameters */ if (file_req->file_id > num_files) { log_text(LOG_FATAL, "Incorrect file id in request: %u", file_req->file_id); return 1; } if (file_req->pos + file_req->size > file_size) { log_text(LOG_FATAL, "I/O request exceeds file size. " "file id: %d file size: %lld req offset: %lld req size: %lld", file_req->file_id, (long long) file_size, (long long) file_req->pos, (long long) file_req->size); return 1; } fd = files[file_req->file_id]; switch (file_req->operation) { case FILE_OP_TYPE_NULL: log_text(LOG_FATAL, "Execute of NULL request called !, aborting"); return 1; case FILE_OP_TYPE_WRITE: /* Store checksum and offset in a buffer when in validation mode */ if (sb_globals.validate) file_fill_buffer(per_thread[thread_id].buffer, file_req->size, file_req->pos); if(file_pwrite(file_req->file_id, per_thread[thread_id].buffer, file_req->size, file_req->pos, thread_id) != (ssize_t)file_req->size) { log_errno(LOG_FATAL, "Failed to write file! file: " FD_FMT " pos: %lld", fd, (long long)file_req->pos); return 1; } /* Check if we have to fsync each write operation */ if (file_fsync_all && file_fsync(file_req->file_id, thread_id)) return 1; /* In async mode stats will me updated on AIO requests completion */ if (file_io_mode != FILE_IO_MODE_ASYNC) { SB_THREAD_MUTEX_LOCK(); write_ops++; bytes_written += file_req->size; SB_THREAD_MUTEX_UNLOCK(); } break; case FILE_OP_TYPE_READ: if(file_pread(file_req->file_id, per_thread[thread_id].buffer, file_req->size, file_req->pos, thread_id) != (ssize_t)file_req->size) { log_errno(LOG_FATAL, "Failed to read file! file: " FD_FMT " pos: %lld", fd, (long long)file_req->pos); return 1; } /* Validate block if run with validation enabled */ if (sb_globals.validate && file_validate_buffer(per_thread[thread_id].buffer, file_req->size, file_req->pos)) { log_text(LOG_FATAL, "Validation failed on file " FD_FMT ", block offset %lld, exiting...", file_req->file_id, (long long) file_req->pos); return 1; } /* In async mode stats will me updated on AIO requests completion */ if(file_io_mode != FILE_IO_MODE_ASYNC) { SB_THREAD_MUTEX_LOCK(); read_ops++; bytes_read += file_req->size; SB_THREAD_MUTEX_UNLOCK(); } break; case FILE_OP_TYPE_FSYNC: /* Ignore fsync requests if we are already fsync'ing each operation */ if (file_fsync_all) break; if(file_fsync(file_req->file_id, thread_id)) return 1; break; default: log_text(LOG_FATAL, "Execute of UNKNOWN file request type called (%d)!, " "aborting", file_req->operation); return 1; } return 0; } static void print_file_extra_flags(void) { log_text(LOG_NOTICE, "Extra file open flags: %s%s%s%s", file_extra_flags == 0 ? "(none)" : "", file_extra_flags & SB_FILE_FLAG_SYNC ? "sync " : "", file_extra_flags & SB_FILE_FLAG_DSYNC ? "dsync ": "", file_extra_flags & SB_FILE_FLAG_DIRECTIO ? "directio" : "" ); } void file_print_mode(void) { char sizestr[16]; print_file_extra_flags(); log_text(LOG_NOTICE, "%d files, %sB each", num_files, sb_print_value_size(sizestr, sizeof(sizestr), file_size)); log_text(LOG_NOTICE, "%sB total file size", sb_print_value_size(sizestr, sizeof(sizestr), file_size * num_files)); log_text(LOG_NOTICE, "Block size %sB", sb_print_value_size(sizestr, sizeof(sizestr), file_block_size)); if (file_merged_requests > 0) log_text(LOG_NOTICE, "Merging requests up to %sB for sequential IO.", sb_print_value_size(sizestr, sizeof(sizestr), file_request_size)); switch (test_mode) { case MODE_RND_WRITE: case MODE_RND_READ: case MODE_RND_RW: log_text(LOG_NOTICE, "Number of IO requests: %" PRIu64, sb_globals.max_events); log_text(LOG_NOTICE, "Read/Write ratio for combined random IO test: %2.2f", file_rw_ratio); break; default: break; } if (file_fsync_freq > 0) log_text(LOG_NOTICE, "Periodic FSYNC enabled, calling fsync() each %d requests.", file_fsync_freq); if (file_fsync_end) log_text(LOG_NOTICE, "Calling fsync() at the end of test, Enabled."); if (file_fsync_all) log_text(LOG_NOTICE, "Calling fsync() after each write operation."); log_text(LOG_NOTICE, "Using %s I/O mode", get_io_mode_str(file_io_mode)); if (sb_globals.validate) log_text(LOG_NOTICE, "Using checksums validation."); log_text(LOG_NOTICE, "Doing %s test", get_test_mode_str(test_mode)); } /* Print intermediate test statistics. TODO: remove the mutex, use sb_stat_t and sb_counter_t. */ void file_report_intermediate(sb_stat_t *stat) { unsigned long long diff_read; unsigned long long diff_written; unsigned long long diff_other_ops; SB_THREAD_MUTEX_LOCK(); diff_read = bytes_read - last_bytes_read; diff_written = bytes_written - last_bytes_written; diff_other_ops = other_ops - last_other_ops; last_bytes_read = bytes_read; last_bytes_written = bytes_written; last_other_ops = other_ops; SB_THREAD_MUTEX_UNLOCK(); log_timestamp(LOG_NOTICE, stat->time_total, "reads: %4.2f MiB/s writes: %4.2f MiB/s fsyncs: %4.2f/s " "latency (ms,%u%%): %4.3f", diff_read / megabyte / stat->time_interval, diff_written / megabyte / stat->time_interval, diff_other_ops / stat->time_interval, sb_globals.percentile, SEC2MS(stat->latency_pct)); } /* Print cumulative test statistics. TODO: remove the mutex, use sb_stat_t and sb_counter_t. */ void file_report_cumulative(sb_stat_t *stat) { const double seconds = stat->time_interval; SB_THREAD_MUTEX_LOCK(); log_text(LOG_NOTICE, "\n" "File operations:\n" " reads/s: %4.2f\n" " writes/s: %4.2f\n" " fsyncs/s: %4.2f\n" "\n" "Throughput:\n" " read, MiB/s: %4.2f\n" " written, MiB/s: %4.2f", read_ops / seconds, write_ops / seconds, other_ops / seconds, bytes_read / megabyte / seconds, bytes_written / megabyte / seconds); clear_stats(); SB_THREAD_MUTEX_UNLOCK(); sb_report_cumulative(stat); } /* Return name for I/O mode */ const char *get_io_mode_str(file_io_mode_t mode) { switch (mode) { case FILE_IO_MODE_SYNC: return "synchronous"; case FILE_IO_MODE_ASYNC: return "asynchronous"; case FILE_IO_MODE_MMAP: #if SIZEOF_SIZE_T == 4 return "slow mmaped"; #else return "fast mmaped"; #endif default: break; } return "(unknown)"; } /* Return name for test mode */ const char *get_test_mode_str(file_test_mode_t mode) { switch (mode) { case MODE_WRITE: return "sequential write (creation)"; case MODE_REWRITE: return "sequential rewrite"; case MODE_READ: return "sequential read"; case MODE_RND_READ: return "random read"; case MODE_RND_WRITE: return "random write"; case MODE_RND_RW: return "random r/w"; case MODE_MIXED: return "mixed"; default: break; } return "(unknown)"; } /* Converts the argument of --file-extra-flags to platform-specific open() flags. Returns 1 on error, 0 on success. */ static int convert_extra_flags(file_flags_t extra_flags, int *open_flags) { if (extra_flags == 0) { #ifdef _WIN32 *open_flags = FILE_ATTRIBUTE_NORMAL; #endif } else { *open_flags = 0; if (extra_flags & SB_FILE_FLAG_SYNC) { #ifdef _WIN32 *open_flags |= FILE_FLAG_WRITE_THROUGH; #else *open_flags |= O_SYNC; #endif } if (extra_flags & SB_FILE_FLAG_DSYNC) { #ifdef O_DSYNC *open_flags |= O_DSYNC; #else log_text(LOG_FATAL, "--file-extra-flags=dsync is not supported on this platform."); return 1; #endif } if (extra_flags & SB_FILE_FLAG_DIRECTIO) { #ifdef HAVE_DIRECTIO /* Will call directio(3) later */ #elif defined(O_DIRECT) *open_flags |= O_DIRECT; #elif defined _WIN32 *open_flags |= FILE_FLAG_NO_BUFFERING; #else log_text(LOG_FATAL, "--file-extra-flags=direct is not supported on this platform."); return 1; #endif } if (extra_flags > SB_FILE_FLAG_DIRECTIO) { log_text(LOG_FATAL, "Unknown extra flags value: %d", (int) extra_flags); return 1; } } return 0; } /* Create files of necessary size for test */ int create_files(void) { unsigned int i; int fd; char file_name[512]; long long offset; long long written = 0; sb_timer_t t; double seconds; int flags = 0; log_text(LOG_NOTICE, "%d files, %ldKb each, %ldMb total", num_files, (long)(file_size / 1024), (long)((file_size * num_files) / (1024 * 1024))); log_text(LOG_NOTICE, "Creating files for the test..."); print_file_extra_flags(); if (convert_extra_flags(file_extra_flags, &flags)) return 1; sb_timer_init(&t); sb_timer_start(&t); for (i=0; i < num_files; i++) { snprintf(file_name, sizeof(file_name), "test_file.%d",i); fd = open(file_name, O_CREAT | O_WRONLY | flags, S_IRUSR | S_IWUSR); if (fd < 0) { log_errno(LOG_FATAL, "Can't open file"); return 1; } #ifndef _WIN32 offset = (long long) lseek(fd, 0, SEEK_END); #else offset = (long long) _lseeki64(fd, 0, SEEK_END); #endif if (offset >= file_size) log_text(LOG_NOTICE, "Reusing existing file %s", file_name); else if (offset > 0) log_text(LOG_NOTICE, "Extending existing file %s", file_name); else log_text(LOG_NOTICE, "Creating file %s", file_name); for (; offset < file_size; written += file_block_size, offset += file_block_size) { /* If in validation mode, fill buffer with random values and write checksum. Not called in parallel, so use per_thread[0]. */ if (sb_globals.validate) file_fill_buffer(per_thread[0].buffer, file_block_size, offset); if (write(fd, per_thread[0].buffer, file_block_size) < 0) goto error; } /* fsync files to prevent cache flush from affecting test results */ #ifndef _WIN32 fsync(fd); #else _commit(fd); #endif close(fd); } seconds = NS2SEC(sb_timer_stop(&t)); if (written > 0) log_text(LOG_NOTICE, "%llu bytes written in %.2f seconds (%.2f MiB/sec).", written, seconds, (double) (written / megabyte) / seconds); else log_text(LOG_NOTICE, "No bytes written."); return 0; error: log_errno(LOG_FATAL, "Failed to write file!"); close(fd); return 1; } /* Remove test files */ int remove_files(void) { unsigned int i; char file_name[512]; log_text(LOG_NOTICE, "Removing test files..."); for (i = 0; i < num_files; i++) { snprintf(file_name, sizeof(file_name), "test_file.%d",i); unlink(file_name); } return 0; } /* 'prepare' command for fileio test */ int file_cmd_prepare(void) { if (parse_arguments()) return 1; /* Make sure that files do not exist for 'sequential write' test mode, create test files for other test modes */ if (test_mode == MODE_WRITE) return remove_files(); return create_files(); } /* 'cleanup' command for fileio test */ int file_cmd_cleanup(void) { if (parse_arguments()) return 1; return remove_files(); } void init_vars(void) { position = 0; /* position in file */ current_file = 0; fsynced_file = 0; /* for counting file to be fsynced */ req_performed = 0; is_dirty = 0; if (sb_globals.validate) { prev_req.size = 0; prev_req.operation = FILE_OP_TYPE_NULL; prev_req.file_id = 0; prev_req.pos = 0; } } void clear_stats(void) { read_ops = 0; write_ops = 0; other_ops = 0; last_other_ops = 0; bytes_read = 0; last_bytes_read = 0; bytes_written = 0; last_bytes_written = 0; } /* Before the benchmark is stopped, issue fsync() if --file-fsync-end is used, and wait for all async operations to complete. */ int file_thread_done(int thread_id) { if (file_fsync_end && test_mode != MODE_READ && test_mode != MODE_RND_READ) { for (unsigned i = 0; i < num_files; i++) { if(file_fsync(i, thread_id)) return 1; } } #ifdef HAVE_LIBAIO if (file_io_mode == FILE_IO_MODE_ASYNC && aio_ctxts[thread_id].nrequests > 0) return file_wait(thread_id, aio_ctxts[thread_id].nrequests); #endif return 0; } #ifdef HAVE_LIBAIO /* Allocate async contexts pool */ int file_async_init(void) { unsigned int i; if (file_io_mode != FILE_IO_MODE_ASYNC) return 0; file_async_backlog = sb_get_value_int("file-async-backlog"); if (file_async_backlog <= 0) { log_text(LOG_FATAL, "Invalid value of file-async-backlog: %d", file_async_backlog); return 1; } aio_ctxts = (sb_aio_context_t *)calloc(sb_globals.threads, sizeof(sb_aio_context_t)); for (i = 0; i < sb_globals.threads; i++) { if (io_queue_init(file_async_backlog, &aio_ctxts[i].io_ctxt)) { log_errno(LOG_FATAL, "io_queue_init() failed!"); return 1; } aio_ctxts[i].events = (struct io_event *)malloc(file_async_backlog * sizeof(struct io_event)); if (aio_ctxts[i].events == NULL) { log_errno(LOG_FATAL, "Failed to allocate async I/O context!"); return 1; } } return 0; } /* Destroy async contexts pool */ int file_async_done(void) { unsigned int i; if (file_io_mode != FILE_IO_MODE_ASYNC) return 0; for (i = 0; i < sb_globals.threads; i++) { io_queue_release(aio_ctxts[i].io_ctxt); free(aio_ctxts[i].events); } free(aio_ctxts); return 0; } /* Submit async I/O requests until the length of request queue exceeds the limit. Then wait for at least one request to complete and proceed. */ int file_submit_or_wait(struct iocb *iocb, sb_file_op_t type, ssize_t len, int thread_id) { sb_aio_oper_t *oper; struct iocb *iocbp; oper = (sb_aio_oper_t *)malloc(sizeof(sb_aio_oper_t)); if (oper == NULL) { log_text(LOG_FATAL, "Failed to allocate AIO operation!"); return 1; } memcpy(&oper->iocb, iocb, sizeof(*iocb)); oper->type = type; oper->len = len; iocbp = &oper->iocb; if (io_submit(aio_ctxts[thread_id].io_ctxt, 1, &iocbp) < 1) { log_errno(LOG_FATAL, "io_submit() failed!"); return 1; } aio_ctxts[thread_id].nrequests++; if (aio_ctxts[thread_id].nrequests < file_async_backlog) return 0; return file_wait(thread_id, 1); } /* Wait for at least nreq I/O requests to complete */ int file_wait(int thread_id, long nreq) { long i; long nr; struct io_event *event; sb_aio_oper_t *oper; struct iocb *iocbp; /* Try to read some events */ #ifdef HAVE_OLD_GETEVENTS (void)nreq; /* unused */ nr = io_getevents(aio_ctxts[thread_id].io_ctxt, file_async_backlog, aio_ctxts[thread_id].events, NULL); #else nr = io_getevents(aio_ctxts[thread_id].io_ctxt, nreq, file_async_backlog, aio_ctxts[thread_id].events, NULL); #endif if (nr < 1) { log_errno(LOG_FATAL, "io_getevents() failed!"); return 1; } /* Verify results */ for (i = 0; i < nr; i++) { event = (struct io_event *)aio_ctxts[thread_id].events + i; iocbp = (struct iocb *)(unsigned long)event->obj; oper = (sb_aio_oper_t *)iocbp; switch (oper->type) { case FILE_OP_TYPE_FSYNC: if (event->res != 0) { log_text(LOG_FATAL, "Asynchronous fsync failed!\n"); return 1; } SB_THREAD_MUTEX_LOCK(); other_ops++; SB_THREAD_MUTEX_UNLOCK(); break; case FILE_OP_TYPE_READ: if ((ssize_t)event->res != oper->len) { log_text(LOG_FATAL, "Asynchronous read failed!\n"); return 1; } SB_THREAD_MUTEX_LOCK(); read_ops++; bytes_read += oper->len; SB_THREAD_MUTEX_UNLOCK(); break; case FILE_OP_TYPE_WRITE: if ((ssize_t)event->res != oper->len) { log_text(LOG_FATAL, "Asynchronous write failed!\n"); return 1; } SB_THREAD_MUTEX_LOCK(); write_ops++; bytes_written += oper->len; SB_THREAD_MUTEX_UNLOCK(); break; default: break; } free(oper); aio_ctxts[thread_id].nrequests--; } return 0; } #endif /* HAVE_LIBAIO */ #ifdef HAVE_MMAP /* Initialize data structures required for mmap'ed I/O operations */ int file_mmap_prepare(void) { unsigned int i; if (file_io_mode != FILE_IO_MODE_MMAP) return 0; file_page_mask = ~(sb_get_allocation_granularity() - 1); /* Extend file sizes for sequential write test */ if (test_mode == MODE_WRITE) for (i = 0; i < num_files; i++) { #ifdef _WIN32 HANDLE hFile = files[i]; LARGE_INTEGER offset; offset.QuadPart = file_size; if (!SetFilePointerEx(hFile ,offset ,NULL, FILE_BEGIN)) { log_errno(LOG_FATAL, "SetFilePointerEx() failed on file %d", i); return 1; } if (!SetEndOfFile(hFile)) { log_errno(LOG_FATAL, "SetEndOfFile() failed on file %d", i); return 1; } offset.QuadPart = 0; SetFilePointerEx(hFile ,offset ,NULL, FILE_BEGIN); #else if (ftruncate(files[i], file_size)) { log_errno(LOG_FATAL, "ftruncate() failed on file %d", i); return 1; } #endif } #if SIZEOF_SIZE_T > 4 mmaps = (void **)malloc(num_files * sizeof(void *)); for (i = 0; i < num_files; i++) { mmaps[i] = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, files[i], 0); if (mmaps[i] == MAP_FAILED) { log_errno(LOG_FATAL, "mmap() failed on file %d", i); return 1; } } #else (void)i; /* unused */ #endif return 0; } /* Destroy data structure used by mmap'ed I/O operations */ int file_mmap_done(void) { unsigned int i; if (file_io_mode != FILE_IO_MODE_MMAP) return 0; #if SIZEOF_SIZE_T > 4 for (i = 0; i < num_files; i++) munmap(mmaps[i], file_size); free(mmaps); #else (void)i; /* unused */ #endif return 0; } #endif /* HAVE_MMAP */ int file_do_fsync(unsigned int id, int thread_id) { FILE_DESCRIPTOR fd = files[id]; #ifdef HAVE_LIBAIO struct iocb iocb; #else (void)thread_id; /* unused */ #endif /* FIXME: asynchronous fsync support is missing in Linux kernel at the moment */ if (file_io_mode == FILE_IO_MODE_SYNC || file_io_mode == FILE_IO_MODE_ASYNC #if defined(HAVE_MMAP) && SIZEOF_SIZE_T == 4 /* Use fsync in mmaped mode on 32-bit architectures */ || file_io_mode == FILE_IO_MODE_MMAP #endif ) { if (file_fsync_mode == FSYNC_ALL) #ifndef _WIN32 return fsync(fd); #else return !FlushFileBuffers(fd); #endif #ifdef F_FULLFSYNC return fcntl(fd, F_FULLFSYNC) != -1; #elif defined(HAVE_FDATASYNC) return fdatasync(fd); #else log_text(LOG_ALERT, "Unknown fsync mode: %d", file_fsync_mode); return -1; #endif } #ifdef HAVE_LIBAIO else if (file_io_mode == FILE_IO_MODE_ASYNC) { /* Use asynchronous fsync */ if (file_fsync_mode == FSYNC_ALL) io_prep_fsync(&iocb, fd); else io_prep_fdsync(&iocb, fd); return file_submit_or_wait(&iocb, FILE_OP_TYPE_FSYNC, 0, thread_id); } #endif #ifdef HAVE_MMAP /* Use msync on file on 64-bit architectures */ else if (file_io_mode == FILE_IO_MODE_MMAP) { #ifndef _WIN32 return msync(mmaps[id], file_size, MS_SYNC | MS_INVALIDATE); #else return !FlushViewOfFile(mmaps[id], (size_t) file_size); #endif } #endif return 1; /* Unknown I/O mode */ } int file_fsync(unsigned int id, int thread_id) { if (file_do_fsync(id, thread_id)) { log_errno(LOG_FATAL, "Failed to fsync file! file: " FD_FMT, files[id]); return 1; } SB_THREAD_MUTEX_LOCK(); other_ops++; SB_THREAD_MUTEX_UNLOCK(); return 0; } #ifdef _WIN32 ssize_t pread(HANDLE hFile, void *buf, ssize_t count, long long offset) { DWORD nBytesRead; OVERLAPPED ov = {0}; LARGE_INTEGER li; if(!count) return 0; #ifdef _WIN64 if(count > UINT_MAX) count= UINT_MAX; #endif li.QuadPart = offset; ov.Offset = li.LowPart; ov.OffsetHigh = li.HighPart; if(!ReadFile(hFile, buf, (DWORD)count, &nBytesRead, &ov)) { DWORD lastError = GetLastError(); if(lastError == ERROR_HANDLE_EOF) return 0; return -1; } return nBytesRead; } ssize_t pwrite(HANDLE hFile, const void *buf, size_t count, long long offset) { DWORD nBytesWritten; OVERLAPPED ov = {0}; LARGE_INTEGER li; if(!count) return 0; #ifdef _WIN64 if(count > UINT_MAX) count= UINT_MAX; #endif li.QuadPart = offset; ov.Offset = li.LowPart; ov.OffsetHigh= li.HighPart; if(!WriteFile(hFile, buf, (DWORD)count, &nBytesWritten, &ov)) { return -1; } else return nBytesWritten; } #define MAP_SHARED 0 #define PROT_READ 1 #define PROT_WRITE 2 #define MAP_FAILED NULL void *mmap(void *addr, size_t len, int prot, int flags, FILE_DESCRIPTOR fd, long long off) { DWORD flProtect; DWORD flMap; void *retval; LARGE_INTEGER li; HANDLE hMap; switch(prot) { case PROT_READ: flProtect = PAGE_READONLY; flMap = FILE_MAP_READ; break; case PROT_READ|PROT_WRITE: flProtect = PAGE_READWRITE; flMap = FILE_MAP_ALL_ACCESS; break; default: return MAP_FAILED; } hMap = CreateFileMapping(fd, NULL, flProtect, 0 , 0, NULL); if(hMap == INVALID_HANDLE_VALUE) return MAP_FAILED; li.QuadPart = off; retval = MapViewOfFileEx(hMap, flMap, li.HighPart, li.LowPart, len, NULL); CloseHandle(hMap); return retval; } int munmap(void *start, size_t len) { (void) len; /* unused */ if(UnmapViewOfFile(start)) return 0; return -1; } #endif ssize_t file_pread(unsigned int file_id, void *buf, ssize_t count, long long offset, int thread_id) { FILE_DESCRIPTOR fd = files[file_id]; #ifdef HAVE_MMAP void *start; long long page_addr; long long page_offset; #endif #ifdef HAVE_LIBAIO struct iocb iocb; #else (void)thread_id; /* unused */ #endif if (file_io_mode == FILE_IO_MODE_SYNC) return pread(fd, buf, count, offset); #ifdef HAVE_LIBAIO else if (file_io_mode == FILE_IO_MODE_ASYNC) { /* Use asynchronous read */ io_prep_pread(&iocb, fd, buf, count, offset); if (file_submit_or_wait(&iocb, FILE_OP_TYPE_READ, count, thread_id)) return 0; return count; } #endif #ifdef HAVE_MMAP else if (file_io_mode == FILE_IO_MODE_MMAP) { # if SIZEOF_SIZE_T == 4 /* Create file mapping for each I/O operation on 32-bit platforms */ page_addr = offset & file_page_mask; page_offset = offset - page_addr; start = mmap(NULL, count + page_offset, PROT_READ, MAP_SHARED, fd, page_addr); if (start == MAP_FAILED) return 0; memcpy(buf, (char *)start + page_offset, count); munmap(start, count + page_offset); return count; # else (void)start; /* unused */ (void)page_addr; /* unused */ (void)page_offset; /* unused */ /* We already have all files mapped on 64-bit platforms */ memcpy(buf, (char *)mmaps[file_id] + offset, count); return count; # endif } #endif /* HAVE_MMAP */ return 1; /* Unknown I/O mode */ } ssize_t file_pwrite(unsigned int file_id, void *buf, ssize_t count, long long offset, int thread_id) { FILE_DESCRIPTOR fd = files[file_id]; #ifdef HAVE_MMAP void *start; size_t page_addr; size_t page_offset; #endif #ifdef HAVE_LIBAIO struct iocb iocb; #else (void)thread_id; /* unused */ #endif if (file_io_mode == FILE_IO_MODE_SYNC) return pwrite(fd, buf, count, offset); #ifdef HAVE_LIBAIO else if (file_io_mode == FILE_IO_MODE_ASYNC) { /* Use asynchronous write */ io_prep_pwrite(&iocb, fd, buf, count, offset); if (file_submit_or_wait(&iocb, FILE_OP_TYPE_WRITE, count, thread_id)) return 0; return count; } #endif #ifdef HAVE_MMAP else if (file_io_mode == FILE_IO_MODE_MMAP) { # if SIZEOF_SIZE_T == 4 /* Create file mapping for each I/O operation on 32-bit platforms */ page_addr = offset & file_page_mask; page_offset = offset - page_addr; start = mmap(NULL, count + page_offset, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr); if (start == MAP_FAILED) return 0; memcpy((char *)start + page_offset, buf, count); munmap(start, count + page_offset); return count; # else (void)start; /* unused */ (void)page_addr; /* unused */ (void)page_offset; /* unused */ /* We already have all files mapped on 64-bit platforms */ memcpy((char *)mmaps[file_id] + offset, buf, count); return count; # endif } #endif /* HAVE_MMAP */ return 0; /* Unknown I/O mode */ } /* Parse the command line arguments */ int parse_arguments(void) { char *mode; unsigned int i; num_files = sb_get_value_int("file-num"); if (num_files <= 0) { log_text(LOG_FATAL, "Invalid value for file-num: %d", num_files); return 1; } total_size = sb_get_value_size("file-total-size"); if (total_size <= 0) { log_text(LOG_FATAL, "Invalid value for file-total-size: %lld", (long long)total_size); return 1; } file_size = total_size / num_files; mode = sb_get_value_string("file-test-mode"); /* File test mode is necessary only for 'run' command */ if (!strcmp(sb_globals.cmdname, "run")) { if (mode == NULL) { log_text(LOG_FATAL, "Missing required argument: --file-test-mode\n"); log_text(LOG_NOTICE, "fileio options:"); sb_print_options(fileio_args); return 1; } if (!strcmp(mode, "seqwr")) test_mode = MODE_WRITE; else if (!strcmp(mode, "seqrewr")) test_mode = MODE_REWRITE; else if (!strcmp(mode, "seqrd")) test_mode = MODE_READ; else if (!strcmp(mode, "rndrd")) test_mode = MODE_RND_READ; else if (!strcmp(mode, "rndwr")) test_mode = MODE_RND_WRITE; else if (!strcmp(mode, "rndrw")) test_mode = MODE_RND_RW; else { log_text(LOG_FATAL, "Invalid IO operations mode: %s.", mode); return 1; } } mode = sb_get_value_string("file-io-mode"); if (mode == NULL) mode = "sync"; if (!strcmp(mode, "sync")) file_io_mode = FILE_IO_MODE_SYNC; else if (!strcmp(mode, "async")) { #ifdef HAVE_LIBAIO file_io_mode = FILE_IO_MODE_ASYNC; #else log_text(LOG_FATAL, "asynchronous I/O mode is unsupported on this platform."); return 1; #endif } else if (!strcmp(mode, "mmap")) { #ifdef HAVE_MMAP file_io_mode = FILE_IO_MODE_MMAP; #else log_text(LOG_FATAL, "mmap'ed I/O mode is unsupported on this platform."); return 1; #endif } else { log_text(LOG_FATAL, "unknown I/O mode: %s", mode); return 1; } file_merged_requests = sb_get_value_int("file-merged-requests"); if (file_merged_requests < 0) { log_text(LOG_FATAL, "Invalid value for file-merged-requests: %d.", file_merged_requests); return 1; } file_block_size = sb_get_value_size("file-block-size"); if (file_block_size <= 0) { log_text(LOG_FATAL, "Invalid value for file-block-size: %d.", file_block_size); return 1; } if (file_merged_requests > 0) file_request_size = file_block_size * file_merged_requests; else file_request_size = file_block_size; mode = sb_get_value_string("file-extra-flags"); sb_list_item_t *pos; SB_LIST_FOR_EACH(pos, sb_get_value_list("file-extra-flags")) { const char *val = SB_LIST_ENTRY(pos, value_t, listitem)->data; if (!strcmp(val, "sync")) file_extra_flags |= SB_FILE_FLAG_SYNC; else if (!strcmp(val, "dsync")) file_extra_flags |= SB_FILE_FLAG_DSYNC; else if (!strcmp(val, "direct")) file_extra_flags |= SB_FILE_FLAG_DIRECTIO; else { log_text(LOG_FATAL, "Invalid value for file-extra-flags: %s", mode); return 1; } } file_fsync_freq = sb_get_value_int("file-fsync-freq"); if (file_fsync_freq < 0) { log_text(LOG_FATAL, "Invalid value for file-fsync-freq: %d.", file_fsync_freq); return 1; } file_fsync_end = sb_get_value_flag("file-fsync-end"); file_fsync_all = sb_get_value_flag("file-fsync-all"); /* file-fsync-all overrides file-fsync-end and file-fsync-freq */ if (file_fsync_all) { file_fsync_end = 0; file_fsync_freq = 0; } mode = sb_get_value_string("file-fsync-mode"); if (!strcmp(mode, "fsync")) file_fsync_mode = FSYNC_ALL; else if (!strcmp(mode, "fdatasync")) { #ifdef HAVE_FDATASYNC file_fsync_mode = FSYNC_DATA; #else log_text(LOG_FATAL, "fdatasync() is unavailable on this platform"); return 1; #endif } else { log_text(LOG_FATAL, "Invalid fsync mode: %s.", mode); return 1; } file_rw_ratio = sb_get_value_double("file-rw-ratio"); if (file_rw_ratio < 0) { log_text(LOG_FATAL, "Invalid value for --file-rw-ratio: %f.", file_rw_ratio); return 1; } per_thread = malloc(sizeof(*per_thread) * sb_globals.threads); for (i = 0; i < sb_globals.threads; i++) { per_thread[i].buffer = sb_memalign(file_request_size, sb_getpagesize()); if (per_thread[i].buffer == NULL) { log_text(LOG_FATAL, "Failed to allocate a memory buffer"); return 1; } memset(per_thread[i].buffer, 0, file_request_size); } return 0; } /* check if two requests are sequential */ void check_seq_req(sb_file_request_t *prev_req, sb_file_request_t *r) { /* Do not check fsync operation at the moment */ if (r->operation == FILE_OP_TYPE_FSYNC || r->operation == FILE_OP_TYPE_NULL) return; /* if old request is NULL do not check against it */ if (prev_req->operation == FILE_OP_TYPE_NULL) return; /* check files */ if (r->file_id - prev_req->file_id>1 && !(r->file_id == 0 && prev_req->file_id == num_files-1)) { log_text(LOG_WARNING, "Discovered too large file difference in seq requests!"); return; } if (r->file_id == prev_req->file_id) { if(r->pos - prev_req->pos != prev_req->size) { log_text(LOG_WARNING, "Discovered too large position difference in seq request!"); return; } } else /* if file changed last request has to complete file and new start */ { if ((prev_req->pos + prev_req->size != file_size) || (r->pos != 0)) { log_text(LOG_WARNING, "Invalid file switch found!"); log_text(LOG_WARNING, "Old: file_id: %d, pos: %d size: %d", prev_req->file_id, (int)prev_req->pos, (int)prev_req->size); log_text(LOG_WARNING, "New: file_id: %d, pos: %d size: %d", r->file_id, (int)r->pos, (int)r->size); return; } } } /* Alignment requirement for mmap(). The same as page size, except on Windows (on Windows it has to be 64KB, even if pagesize is only 4 or 8KB) */ unsigned long sb_get_allocation_granularity(void) { #ifdef _WIN32 SYSTEM_INFO info; GetSystemInfo(&info); return info.dwAllocationGranularity; #else return sb_getpagesize(); #endif } static void sb_free_memaligned(void *buf) { #ifdef _WIN32 VirtualFree(buf,0,MEM_FREE); #else free(buf); #endif } static FILE_DESCRIPTOR sb_open(const char *name) { FILE_DESCRIPTOR file; int flags = 0; if (convert_extra_flags(file_extra_flags, &flags)) return SB_INVALID_FILE; #ifndef _WIN32 file = open(name, O_RDWR | flags, S_IRUSR | S_IWUSR); #else file = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, flags, NULL); #endif #ifdef HAVE_DIRECTIO if (VALID_FILE(file) && file_extra_flags & SB_FILE_FLAG_DIRECTIO && directio(file, DIRECTIO_ON)) { log_errno(LOG_FATAL, "directio() failed"); return SB_INVALID_FILE; } #endif return file; } /* Create a file with a given path. Signal an error if the file already exists. Return a non-zero value on error. */ static int sb_create(const char *path) { FILE_DESCRIPTOR file; int res; #ifndef _WIN32 file = open(path, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); res = !VALID_FILE(file); close(file); #else file = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); res = !VALID_FILE(file); CloseHandle(file); #endif return res; } /* Fill buffer with random values and write checksum */ void file_fill_buffer(unsigned char *buf, unsigned int len, size_t offset) { unsigned int i; for (i = 0; i < len - (FILE_CHECKSUM_LENGTH + FILE_OFFSET_LENGTH); i++) buf[i] = sb_rand_uniform_uint64() & 0xFF; /* Store the checksum */ *(int *)(void *)(buf + i) = (int)crc32(0, (unsigned char *)buf, len - (FILE_CHECKSUM_LENGTH + FILE_OFFSET_LENGTH)); /* Store the offset */ *(long *)(void *)(buf + i + FILE_CHECKSUM_LENGTH) = offset; } /* Validate checksum and offset of block read from disk */ int file_validate_buffer(unsigned char *buf, unsigned int len, size_t offset) { unsigned int checksum; unsigned int cs_offset; cs_offset = len - (FILE_CHECKSUM_LENGTH + FILE_OFFSET_LENGTH); checksum = (unsigned int)crc32(0, (unsigned char *)buf, cs_offset); if (checksum != *(unsigned int *)(void *)(buf + cs_offset)) { log_text(LOG_FATAL, "Checksum mismatch in block with offset: %lld", (long long) offset); log_text(LOG_FATAL, " Calculated value: 0x%x Stored value: 0x%x", checksum, *(unsigned int *)(void *)(buf + cs_offset)); return 1; } if (offset != *(size_t *)(void *)(buf + cs_offset + FILE_CHECKSUM_LENGTH)) { log_text(LOG_FATAL, "Offset mismatch in block:"); log_text(LOG_FATAL, " Actual offset: %zu Stored offset: %zu", offset, *(size_t *)(void *)(buf + cs_offset + FILE_CHECKSUM_LENGTH)); return 1; } return 0; } sysbench-1.0.18/src/tests/fileio/crc32.h0000600000175000017500000000026213553247311015504 0ustar jpjp#ifndef CRC32_H #ifdef HAVE_CONFIG_H #include #endif #define CRC32_H extern unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned len); #endif sysbench-1.0.18/src/tests/fileio/Makefile.am0000600000175000017500000000167113553247311016460 0ustar jpjp# Copyright (C) 2004 MySQL AB # Copyright (C) 2004-2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA noinst_LIBRARIES = libsbfileio.a libsbfileio_a_SOURCES = sb_fileio.c ../sb_fileio.h crc32.c crc32.h crc32tbl.h libsbfileio_a_CPPFLAGS = $(AM_CPPFLAGS) sysbench-1.0.18/src/tests/CMakeLists.txt0000600000175000017500000000010613553247311015705 0ustar jpjpINCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) ADD_LIBRARY(sbtests sb_cpu.) sysbench-1.0.18/src/tests/threads/0000700000175000017500000000000013553247311014600 5ustar jpjpsysbench-1.0.18/src/tests/threads/sb_threads.c0000600000175000017500000000753613553247311017077 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 # include "sb_win.h" #endif #ifdef HAVE_PTHREAD_H # include #endif #include "sysbench.h" #include "sb_ck_pr.h" /* How to test scheduler pthread_yield or sched_yield */ #ifdef HAVE_PTHREAD_YIELD #define YIELD pthread_yield #elif defined (_WIN32) #define YIELD SwitchToThread #else #define YIELD sched_yield #endif /* Threads test arguments */ static sb_arg_t threads_args[] = { SB_OPT("thread-yields", "number of yields to do per request", "1000", INT), SB_OPT("thread-locks", "number of locks per thread", "8", INT), SB_OPT_END }; /* Threads test operations */ static int threads_init(void); static int threads_prepare(void); static void threads_print_mode(void); static sb_event_t threads_next_event(int); static int threads_execute_event(sb_event_t *, int); static int threads_cleanup(void); static sb_test_t threads_test = { .sname = "threads", .lname = "Threads subsystem performance test", .ops = { .init = threads_init, .prepare = threads_prepare, .print_mode = threads_print_mode, .next_event = threads_next_event, .execute_event = threads_execute_event, .cleanup = threads_cleanup }, .args = threads_args }; static unsigned int thread_yields; static unsigned int thread_locks; static pthread_mutex_t *test_mutexes; static unsigned int req_performed; int register_test_threads(sb_list_t *tests) { SB_LIST_ADD_TAIL(&threads_test.listitem, tests); return 0; } int threads_init(void) { thread_yields = sb_get_value_int("thread-yields"); thread_locks = sb_get_value_int("thread-locks"); req_performed = 0; return 0; } int threads_prepare(void) { unsigned int i; test_mutexes = (pthread_mutex_t *)malloc(thread_locks * sizeof(pthread_mutex_t)); if (test_mutexes == NULL) { log_text(LOG_FATAL, "Memory allocation failure!"); return 1; } for(i = 0; i < thread_locks; i++) pthread_mutex_init(test_mutexes + i, NULL); return 0; } int threads_cleanup(void) { unsigned int i; for(i=0; i < thread_locks; i++) pthread_mutex_destroy(test_mutexes + i); free(test_mutexes); return 0; } sb_event_t threads_next_event(int thread_id) { sb_event_t sb_req; sb_threads_request_t *threads_req = &sb_req.u.threads_request; (void) thread_id; /* unused */ sb_req.type = SB_REQ_TYPE_THREADS; threads_req->lock_num = ck_pr_faa_uint(&req_performed, 1) % thread_locks; return sb_req; } int threads_execute_event(sb_event_t *sb_req, int thread_id) { unsigned int i; sb_threads_request_t *threads_req = &sb_req->u.threads_request; (void) thread_id; /* unused */ for(i = 0; i < thread_yields; i++) { pthread_mutex_lock(&test_mutexes[threads_req->lock_num]); YIELD(); pthread_mutex_unlock(&test_mutexes[threads_req->lock_num]); } return 0; } void threads_print_mode(void) { log_text(LOG_INFO, "Doing thread subsystem performance test"); log_text(LOG_INFO, "Thread yields per test: %d Locks used: %d", thread_yields, thread_locks); } sysbench-1.0.18/src/tests/threads/CMakeLists.txt0000600000175000017500000000160213553247311017341 0ustar jpjp# Copyright (C) 2008 MySQL AB # Copyright (C) 2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/tests) add_library(sbthreads sb_threads.c) sysbench-1.0.18/src/tests/threads/Makefile.am0000600000175000017500000000164313553247311016642 0ustar jpjp# Copyright (C) 2004 MySQL AB # Copyright (C) 2004-2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA noinst_LIBRARIES = libsbthreads.a libsbthreads_a_SOURCES = sb_threads.c ../sb_threads.h libsbthreads_a_CPPFLAGS = $(AM_CPPFLAGS) sysbench-1.0.18/src/tests/sb_threads.h0000600000175000017500000000175413553247311015446 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_THREADS_H #define SB_THREADS_H /* Threads request definition */ typedef struct { unsigned int lock_num; } sb_threads_request_t; int register_test_threads(sb_list_t *tests); #endif sysbench-1.0.18/src/tests/cpu/0000700000175000017500000000000013553247311013735 5ustar jpjpsysbench-1.0.18/src/tests/cpu/CMakeLists.txt0000600000175000017500000000157213553247311016504 0ustar jpjp# Copyright (C) 2008 MySQL AB # Copyright (C) 2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/tests) ADD_LIBRARY(sbcpu sb_cpu.c) sysbench-1.0.18/src/tests/cpu/sb_cpu.c0000600000175000017500000000616513553247311015366 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 # include "sb_win.h" #endif #ifdef HAVE_MATH_H # include #endif #include #include "sysbench.h" /* CPU test arguments */ static sb_arg_t cpu_args[] = { SB_OPT("cpu-max-prime", "upper limit for primes generator", "10000", INT), SB_OPT_END }; /* CPU test operations */ static int cpu_init(void); static void cpu_print_mode(void); static sb_event_t cpu_next_event(int thread_id); static int cpu_execute_event(sb_event_t *, int); static void cpu_report_cumulative(sb_stat_t *); static int cpu_done(void); static sb_test_t cpu_test = { .sname = "cpu", .lname = "CPU performance test", .ops = { .init = cpu_init, .print_mode = cpu_print_mode, .next_event = cpu_next_event, .execute_event = cpu_execute_event, .report_cumulative = cpu_report_cumulative, .done = cpu_done }, .args = cpu_args }; /* Upper limit for primes */ static unsigned int max_prime; int register_test_cpu(sb_list_t * tests) { SB_LIST_ADD_TAIL(&cpu_test.listitem, tests); return 0; } int cpu_init(void) { int prime_option= sb_get_value_int("cpu-max-prime"); if (prime_option <= 0) { log_text(LOG_FATAL, "Invalid value of cpu-max-prime: %d.", prime_option); return 1; } max_prime= (unsigned int)prime_option; return 0; } sb_event_t cpu_next_event(int thread_id) { sb_event_t req; (void) thread_id; /* unused */ req.type = SB_REQ_TYPE_CPU; return req; } int cpu_execute_event(sb_event_t *r, int thread_id) { unsigned long long c; unsigned long long l; double t; unsigned long long n=0; (void)thread_id; /* unused */ (void)r; /* unused */ /* So far we're using very simple test prime number tests in 64bit */ for(c=3; c < max_prime; c++) { t = sqrt((double)c); for(l = 2; l <= t; l++) if (c % l == 0) break; if (l > t ) n++; } return 0; } void cpu_print_mode(void) { log_text(LOG_INFO, "Doing CPU performance benchmark\n"); log_text(LOG_NOTICE, "Prime numbers limit: %d\n", max_prime); } /* Print cumulative stats. */ void cpu_report_cumulative(sb_stat_t *stat) { log_text(LOG_NOTICE, "CPU speed:"); log_text(LOG_NOTICE, " events per second: %8.2f", stat->events / stat->time_interval); sb_report_cumulative(stat); } int cpu_done(void) { return 0; } sysbench-1.0.18/src/tests/cpu/Makefile.am0000600000175000017500000000161713553247311016000 0ustar jpjp# Copyright (C) 2004 MySQL AB # Copyright (C) 2004-2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA noinst_LIBRARIES = libsbcpu.a libsbcpu_a_SOURCES = sb_cpu.c ../sb_cpu.h libsbcpu_a_CPPFLAGS = $(AM_CPPFLAGS) sysbench-1.0.18/src/tests/Makefile.am0000600000175000017500000000151213553247311015203 0ustar jpjp# Copyright (C) 2004 MySQL AB # Copyright (C) 2004-2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA SUBDIRS = cpu fileio memory threads mutex sysbench-1.0.18/src/sb_options.h0000600000175000017500000000742113553247311014342 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef OPTIONS_H #define OPTIONS_H #include #include #include "sb_list.h" /* Helper option declaration macros */ #define SB_OPT(n, d, v, t) \ { .name = (n), \ .desc = (d), \ .type = SB_ARG_TYPE_##t, \ .value = (v) } #define SB_OPT_END { .type = SB_ARG_TYPE_NULL } /* Option types definition */ typedef enum { SB_ARG_TYPE_NULL, SB_ARG_TYPE_BOOL, SB_ARG_TYPE_INT, SB_ARG_TYPE_SIZE, SB_ARG_TYPE_DOUBLE, SB_ARG_TYPE_STRING, SB_ARG_TYPE_LIST, SB_ARG_TYPE_FILE, SB_ARG_TYPE_MAX } sb_arg_type_t; /* Option validation function */ typedef bool sb_opt_validate_t(const char *, const char *); /* Test option definition */ typedef struct { const char *name; const char *desc; const char *value; sb_arg_type_t type; sb_opt_validate_t *validate; } sb_arg_t; typedef struct { char *data; char ignore; sb_list_item_t listitem; } value_t; typedef struct { char *name; sb_arg_type_t type; sb_list_t values; char ignore; sb_opt_validate_t *validate; sb_list_item_t listitem; } option_t; /* Initilize options library */ int sb_options_init(void); /* Release resource allocated by the options library */ int sb_options_done(void); /* Register set of command line arguments */ int sb_register_arg_set(sb_arg_t *set); /* Set value 'value' of type 'type' for option 'name' */ option_t *set_option(const char *name, const char *value, sb_arg_type_t type); /* Find option specified by 'name' */ option_t *sb_find_option(const char *name); /* Print list of options specified by 'opts' */ void sb_print_options(sb_arg_t *opts); int sb_get_value_flag(const char *name); int sb_get_value_int(const char *name); unsigned long long sb_get_value_size(const char *name); double sb_get_value_double(const char *name); char *sb_get_value_string(const char *name); sb_list_t *sb_get_value_list(const char *name); char *sb_print_value_size(char *buf, unsigned int buflen, double value); int sb_opt_to_flag(option_t *); int sb_opt_to_int(option_t *); unsigned long long sb_opt_to_size(option_t *); double sb_opt_to_double(option_t *); char *sb_opt_to_string(option_t *); sb_list_t *sb_opt_to_list(option_t *); bool sb_opt_copy(const char *to, const char *from); sb_list_item_t *sb_options_enum_start(void); sb_list_item_t *sb_options_enum_next(sb_list_item_t *, option_t **); value_t *new_value(void); option_t *new_option(void); void free_values(sb_list_t *); void free_options(sb_list_t *); value_t *add_value(sb_list_t *, const char *); value_t *find_value(sb_list_t *, const char *); option_t *add_option(sb_list_t *, const char *); option_t *find_option(sb_list_t *, const char *); int remove_value(sb_list_t *, char *); int remove_option(sb_list_t *, char *); sb_list_t *read_config(FILE *, sb_list_t *); int write_config(FILE *, sb_list_t *); #endif /* OPTIONS_H */ sysbench-1.0.18/src/sb_histogram.h0000600000175000017500000000772713553247311014655 0ustar jpjp/* Copyright (C) 2011-2017 Alexey Kopytov. 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SB_HISTOGRAM_H #define SB_HISTOGRAM_H #include #ifdef HAVE_PTHREAD_H # include #endif typedef struct { /* Cumulative histogram array. Updated 'on demand' by sb_histogram_get_pct_intermediate(). Protected by 'lock'. */ uint64_t *cumulative_array; /* Total number of events in cumulative_array. Updated on demand by sb_histogram_get_pct_intermediate(). Protected by 'lock'. */ uint64_t cumulative_nevents; /* Temporary array for intermediate percentile calculations. Protected by 'lock'. */ uint64_t *temp_array; /* Intermediate histogram values are split into multiple slots and updated with atomics. Aggregations into cumulative values is performed by sb_histogram_get_pct_intermediate() function. */ uint64_t **interm_slots; /* Number of elements in each array */ size_t array_size; /* Lower bound of values to track */ double range_min; /* Upper bound of values to track */ double range_max; /* Value to deduct to calculate histogram range based on array element */ double range_deduct; /* Value to multiply to calculate histogram range based array element */ double range_mult; /* rwlock to protect cumulative_array and cumulative_nevents from concurrent updates. */ pthread_rwlock_t lock; } sb_histogram_t; /* Global latency histogram */ extern sb_histogram_t sb_latency_histogram; /* Allocate a new histogram and initialize it with sb_histogram_init(). */ sb_histogram_t *sb_histogram_new(size_t size, double range_min, double range_max); /* Deallocate a histogram allocated with sb_histogram_new(). */ void sb_histogram_delete(sb_histogram_t *h); /* Initialize a new histogram object with a given array size and value bounds. */ int sb_histogram_init(sb_histogram_t *h, size_t size, double range_min, double range_max); /* Update histogram with a given value. */ void sb_histogram_update(sb_histogram_t *h, double value); /* Calculate a given percentile value from the intermediate histogram values, then merge intermediate values into cumulative ones atomically, i.e. in a way that no concurrent updates are lost and will be accounted in either the current or later merge of intermediate clues. */ double sb_histogram_get_pct_intermediate(sb_histogram_t *h, double percentile); /* Merge intermediate histogram values into cumulative ones and calculate a given percentile value from the cumulative array. */ double sb_histogram_get_pct_cumulative(sb_histogram_t *h, double percentile); /* Similar to sb_histogram_get_pct_cumulative(), but also resets cumulative stats right after calculating the returned percentile. The reset happens atomically so that no conucrrent updates are lost after percentile calculation. This is currently used only by 'checkpoint' reports. */ double sb_histogram_get_pct_checkpoint(sb_histogram_t *h, double percentile); /* Print a given histogram to stdout */ void sb_histogram_print(sb_histogram_t *h); /* Destroy a given histogram object */ void sb_histogram_done(sb_histogram_t *h); #endif sysbench-1.0.18/src/sysbench.h0000600000175000017500000002037313553247311014002 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SYSBENCH_H #define SYSBENCH_H #ifdef STDC_HEADERS # include # include # include # include #endif #ifdef HAVE_UNISTD_H # include # include #endif #ifdef HAVE_PTHREAD_H # include #endif #include "sb_list.h" #include "sb_options.h" #include "sb_timer.h" #include "sb_logger.h" #include "tests/sb_cpu.h" #include "tests/sb_fileio.h" #include "tests/sb_memory.h" #include "tests/sb_threads.h" #include "tests/sb_mutex.h" /* Macros to control global execution mutex */ #define SB_THREAD_MUTEX_LOCK() pthread_mutex_lock(&sb_globals.exec_mutex) #define SB_THREAD_MUTEX_UNLOCK() pthread_mutex_unlock(&sb_globals.exec_mutex) /* Maximum number of elements in --report-checkpoints list */ #define MAX_CHECKPOINTS 256 /* Request types definition */ typedef enum { SB_REQ_TYPE_NULL, SB_REQ_TYPE_CPU, SB_REQ_TYPE_MEMORY, SB_REQ_TYPE_FILE, SB_REQ_TYPE_SQL, SB_REQ_TYPE_THREADS, SB_REQ_TYPE_MUTEX, SB_REQ_TYPE_SCRIPT } sb_event_type_t; /* Request structure definition */ struct sb_test; /* Forward declaration */ typedef struct { int type; struct sb_test_t *test; /* type-specific data */ union { sb_file_request_t file_request; sb_threads_request_t threads_request; sb_mutex_request_t mutex_request; } u; } sb_event_t; /* Statistics */ typedef struct { uint32_t threads_running; /* Number of active threads */ double time_interval; /* Time elapsed since the last report */ double time_total; /* Time elapsed since the benchmark start */ double latency_pct; /* Latency percentile */ double latency_min; /* Minimum latency (cumulative reports only) */ double latency_max; /* Maximum latency (cumulative reports only) */ double latency_avg; /* Average latency (cumulative reports only) */ double latency_sum; /* Sum latency (cumulative reports only) */ uint64_t events; /* Number of executed events */ uint64_t reads; /* Number of read operations */ uint64_t writes; /* Number of write operations */ uint64_t other; /* Number of other operations */ uint64_t errors; /* Number of ignored errors */ uint64_t reconnects; /* Number of reconnects to server */ uint64_t queue_length; /* Event queue length (tx_rate-only) */ uint64_t concurrency; /* Number of in-flight events (tx_rate-only) */ } sb_stat_t; /* Commands */ typedef int sb_builtin_cmd_func_t(void); typedef int sb_custom_cmd_func_t(int); /* Test operations definition */ typedef int sb_op_init(void); typedef int sb_op_prepare(void); typedef int sb_op_thread_init(int); typedef int sb_op_thread_run(int); typedef void sb_op_print_mode(void); typedef sb_event_t sb_op_next_event(int); typedef int sb_op_execute_event(sb_event_t *, int); typedef void sb_op_report(sb_stat_t *); typedef int sb_op_thread_done(int); typedef int sb_op_cleanup(void); typedef int sb_op_done(void); /* Test commands structure definitions */ typedef struct { sb_builtin_cmd_func_t *help; /* print help */ sb_builtin_cmd_func_t *prepare; /* prepare for the test */ sb_builtin_cmd_func_t *run; /* run the test */ sb_builtin_cmd_func_t *cleanup; /* cleanup the test database, files, etc. */ } sb_builtin_cmds_t; /* Test operations structure definition */ typedef struct { sb_op_init *init; /* initialization function */ sb_op_prepare *prepare; /* called after timers start, but before thread execution */ sb_op_thread_init *thread_init; /* thread initialization (called when each thread starts) */ sb_op_print_mode *print_mode; /* print mode function */ sb_op_next_event *next_event; /* event generation function */ sb_op_execute_event *execute_event; /* event execution function */ sb_op_report *report_intermediate; /* intermediate reports handler */ sb_op_report *report_cumulative; /* cumulative reports handler */ sb_op_thread_run *thread_run; /* main thread loop */ sb_op_thread_done *thread_done; /* thread finalize function */ sb_op_cleanup *cleanup; /* called after exit from thread, but before timers stop */ sb_op_done *done; /* finalize function */ } sb_operations_t; /* Test structure definition */ typedef struct sb_test { const char *sname; const char *lname; sb_operations_t ops; sb_builtin_cmds_t builtin_cmds; sb_arg_t *args; sb_list_item_t listitem; } sb_test_t; /* sysbench global variables */ typedef struct { int error CK_CC_CACHELINE; /* global error flag */ int argc; /* command line arguments count */ char **argv; /* command line arguments */ unsigned int tx_rate; /* target transaction rate */ uint64_t max_events; /* maximum number of events to execute */ uint64_t max_time_ns; /* total execution time limit */ pthread_mutex_t exec_mutex CK_CC_CACHELINE; /* execution mutex */ const char *testname; /* test name or script path to execute */ const char *cmdname; /* command passed from command line */ unsigned int threads CK_CC_CACHELINE; /* number of threads to use */ unsigned int threads_running; /* number of threads currently active */ unsigned int report_interval; /* intermediate reports interval */ unsigned int percentile; /* percentile rank for latency stats */ unsigned int histogram; /* show histogram in latency stats */ /* array of report checkpoints */ unsigned int checkpoints[MAX_CHECKPOINTS]; unsigned int n_checkpoints; /* number of checkpoints */ unsigned char debug; /* debug flag */ unsigned int timeout; /* forced shutdown timeout */ unsigned char validate; /* validation flag */ unsigned char verbosity CK_CC_CACHELINE; /* log verbosity */ int concurrency CK_CC_CACHELINE; /* number of concurrent requests when tx-rate is used */ int force_shutdown CK_CC_CACHELINE; /* whether we must force test shutdown */ int forced_shutdown_in_progress; uint64_t nevents CK_CC_CACHELINE; /* event counter */ } sb_globals_t; extern sb_globals_t sb_globals CK_CC_CACHELINE; extern pthread_mutex_t event_queue_mutex CK_CC_CACHELINE; /* Global execution timer */ extern sb_timer_t sb_exec_timer CK_CC_CACHELINE; /* timers for checkpoint reports */ extern sb_timer_t sb_intermediate_timer; extern sb_timer_t sb_checkpoint_timer; extern TLS int sb_tls_thread_id; bool sb_more_events(int thread_id); sb_event_t sb_next_event(sb_test_t *test, int thread_id); void sb_event_start(int thread_id); void sb_event_stop(int thread_id); /* Print a description of available command line options for the current test */ void sb_print_test_options(void); /* Default intermediate reports handler */ void sb_report_intermediate(sb_stat_t *stat); /* Default cumulative reports handler */ void sb_report_cumulative(sb_stat_t *stat); /* Allocate an array of objects of the specified size for all threads, both worker and background ones. */ void *sb_alloc_per_thread_array(size_t size); #endif sysbench-1.0.18/src/db_driver.c0000600000175000017500000006046113553247311014121 0ustar jpjp/* Copyright (C) 2004 MySQL AB Copyright (C) 2004-2017 Alexey Kopytov 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef _WIN32 #include "sb_win.h" #endif #ifdef STDC_HEADERS # include # include # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include #include "db_driver.h" #include "sb_list.h" #include "sb_histogram.h" #include "sb_ck_pr.h" /* Query length limit for bulk insert queries */ #define BULK_PACKET_SIZE (512*1024) /* How many rows to insert before COMMITs (used in bulk insert) */ #define ROWS_BEFORE_COMMIT 1000 /* Global variables */ db_globals_t db_globals CK_CC_CACHELINE; static sb_list_t drivers; /* list of available DB drivers */ static uint8_t stats_enabled; static bool db_global_initialized; static pthread_once_t db_global_once = PTHREAD_ONCE_INIT; /* Timers used in debug mode */ static sb_timer_t *exec_timers; static sb_timer_t *fetch_timers; /* Static functions */ static int db_parse_arguments(void); #if 0 static void db_free_row(db_row_t *); #endif static int db_bulk_do_insert(db_conn_t *, int); static void db_reset_stats(void); static int db_free_results_int(db_conn_t *con); /* DB layer arguments */ static sb_arg_t db_args[] = { SB_OPT("db-driver", "specifies database driver to use " "('help' to get list of available drivers)", #ifdef USE_MYSQL "mysql", #else NULL, #endif STRING), SB_OPT("db-ps-mode", "prepared statements usage mode {auto, disable}", "auto", STRING), SB_OPT("db-debug", "print database-specific debug information", "off", BOOL), SB_OPT_END }; /* Register available database drivers and command line arguments */ int db_register(void) { sb_list_item_t *pos; db_driver_t *drv; /* Register database drivers */ SB_LIST_INIT(&drivers); #ifdef USE_MYSQL register_driver_mysql(&drivers); #endif #ifdef USE_DRIZZLE register_driver_drizzle(&drivers); #endif #ifdef USE_ATTACHSQL register_driver_attachsql(&drivers); #endif #ifdef USE_DRIZZLECLIENT register_driver_drizzleclient(&drivers); #endif #ifdef USE_ORACLE register_driver_oracle(&drivers); #endif #ifdef USE_PGSQL register_driver_pgsql(&drivers); #endif /* Register command line options for each driver */ SB_LIST_FOR_EACH(pos, &drivers) { drv = SB_LIST_ENTRY(pos, db_driver_t, listitem); if (drv->args != NULL) sb_register_arg_set(drv->args); drv->initialized = false; pthread_mutex_init(&drv->mutex, NULL); } /* Register general command line arguments for DB API */ sb_register_arg_set(db_args); return 0; } /* Print list of available drivers and their options */ void db_print_help(void) { sb_list_item_t *pos; db_driver_t *drv; log_text(LOG_NOTICE, "General database options:\n"); sb_print_options(db_args); log_text(LOG_NOTICE, ""); log_text(LOG_NOTICE, "Compiled-in database drivers:"); SB_LIST_FOR_EACH(pos, &drivers) { drv = SB_LIST_ENTRY(pos, db_driver_t, listitem); log_text(LOG_NOTICE, " %s - %s", drv->sname, drv->lname); } log_text(LOG_NOTICE, ""); SB_LIST_FOR_EACH(pos, &drivers) { drv = SB_LIST_ENTRY(pos, db_driver_t, listitem); log_text(LOG_NOTICE, "%s options:", drv->sname); sb_print_options(drv->args); } } static void enable_print_stats(void) { ck_pr_fence_store(); ck_pr_store_8(&stats_enabled, 1); } static void disable_print_stats(void) { ck_pr_store_8(&stats_enabled, 0); ck_pr_fence_store(); } static bool check_print_stats(void) { bool rc = ck_pr_load_8(&stats_enabled) == 1; ck_pr_fence_load(); return rc; } static void db_init(void) { if (SB_LIST_IS_EMPTY(&drivers)) { log_text(LOG_FATAL, "No DB drivers available"); return; } if (db_parse_arguments()) return; /* Initialize timers if in debug mode */ if (db_globals.debug) { exec_timers = sb_alloc_per_thread_array(sizeof(sb_timer_t)); fetch_timers = sb_alloc_per_thread_array(sizeof(sb_timer_t)); } db_reset_stats(); enable_print_stats(); db_global_initialized = true; } /* Initialize a driver specified by 'name' and return a handle to it If NULL is passed as a name, then use the driver passed in --db-driver command line option */ db_driver_t *db_create(const char *name) { db_driver_t *drv = NULL; db_driver_t *tmp; sb_list_item_t *pos; pthread_once(&db_global_once, db_init); if (!db_global_initialized) goto err; if (name == NULL && db_globals.driver == NULL) { drv = SB_LIST_ENTRY(SB_LIST_ITEM_NEXT(&drivers), db_driver_t, listitem); /* Is it the only driver available? */ if (SB_LIST_ITEM_NEXT(&(drv->listitem)) == SB_LIST_ITEM_PREV(&(drv->listitem))) log_text(LOG_INFO, "No DB drivers specified, using %s", drv->sname); else { log_text(LOG_FATAL, "Multiple DB drivers are available. " "Use --db-driver=name to specify which one to use"); goto err; } } else { if (name == NULL) name = db_globals.driver; SB_LIST_FOR_EACH(pos, &drivers) { tmp = SB_LIST_ENTRY(pos, db_driver_t, listitem); if (!strcmp(tmp->sname, name)) { drv = tmp; break; } } } if (drv == NULL) { log_text(LOG_FATAL, "invalid database driver name: '%s'", name); goto err; } /* Initialize database driver only once */ pthread_mutex_lock(&drv->mutex); if (!drv->initialized) { if (drv->ops.init()) { pthread_mutex_unlock(&drv->mutex); goto err; } drv->initialized = true; } pthread_mutex_unlock(&drv->mutex); if (drv->ops.thread_init != NULL && drv->ops.thread_init(sb_tls_thread_id)) { log_text(LOG_FATAL, "thread-local driver initialization failed."); return NULL; } return drv; err: return NULL; } /* Deinitialize a driver object */ int db_destroy(db_driver_t *drv) { if (drv->ops.thread_done != NULL) return drv->ops.thread_done(sb_tls_thread_id); return 0; } /* Describe database capabilities */ int db_describe(db_driver_t *drv, drv_caps_t *caps) { if (drv->ops.describe == NULL) return 1; return drv->ops.describe(caps); } /* Connect to database */ db_conn_t *db_connection_create(db_driver_t *drv) { db_conn_t *con; SB_COMPILE_TIME_ASSERT(sizeof(db_conn_t) % CK_MD_CACHELINE == 0); con = (db_conn_t *)calloc(1, sizeof(db_conn_t)); if (con == NULL) return NULL; con->driver = drv; con->state = DB_CONN_READY; con->thread_id = sb_tls_thread_id; if (drv->ops.connect(con)) { free(con); return NULL; } return con; } /* Disconnect from database */ int db_connection_close(db_conn_t *con) { int rc; db_driver_t *drv = con->driver; if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to close an already closed connection"); return 0; } else if (con->state == DB_CONN_RESULT_SET) { db_free_results_int(con); } rc = drv->ops.disconnect(con); con->state = DB_CONN_INVALID; return rc; } /* Reconnect with the same connection parameters */ int db_connection_reconnect(db_conn_t *con) { int rc; db_driver_t *drv = con->driver; if (drv->ops.reconnect == NULL) { log_text(LOG_ALERT, "reconnect is not supported by the current driver"); return 0; } if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to close an already closed connection"); return 0; } else if (con->state == DB_CONN_RESULT_SET) { db_free_results_int(con); } rc = drv->ops.reconnect(con); if (rc == DB_ERROR_FATAL) { con->state = DB_CONN_INVALID; sb_counter_inc(con->thread_id, SB_CNT_ERROR); } else { con->state = DB_CONN_READY; sb_counter_inc(con->thread_id, SB_CNT_RECONNECT); /* Clear DB_ERROR_IGNORABLE */ rc = DB_ERROR_NONE; } return rc; } /* Disconnect and release memory allocated by a connection object */ void db_connection_free(db_conn_t *con) { if (con->state != DB_CONN_INVALID) db_connection_close(con); free(con); } /* Prepare statement */ db_stmt_t *db_prepare(db_conn_t *con, const char *query, size_t len) { db_stmt_t *stmt; if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); return NULL; } stmt = (db_stmt_t *)calloc(1, sizeof(db_stmt_t)); if (stmt == NULL) return NULL; stmt->connection = con; if (con->driver->ops.prepare(stmt, query, len)) { con->error = DB_ERROR_FATAL; free(stmt); return NULL; } return stmt; } /* Bind parameters for prepared statement */ int db_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len) { db_conn_t *con = stmt->connection; if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); return 1; } return con->driver->ops.bind_param(stmt, params, len); } /* Bind results for prepared statement */ int db_bind_result(db_stmt_t *stmt, db_bind_t *results, size_t len) { db_conn_t *con = stmt->connection; if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); return 1; } return con->driver->ops.bind_result(stmt, results, len); } /* Execute prepared statement */ db_result_t *db_execute(db_stmt_t *stmt) { db_conn_t *con = stmt->connection; db_result_t *rs = &con->rs; int rc; if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); return NULL; } else if (con->state == DB_CONN_RESULT_SET && (rc = db_free_results_int(con)) != 0) { return NULL; } rs->statement = stmt; con->error = con->driver->ops.execute(stmt, rs); sb_counter_inc(con->thread_id, rs->counter); if (SB_LIKELY(con->error == DB_ERROR_NONE)) { if (rs->counter == SB_CNT_READ) { con->state = DB_CONN_RESULT_SET; return rs; } con->state = DB_CONN_READY; return NULL; } return NULL; } /* Fetch row from result set of a query */ db_row_t *db_fetch_row(db_result_t *rs) { db_conn_t *con = SB_CONTAINER_OF(rs, db_conn_t, rs); if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); return NULL; } else if (con->state != DB_CONN_RESULT_SET) { log_text(LOG_ALERT, "attempt to fetch row from an invalid result set"); return NULL; } if (con->driver->ops.fetch_row == NULL) { log_text(LOG_ALERT, "fetching rows is not supported by the driver"); } if (rs->nrows == 0 || rs->nfields == 0) { log_text(LOG_ALERT, "attempt to fetch row from an empty result set"); return NULL; } if (rs->row.values == NULL) { rs->row.values = malloc(rs->nfields * sizeof(db_value_t)); } if (con->driver->ops.fetch_row(rs, &rs->row)) { return NULL; } return &rs->row; } /* Execute non-prepared statement */ db_result_t *db_query(db_conn_t *con, const char *query, size_t len) { db_result_t *rs = &con->rs; int rc; if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); con->error = DB_ERROR_FATAL; return NULL; } else if (con->state == DB_CONN_RESULT_SET && (rc = db_free_results_int(con)) != 0) { con->error = DB_ERROR_FATAL; return NULL; } con->error = con->driver->ops.query(con, query, len, rs); sb_counter_inc(con->thread_id, rs->counter); if (SB_LIKELY(con->error == DB_ERROR_NONE)) { if (rs->counter == SB_CNT_READ) { con->state = DB_CONN_RESULT_SET; return rs; } con->state = DB_CONN_READY; return NULL; } return NULL; } /* Free result set */ static int db_free_results_int(db_conn_t *con) { int rc; rc = con->driver->ops.free_results(&con->rs); if (con->rs.row.values != NULL) { free(con->rs.row.values); con->rs.row.values = NULL; } con->rs.nrows = 0; con->rs.nfields = 0; con->rs.statement = NULL; con->state = DB_CONN_READY; return rc; } int db_free_results(db_result_t *rs) { db_conn_t * const con = SB_CONTAINER_OF(rs, db_conn_t, rs); if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); return 1; } else if (con->state != DB_CONN_RESULT_SET) { log_text(LOG_ALERT, "attempt to free an invalid result set"); return 1; } return db_free_results_int(con); } /* Close prepared statement */ int db_close(db_stmt_t *stmt) { int rc; db_conn_t *con = stmt->connection; if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); return 0; } else if (con->state == DB_CONN_RESULT_SET && (rc = db_free_results_int(con)) != 0) { return DB_ERROR_FATAL; } if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); return 0; } else if (con->state == DB_CONN_RESULT_SET && con->rs.statement == stmt && (rc = db_free_results_int(con)) != 0) { return 0; } rc = con->driver->ops.close(stmt); if (stmt->query != NULL) { free(stmt->query); stmt->query = NULL; } if (stmt->bound_param != NULL) { free(stmt->bound_param); stmt->bound_param = NULL; } free(stmt); return rc; } /* Uninitialize DB API */ void db_done(void) { sb_list_item_t *pos; db_driver_t *drv; if (!db_global_initialized) return; disable_print_stats(); if (db_globals.debug) { free(exec_timers); free(fetch_timers); exec_timers = fetch_timers = NULL; } SB_LIST_FOR_EACH(pos, &drivers) { drv = SB_LIST_ENTRY(pos, db_driver_t, listitem); if (drv->initialized) { drv->ops.done(); pthread_mutex_destroy(&drv->mutex); } } return; } /* Parse command line arguments */ int db_parse_arguments(void) { char *s; s = sb_get_value_string("db-ps-mode"); if (!strcmp(s, "auto")) db_globals.ps_mode = DB_PS_MODE_AUTO; else if (!strcmp(s, "disable")) db_globals.ps_mode = DB_PS_MODE_DISABLE; else { log_text(LOG_FATAL, "Invalid value for db-ps-mode: %s", s); return 1; } db_globals.driver = sb_get_value_string("db-driver"); db_globals.debug = sb_get_value_flag("db-debug"); return 0; } /* Produce character representation of a 'bind' variable */ int db_print_value(db_bind_t *var, char *buf, int buflen) { int n; db_time_t *tm; if (var->is_null != NULL && *var->is_null) { n = snprintf(buf, buflen, "NULL"); return (n < buflen) ? n : -1; } switch (var->type) { case DB_TYPE_TINYINT: n = snprintf(buf, buflen, "%hhd", *(char *)var->buffer); break; case DB_TYPE_SMALLINT: n = snprintf(buf, buflen, "%hd", *(short *)var->buffer); break; case DB_TYPE_INT: n = snprintf(buf, buflen, "%d", *(int *)var->buffer); break; case DB_TYPE_BIGINT: n = snprintf(buf, buflen, "%lld", *(long long *)var->buffer); break; case DB_TYPE_FLOAT: n = snprintf(buf, buflen, "%f", *(float *)var->buffer); break; case DB_TYPE_DOUBLE: n = snprintf(buf, buflen, "%f", *(double *)var->buffer); break; case DB_TYPE_CHAR: case DB_TYPE_VARCHAR: n = snprintf(buf, buflen, "'%s'", (char *)var->buffer); break; case DB_TYPE_DATE: tm = (db_time_t *)var->buffer; n = snprintf(buf, buflen, "'%d-%d-%d'", tm->year, tm->month, tm->day); break; case DB_TYPE_TIME: tm = (db_time_t *)var->buffer; n = snprintf(buf, buflen, "'%d:%d:%d'", tm->hour, tm->minute, tm->second); break; case DB_TYPE_DATETIME: case DB_TYPE_TIMESTAMP: tm = (db_time_t *)var->buffer; n = snprintf(buf, buflen, "'%d-%d-%d %d:%d:%d'", tm->year, tm->month, tm->day, tm->hour, tm->minute, tm->second); break; default: n = 0; break; } return (n < buflen) ? n : -1; } #if 0 /* Free row fetched by db_fetch_row() */ void db_free_row(db_row_t *row) { free(row); } #endif /* Initialize multi-row insert operation */ int db_bulk_insert_init(db_conn_t *con, const char *query, size_t query_len) { drv_caps_t driver_caps; int rc; if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); return 0; } else if (con->state == DB_CONN_RESULT_SET && (rc = db_free_results_int(con)) != 0) { return 0; } /* Get database capabilites */ if (db_describe(con->driver, &driver_caps)) { log_text(LOG_FATAL, "failed to get database capabilities!"); return 1; } /* Allocate query buffer */ if (query_len + 1 > BULK_PACKET_SIZE) { log_text(LOG_FATAL, "Query length exceeds the maximum value (%u), aborting", BULK_PACKET_SIZE); return 1; } con->bulk_buflen = BULK_PACKET_SIZE; con->bulk_buffer = (char *)malloc(con->bulk_buflen); if (con->bulk_buffer == NULL) return 1; con->bulk_commit_max = driver_caps.needs_commit ? ROWS_BEFORE_COMMIT : 0; con->bulk_commit_cnt = 0; strcpy(con->bulk_buffer, query); con->bulk_ptr = query_len; con->bulk_values = query_len; con->bulk_cnt = 0; return 0; } /* Add row to multi-row insert operation */ int db_bulk_insert_next(db_conn_t *con, const char *query, size_t query_len) { int rc; if (con->state == DB_CONN_INVALID) { log_text(LOG_ALERT, "attempt to use an already closed connection"); return 0; } else if (con->state == DB_CONN_RESULT_SET && (rc = db_free_results_int(con)) != 0) { return 0; } if (con->bulk_buffer == NULL) { log_text(LOG_ALERT, "attempt to call bulk_insert_next() before bulk_insert_init()"); return 1; } /* Reserve space for '\0' and ',' (if not the first chunk in a bulk insert */ if (con->bulk_ptr + query_len + 1 + (con->bulk_cnt>0) > con->bulk_buflen) { /* Is this a first row? */ if (!con->bulk_cnt) { log_text(LOG_FATAL, "Query length exceeds the maximum value (%u), aborting", con->bulk_buflen); return 1; } if (db_bulk_do_insert(con, 0)) return 1; } if (con->bulk_cnt > 0) { con->bulk_buffer[con->bulk_ptr] = ','; strcpy(con->bulk_buffer + con->bulk_ptr + 1, query); } else strcpy(con->bulk_buffer + con->bulk_ptr, query); con->bulk_ptr += query_len + (con->bulk_cnt > 0); con->bulk_cnt++; return 0; } /* Do the actual INSERT (and COMMIT, if necessary) */ static int db_bulk_do_insert(db_conn_t *con, int is_last) { if (!con->bulk_cnt) return 0; if (db_query(con, con->bulk_buffer, con->bulk_ptr) == NULL && con->error != DB_ERROR_NONE) return 1; if (con->bulk_commit_max != 0) { con->bulk_commit_cnt += con->bulk_cnt; if (is_last || con->bulk_commit_cnt >= con->bulk_commit_max) { if (db_query(con, "COMMIT", 6) == NULL && con->error != DB_ERROR_NONE) return 1; con->bulk_commit_cnt = 0; } } con->bulk_ptr = con->bulk_values; con->bulk_cnt = 0; return 0; } /* Finish multi-row insert operation */ int db_bulk_insert_done(db_conn_t *con) { /* Flush remaining data in buffer, if any */ if (db_bulk_do_insert(con, 1)) return 1; if (con->bulk_buffer != NULL) { free(con->bulk_buffer); con->bulk_buffer = NULL; } return 0; } void db_report_intermediate(sb_stat_t *stat) { /* Use default stats handler if no drivers are used */ if (!check_print_stats()) { sb_report_intermediate(stat); return; } const double seconds = stat->time_interval; log_timestamp(LOG_NOTICE, stat->time_total, "thds: %u tps: %4.2f " "qps: %4.2f (r/w/o: %4.2f/%4.2f/%4.2f) " "lat (ms,%u%%): %4.2f err/s: %4.2f " "reconn/s: %4.2f", stat->threads_running, stat->events / seconds, (stat->reads + stat->writes + stat->other) / seconds, stat->reads / seconds, stat->writes / seconds, stat->other / seconds, sb_globals.percentile, SEC2MS(stat->latency_pct), stat->errors / seconds, stat->reconnects / seconds); if (sb_globals.tx_rate > 0) { log_timestamp(LOG_NOTICE, stat->time_total, "queue length: %" PRIu64", concurrency: %" PRIu64, stat->queue_length, stat->concurrency); } } void db_report_cumulative(sb_stat_t *stat) { sb_timer_t exec_timer; sb_timer_t fetch_timer; /* Use default stats handler if no drivers are used */ if (!check_print_stats()) { sb_report_cumulative(stat); return; } const double seconds = stat->time_interval; const uint64_t queries = stat->reads + stat->writes + stat->other; log_text(LOG_NOTICE, "SQL statistics:"); log_text(LOG_NOTICE, " queries performed:"); log_text(LOG_NOTICE, " read: %" PRIu64, stat->reads); log_text(LOG_NOTICE, " write: %" PRIu64, stat->writes); log_text(LOG_NOTICE, " other: %" PRIu64, stat->other); log_text(LOG_NOTICE, " total: %" PRIu64, queries); log_text(LOG_NOTICE, " transactions: %-6" PRIu64 " (%.2f per sec.)", stat->events, stat->events / seconds); log_text(LOG_NOTICE, " queries: %-6" PRIu64 " (%.2f per sec.)", queries, queries / seconds); log_text(LOG_NOTICE, " ignored errors: %-6" PRIu64 " (%.2f per sec.)", stat->errors, stat->errors / seconds); log_text(LOG_NOTICE, " reconnects: %-6" PRIu64 " (%.2f per sec.)", stat->reconnects, stat->reconnects / seconds); if (db_globals.debug) { sb_timer_init(&exec_timer); sb_timer_init(&fetch_timer); for (unsigned i = 0; i < sb_globals.threads; i++) { exec_timer = sb_timer_merge(&exec_timer, exec_timers + i); fetch_timer = sb_timer_merge(&fetch_timer, fetch_timers + i); } log_text(LOG_DEBUG, ""); log_text(LOG_DEBUG, "Query execution statistics:"); log_text(LOG_DEBUG, " min: %.4fs", NS2SEC(sb_timer_min(&exec_timer))); log_text(LOG_DEBUG, " avg: %.4fs", NS2SEC(sb_timer_avg(&exec_timer))); log_text(LOG_DEBUG, " max: %.4fs", NS2SEC(sb_timer_max(&exec_timer))); log_text(LOG_DEBUG, " total: %.4fs", NS2SEC(sb_timer_sum(&exec_timer))); log_text(LOG_DEBUG, "Results fetching statistics:"); log_text(LOG_DEBUG, " min: %.4fs", NS2SEC(sb_timer_min(&fetch_timer))); log_text(LOG_DEBUG, " avg: %.4fs", NS2SEC(sb_timer_avg(&fetch_timer))); log_text(LOG_DEBUG, " max: %.4fs", NS2SEC(sb_timer_max(&fetch_timer))); log_text(LOG_DEBUG, " total: %.4fs", NS2SEC(sb_timer_sum(&fetch_timer))); } /* Report sysbench general stats */ sb_report_cumulative(stat); } static void db_reset_stats(void) { unsigned int i; /* So that intermediate stats are calculated from the current moment rather than from the previous intermediate report */ sb_timer_current(&sb_intermediate_timer); if (db_globals.debug) { for (i = 0; i < sb_globals.threads; i++) { sb_timer_init(exec_timers + i); sb_timer_init(fetch_timers + i); } } } sysbench-1.0.18/COPYING0000600000175000017500000004325413553247311012262 0ustar jpjp GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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; either version 2 of the License, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. sysbench-1.0.18/README-WIN.txt0000600000175000017500000000073613553247311013356 0ustar jpjpAs of sysbench 1.0 support for native Windows builds was dropped. It may be re-introduced in later versions. Currently, the recommended way to build sysbench on Windows is using Windows Subsystem for Linux available in Windows 10: https://msdn.microsoft.com/en-us/commandline/wsl/about After installing WSL and getting a bash prompt, following Debian/Ubuntu build instructions is sufficient. Alternatively, one can build and use sysbench 0.5 natively for Windows. sysbench-1.0.18/doc/0000700000175000017500000000000013553247311011762 5ustar jpjpsysbench-1.0.18/doc/manual.xml0000600000175000017500000010727013553247311013772 0ustar jpjp sysbench manual Alexey Kopytov
kaamos@users.sourceforge.net
2004-2006 MySQL AB
About this document This document is a user manual for sysbench, a multi-threaded benchmark tool available from http://launchpad.net/sysbench. This document describes features provided by the 0.4.x development branch of sysbench. New features available in the newer 0.5.x branch are not covered by this document.
Translations The following translations of this document are currently available: Serbo-Croatian http://science.webhostinggeeks.com/sysbench-manual/.
Acknowledgments Thanks to Vera Djuraskovic veradjuraskovic@webhostinggeeks.com for contributing a Serbo-Croatian translation of this document.
Introduction sysbench is a modular, cross-platform and multi-threaded benchmark tool for evaluating OS parameters that are important for a system running a database under intensive load. The idea of this benchmark suite is to quickly get an impression about system performance without setting up complex database benchmarks or even without installing a database at all.
Features of sysbench Current features allow to test the following system parameters: file I/O performance scheduler performance memory allocation and transfer speed POSIX threads implementation performance database server performance
Design The design is very simple. sysbench runs a specified number of threads and they all execute requests in parallel. The actual workload produced by requests depends on the specified test mode. You can limit either the total number of requests or the total time for the benchmark, or both. Available test modes are implemented by compiled-in modules, and sysbench was designed to make adding new test modes an easy task. Each test mode may have additional (or workload-specific) options.
Installation If you are building sysbench from a Bazaar repository rather than from a release tarball, you should run ./autogen.sh before building. The following standart procedure will be sufficient to build sysbench in most cases: ./configure make make install The above procedure will try to compile sysbench with MySQL support by default. If you have MySQL headers and libraries in non-standard locations (and no mysql_config can be found in the PATH environmental variable), then you can specify them explicitly with and options to ./configure. To compile sysbench without MySQL support, use . In this case all database-related test modes will be unavailable. If you are running on a 64-bit platform, make sure to build a 64-bit binary by passing the proper target platform and compiler options to configure script. You can also consult the INSTALL file for generic installation instructions.
Usage
General syntax The general syntax for sysbench is as follows: sysbench [common-options] --test=name [test-options] command See for a description of common options and documentation for particular test mode for a list of test-specific options. Below is a brief description of available commands and their purpose: prepare Performs preparative actions for those tests which need them, e.g. creating the necessary files on disk for the test, or filling the test database for the test. run Runs the actual test specified with the option. cleanup Removes temporary data after the test run in those tests which create one. help Displays usage information for a test specified with the option. Also you can use sysbench help to display the brief usage summary and the list of available test modes.
General command line options The table below lists the supported common options, their descriptions and default values: OptionDescriptionDefault value The total number of worker threads to create1 Limit for total number of requests. 0 means unlimited10000 Limit for total execution time in seconds. 0 (default) means unlimited0 Size of stack for each thread32K Specifies if random numbers generator should be initialized from timer before the test startoff Periodically report intermediate statistics with a specified interval in seconds. Note that statistics produced by this option is per-interval rather than cumulative. 0 disables intermediate reports0 Name of the test mode to runRequired Print more debug infooff Perform validation of test results where possible off Print help on general syntax or on a test mode specified with --test, and exitoff Verbosity level (0 - only critical messages, 5 - debug)4 sysbench measures execution times for all processed requests to display statistical information like minimal, average and maximum execution time. For most benchmarks it is also useful to know a request execution time value matching some percentile (e.g. 95% percentile means we should drop 5% of the most long requests and choose the maximal value from the remaining ones). This option allows to specify a percentile rank of query execution times to count 95 Perform validation of test results where possibleoff Note that numerical values for all size options (like in this table) may be specified by appending the corresponding multiplicative suffix (K for kilobytes, M for megabytes, G for gigabytes and T for terabytes).
Test modes This section gives a detailed description for each test mode available in sysbench.
<option>cpu</option>
The is one of the most simple benchmarks in sysbench. In this mode each request consists in calculation of prime numbers up to a value specified by the option. All calculations are performed using 64-bit integers. Each thread executes the requests concurrently until either the total number of requests or the total execution time exceed the limits specified with the common command line options. Example: sysbench --test=cpu --cpu-max-prime=20000 run
<option>threads</option>
This test mode was written to benchmark scheduler performance, more specifically the cases when a scheduler has a large number of threads competing for some set of mutexes. sysbench creates a specified number of threads and a specified number of mutexes. Then each thread starts running the requests consisting of locking the mutex, yielding the CPU, so the thread is placed in the run queue by the scheduler, then unlocking the mutex when the thread is rescheduled back to execution. For each request, the above actions are run several times in a loop, so the more iterations is performed, the more concurrency is placed on each mutex. The following options are available in this test mode: OptionDescriptionDefault value Number of lock/yield/unlock loops to execute per each request1000 Number of mutexes to create8 Example: sysbench --num-threads=64 --test=threads --thread-yields=100 --thread-locks=2 run
<option>mutex</option>
This test mode was written to emulate a situation when all threads run concurrently most of the time, acquiring the mutex lock only for a short period of time (incrementing a global variable). So the purpose of this benchmarks is to examine the performance of mutex implementation. The following options are available in this test mode: OptionDescriptionDefault value Number of mutexes. The actual mutex to lock is chosen randomly before each lock4096 Number of mutex locks to acquire per each request50000 Number of iterations for an empty loop to perform before acquiring the lock10000
<option>memory</option> This test mode can be used to benchmark sequential memory reads or writes. Depending on command line options each thread can access either a global or a local block for all memory operations. The following options are available in this test mode: OptionDescriptionDefault value Size of memory block to use1K Possible values: , . Specifies whether each thread will use a globally allocated memory block, or a local one. global Total size of data to transfer100G Type of memory operations. Possible values: , . 100G
<option>fileio</option> This test mode can be used to produce various kinds of file I/O workloads. At the stage sysbench creates a specified number of files with a specified total size, then at the stage, each thread performs specified I/O operations on this set of files. When the global option is used with the test mode, sysbench performs checksums validation on all data read from the disk. On each write operation the block is filled with random values, then the checksum is calculated and stored in the block along with the offset of this block within a file. On each read operation the block is validated by comparing the stored offset with the real offset, and the stored checksum with the real calculated checksum. The following I/O operations are supported: seqwr sequential write seqrewr sequential rewrite seqrd sequential read rndrd random read rndwr random write rndrw combined random read/write Also, the following file access modes can be specified, if the underlying platform supports them: Asynchronous I/O mode At the moment only Linux AIO implementation is supported. When running in asynchronous mode, sysbench queues a specified number of I/O requests using Linux AIO API, then waits for at least one of submitted requests to complete. After that a new series of I/O requests is submitted. Slow mode In this mode sysbench will use 'ed I/O. However, a separate will be used for each I/O request due to the limitation of 32-bit architectures (we cannot the whole file, as its size migth possibly exceed the maximum of 2 GB of the process address space). Fast mode On 64-bit architectures it is possible to the whole file into the process address space, avoiding the limitation of 2 GB on 32-bit platforms. Using instead of Flush only data buffers, but not the metadata. Additional flags to sysbench can use additional flags to , such as , and . Below is a list of test-specific option for the fileio mode: OptionDescriptionDefault value Number of files to create128 Block size to use in all I/O operations 16K Total size of files2G Type of workload to produce. Possible values: , , , , , (see above) required I/O mode. Possible values: , , , sync Number of asynchronous operations to queue per thread (only for , see above) 128 Additional flags to use with Do after this number of requests (0 - don't use ) 100 Do after each write operation no Do at the end of the test yes Which method to use for synchronization. Possible values: , (see above) fsync Merge at most this number of I/O requests if possible (0 - don't merge) 0 reads/writes ration for combined random read/write test 1.5 Usage example: $ sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw prepare $ sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw run $ sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw cleanup In the above example the first command creates 128 files with the total size of 3 GB in the current directory, the second command runs the actual benchmark and displays the results upon completion, and the third one removes the files used for the test.
<option>oltp</option>
This test mode was written to benchmark a real database performance. At the prepare stage the following table is created in the specified database ( by default): CREATE TABLE `sbtest` ( `id` int(10) unsigned NOT NULL auto_increment, `k` int(10) unsigned NOT NULL default '0', `c` char(120) NOT NULL default '', `pad` char(60) NOT NULL default '', PRIMARY KEY (`id`), KEY `k` (`k`); Then this table is filled with a specified number of rows. The following execution modes are available at the run stage: Simple In this mode each thread runs simple queries of the following form: SELECT c FROM sbtest WHERE id=N where N takes a random value in range 1..<table size> Advanced transactional Each thread performs transactions on the test table. If the test table and database support transactions (e.g. InnoDB engine in MySQL), then / statements will be used to start/stop a transaction. Otherwise, sysbench will use / statements (e.g. for MyISAM engine in MySQL). If some rows are deleted in a transaction, the same rows will be inserted within the same transaction, so this test mode does not destruct any data in the test table and can be run multiple times on the same table. Depending on the command line options, each transaction may contain the following statements: Point queries: SELECT c FROM sbtest WHERE id=N Range queries: SELECT c FROM sbtest WHERE id BETWEEN N AND M Range SUM() queries: SELECT SUM(K) FROM sbtest WHERE id BETWEEN N and M Range ORDER BY queries:SELECT c FROM sbtest WHERE id between N and M ORDER BY c Range DISTINCT queries:SELECT DISTINCT c FROM sbtest WHERE id BETWEEN N and M ORDER BY c UPDATEs on index column:UPDATE sbtest SET k=k+1 WHERE id=N UPDATEs on non-index column:UPDATE sbtest SET c=N WHERE id=M DELETE queries:DELETE FROM sbtest WHERE id=N INSERT queries:INSERT INTO sbtest VALUES (...) Non-transactional This mode is similar to Simple, but you can also choose the query to run. Note that unlike the Advanced transactional mode, this one does not preserve the test table between requests, so you should recreate it with the appropriate cleanup/prepare commands between consecutive benchmarks. Below is a list of possible queries: Point queries: SELECT pad FROM sbtest WHERE id=N UPDATEs on index column: UPDATE sbtest SET k=k+1 WHERE id=N UPDATEs on non-index column: UPDATE sbtest SET c=N WHERE id=M DELETE queries: DELETE FROM sbtest WHERE id=N The generated row IDs are unique over each test run, so no row is deleted twice. INSERT queries: INSERT INTO sbtest (k, c, pad) VALUES(N, M, S) Below is a list of options available for the database test mode: OptionDescriptionDefault value Execution mode (see above). Possible values: (simple), (advanced transactional) and (non-transactional) Read-only mode. No , or queries will be performed. off Re-connect to serveron each transaction. off Range size for range queries100 Number of point select queries in a single transaction 10 Number of simple range queries in a single transaction 1 Number of SUM range queries in a single transaction 1 Number of ORDER range queries in a single transaction 1 Number of DISTINCT range queries in a single transaction 1 Number of index UPDATE queries in a single transaction 1 Number of non-index UPDATE queries in a single transaction 1 Type of queries for non-transactional execution mode (see above). Possible values: , , , , . Time in microseconds to sleep after each connection to database 10000 Minimum time in microseconds to sleep after each request 0 Maximum time in microseconds to sleep after each request 0 Name of the test table sbtest Number of rows in the test table 10000 Distribution of random numbers. Possible values: (uniform distribution), (gaussian distribution) and . With special distribution a specified percent of numbers is generated in a specified percent of cases (see options below). Percentage of values to be treated as 'special' (for special distribution) 1 Percentage of cases when 'special' values are generated (for special distribution) 75 If the database driver supports Prepared Statements API, sysbench will use server-side prepared statements for all queries where possible. Otherwise, client-side (or emulated) prepared statements will be used. This option allows to force using emulation even when PS API is available. Possible values: , . Also, each database driver may provide its own options. Currently only MySQL driver is available. Below is a list of MySQL-specific options: OptionDescriptionDefault value MySQL server host. Starting from version 0.4.5 you may specify a list of hosts separated by commas. In this case sysbench will distribute connections between specified MySQL hosts on a round-robin basis. Note that all connection ports and passwords must be the same on all hosts. Also, databases and tables must be prepared explicitely on each host before executing the benchmark. MySQL server port (in case TCP/IP connection should be used) 3306 Unix socket file to communicate with the MySQL server MySQL user user MySQL password MySQL database name. Note sysbench will not automatically create this database. You should create it manually and grant the appropriate privileges to a user which will be used to access the test table. sbtest Type of the test table. Possible values: , , , , . innodb MAX_ROWS option for MyISAM tables (required for big tables) 1000000 Example usage: $ sysbench --test=oltp --mysql-table-engine=myisam --oltp-table-size=1000000 --mysql-socket=/tmp/mysql.sock prepare $ sysbench --num-threads=16 --max-requests=100000 --test=oltp --oltp-table-size=1000000 --mysql-socket=/tmp/mysql.sock --oltp-read-only=on run The first command will create a MyISAM table 'sbtest' in a database 'sbtest' on a MySQL server using socket, then fill this table with 1M records. The second command will run the actual benchmark with 16 client threads, limiting the total number of request by 100,000.
sysbench-1.0.18/doc/xsl/0000700000175000017500000000000013553247311012570 5ustar jpjpsysbench-1.0.18/doc/xsl/catalog.xml.in0000600000175000017500000000133113553247311015331 0ustar jpjp @CAT_ENTRY_START@ @CAT_ENTRY_END@ sysbench-1.0.18/doc/xsl/xhtml-common.xsl0000600000175000017500000000326413553247311015751 0ustar jpjp
        
          
        
      
        
      
sysbench-1.0.18/doc/xsl/Makefile.am0000600000175000017500000000154013553247311014626 0ustar jpjp# Copyright (C) 2008 MySQL AB # Copyright (C) 2008 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA EXTRA_DIST=catalog.xml.in xhtml-chunk.xsl xhtml-common.xsl xhtml.xsl sysbench-1.0.18/doc/xsl/xhtml-chunk.xsl0000600000175000017500000000342713553247311015572 0ustar jpjp Error is not a chunk! -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd sysbench-1.0.18/doc/xsl/xhtml.xsl0000600000175000017500000000074613553247311014465 0ustar jpjp sysbench-1.0.18/doc/Makefile.am0000600000175000017500000000117113553247311014020 0ustar jpjpXSLTPROC=xsltproc XSLTPROC_FLAGS=@XSLTPROC_FLAGS@ XHTML_STYLESHEET=$(srcdir)/xsl/xhtml.xsl CHUNK_XHTML_STYLESHEET=$(srcdir)/xsl/xhtml-chunk.xsl XML_CATALOG_FILES=$(srcdir)/xsl/catalog.xml dist_html_DATA = manual.html EXTRA_DIST=manual.xml SUBDIRS = xsl if have_xsltproc manual.html: ${top_srcdir}/doc/manual.xml XML_CATALOG_FILES=$(XML_CATALOG_FILES) $(XSLTPROC) $(XSLTPROC_FLAGS) -o $@ $(XHTML_STYLESHEET) $< chunk: ${top_srcdir}/doc/manual.xml $(XSLTPROC) $(XSLTPROC_FLAGS) $(CHUNK_XHTML_STYLESHEET) $< else chunk: manual.html: touch $@ endif clean-local: $(RM) -f *.html distclean-local: $(RM) -f xsl/catalog.xml sysbench-1.0.18/autogen.sh0000700000175000017500000000600213553247311013214 0ustar jpjp#!/usr/bin/env bash # Taken from lighthttpd server (BSD). Thanks Jan! # Run this to generate all the initial makefiles, etc. die() { echo "$@"; exit 1; } ACLOCAL_FLAGS="-I m4" LIBTOOLIZE_FLAGS="--copy --force" AUTOMAKE_FLAGS="-c --foreign --add-missing" ARGV0=$0 ARGS="$@" run() { echo "$ARGV0: running \`$@' $ARGS" $@ $ARGS } ## jump out if one of the programs returns 'false' set -e if test x$ACLOCAL = x; then if test \! "x`which aclocal-1.10 2> /dev/null | grep -v '^no'`" = x; then ACLOCAL=aclocal-1.10 elif test \! "x`which aclocal110 2> /dev/null | grep -v '^no'`" = x; then ACLOCAL=aclocal110 elif test \! "x`which aclocal 2> /dev/null | grep -v '^no'`" = x; then ACLOCAL=aclocal else echo "automake 1.10.x (aclocal) wasn't found, exiting"; exit 1 fi fi if test x$LIBTOOLIZE = x; then if test \! "x`which libtoolize15 2> /dev/null | grep -v '^no'`" = x; then LIBTOOLIZE=libtoolize15 elif test \! "x`which libtoolize14 2> /dev/null | grep -v '^no'`" = x; then LIBTOOLIZE=libtoolize14 elif test \! "x`which glibtoolize 2> /dev/null | grep -v '^no'`" = x; then LIBTOOLIZE=glibtoolize elif test \! "x`which libtoolize 2> /dev/null | grep -v '^no'`" = x; then LIBTOOLIZE=libtoolize else echo "libtoolize 1.4+ wasn't found, exiting"; exit 1 fi fi if test x$AUTOMAKE = x; then if test \! "x`which automake-1.10 2> /dev/null | grep -v '^no'`" = x; then AUTOMAKE=automake-1.10 elif test \! "x`which automake110 2> /dev/null | grep -v '^no'`" = x; then AUTOMAKE=automake110 elif test \! "x`which automake 2> /dev/null | grep -v '^no'`" = x; then AUTOMAKE=automake else echo "automake 1.10.x wasn't found, exiting"; exit 1 fi fi ## macosx has autoconf-2.59 and autoconf-2.60 if test x$AUTOCONF = x; then if test \! "x`which autoconf-2.59 2> /dev/null | grep -v '^no'`" = x; then AUTOCONF=autoconf-2.59 elif test \! "x`which autoconf259 2> /dev/null | grep -v '^no'`" = x; then AUTOCONF=autoconf259 elif test \! "x`which autoconf 2> /dev/null | grep -v '^no'`" = x; then AUTOCONF=autoconf else echo "autoconf 2.59+ wasn't found, exiting"; exit 1 fi fi if test x$AUTOHEADER = x; then if test \! "x`which autoheader-2.59 2> /dev/null | grep -v '^no'`" = x; then AUTOHEADER=autoheader-2.59 elif test \! "x`which autoheader259 2> /dev/null | grep -v '^no'`" = x; then AUTOHEADER=autoheader259 elif test \! "x`which autoheader 2> /dev/null | grep -v '^no'`" = x; then AUTOHEADER=autoheader else echo "autoconf 2.59+ (autoheader) wasn't found, exiting"; exit 1 fi fi run $LIBTOOLIZE $LIBTOOLIZE_FLAGS || die "Can't execute libtoolize" run $ACLOCAL $ACLOCAL_FLAGS || die "Can't execute aclocal" run $AUTOHEADER || die "Can't execute autoheader" run $AUTOMAKE $AUTOMAKE_FLAGS || die "Can't execute automake" run $AUTOCONF || die "Can't execute autoconf" echo -n "Libtoolized with: " $LIBTOOLIZE --version | head -1 echo -n "Automade with: " $AUTOMAKE --version | head -1 echo -n "Configured with: " $AUTOCONF --version | head -1 sysbench-1.0.18/README-Oracle.md0000600000175000017500000000402513553247311013702 0ustar jpjp**WARNING: Oracle support is unmaintained as of sysbench 1.0. You may want to try [sysbench 0.5](https://github.com/akopytov/sysbench/tree/0.5) instead. The corresponding code and instructions below are still in the source tree in case somebody wants to update them. Patches are always welcome! ** -------------------------------------------------------------- Oracle Build steps -------------------------------------------------------------- Using Ubuntu 14.04 - intructions dated for 21/09/2016 (Was built on AWS in an r3.xlarge These actions were done against 0.5 checkout) * Setup Oracle Instant Client - https://help.ubuntu.com/community/Oracle%20Instant%20Client download from http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html. The following RPM's and upload them to the server: - oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm - oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm ``` alien -i oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm alien -i oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm ``` * Install Cuda - http://www.r-tutor.com/gpu-computing/cuda-installation/cuda7.5-ubuntu ``` wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64/cuda-repo-ubuntu1404_7.5-18_amd64.deb sudo dpkg -i cuda-repo-ubuntu1404_7.5-18_amd64.deb sudo apt-get update sudo apt-get install cuda export CUDA_HOME=/usr/local/cuda-7.5 export LD_LIBRARY_PATH=${CUDA_HOME}/lib64 PATH=${CUDA_HOME}/bin:${PATH} export PATH echo "/usr/lib/oracle/12.1/client64/lib" > /etc/ld.so.conf.d/oracle-client-12.1.conf ldconfig ``` * Build sysbench Use the following `configure` option to build with Oracle support: ``` ./configure --with-oracle="/usr/lib/oracle/12.1/client64" ``` Run the following commands to allow sysbench use the full number of cores: ``` sudo sh -c 'for x in /sys/class/net/eth0/queues/rx-*; do echo ffffffff> $x/rps_cpus; done' sudo sh -c "echo 32768 > /proc/sys/net/core/rps_sock_flow_entries" sudo sh -c "echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt" ``` sysbench-1.0.18/.gitignore0000600000175000017500000000324413553247311013212 0ustar jpjp*.o *.a Makefile Makefile.in aclocal.m4 autom4te.cache /config/config.h /config/ltmain.sh /config/stamp-h1 /doc/manual.html /config.log /config.status /configure /libtool /doc/xsl/catalog.xml /src/.deps /src/.libs /src/sysbench /src/drivers/mysql/.deps /src/drivers/oracle/.deps /src/drivers/pgsql/.deps /src/tests/cpu/.deps /src/tests/fileio/.deps /src/tests/memory/.deps /src/tests/mutex/.deps /src/tests/oltp/.deps /src/tests/threads/.deps /TAGS /backup.bzr /config/config.guess /config/config.h.in /config/config.sub /src/TAGS /src/drivers/TAGS /src/drivers/mysql/TAGS /src/tests/TAGS /src/tests/cpu/TAGS /src/tests/fileio/TAGS /src/tests/memory/TAGS /src/tests/mutex/TAGS /src/tests/oltp/TAGS /src/tests/threads/TAGS /config/compile /config/depcomp /config/install-sh /config/missing /m4/libtool.m4 /m4/ltoptions.m4 /m4/ltsugar.m4 /m4/ltversion.m4 /m4/lt~obsolete.m4 /src/drivers/drizzle/.deps /src/scripting/.deps /src/scripting/lua/src/.deps GPATH GRTAGS GTAGS /config/ar-lib /src/drivers/attachsql/.deps/ /config/test-driver *.DS_Store /tests/*.log /tests/*.trs *.gcda *.gcno /tests/include/config.sh /third_party/concurrency_kit/include/ /third_party/concurrency_kit/lib/ /third_party/concurrency_kit/share/ /third_party/concurrency_kit/tmp/ third_party/luajit/bin/ third_party/luajit/inc/ third_party/luajit/lib/ third_party/luajit/share/ third_party/luajit/tmp/ src/lua/internal/sysbench.lua.h src/lua/internal/sysbench.sql.lua.h /src/lua/internal/sysbench.rand.lua.h /src/lua/internal/sysbench.opt.lua.h tests/t/*.err /src/lua/internal/sysbench.cmdline.lua.h /src/lua/internal/sysbench.compat.lua.h /src/lua/internal/sysbench.histogram.lua.h parts prime stage *.snap /snap/snapcraft.yaml sysbench-1.0.18/mkinstalldirs0000700000175000017500000000370413553247311014027 0ustar jpjp#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" 1>&2 exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac case $dirmode in '') if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # End: # mkinstalldirs ends here sysbench-1.0.18/m4/0000700000175000017500000000000013553247311011535 5ustar jpjpsysbench-1.0.18/m4/ax_check_docbook.m40000600000175000017500000000327313553247311015253 0ustar jpjpdnl --------------------------------------------------------------------------- dnl Macro: AX_CHECK_DOCBOOK dnl Check for availability of various DocBook utilities and perform necessary dnl substitutions dnl --------------------------------------------------------------------------- AC_DEFUN([AX_CHECK_DOCBOOK], [ # It's just rude to go over the net to build XSLTPROC_FLAGS=--nonet DOCBOOK_ROOT= for i in /etc/xml/catalog /usr/local/etc/xml/catalog /opt/local/etc/xml/catalog ; do if test -f $i; then XML_CATALOG="$i" fi done if test -z "$XML_CATALOG" ; then for i in /usr/share/sgml/docbook/stylesheet/xsl/nwalsh /usr/share/sgml/docbook/xsl-stylesheets/ /opt/local/share/xsl/docbook-xsl/xhtml/ ; do if test -d "$i"; then DOCBOOK_ROOT=$i fi done # Last resort - try net if test -z "$DOCBOOK_ROOT"; then XSLTPROC_FLAGS= fi else CAT_ENTRY_START='' fi AC_CHECK_PROG(XSLTPROC,xsltproc,xsltproc,) XSLTPROC_WORKS=no if test -n "$XSLTPROC"; then AC_MSG_CHECKING([whether xsltproc works]) if test -n "$XML_CATALOG"; then DB_FILE="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl" else DB_FILE="$DOCBOOK_ROOT/docbook.xsl" fi $XSLTPROC $XSLTPROC_FLAGS $DB_FILE >/dev/null 2>&1 << END END if test "$?" = 0; then XSLTPROC_WORKS=yes fi AC_MSG_RESULT($XSLTPROC_WORKS) fi AM_CONDITIONAL(have_xsltproc, test "$XSLTPROC_WORKS" = "yes") AC_SUBST(XML_CATALOG) AC_SUBST(XSLTPROC_FLAGS) AC_SUBST(DOCBOOK_ROOT) AC_SUBST(CAT_ENTRY_START) AC_SUBST(CAT_ENTRY_END) ]) sysbench-1.0.18/m4/ax_check_compile_flag.m40000600000175000017500000000631713553247311016256 0ustar jpjp# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # # Check whether the given FLAG works with the current language's compiler # or gives an error. (Warnings, however, are ignored) # # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on # success/failure. # # If EXTRA-FLAGS is defined, it is added to the current language's default # flags (e.g. CFLAGS) when the check is done. The check is thus made with # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to # force the compiler to issue an error when a bad flag is given. # # INPUT gives an alternative input source to AC_COMPILE_IFELSE. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # 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, either version 3 of the License, or (at your # option) any later version. # # 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, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 5 AC_DEFUN([AX_CHECK_COMPILE_FLAG], [ AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl ])dnl AX_CHECK_COMPILE_FLAGS sysbench-1.0.18/m4/ac_check_pgsql.m40000600000175000017500000000472113553247311014733 0ustar jpjpdnl --------------------------------------------------------------------------- dnl Macro: AC_CHECK_PGSQL dnl First check for custom PostgreSQL paths in --with-pgsql-* options. dnl If some paths are missing, check if pg_config exists. dnl --------------------------------------------------------------------------- AC_DEFUN([AC_CHECK_PGSQL],[ # Check for custom includes path if test [ -z "$ac_cv_pgsql_includes" ] then AC_ARG_WITH([pgsql-includes], AC_HELP_STRING([--with-pgsql-includes], [path to PostgreSQL header files]), [ac_cv_pgsql_includes=$withval]) fi if test [ -n "$ac_cv_pgsql_includes" ] then AC_CACHE_CHECK([PostgreSQL includes], [ac_cv_pgsql_includes], [ac_cv_pgsql_includes=""]) PGSQL_CFLAGS="-I$ac_cv_pgsql_includes" fi # Check for custom library path if test [ -z "$ac_cv_pgsql_libs" ] then AC_ARG_WITH([pgsql-libs], AC_HELP_STRING([--with-pgsql-libs], [path to PostgreSQL libraries]), [ac_cv_pgsql_libs=$withval]) fi if test [ -n "$ac_cv_pgsql_libs" ] then AC_CACHE_CHECK([PostgreSQL libraries], [ac_cv_pgsql_libs], [ac_cv_pgsql_libs=""]) PGSQL_LIBS="-L$ac_cv_pgsql_libs -lpq" fi # If some path is missing, try to autodetermine with pgsql_config if test [ -z "$ac_cv_pgsql_includes" -o -z "$ac_cv_pgsql_libs" ] then if test [ -z "$pgconfig" ] then AC_PATH_PROG(pgconfig,pg_config) fi if test [ -z "$pgconfig" ] then AC_MSG_ERROR([pg_config executable not found ******************************************************************************** ERROR: cannot find PostgreSQL libraries. If you want to compile with PosgregSQL support, you must either specify file locations explicitly using --with-pgsql-includes and --with-pgsql-libs options, or make sure path to pg_config is listed in your PATH environment variable. If you want to disable PostgreSQL support, use --without-pgsql option. ******************************************************************************** ]) else if test [ -z "$ac_cv_pgsql_includes" ] then AC_MSG_CHECKING(PostgreSQL C flags) PGSQL_CFLAGS="-I`${pgconfig} --includedir`" AC_MSG_RESULT($PGSQL_CFLAGS) fi if test [ -z "$ac_cv_pgsql_libs" ] then AC_MSG_CHECKING(PostgreSQL linker flags) PGSQL_LIBS="-L`${pgconfig} --libdir` -lpq" AC_MSG_RESULT($PGSQL_LIBS) fi fi fi ]) sysbench-1.0.18/m4/ax_gcc_x86_cpuid.m40000600000175000017500000000716713553247311015131 0ustar jpjp# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html # =========================================================================== # # SYNOPSIS # # AX_GCC_X86_CPUID(OP) # AX_GCC_X86_CPUID_COUNT(OP, COUNT) # # DESCRIPTION # # On Pentium and later x86 processors, with gcc or a compiler that has a # compatible syntax for inline assembly instructions, run a small program # that executes the cpuid instruction with input OP. This can be used to # detect the CPU type. AX_GCC_X86_CPUID_COUNT takes an additional COUNT # parameter that gets passed into register ECX before calling cpuid. # # On output, the values of the eax, ebx, ecx, and edx registers are stored # as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable # ax_cv_gcc_x86_cpuid_OP. # # If the cpuid instruction fails (because you are running a # cross-compiler, or because you are not using gcc, or because you are on # a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP # is set to the string "unknown". # # This macro mainly exists to be used in AX_GCC_ARCHFLAG. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2008 Matteo Frigo # Copyright (c) 2015 Michael Petch # # 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, either version 3 of the License, or (at your # option) any later version. # # 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, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 10 AC_DEFUN([AX_GCC_X86_CPUID], [AX_GCC_X86_CPUID_COUNT($1, 0) ]) AC_DEFUN([AX_GCC_X86_CPUID_COUNT], [AC_REQUIRE([AC_PROG_CC]) AC_LANG_PUSH([C]) AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1, [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include ], [ int op = $1, level = $2, eax, ebx, ecx, edx; FILE *f; __asm__ __volatile__ ("xchg %%ebx, %1\n" "cpuid\n" "xchg %%ebx, %1\n" : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) : "a" (op), "2" (level)); f = fopen("conftest_cpuid", "w"); if (!f) return 1; fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx); fclose(f); return 0; ])], [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid], [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid], [ax_cv_gcc_x86_cpuid_$1=unknown])]) AC_LANG_POP([C]) ]) sysbench-1.0.18/m4/extensions.m40000600000175000017500000000212113553247311014174 0ustar jpjpdnl Provide AC_USE_SYSTEM_EXTENSIONS for old autoconf machines. AC_DEFUN([ACX_USE_SYSTEM_EXTENSIONS],[ ifdef([AC_USE_SYSTEM_EXTENSIONS],[ AC_USE_SYSTEM_EXTENSIONS ],[ AC_BEFORE([$0], [AC_COMPILE_IFELSE]) AC_BEFORE([$0], [AC_RUN_IFELSE]) AC_REQUIRE([AC_GNU_SOURCE]) AC_REQUIRE([AC_AIX]) AC_REQUIRE([AC_MINIX]) AH_VERBATIM([__EXTENSIONS__], [/* Enable extensions on Solaris. */ #ifndef __EXTENSIONS__ # undef __EXTENSIONS__ #endif #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif]) AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], [ac_cv_safe_to_define___extensions__], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([ # define __EXTENSIONS__ 1 AC_INCLUDES_DEFAULT])], [ac_cv_safe_to_define___extensions__=yes], [ac_cv_safe_to_define___extensions__=no])]) test $ac_cv_safe_to_define___extensions__ = yes && AC_DEFINE([__EXTENSIONS__]) AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) AC_DEFINE([_TANDEM_SOURCE]) ]) ]) sysbench-1.0.18/m4/ax_compiler_vendor.m40000600000175000017500000000702613553247311015665 0ustar jpjp# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html # =========================================================================== # # SYNOPSIS # # AX_COMPILER_VENDOR # # DESCRIPTION # # Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun, # hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft, # watcom, etc. The vendor is returned in the cache variable # $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2008 Matteo Frigo # # 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, either version 3 of the License, or (at your # option) any later version. # # 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, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 16 AC_DEFUN([AX_COMPILER_VENDOR], [AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, dnl Please add if possible support to ax_compiler_version.m4 [# note: don't check for gcc first since some other compilers define __GNUC__ vendors="intel: __ICC,__ECC,__INTEL_COMPILER ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__ pathscale: __PATHCC__,__PATHSCALE__ clang: __clang__ cray: _CRAYC fujitsu: __FUJITSU gnu: __GNUC__ sun: __SUNPRO_C,__SUNPRO_CC hp: __HP_cc,__HP_aCC dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland: __BORLANDC__,__CODEGEARC__,__TURBOC__ comeau: __COMO__ kai: __KCC lcc: __LCC__ sgi: __sgi,sgi microsoft: _MSC_VER metrowerks: __MWERKS__ watcom: __WATCOMC__ portland: __PGI tcc: __TINYC__ unknown: UNKNOWN" for ventest in $vendors; do case $ventest in *:) vendor=$ventest; continue ;; *) vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" ;; esac AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ #if !($vencpp) thisisanerror; #endif ])], [break]) done ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1` ]) ]) sysbench-1.0.18/m4/ac_check_aio.m40000600000175000017500000000235313553247311014354 0ustar jpjpdnl --------------------------------------------------------------------------- dnl Macro: AC_CHECK_AIO dnl Check for Linux AIO availability on the target system dnl Also, check the version of libaio library (at the moment, there are two dnl versions with incompatible interfaces). dnl --------------------------------------------------------------------------- AC_DEFUN([AC_CHECK_AIO],[ if test x$enable_aio = xyes; then AC_CHECK_HEADER([libaio.h], [AC_DEFINE(HAVE_LIBAIO_H,1,[Define to 1 if your system has header file])], [enable_aio=no]) fi if test x$enable_aio = xyes; then AC_CHECK_LIB([aio], [io_queue_init], , [enable_aio=no]) fi if test x$enable_aio = xyes; then AC_MSG_CHECKING(if io_getevents() has an old interface) AC_COMPILE_IFELSE([AC_LANG_PROGRAM( [[ #ifdef HAVE_LIBAIO_H # include #endif struct io_event event; io_context_t ctxt; ]], [[ (void)io_getevents(ctxt, 1, &event, NULL); ]] ) ], [ AC_DEFINE([HAVE_OLD_GETEVENTS], 1, [Define to 1 if libaio has older getevents() interface]) AC_MSG_RESULT(yes) ], [AC_MSG_RESULT(no)] ) fi ]) sysbench-1.0.18/m4/sb_autoconf_compat.m40000600000175000017500000000124013553247311015643 0ustar jpjp# --------------------------------------------------------------------------- # Provide various compatibility macros for older Autoconf machines # Definitions were copied from the Autoconf source code. # --------------------------------------------------------------------------- m4_ifdef([AS_VAR_IF],,m4_define([AS_VAR_IF], [AS_LITERAL_WORD_IF([$1], [AS_IF(m4_ifval([$2], [[test "x$$1" = x[]$2]], [[${$1:+false} :]])], [AS_VAR_COPY([as_val], [$1]) AS_IF(m4_ifval([$2], [[test "x$as_val" = x[]$2]], [[${as_val:+false} :]])], [AS_IF(m4_ifval([$2], [[eval test \"x\$"$1"\" = x"_AS_ESCAPE([$2], [`], [\"$])"]], [[eval \${$1:+false} :]])]), [$3], [$4])]))dnl sysbench-1.0.18/m4/lib-ld.m40000600000175000017500000000653113553247311013151 0ustar jpjp# lib-ld.m4 serial 3 (gettext-0.13) dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Subroutines of libtool.m4, dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision dnl with libtool.m4. dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. AC_DEFUN([AC_LIB_PROG_LD_GNU], [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, [# I'd rather use --version here, but apparently some GNU ld's only accept -v. case `$LD -v 2>&1 conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by GCC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]* | [A-Za-z]:[\\/]*)] [re_direlt='/[^/][^/]*/\.\./'] # Canonicalize the path of ld ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(acl_cv_path_LD, [if test -z "$LD"; then IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in *GNU* | *'with BFD'*) test "$with_gnu_ld" != no && break ;; *) test "$with_gnu_ld" != yes && break ;; esac fi done IFS="$ac_save_ifs" else acl_cv_path_LD="$LD" # Let the user override the test with a path. fi]) LD="$acl_cv_path_LD" if test -n "$LD"; then AC_MSG_RESULT($LD) else AC_MSG_RESULT(no) fi test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) AC_LIB_PROG_LD_GNU ]) sysbench-1.0.18/m4/sb_luajit.m40000600000175000017500000000477113553247311013766 0ustar jpjp# Copyright (C) 2016 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # --------------------------------------------------------------------------- # Macro: SB_LUAJIT # --------------------------------------------------------------------------- AC_DEFUN([SB_LUAJIT], [ AC_ARG_WITH([system-luajit], AC_HELP_STRING([--with-system-luajit], [Use system-provided LuaJIT headers and library (requires pkg-config)]), [sb_use_luajit="system"], [sb_use_luajit="bundled"]) AC_CACHE_CHECK([whether to build with system or bundled LuaJIT], [sb_cv_lib_luajit], [ AS_IF([test "x$sb_use_luajit" = "xsystem"], [ sb_cv_lib_luajit=[system] ], [ sb_cv_lib_luajit=[bundled] ]) ]) AS_IF([test "x$sb_cv_lib_luajit" = "xsystem"], # let PKG_CHECK_MODULES set LUAJIT_CFLAGS and LUAJIT_LIBS for system libluajit [PKG_CHECK_MODULES([LUAJIT], [luajit])], # Set LUAJIT_CFLAGS and LUAJIT_LIBS manually for bundled libluajit [ LUAJIT_CFLAGS="-I\$(abs_top_builddir)/third_party/luajit/inc" LUAJIT_LIBS="\$(abs_top_builddir)/third_party/luajit/lib/libluajit-5.1.a" ] ) AC_DEFINE_UNQUOTED([SB_WITH_LUAJIT], ["$sb_use_luajit"], [Whether system or bundled LuaJIT is used]) AM_CONDITIONAL([USE_BUNDLED_LUAJIT], [test "x$sb_use_luajit" = xbundled]) AS_CASE([$host_os:$host_cpu], # Add extra flags when building a 64-bit application on OS X, # http://luajit.org/install.html [*darwin*:x86_64], [LUAJIT_LDFLAGS="-pagezero_size 10000 -image_base 100000000"], # -ldl and -rdynamic are required on Linux [*linux*:*], [ LUAJIT_LIBS="$LUAJIT_LIBS -ldl" LUAJIT_LDFLAGS="-rdynamic" ], # -rdynamic is required on FreeBSD [*freebsd*:*], [ LUAJIT_LDFLAGS="-rdynamic" ] ) AC_SUBST([LUAJIT_LDFLAGS]) ]) sysbench-1.0.18/m4/ax_gcc_func_attribute.m40000600000175000017500000002015013553247311016321 0ustar jpjp# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html # =========================================================================== # # SYNOPSIS # # AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE) # # DESCRIPTION # # This macro checks if the compiler supports one of GCC's function # attributes; many other compilers also provide function attributes with # the same syntax. Compiler warnings are used to detect supported # attributes as unsupported ones are ignored by default so quieting # warnings when using this macro will yield false positives. # # The ATTRIBUTE parameter holds the name of the attribute to be checked. # # If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_. # # The macro caches its result in the ax_cv_have_func_attribute_ # variable. # # The macro currently supports the following function attributes: # # alias # aligned # alloc_size # always_inline # artificial # cold # const # constructor # constructor_priority for constructor attribute with priority # deprecated # destructor # dllexport # dllimport # error # externally_visible # fallthrough # flatten # format # format_arg # gnu_inline # hot # ifunc # leaf # malloc # noclone # noinline # nonnull # noreturn # nothrow # optimize # pure # sentinel # sentinel_position # unused # used # visibility # warning # warn_unused_result # weak # weakref # # Unsupported function attributes will be tested with a prototype # returning an int and not accepting any arguments and the result of the # check might be wrong or meaningless so use with care. # # LICENSE # # Copyright (c) 2013 Gabriele Svelto # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 9 AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1]) AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([ m4_case([$1], [alias], [ int foo( void ) { return 0; } int bar( void ) __attribute__(($1("foo"))); ], [aligned], [ int foo( void ) __attribute__(($1(32))); ], [alloc_size], [ void *foo(int a) __attribute__(($1(1))); ], [always_inline], [ inline __attribute__(($1)) int foo( void ) { return 0; } ], [artificial], [ inline __attribute__(($1)) int foo( void ) { return 0; } ], [cold], [ int foo( void ) __attribute__(($1)); ], [const], [ int foo( void ) __attribute__(($1)); ], [constructor_priority], [ int foo( void ) __attribute__((__constructor__(65535/2))); ], [constructor], [ int foo( void ) __attribute__(($1)); ], [deprecated], [ int foo( void ) __attribute__(($1(""))); ], [destructor], [ int foo( void ) __attribute__(($1)); ], [dllexport], [ __attribute__(($1)) int foo( void ) { return 0; } ], [dllimport], [ int foo( void ) __attribute__(($1)); ], [error], [ int foo( void ) __attribute__(($1(""))); ], [externally_visible], [ int foo( void ) __attribute__(($1)); ], [fallthrough], [ int foo( void ) {switch (0) { case 1: __attribute__(($1)); case 2: break ; }}; ], [flatten], [ int foo( void ) __attribute__(($1)); ], [format], [ int foo(const char *p, ...) __attribute__(($1(printf, 1, 2))); ], [format_arg], [ char *foo(const char *p) __attribute__(($1(1))); ], [gnu_inline], [ inline __attribute__(($1)) int foo( void ) { return 0; } ], [hot], [ int foo( void ) __attribute__(($1)); ], [ifunc], [ int my_foo( void ) { return 0; } static int (*resolve_foo(void))(void) { return my_foo; } int foo( void ) __attribute__(($1("resolve_foo"))); ], [leaf], [ __attribute__(($1)) int foo( void ) { return 0; } ], [malloc], [ void *foo( void ) __attribute__(($1)); ], [noclone], [ int foo( void ) __attribute__(($1)); ], [noinline], [ __attribute__(($1)) int foo( void ) { return 0; } ], [nonnull], [ int foo(char *p) __attribute__(($1(1))); ], [noreturn], [ void foo( void ) __attribute__(($1)); ], [nothrow], [ int foo( void ) __attribute__(($1)); ], [optimize], [ __attribute__(($1(3))) int foo( void ) { return 0; } ], [pure], [ int foo( void ) __attribute__(($1)); ], [sentinel], [ int foo(void *p, ...) __attribute__(($1)); ], [sentinel_position], [ int foo(void *p, ...) __attribute__(($1(1))); ], [returns_nonnull], [ void *foo( void ) __attribute__(($1)); ], [unused], [ int foo( void ) __attribute__(($1)); ], [used], [ int foo( void ) __attribute__(($1)); ], [visibility], [ int foo_def( void ) __attribute__(($1("default"))); int foo_hid( void ) __attribute__(($1("hidden"))); int foo_int( void ) __attribute__(($1("internal"))); int foo_pro( void ) __attribute__(($1("protected"))); ], [warning], [ int foo( void ) __attribute__(($1(""))); ], [warn_unused_result], [ int foo( void ) __attribute__(($1)); ], [weak], [ int foo( void ) __attribute__(($1)); ], [weakref], [ static int foo( void ) { return 0; } static int bar( void ) __attribute__(($1("foo"))); ], [ m4_warn([syntax], [Unsupported attribute $1, the test may fail]) int foo( void ) __attribute__(($1)); ] )], []) ], dnl GCC doesn't exit with an error if an unknown attribute is dnl provided but only outputs a warning, so accept the attribute dnl only if no warning were issued. [AS_IF([test -s conftest.err], [AS_VAR_SET([ac_var], [no])], [AS_VAR_SET([ac_var], [yes])])], [AS_VAR_SET([ac_var], [no])]) ]) AS_IF([test yes = AS_VAR_GET([ac_var])], [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1, [Define to 1 if the system has the `$1' function attribute])], []) AS_VAR_POPDEF([ac_var]) ]) sysbench-1.0.18/m4/sb_concurrency_kit.m40000600000175000017500000000644413553247311015676 0ustar jpjp# Copyright (C) 2016-2017 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # --------------------------------------------------------------------------- # Macro: SB_CONCURRENCY_KIT # --------------------------------------------------------------------------- AC_DEFUN([SB_CONCURRENCY_KIT], [ AC_ARG_WITH([system-ck], AC_HELP_STRING([--with-system-ck], [Use system-provided Concurrency Kit headers and library (requires pkg-config)]), [sb_use_ck="system"], [sb_use_ck="bundled"]) AC_CACHE_CHECK([whether to build with system or bundled Concurrency Kit], [sb_cv_lib_ck], [ AS_IF([test "x$sb_use_ck" = "xsystem"], [ sb_cv_lib_ck=[system] ], [ sb_cv_lib_ck=[bundled] ]) ]) AS_IF([test "x$sb_cv_lib_ck" = "xsystem"], # let PKG_CHECK_MODULES set CK_CFLAGS and CK_LIBS for system libck [PKG_CHECK_MODULES([CK], [ck])], # Set CK_CFLAGS and CK_LIBS manually for bundled libck [ CK_CFLAGS="-I\$(abs_top_builddir)/third_party/concurrency_kit/include" CK_LIBS="\$(abs_top_builddir)/third_party/concurrency_kit/lib/libck.a" case $target_cpu in powerpc*|aarch64) # Assume 128-byte cache line on AArch64 and PowerPC CPPFLAGS="${CPPFLAGS} -DCK_MD_CACHELINE=128" ;; # Force --platform=i*86 for CK, otherwise its configure script # autodetects target based on 'uname -m' which doesn't work for # cross-compiliation i486*|i586*) CK_CONFIGURE_FLAGS="--platform=i586" ;; i686*) CK_CONFIGURE_FLAGS="--platform=i686" ;; mips64*) CK_CONFIGURE_FLAGS="--use-cc-builtins" ;; esac # Add --enable-lse to CK build flags, if LSE instructions are supported by # the target architecture if test "$cross_compiling" = no -a "$host_cpu" = aarch64; then AC_MSG_CHECKING([whether LSE instructions are supported]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM(, [[ unsigned long long d = 1, a = 1; unsigned long long *t = &a; __asm__ __volatile__( "stadd %0, [%1];" : "+&r" (d) : "r" (t) : "memory"); ]])], [ CK_CONFIGURE_FLAGS="--enable-lse" AC_MSG_RESULT([yes]) ], [ CK_CONFIGURE_FLAGS="" AC_MSG_RESULT([no]) ] ) AC_SUBST([CK_CONFIGURE_FLAGS]) fi ] ) AC_DEFINE_UNQUOTED([SB_WITH_CK], ["$sb_use_ck"], [Whether system or bundled Concurrency Ki is used]) AM_CONDITIONAL([USE_BUNDLED_CK], [test "x$sb_use_ck" = xbundled]) ]) sysbench-1.0.18/m4/ax_tls.m40000600000175000017500000000574513553247311013306 0ustar jpjp# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_tls.html # =========================================================================== # # SYNOPSIS # # AX_TLS([action-if-found], [action-if-not-found]) # # DESCRIPTION # # Provides a test for the compiler support of thread local storage (TLS) # extensions. Defines TLS if it is found. Currently knows about C++11, # GCC/ICC, and MSVC. I think SunPro uses the same as GCC, and Borland # apparently supports either. # # LICENSE # # Copyright (c) 2008 Alan Woodland # Copyright (c) 2010 Diego Elio Petteno` # # 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, either version 3 of the License, or (at your # option) any later version. # # 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, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 14 AC_DEFUN([AX_TLS], [ AC_MSG_CHECKING([for thread local storage (TLS) class]) AC_CACHE_VAL([ac_cv_tls], [for ax_tls_keyword in thread_local _Thread_local __thread '__declspec(thread)' none; do AS_CASE([$ax_tls_keyword], [none], [ac_cv_tls=none ; break], [AC_TRY_COMPILE( [#include static void foo(void) { static ] $ax_tls_keyword [ int bar; exit(1); }], [], [ac_cv_tls=$ax_tls_keyword ; break], ac_cv_tls=none )]) done ]) AC_MSG_RESULT([$ac_cv_tls]) AS_IF([test "$ac_cv_tls" != "none"], [AC_DEFINE_UNQUOTED([TLS],[$ac_cv_tls],[If the compiler supports a TLS storage class define it to that here]) m4_ifnblank([$1],[$1])], [m4_ifnblank([$2],[$2])]) ]) sysbench-1.0.18/m4/ax_gcc_archflag.m40000600000175000017500000003132113553247311015054 0ustar jpjp# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html # =========================================================================== # # SYNOPSIS # # AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE]) # # DESCRIPTION # # This macro tries to guess the "native" arch corresponding to the target # architecture for use with gcc's -march=arch or -mtune=arch flags. If # found, the cache variable $ax_cv_gcc_archflag is set to this flag and # ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is set to # "unknown" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is # to add $ax_cv_gcc_archflag to the end of $CFLAGS. # # PORTABLE? should be either [yes] (default) or [no]. In the former case, # the flag is set to -mtune (or equivalent) so that the architecture is # only used for tuning, but the instruction set used is still portable. In # the latter case, the flag is set to -march (or equivalent) so that # architecture-specific instructions are enabled. # # The user can specify --with-gcc-arch= in order to override the # macro's choice of architecture, or --without-gcc-arch to disable this. # # When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is # called unless the user specified --with-gcc-arch manually. # # Requires macros: AX_CHECK_COMPILE_FLAG, AX_GCC_X86_CPUID # # (The main emphasis here is on recent CPUs, on the principle that doing # high-performance computing on old hardware is uncommon.) # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2008 Matteo Frigo # Copyright (c) 2014 Tsukasa Oi # Copyright (c) 2017-2018 Alexey Kopytov # # 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, either version 3 of the License, or (at your # option) any later version. # # 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, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 21 AC_DEFUN([AX_GCC_ARCHFLAG], [AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_SED]) AC_REQUIRE([AX_COMPILER_VENDOR]) AC_ARG_WITH(gcc-arch, [AS_HELP_STRING([--with-gcc-arch=], [use architecture for gcc -march/-mtune, instead of guessing])], ax_gcc_arch=$withval, ax_gcc_arch=yes) AC_MSG_CHECKING([for gcc architecture flag]) AC_MSG_RESULT([]) AC_CACHE_VAL(ax_cv_gcc_archflag, [ ax_cv_gcc_archflag="unknown" if test "$GCC" = yes; then if test "x$ax_gcc_arch" = xyes; then ax_gcc_arch="" if test "$cross_compiling" = no; then case $host_cpu in i[[3456]]86*|x86_64*|amd64*) # use cpuid codes AX_GCC_X86_CPUID(0) AX_GCC_X86_CPUID(1) case $ax_cv_gcc_x86_cpuid_0 in *:756e6547:6c65746e:49656e69) # Intel case $ax_cv_gcc_x86_cpuid_1 in *5[[4578]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;; *5[[123]]?:*:*:*) ax_gcc_arch=pentium ;; *0?61?:*:*:*|?61?:*:*:*|61?:*:*:*) ax_gcc_arch=pentiumpro ;; *0?6[[356]]?:*:*:*|?6[[356]]?:*:*:*|6[[356]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;; *0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;; *0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;; *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) ax_gcc_arch="yonah pentium-m pentium3 pentiumpro" ;; *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;; *1?6[[7d]]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;; *1?6[[aef]]?:*:*:*|*2?6e?:*:*:*) ax_gcc_arch="nehalem corei7 core2 pentium-m pentium3 pentiumpro" ;; *2?6[[5cf]]?:*:*:*) ax_gcc_arch="westmere corei7 core2 pentium-m pentium3 pentiumpro" ;; *2?6[[ad]]?:*:*:*) ax_gcc_arch="sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; *3?6[[ae]]?:*:*:*) ax_gcc_arch="ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) ax_gcc_arch="haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; *3?6d?:*:*:*|*4?6[[7f]]?:*:*:*|*5?66?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; *1?6c?:*:*:*|*2?6[[67]]?:*:*:*|*3?6[[56]]?:*:*:*) ax_gcc_arch="bonnell atom core2 pentium-m pentium3 pentiumpro" ;; *3?67?:*:*:*|*[[45]]?6[[ad]]?:*:*:*) ax_gcc_arch="silvermont atom core2 pentium-m pentium3 pentiumpro" ;; *000?f[[012]]?:*:*:*|?f[[012]]?:*:*:*|f[[012]]?:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;; *000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) ax_gcc_arch="nocona prescott pentium4 pentiumpro" ;; # fallback *5??:*:*:*) ax_gcc_arch=pentium ;; *??6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;; *6??:*:*:*) ax_gcc_arch=pentiumpro ;; *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;; esac ;; *:68747541:444d4163:69746e65) # AMD case $ax_cv_gcc_x86_cpuid_1 in *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;; *5[[8]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;; *5[[9d]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;; *6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;; *6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;; *6[[678a]]?:*:*:*) ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;; *000?f[[4578bcef]]?:*:*:*|?f[[4578bcef]]?:*:*:*|f[[4578bcef]]?:*:*:*|*001?f[[4578bcf]]?:*:*:*|1?f[[4578bcf]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;; *002?f[[13457bcf]]?:*:*:*|2?f[[13457bcf]]?:*:*:*|*004?f[[138bcf]]?:*:*:*|4?f[[138bcf]]?:*:*:*|*005?f[[df]]?:*:*:*|5?f[[df]]?:*:*:*|*006?f[[8bcf]]?:*:*:*|6?f[[8bcf]]?:*:*:*|*007?f[[cf]]?:*:*:*|7?f[[cf]]?:*:*:*|*00c?f1?:*:*:*|c?f1?:*:*:*|*020?f3?:*:*:*|20?f3?:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;; *010?f[[245689a]]?:*:*:*|10?f[[245689a]]?:*:*:*|*030?f1?:*:*:*|30?f1?:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;; *050?f[[12]]?:*:*:*|50?f[[12]]?:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;; *060?f1?:*:*:*|60?f1?:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;; *060?f2?:*:*:*|60?f2?:*:*:*|*061?f[[03]]?:*:*:*|61?f[[03]]?:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;; *063?f0?:*:*:*|63?f0?:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;; *07[[03]]?f0?:*:*:*|7[[03]]?f0?:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;; # fallback *0[[13]]??f??:*:*:*|[[13]]??f??:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;; *020?f??:*:*:*|20?f??:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;; *05??f??:*:*:*|5??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;; *060?f??:*:*:*|60?f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;; *061?f??:*:*:*|61?f??:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;; *06??f??:*:*:*|6??f??:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;; *070?f??:*:*:*|70?f??:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;; *???f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;; esac ;; *:746e6543:736c7561:48727561) # IDT / VIA (Centaur) case $ax_cv_gcc_x86_cpuid_1 in *54?:*:*:*) ax_gcc_arch=winchip-c6 ;; *5[[89]]?:*:*:*) ax_gcc_arch=winchip2 ;; *66?:*:*:*) ax_gcc_arch=winchip2 ;; *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;; *6[[9adf]]?:*:*:*) ax_gcc_arch="c3-2 c3" ;; esac ;; esac if test x"$ax_gcc_arch" = x; then # fallback case $host_cpu in i586*) ax_gcc_arch=pentium ;; i686*) ax_gcc_arch=pentiumpro ;; esac fi ;; sparc*) AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/]) cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null` cputype=`echo "$cputype" | tr -d ' -' | $SED 's/SPARCIIi/SPARCII/' |tr $as_cr_LETTERS $as_cr_letters` case $cputype in *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;; *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;; *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;; *supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;; *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;; *cypress*) ax_gcc_arch=cypress ;; esac ;; alphaev5) ax_gcc_arch=ev5 ;; alphaev56) ax_gcc_arch=ev56 ;; alphapca56) ax_gcc_arch="pca56 ev56" ;; alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;; alphaev6) ax_gcc_arch=ev6 ;; alphaev67) ax_gcc_arch=ev67 ;; alphaev68) ax_gcc_arch="ev68 ev67" ;; alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;; alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;; alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;; powerpc*) cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | $SED 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null` cputype=`echo $cputype | $SED -e 's/ppc//g;s/ *//g'` case $cputype in *750*) ax_gcc_arch="750 G3" ;; *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;; *74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;; *74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;; *970*) ax_gcc_arch="970 G5 power4";; *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";; *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";; 603ev|8240) ax_gcc_arch="$cputype 603e 603";; *) ax_gcc_arch=$cputype ;; esac ax_gcc_arch="$ax_gcc_arch powerpc" ;; aarch64) cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` case $cpuimpl in 0x42) case $cpuarch in 8) case $cpuvar in 0x0) ax_gcc_arch="thunderx2t99 vulcan armv8.1-a armv8-a+lse armv8-a native" ;; esac ;; esac ;; 0x43) case $cpuarch in 8) case $cpuvar in 0x0) ax_gcc_arch="thunderx armv8-a native" ;; 0x1) ax_gcc_arch="thunderx+lse armv8.1-a armv8-a+lse armv8-a native" ;; esac ;; esac ;; esac ;; esac fi # not cross-compiling fi # guess arch if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code flag_prefixes="-mtune=" if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then flag_prefixes="-march="; fi # -mcpu=$arch and m$arch generate nonportable code on every arch except # x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr. case $host_cpu in i*86|x86_64*|amd64*) flag_prefixes="$flag_prefixes -mcpu= -m";; esac else flag_prefixes="-march= -mcpu= -m" fi for flag_prefix in $flag_prefixes; do for arch in $ax_gcc_arch; do flag="$flag_prefix$arch" AX_CHECK_COMPILE_FLAG($flag, [if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then if test "x[]m4_default([$1],yes)" = xyes; then if test "x$flag" = "x-march=$arch"; then flag=-mtune=$arch; fi fi fi; ax_cv_gcc_archflag=$flag; break]) done test "x$ax_cv_gcc_archflag" = xunknown || break done fi fi # $GCC=yes ]) AC_MSG_CHECKING([for gcc architecture flag]) AC_MSG_RESULT($ax_cv_gcc_archflag) if test "x$ax_cv_gcc_archflag" = xunknown; then m4_default([$3],:) else m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"]) fi ]) sysbench-1.0.18/m4/lib-link.m40000600000175000017500000007205513553247311013513 0ustar jpjp# lib-link.m4 serial 13 (gettext-0.17) dnl Copyright (C) 2001-2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_PREREQ(2.54) dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and dnl augments the CPPFLAGS variable. dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. AC_DEFUN([AC_LIB_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) define([Name],[translit([$1],[./-], [___])]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ AC_LIB_LINKFLAGS_BODY([$1], [$2]) ac_cv_lib[]Name[]_libs="$LIB[]NAME" ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" ac_cv_lib[]Name[]_cppflags="$INC[]NAME" ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX" ]) LIB[]NAME="$ac_cv_lib[]Name[]_libs" LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" INC[]NAME="$ac_cv_lib[]Name[]_cppflags" LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) AC_SUBST([LIB]NAME[_PREFIX]) dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the dnl results of this search when this library appears as a dependency. HAVE_LIB[]NAME=yes undefine([Name]) undefine([NAME]) ]) dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) dnl searches for libname and the libraries corresponding to explicit and dnl implicit dependencies, together with the specified include files and dnl the ability to compile and link the specified testcode. If found, it dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) define([Name],[translit([$1],[./-], [___])]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME dnl accordingly. AC_LIB_LINKFLAGS_BODY([$1], [$2]) dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, dnl because if the user has installed lib[]Name and not disabled its use dnl via --without-lib[]Name-prefix, he wants to use it. ac_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ ac_save_LIBS="$LIBS" LIBS="$LIBS $LIB[]NAME" AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) LIBS="$ac_save_LIBS" ]) if test "$ac_cv_lib[]Name" = yes; then HAVE_LIB[]NAME=yes AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) AC_MSG_CHECKING([how to link with lib[]$1]) AC_MSG_RESULT([$LIB[]NAME]) else HAVE_LIB[]NAME=no dnl If $LIB[]NAME didn't lead to a usable library, we don't need dnl $INC[]NAME either. CPPFLAGS="$ac_save_CPPFLAGS" LIB[]NAME= LTLIB[]NAME= LIB[]NAME[]_PREFIX= fi AC_SUBST([HAVE_LIB]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) AC_SUBST([LIB]NAME[_PREFIX]) undefine([Name]) undefine([NAME]) ]) dnl Determine the platform dependent parameters needed to use rpath: dnl acl_libext, dnl acl_shlibext, dnl acl_hardcode_libdir_flag_spec, dnl acl_hardcode_libdir_separator, dnl acl_hardcode_direct, dnl acl_hardcode_minus_L. AC_DEFUN([AC_LIB_RPATH], [ dnl Tell automake >= 1.10 to complain if config.rpath is missing. m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done ]) wl="$acl_cv_wl" acl_libext="$acl_cv_libext" acl_shlibext="$acl_cv_shlibext" acl_libname_spec="$acl_cv_libname_spec" acl_library_names_spec="$acl_cv_library_names_spec" acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" acl_hardcode_direct="$acl_cv_hardcode_direct" acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" dnl Determine whether the user wants rpath handling at all. AC_ARG_ENABLE(rpath, [ --disable-rpath do not hardcode runtime library paths], :, enable_rpath=yes) ]) dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. AC_DEFUN([AC_LIB_LINKFLAGS_BODY], [ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) dnl Autoconf >= 2.61 supports dots in --with options. define([N_A_M_E],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit([$1],[.],[_])],[$1])]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_LIB_ARG_WITH([lib]N_A_M_E[-prefix], [ --with-lib]N_A_M_E[-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib --without-lib]N_A_M_E[-prefix don't search for lib$1 in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi ]) dnl Search the library and its dependencies in $additional_libdir and dnl $LDFLAGS. Using breadth-first-seach. LIB[]NAME= LTLIB[]NAME= INC[]NAME= LIB[]NAME[]_PREFIX= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='$1 $2' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" dnl See if it was already located by an earlier AC_LIB_LINKFLAGS dnl or AC_LIB_HAVE_LINKFLAGS call. uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" else dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined dnl that this library doesn't exist. So just drop it. : fi else dnl Search the library lib$name in $additional_libdir and $LDFLAGS dnl and the already constructed $LIBNAME/$LTLIBNAME. found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" dnl The same code as in the loop below: dnl First look for a shared library. if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi dnl Then look for a static library. if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` dnl First look for a shared library. if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi dnl Then look for a static library. if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then dnl Found the library. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then dnl Linking with a shared library. We attempt to hardcode its dnl directory into the executable's runpath, unless it's the dnl standard /usr/lib. if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then dnl No hardcoding is needed. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl Use an explicit option to hardcode DIR into the resulting dnl binary. dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi dnl The hardcoding into $LIBNAME is system dependent. if test "$acl_hardcode_direct" = yes; then dnl Using DIR/libNAME.so during linking hardcodes DIR into the dnl resulting binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then dnl Use an explicit option to hardcode DIR into the resulting dnl binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else dnl Rely on "-L$found_dir". dnl But don't add it if it's already contained in the LDFLAGS dnl or the already constructed $LIBNAME haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH dnl here, because this doesn't fit in flags passed to the dnl compiler. So give up. No hardcoding. This affects only dnl very old systems. dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then dnl Linking with a static library. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" else dnl We shouldn't come here, but anyway it's good to have a dnl fallback. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" fi fi dnl Assume the include files are nearby. additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` LIB[]NAME[]_PREFIX="$basedir" additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then dnl Potentially add $additional_includedir to $INCNAME. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's /usr/local/include and we are using GCC on Linux, dnl 3. if it's already present in $CPPFLAGS or the already dnl constructed $INCNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INC[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $INCNAME. INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" fi fi fi fi fi dnl Look for dependencies. if test -n "$found_la"; then dnl Read the .la file. It defines the variables dnl dlname, library_names, old_library, dependency_libs, current, dnl age, revision, installed, dlopen, dlpreopen, libdir. save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" dnl We use only dependency_libs. for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's /usr/local/lib and we are using GCC on Linux, dnl 3. if it's already present in $LDFLAGS or the already dnl constructed $LIBNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LIBNAME. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LTLIBNAME. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) dnl Handle this in the next round. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) dnl Handle this in the next round. Throw away the .la's dnl directory; it is already contained in a preceding -L dnl option. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) dnl Most likely an immediate library name. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" ;; esac done fi else dnl Didn't find the library; assume it is in the system directories dnl known to the linker and runtime loader. (All the system dnl directories known to the linker should also be known to the dnl runtime loader, otherwise the system is severely misconfigured.) LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user must dnl pass all path elements in one option. We can arrange that for a dnl single library, but not when more than one $LIBNAMEs are used. alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" else dnl The -rpath options are cumulative. for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then dnl When using libtool, the option that works for both libraries and dnl executables is -R. The -R options are cumulative. for found_dir in $ltrpathdirs; do LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" done fi ]) dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, dnl unless already present in VAR. dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes dnl contains two or three consecutive elements that belong together. AC_DEFUN([AC_LIB_APPENDTOVAR], [ for element in [$2]; do haveit= for x in $[$1]; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then [$1]="${[$1]}${[$1]:+ }$element" fi done ]) dnl For those cases where a variable contains several -L and -l options dnl referring to unknown libraries and directories, this macro determines the dnl necessary additional linker options for the runtime path. dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) dnl sets LDADDVAR to linker options needed together with LIBSVALUE. dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, dnl otherwise linking without libtool is assumed. AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], [ AC_REQUIRE([AC_LIB_RPATH]) AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) $1= if test "$enable_rpath" != no; then if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then dnl Use an explicit option to hardcode directories into the resulting dnl binary. rpathdirs= next= for opt in $2; do if test -n "$next"; then dir="$next" dnl No need to hardcode the standard /usr/lib. if test "X$dir" != "X/usr/$acl_libdirstem"; then rpathdirs="$rpathdirs $dir" fi next= else case $opt in -L) next=yes ;; -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` dnl No need to hardcode the standard /usr/lib. if test "X$dir" != "X/usr/$acl_libdirstem"; then rpathdirs="$rpathdirs $dir" fi next= ;; *) next= ;; esac fi done if test "X$rpathdirs" != "X"; then if test -n ""$3""; then dnl libtool is used for linking. Use -R options. for dir in $rpathdirs; do $1="${$1}${$1:+ }-R$dir" done else dnl The linker is used for linking directly. if test -n "$acl_hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user dnl must pass all path elements in one option. alldirs= for dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" $1="$flag" else dnl The -rpath options are cumulative. for dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" $1="${$1}${$1:+ }$flag" done fi fi fi fi fi AC_SUBST([$1]) ]) sysbench-1.0.18/m4/acx_pthread.m40000600000175000017500000002535113553247311014271 0ustar jpjp##### http://autoconf-archive.cryp.to/acx_pthread.html # # SYNOPSIS # # ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. # It sets the PTHREAD_LIBS output variable to the threads library and # linker flags, and the PTHREAD_CFLAGS output variable to any special # C compiler flags that are needed. (The user can also force certain # compiler flags/libs to be tested by setting these environment # variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). # (This is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these # flags, but also link it with them as well. e.g. you should link # with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS # $LIBS # # If you are only building threads programs, you may wish to use # these variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute # constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to # that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # ACTION-IF-FOUND is a list of shell commands to run if a threads # library is found, and ACTION-IF-NOT-FOUND is a list of commands to # run it if it is not found. If ACTION-IF-FOUND is not specified, the # default action will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or # if you have any other suggestions or comments. This macro was based # on work by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) # (with help from M. Frigo), as well as ac_pthread and hb_pthread # macros posted by Alejandro Forero Cuervo to the autoconf macro # repository. We are also grateful for the helpful feedback of # numerous users. # # LAST MODIFICATION # # 2006-05-29 # # COPYLEFT # # Copyright (c) 2006 Steven G. Johnson # # 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; either version 2 of the # License, or (at your option) any later version. # # 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. # # As a special exception, the respective Autoconf Macro's copyright # owner gives unlimited permission to copy, distribute and modify the # configure scripts that are the output of Autoconf when processing # the Macro. You need not follow the terms of the GNU General Public # License when using or distributing such scripts, even though # portions of the text of the Macro appear in them. The GNU General # Public License (GPL) does govern all other use of the material that # constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the # Autoconf Macro released by the Autoconf Macro Archive. When you # make and distribute a modified version of the Autoconf Macro, you # may extend this special exception to the GPL to apply to your # modified version as well. AC_DEFUN([ACX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_PUSH([C]) acx_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) AC_MSG_RESULT($acx_pthread_ok) if test x"$acx_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) if test x"$acx_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ]])],[acx_pthread_ok=yes],[]) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($acx_pthread_ok) if test "x$acx_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$acx_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int attr=$attr; return attr;]])],[attr_name=$attr; break],[]) done AC_MSG_RESULT($attr_name) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$acx_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else acx_pthread_ok=no $2 fi AC_LANG_POP([]) ])dnl ACX_PTHREAD sysbench-1.0.18/m4/sb_check_mysql.m40000600000175000017500000001121413553247311014766 0ustar jpjpdnl --------------------------------------------------------------------------- dnl Macro: SB_CHECK_MYSQL dnl First check if the MySQL root directory is specified with --with-mysql. dnl Otherwise check for custom MySQL paths in --with-mysql-includes and dnl --with-mysql-libs. If some paths are not specified explicitly, try to get dnl them from mysql_config. dnl --------------------------------------------------------------------------- AC_DEFUN([SB_CHECK_MYSQL],[ AS_IF([test "x$with_mysql" != xno], [ # Check for custom MySQL root directory if test [ "x$with_mysql" != xyes -a "x$with_mysql" != xno ] then ac_cv_mysql_root=`echo "$with_mysql" | sed -e 's+/$++'` if test [ -d "$ac_cv_mysql_root/include" -a \ -d "$ac_cv_mysql_root/libmysql_r" ] then ac_cv_mysql_includes="$ac_cv_mysql_root/include" ac_cv_mysql_libs="$ac_cv_mysql_root/libmysql_r" elif test [ -x "$ac_cv_mysql_root/bin/mysql_config" ] then mysqlconfig="$ac_cv_mysql_root/bin/mysql_config" else AC_MSG_ERROR([invalid MySQL root directory: $ac_cv_mysql_root]) fi fi # Check for custom includes path if test [ -z "$ac_cv_mysql_includes" ] then AC_ARG_WITH([mysql-includes], AC_HELP_STRING([--with-mysql-includes], [path to MySQL header files]), [ac_cv_mysql_includes=$withval]) fi if test [ -n "$ac_cv_mysql_includes" ] then AC_CACHE_CHECK([MySQL includes], [ac_cv_mysql_includes], [ac_cv_mysql_includes=""]) MYSQL_CFLAGS="-I$ac_cv_mysql_includes" fi # Check for custom library path if test [ -z "$ac_cv_mysql_libs" ] then AC_ARG_WITH([mysql-libs], AC_HELP_STRING([--with-mysql-libs], [path to MySQL libraries]), [ac_cv_mysql_libs=$withval]) fi if test [ -n "$ac_cv_mysql_libs" ] then # Trim trailing '.libs' if user passed it in --with-mysql-libs option ac_cv_mysql_libs=`echo ${ac_cv_mysql_libs} | sed -e 's/.libs$//' \ -e 's+.libs/$++'` AC_CACHE_CHECK([MySQL libraries], [ac_cv_mysql_libs], [ac_cv_mysql_libs=""]) save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" LDFLAGS="-L$ac_cv_mysql_libs" LIBS="" # libmysqlclient_r has been removed in MySQL 5.7 AC_SEARCH_LIBS([mysql_real_connect], [mysqlclient_r mysqlclient], [], AC_MSG_ERROR([cannot find MySQL client libraries in $ac_cv_mysql_libs])) MYSQL_LIBS="$LDFLAGS $LIBS" LIBS="$save_LIBS" LDFLAGS="$save_LDFLAGS" fi # If some path is missing, try to autodetermine with mysql_config if test [ -z "$ac_cv_mysql_includes" -o -z "$ac_cv_mysql_libs" ] then if test [ -z "$mysqlconfig" ] then AC_PATH_PROG(mysqlconfig,mysql_config) fi if test [ -z "$mysqlconfig" ] then AC_MSG_ERROR([mysql_config executable not found ******************************************************************************** ERROR: cannot find MySQL libraries. If you want to compile with MySQL support, please install the package containing MySQL client libraries and headers. On Debian-based systems the package name is libmysqlclient-dev. On RedHat-based systems, it is mysql-devel. If you have those libraries installed in non-standard locations, you must either specify file locations explicitly using --with-mysql-includes and --with-mysql-libs options, or make sure path to mysql_config is listed in your PATH environment variable. If you want to disable MySQL support, use --without-mysql option. ******************************************************************************** ]) else if test [ -z "$ac_cv_mysql_includes" ] then AC_MSG_CHECKING(MySQL C flags) MYSQL_CFLAGS=`${mysqlconfig} --cflags` AC_MSG_RESULT($MYSQL_CFLAGS) fi if test [ -z "$ac_cv_mysql_libs" ] then AC_MSG_CHECKING(MySQL linker flags) MYSQL_LIBS=`${mysqlconfig} --libs_r` AC_MSG_RESULT($MYSQL_LIBS) fi fi fi AC_DEFINE([USE_MYSQL], 1, [Define to 1 if you want to compile with MySQL support]) USE_MYSQL=1 AC_SUBST([MYSQL_LIBS]) AC_SUBST([MYSQL_CFLAGS]) AC_MSG_CHECKING([if mysql.h defines MYSQL_OPT_SSL_MODE]) SAVE_CFLAGS="${CFLAGS}" CFLAGS="${CFLAGS} ${MYSQL_CFLAGS}" AC_COMPILE_IFELSE([AC_LANG_PROGRAM( [[ #include enum mysql_option opt = MYSQL_OPT_SSL_MODE; ]])], [ AC_DEFINE([HAVE_MYSQL_OPT_SSL_MODE], 1, [Define to 1 if mysql.h defines MYSQL_OPT_SSL_MODE]) AC_MSG_RESULT([yes]) ], [AC_MSG_RESULT([no])]) ]) CFLAGS="${SAVE_CFLAGS}" AM_CONDITIONAL([USE_MYSQL], test "x$with_mysql" != xno) AC_SUBST([USE_MYSQL]) ]) sysbench-1.0.18/m4/lib-prefix.m40000600000175000017500000001503613553247311014047 0ustar jpjp# lib-prefix.m4 serial 5 (gettext-0.15) dnl Copyright (C) 2001-2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't dnl require excessive bracketing. ifdef([AC_HELP_STRING], [AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], [AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed dnl to access previously installed libraries. The basic assumption is that dnl a user will want packages to use other packages he previously installed dnl with the same --prefix option. dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate dnl libraries, but is otherwise very convenient. AC_DEFUN([AC_LIB_PREFIX], [ AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_LIB_ARG_WITH([lib-prefix], [ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib --without-lib-prefix don't search for libraries in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi ]) if test $use_additional = yes; then dnl Potentially add $additional_includedir to $CPPFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's already present in $CPPFLAGS, dnl 3. if it's /usr/local/include and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= for x in $CPPFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $CPPFLAGS. CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" fi fi fi fi dnl Potentially add $additional_libdir to $LDFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's already present in $LDFLAGS, dnl 3. if it's /usr/local/lib and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= for x in $LDFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LDFLAGS. LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" fi fi fi fi fi ]) dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, dnl acl_final_exec_prefix, containing the values to which $prefix and dnl $exec_prefix will expand at the end of the configure script. AC_DEFUN([AC_LIB_PREPARE_PREFIX], [ dnl Unfortunately, prefix and exec_prefix get only finally determined dnl at the end of configure. if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" ]) dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the dnl variables prefix and exec_prefix bound to the values they will have dnl at the end of the configure script. AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], [ acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" $1 exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" ]) dnl AC_LIB_PREPARE_MULTILIB creates a variable acl_libdirstem, containing dnl the basename of the libdir, either "lib" or "lib64". AC_DEFUN([AC_LIB_PREPARE_MULTILIB], [ dnl There is no formal standard regarding lib and lib64. The current dnl practice is that on a system supporting 32-bit and 64-bit instruction dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit dnl libraries go under $prefix/lib. We determine the compiler's default dnl mode by looking at the compiler's library search path. If at least dnl of its elements ends in /lib64 or points to a directory whose absolute dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the dnl default, namely "lib". acl_libdirstem=lib searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` if test -n "$searchpath"; then acl_save_IFS="${IFS= }"; IFS=":" for searchdir in $searchpath; do if test -d "$searchdir"; then case "$searchdir" in */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; *) searchdir=`cd "$searchdir" && pwd` case "$searchdir" in */lib64 ) acl_libdirstem=lib64 ;; esac ;; esac fi done IFS="$acl_save_IFS" fi ]) sysbench-1.0.18/.travis.yml0000600000175000017500000001433713553247311013340 0ustar jpjp# vim ft=yaml # # Travis CI configuration dist: trusty sudo: required services: - docker - mysql - postgresql git: depth: 100500 language: c os: - linux - osx compiler: - gcc - clang env: matrix: - TARGET=distcheck - TARGET=test - TARGET=coverage - OS=el DIST=6 - OS=el DIST=7 - OS=el DIST=8 - OS=fedora DIST=29 - OS=fedora DIST=30 - OS=fedora DIST=rawhide - OS=ubuntu DIST=xenial - OS=ubuntu DIST=bionic - OS=ubuntu DIST=disco - OS=ubuntu DIST=eoan - OS=debian DIST=jessie - OS=debian DIST=stretch - OS=debian DIST=buster - OS=debian DIST=sid - OS=ubuntu DIST=xenial ARCH=i386 - OS=ubuntu DIST=bionic ARCH=i386 - OS=ubuntu DIST=disco ARCH=i386 - OS=ubuntu DIST=eoan ARCH=i386 - OS=debian DIST=jessie ARCH=i386 - OS=debian DIST=stretch ARCH=i386 - OS=debian DIST=buster ARCH=i386 - OS=debian DIST=sid ARCH=i386 matrix: exclude: - env: OS=el DIST=6 compiler: clang - env: OS=el DIST=7 compiler: clang - env: OS=el DIST=8 compiler: clang - env: OS=fedora DIST=29 compiler: clang - env: OS=fedora DIST=30 compiler: clang - env: OS=fedora DIST=rawhide compiler: clang - env: OS=ubuntu DIST=xenial compiler: clang - env: OS=ubuntu DIST=bionic compiler: clang - env: OS=ubuntu DIST=disco compiler: clang - env: OS=ubuntu DIST=eoan compiler: clang - env: OS=debian DIST=jessie compiler: clang - env: OS=debian DIST=stretch compiler: clang - env: OS=debian DIST=buster compiler: clang - env: OS=debian DIST=sid compiler: clang - env: OS=ubuntu DIST=xenial ARCH=i386 compiler: clang - env: OS=ubuntu DIST=bionic ARCH=i386 compiler: clang - env: OS=ubuntu DIST=disco ARCH=i386 compiler: clang - env: OS=ubuntu DIST=eoan ARCH=i386 compiler: clang - env: OS=debian DIST=jessie ARCH=i386 compiler: clang - env: OS=debian DIST=stretch ARCH=i386 compiler: clang - env: OS=debian DIST=buster ARCH=i386 compiler: clang - env: OS=debian DIST=sid ARCH=i386 compiler: clang - env: OS=el DIST=6 os: osx - env: OS=el DIST=7 os: osx - env: OS=el DIST=8 os: osx - env: OS=fedora DIST=29 os: osx - env: OS=fedora DIST=30 os: osx - env: OS=fedora DIST=rawhide os: osx - env: OS=ubuntu DIST=xenial os: osx - env: OS=ubuntu DIST=bionic os: osx - env: OS=ubuntu DIST=disco os: osx - env: OS=ubuntu DIST=eoan os: osx - env: OS=debian DIST=jessie os: osx - env: OS=debian DIST=stretch os: osx - env: OS=debian DIST=buster os: osx - env: OS=debian DIST=sid os: osx - env: TARGET=distcheck compiler: clang - env: TARGET=distcheck os: osx - env: TARGET=coverage os: osx - env: TARGET=coverage compiler: clang - os: osx compiler: gcc addons: apt: packages: - libmysqlclient-dev - libpq-dev - libaio-dev - clang-3.6 before_install: # Upload builds corresponding to release tags to the 'sysbench' # repository, push other ones to 'sysbench-prereleases' - git describe --long --always - commits=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\2/p') - > if [ ${commits:-0} = 0 ]; then export VERSION=$(git describe) PACKAGECLOUD_REPO=sysbench else PACKAGECLOUD_REPO=sysbench-prereleases fi - > if [ "x$TARGET" = "xtest" ]; then case "${TRAVIS_OS_NAME:-linux}" in osx) brew install mysql # OS X requires servers to be started explicitly brew services start mysql # Avoid PostgreSQL upgrade woes, just reinstall the database brew uninstall --ignore-dependencies postgresql rm -rf /usr/local/var/postgres brew install postgresql echo "Starting PostgreSQL" pg_ctl -wD /usr/local/var/postgres start echo "Creating user postgres" createuser -s postgres ;; linux) export ASAN_OPTIONS="detect_leaks=0" if [ "${CC}" = "clang" ]; then CC=clang-3.6 fi ;; esac fi install: - pip2 install --user urllib3[secure] cpp-coveralls - > case "${TRAVIS_OS_NAME:-linux}" in osx) # OS X requires this for user-local pip packages export PATH=~/Library/Python/2.7/bin:$PATH ;; esac before_script: - mysql -u root -e 'CREATE DATABASE sbtest' - psql -U postgres -c 'CREATE DATABASE sbtest' script: - > if [ -n "$TARGET" ]; then case "$TARGET" in test) ./autogen.sh && ./configure --with-mysql --with-pgsql make SBTEST_MYSQL_ARGS="--mysql-user=root" SBTEST_PGSQL_ARGS="--pgsql-user=postgres" make test ;; distcheck) ./autogen.sh && ./configure --without-mysql make make distcheck ;; coverage) ./autogen.sh && ./configure --enable-coverage --enable-asan --enable-msan --with-mysql --with-pgsql make -j2 SBTEST_MYSQL_ARGS="--mysql-user=root" SBTEST_PGSQL_ARGS="--pgsql-user=postgres" make test ;; esac else # To avoid name conflicts, deploy source packages only for # "default", i.e. x86_64 architecture if [[ -z "${ARCH}" ]]; then PACKAGECLOUD_GLOB='build/*.{rpm,deb,dsc}' else # Exclude *.src.rpm and *.dsc PACKAGECLOUD_GLOB='build/*{[^c].rpm,.deb}' fi git clone https://github.com/akopytov/packpack.git packpack packpack/packpack fi deploy: # Deploy packages to PackageCloud - provider: packagecloud username: "${PACKAGECLOUD_USER}" repository: "${PACKAGECLOUD_REPO}" token: "${PACKAGECLOUD_TOKEN}" dist: "${OS}/${DIST}" package_glob: "${PACKAGECLOUD_GLOB}" skip_cleanup: true on: all_branches: true condition: -n "$OS" && -n "$DIST" && -n "$PACKAGECLOUD_TOKEN" && "$DIST" != "rawhide" && "$DIST" != "sid" after_success: - > if [ "x$TARGET" = "xcoverage" ]; then coveralls --exclude third_party/ --gcov-options '\-lp' fi # Local variables: # mode: yaml # End: sysbench-1.0.18/README.md0000600000175000017500000003732613553247311012511 0ustar jpjp[![Latest Release][release-badge]][release-url] [![Build Status][travis-badge]][travis-url] [![Debian Packages][deb-badge]][deb-url] [![RPM Packages][rpm-badge]][rpm-url] [![Coverage Status][coveralls-badge]][coveralls-url] [![License][license-badge]][license-url] **Table of Contents** - [sysbench](#sysbench) - [Features](#features) - [Installing from Binary Packages](#installing-from-binary-packages) - [Linux](#linux) - [macOS](#macos) - [Windows](#windows) - [Building and Installing From Source](#building-and-installing-from-source) - [Build Requirements](#build-requirements) - [Windows](#windows) - [Debian/Ubuntu](#debianubuntu) - [RHEL/CentOS](#rhelcentos) - [Fedora](#fedora) - [macOS](#macos) - [Build and Install](#build-and-install) - [Usage](#usage) - [General Syntax](#general-syntax) - [General Command Line Options](#general-command-line-options) - [Versioning](#versioning) # sysbench sysbench is a scriptable multi-threaded benchmark tool based on LuaJIT. It is most frequently used for database benchmarks, but can also be used to create arbitrarily complex workloads that do not involve a database server. sysbench comes with the following bundled benchmarks: - `oltp_*.lua`: a collection of OLTP-like database benchmarks - `fileio`: a filesystem-level benchmark - `cpu`: a simple CPU benchmark - `memory`: a memory access benchmark - `threads`: a thread-based scheduler benchmark - `mutex`: a POSIX mutex benchmark ## Features - extensive statistics about rate and latency is available, including latency percentiles and histograms; - low overhead even with thousands of concurrent threads. sysbench is capable of generating and tracking hundreds of millions of events per second; - new benchmarks can be easily created by implementing pre-defined hooks in user-provided Lua scripts; - can be used as a general-purpose Lua interpreter as well, simply replace `#!/usr/bin/lua` with `#!/usr/bin/sysbench` in your script. # Installing from Binary Packages ## Linux The easiest way to download and install sysbench on Linux is using binary package repositories hosted by [packagecloud](https://packagecloud.io). The repositories are automatically updated on each sysbench release. Currently x86_64, i386 and aarch64 binaries are available. Multiple methods to download and install sysbench packages are available and described at . Quick install instructions: - Debian/Ubuntu ``` shell curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | sudo bash sudo apt -y install sysbench ``` - RHEL/CentOS: ``` shell curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash sudo yum -y install sysbench ``` - Fedora: ``` shell curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash sudo dnf -y install sysbench ``` ## macOS On macOS, up-to-date sysbench packages are available from Homebrew: ```shell # Add --with-postgresql if you need PostgreSQL support brew install sysbench ``` ## Windows As of sysbench 1.0 support for native Windows builds was dropped. It may be re-introduced in later releases. Currently, the recommended way to obtain sysbench on Windows is using [Windows Subsystem for Linux available in Windows 10](https://msdn.microsoft.com/en-us/commandline/wsl/about). After installing WSL and getting into he bash prompt on Windows following Debian/Ubuntu installation instructions is sufficient. Alternatively, one can use WSL to build and install sysbench from source, or use an older sysbench release to build a native binary. # Building and Installing From Source It is recommended to install sysbench from the official binary packages as described in [Installing from Binary Packages](#installing-from-binary-packages). Below are instruction for cases when you want to use sysbench on an architecture for which no binary packages are available. ## Build Requirements ### Windows As of sysbench 1.0 support for native Windows builds was dropped. It may be re-introduced in later versions. Currently, the recommended way to build sysbench on Windows is using [Windows Subsystem for Linux available in Windows 10](https://msdn.microsoft.com/en-us/commandline/wsl/about). After installing WSL and getting into bash prompt on Windows, following Debian/Ubuntu build instructions is sufficient. Alternatively, one can build and use an older 0.5 release on Windows. ### Debian/Ubuntu ``` shell apt -y install make automake libtool pkg-config libaio-dev # For MySQL support apt -y install libmysqlclient-dev libssl-dev # For PostgreSQL support apt -y install libpq-dev ``` ### RHEL/CentOS ``` shell yum -y install make automake libtool pkgconfig libaio-devel # For MySQL support, replace with mysql-devel on RHEL/CentOS 5 yum -y install mariadb-devel openssl-devel # For PostgreSQL support yum -y install postgresql-devel ``` ### Fedora ``` shell dnf -y install make automake libtool pkgconfig libaio-devel # For MySQL support dnf -y install mariadb-devel openssl-devel # For PostgreSQL support dnf -y install postgresql-devel ``` ### macOS Assuming you have Xcode (or Xcode Commane Line Tools) and Homebrew installed: ``` shell brew install automake libtool openssl pkg-config # For MySQL support brew install mysql # For PostgreSQL support brew install postgresql # openssl is not linked by Homebrew, this is to avoid "ld: library not found for -lssl" export LDFLAGS=-L/usr/local/opt/openssl/lib ``` ## Build and Install ``` shell ./autogen.sh # Add --with-pgsql to build with PostgreSQL support ./configure make -j make install ``` The above will build sysbench with MySQL support by default. If you have MySQL headers and libraries in non-standard locations (and no `mysql_config` can be found in the `PATH`), you can specify them explicitly with `--with-mysql-includes` and `--with-mysql-libs` options to `./configure`. To compile sysbench without MySQL support, use `--without-mysql`. If no database drivers are available database-related scripts will not work, but other benchmarks will be functional. See [README-Oracle.md](README-Oracle.md) for instructions on building with Oracle client libraries. # Usage ## General Syntax The general command line syntax for sysbench is: sysbench [options]... [testname] [command] - *testname* is an optional name of a built-in test (e.g. `fileio`, `memory`, `cpu`, etc.), or a name of one of the bundled Lua scripts (e.g. `oltp_read_only`), or a *path* to a custom Lua script. If no test name is specified on the command line (and thus, there is no *command* too, as in that case it would be parsed as a *testname*), or the test name is a dash ("`-`"), then sysbench expects a Lua script to execute on its standard input. - *command* is an optional argument that will be passed by sysbench to the built-in test or script specified with *testname*. *command* defines the *action* that must be performed by the test. The list of available commands depends on a particular test. Some tests also implement their own custom commands. Below is a description of typical test commands and their purpose: + `prepare`: performs preparative actions for those tests which need them, e.g. creating the necessary files on disk for the `fileio` test, or filling the test database for database benchmarks. + `run`: runs the actual test specified with the *testname* argument. This command is provided by all tests. + `cleanup`: removes temporary data after the test run in those tests which create one. + `help`: displays usage information for the test specified with the *testname* argument. This includes the full list of commands provided by the test, so it should be used to get the available commands. - *options* is a list of zero or more command line options starting with `'--'`. As with commands, the `sysbench testname help` command should be used to describe available options provided by a particular test. See [General command line options](README.md#general-command-line-options) for a description of general options provided by sysbench itself. You can use `sysbench --help` to display the general command line syntax and options. ## General Command Line Options The table below lists the supported common options, their descriptions and default values: *Option* | *Description* | *Default value* ----------------------|---------------|---------------- | `--threads` | The total number of worker threads to create | 1 | | `--events` | Limit for total number of requests. 0 (the default) means no limit | 0 | | `--time` | Limit for total execution time in seconds. 0 means no limit | 10 | | `--rate` | Average transactions rate. The number specifies how many events (transactions) per seconds should be executed by all threads on average. 0 (default) means unlimited rate, i.e. events are executed as fast as possible | 0 | | `--thread-stack-size` | Size of stack for each thread | 32K | | `--report-interval` | Periodically report intermediate statistics with a specified interval in seconds. Note that statistics produced by this option is per-interval rather than cumulative. 0 disables intermediate reports | 0 | | `--debug` | Print more debug info | off | | `--validate` | Perform validation of test results where possible | off | | `--help` | Print help on general syntax or on a test mode specified with --test, and exit | off | | `--verbosity` | Verbosity level (0 - only critical messages, 5 - debug) | 4 | | `--percentile` | sysbench measures execution times for all processed requests to display statistical information like minimal, average and maximum execution time. For most benchmarks it is also useful to know a request execution time value matching some percentile (e.g. 95% percentile means we should drop 5% of the most long requests and choose the maximal value from the remaining ones). This option allows to specify a percentile rank of query execution times to count | 95 | Note that numerical values for all *size* options (like `--thread-stack-size` in this table) may be specified by appending the corresponding multiplicative suffix (K for kilobytes, M for megabytes, G for gigabytes and T for terabytes). # Versioning For transparency and insight into its release cycle, and for striving to maintain backward compatibility, sysbench will be maintained under the Semantic Versioning guidelines as much as possible. Releases will be numbered with the following format: `..` And constructed with the following guidelines: * Breaking backward compatibility bumps the major (and resets the minor and patch) * New additions without breaking backward compatibility bumps the minor (and resets the patch) * Bug fixes and misc changes bumps the patch For more information on SemVer, please visit [http://semver.org/](http://semver.org/). [coveralls-badge]: https://coveralls.io/repos/github/akopytov/sysbench/badge.svg?branch=1.0 [coveralls-url]: https://coveralls.io/github/akopytov/sysbench?branch=1.0 [travis-badge]: https://travis-ci.org/akopytov/sysbench.svg?branch=1.0 [travis-url]: https://travis-ci.org/akopytov/sysbench?branch=1.0 [license-badge]: https://img.shields.io/badge/license-GPLv2-blue.svg [license-url]: COPYING [release-badge]: https://img.shields.io/github/release/akopytov/sysbench.svg [release-url]: https://github.com/akopytov/sysbench/releases/latest [deb-badge]: https://img.shields.io/badge/Packages-Debian-red.svg?style=flat [deb-url]: https://packagecloud.io/akopytov/sysbench?filter=debs [rpm-badge]: https://img.shields.io/badge/Packages-RPM-blue.svg?style=flat [rpm-url]: https://packagecloud.io/akopytov/sysbench?filter=rpms sysbench-1.0.18/snap/0000700000175000017500000000000013553247311012156 5ustar jpjpsysbench-1.0.18/snap/snapcraft.yaml.in0000600000175000017500000000163313553247311015435 0ustar jpjpname: sysbench version: @PACKAGE_VERSION@ summary: Scriptable database and system performance benchmark description: | sysbench is a scriptable multi-threaded benchmark tool based on LuaJIT. It is most frequently used for database benchmarks, but can also be used to create arbitrarily complex workloads that do not involve a database server. sysbench comes with the following bundled benchmarks: - oltp_*.lua: a collection of OLTP-like database benchmarks - fileio: a filesystem-level benchmark - cpu: a simple CPU benchmark - memory: a memory access benchmark - threads: a thread-based scheduler benchmark - mutex: a POSIX mutex benchmark grade: stable confinement: classic apps: sysbench: command: sysbench plugs: - network parts: sysbench: source: . plugin: autotools build-packages: - libmysqlclient-dev stage-packages: - libmysqlclient20 - libaio1 sysbench-1.0.18/configure.ac0000600000175000017500000003463013553247311013513 0ustar jpjp# Process this file with autoconf to produce a configure script. AC_PREREQ(2.63) AC_INIT([sysbench],[1.0.18],[https://github.com/akopytov/sysbench/issues], [sysbench], [https://github.com/akopytov/sysbench]) AC_CONFIG_AUX_DIR([config]) # Define m4_ifblank and m4_ifnblank macros from introduced in # autotools 2.64 m4sugar.m4 if using an earlier autotools. m4_ifdef([m4_ifblank], [], [ m4_define([m4_ifblank], [m4_if(m4_translit([[$1]], [ ][ ][ ]), [], [$2], [$3])]) ]) m4_ifdef([m4_ifnblank], [], [ m4_define([m4_ifnblank], [m4_if(m4_translit([[$1]], [ ][ ][ ]), [], [$3], [$2])]) ]) # Setting CFLAGS here prevents AC_CANONICAL_TARGET from injecting them SAVE_CFLAGS=${CFLAGS} SAVE_CXXFLAGS=${CXXFLAGS} CFLAGS= CXXFLAGS= AC_CANONICAL_TARGET CFLAGS=${SAVE_CFLAGS} CXXFLAGS=${SAVE_CXXFLAGS} AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_CONFIG_SRCDIR([src/sysbench.c]) AC_CONFIG_HEADER([config/config.h]) AC_CONFIG_MACRO_DIR([m4]) m4_pattern_forbid([^PKG_[A-Z_]+$], [pkg-config has to be installed to build sysbench]) ACX_USE_SYSTEM_EXTENSIONS AC_PROG_CC AC_PROG_CC_C99 AC_PROG_CPP AM_PROG_CC_C_O if test x"$ac_cv_prog_cc_c99" = xno; then AC_MSG_ERROR([a C99 compiler is required to build sysbench]) fi # Try to guess the most optimal compiler architecture flag, unless it's already # been specified by the user via CFLAGS (or --without-gcc-arch is passed to # configure) AS_CASE([$CFLAGS], [*-march=*],, [AX_GCC_ARCHFLAG([no])] ) m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_PROG_LIBTOOL AC_CHECK_PROG(sb_have_pkg_config, pkg-config, yes, no) if test x"$sb_have_pkg_config" = xno; then AC_MSG_ERROR([the pkg-config package is required to build sysbench]) fi AX_COMPILER_VENDOR # Checks for user arguments AC_LIB_PREFIX() # Additional linker flags AC_ARG_WITH([extra-ldflags], AS_HELP_STRING([--with-extra-ldflags],[additional linker flags, e.g. -all-static]), EXTRA_LDFLAGS=$withval ) AC_SUBST(EXTRA_LDFLAGS) CPPFLAGS="-D_GNU_SOURCE ${CPPFLAGS}" # Mac OS X requires _DARWIN_C_SOURCE for valloc(3) to be visible case "${host_cpu}-${host_os}" in *-darwin*) CPPFLAGS="-D_DARWIN_C_SOURCE ${CPPFLAGS}";; esac # Build optimized or debug version ? # First check for gcc and g++ if test "$GCC" = "yes" then CFLAGS="-ggdb3 ${CFLAGS}" DEBUG_CFLAGS="-O0" OPTIMIZE_CFLAGS="-O2 -funroll-loops" GCOV_CFLAGS="-O0 --coverage" GCOV_LDFLAGS="-coverage" ASAN_CFLAGS="-fsanitize=address" ASAN_LDFLAGS="${ASAN_CFLAGS}" MSAN_CFLAGS="-fsanitize=memory" MSAN_LDFLAGS="${MSAN_LDFLAGS}" fi if test "$ax_cv_c_compiler_vendor" = "sun" then isainfo_k=`isainfo -k` if test "$target_cpu" = "sparc" then MEMALIGN_FLAGS="-xmemalign=8s" IS_64="-m64" LDFLAGS="${LDFLAGS} -L/usr/lib/${isainfo_k} -L/usr/local/lib/${isainfo_k}" else if test "$isainfo_k" = "amd64" then IS_64="-m64" LDFLAGS="${LDFLAGS} -L/usr/lib/${isainfo_k} -L/usr/local/lib/${isainfo_k}" fi fi CPPFLAGS="${CPPFLAGS} -I/usr/local/include" CFLAGS="-g -mt ${IS_64} ${MEMALIGN_FLAGS} ${CFLAGS}" DEBUG_CFLAGS="-xO0" OPTIMIZE_CFLAGS="-xO2 -xlibmil -xdepend -Xa -mt -xstrconst" # TODO: Set flags for Gcov-enabled builds, if supported by Sun Studio fi # Check if we should compile with MySQL support AC_ARG_WITH([mysql], AS_HELP_STRING([--with-mysql], [compile with MySQL support (default is enabled)]), [], [with_mysql=yes]) AC_MSG_CHECKING([whether to compile with MySQL support]) AS_IF([test "x$with_mysql" != "xno"], [mysql_support=yes], [mysql_support=no]) AC_MSG_RESULT([$mysql_support]) # Check if we should compile with Drizzle support AC_ARG_WITH([drizzle], AS_HELP_STRING([--with-drizzle], [compile with Drizzle support (default is disabled)]), [], [with_drizzle=no]) AC_MSG_CHECKING([whether to compile with Drizzle support]) AS_IF([test "x$with_drizzle" != "xno"], [drizzle_support=yes], [drizzle_support=no]) AC_MSG_RESULT([$drizzle_support]) # Check if we should compile with libattachsql support AC_ARG_WITH([attachsql], AS_HELP_STRING([--with-attachsql], [compile with libattachsql support (default is disabled)]), [], [with_attachsql=no]) AC_MSG_CHECKING([whether to compile with libattachsql support]) AS_IF([test "x$with_attachsql" != "xno"], [attachsql_support=yes], [attachsql_support=no]) AC_MSG_RESULT([$attachsql_support]) # Check if we should compile with Oracle support AC_ARG_WITH([oracle], AS_HELP_STRING([--with-oracle], [compile with Oracle support (default is disabled)]), [], [with_oracle=no]) AC_MSG_CHECKING([whether to compile with Oracle support]) AS_IF([test "x$with_oracle" != "xno"], [oracle_support=yes], [oracle_support=no]) AC_MSG_RESULT([$oracle_support]) # Check if we should compile with PostgreSQL support AC_ARG_WITH([pgsql], AS_HELP_STRING([--with-pgsql], [compile with PostgreSQL support (default is disabled)]), [], [with_pgsql=no]) AC_MSG_CHECKING([whether to compile with PostgreSQL support]) AS_IF([test "x$with_pgsql" != "xno"], [pgsql_support=yes], [pgsql_support=no]) AC_MSG_RESULT([$pgsql_support]) # Set LuaJIT flags SB_LUAJIT # Set Concurrency Kit flags SB_CONCURRENCY_KIT # Check if we should enable large files support AC_ARG_ENABLE(largefile, AS_HELP_STRING([--enable-largefile],[enable large files support (default is enabled)]), , enable_largefile=yes ) # For SHM_HUGETLB on Linux AC_CHECK_DECLS(SHM_HUGETLB, AC_DEFINE([HAVE_LARGE_PAGES], [1], [Define if you have large pages support]) AC_DEFINE([HUGETLB_USE_PROC_MEMINFO], [1], [Define if /proc/meminfo shows the huge page size (Linux only)]) , , [ #include ] ) # Check if we should enable Linux AIO support AC_ARG_ENABLE(aio, AS_HELP_STRING([--enable-aio],[enable Linux asynchronous I/O support (default is enabled)]), , enable_aio=yes ) AC_CHECK_DECLS(O_SYNC, , AC_DEFINE([O_SYNC], [O_FSYNC], [Define to the appropriate value for O_SYNC on your platform]), [ #include ] ) # Checks for programs. AX_CHECK_DOCBOOK # Checks for libraries. ACX_PTHREAD AC_CHECK_LIB(m, sqrt) SB_CHECK_MYSQL AS_IF([test "x$with_drizzle" != xno], [ AC_LIB_HAVE_LINKFLAGS(drizzle,, [#include ], [ int x= DRIZZLE_RETURN_ERROR_CODE; const char *version= drizzle_version(); ]) AS_IF([test "x$ac_cv_libdrizzle" = xyes], [ AC_DEFINE([USE_DRIZZLE],1, [Define to 1 if you want to compile with Drizzle support]) ]) ]) AM_CONDITIONAL(USE_DRIZZLE, test x$ac_cv_libdrizzle = xyes) AS_IF([test "x$with_attachsql" != xno], [ AC_LIB_HAVE_LINKFLAGS(attachsql,, [#include ], [ const char *version= attachsql_get_library_version(); ]) AS_IF([test "x$ac_cv_libattachsql" = xyes], [ AC_DEFINE(USE_ATTACHSQL,1, [Define to 1 if you want to compile with libattachsql support]) ]) ]) AM_CONDITIONAL(USE_ATTACHSQL, test x$ac_cv_libattachsql = xyes) AS_IF([test x$with_oracle != xno], [ AC_DEFINE(USE_ORACLE,1,[Define to 1 if you want to compile with Oracle support]) ORA_LIBS="-L${sb_with_oracle}/lib -lclntsh" ORA_CFLAGS="-I${with_oracle}/include -I${with_oracle}/rdbms/demo -I${with_oracle}/rdbms/public" AC_SUBST([ORA_LIBS]) AC_SUBST([ORA_CFLAGS]) ]) AM_CONDITIONAL(USE_ORACLE, test x$with_oracle != xno) AS_IF([test x$with_pgsql != xno], [ AC_CHECK_PGSQL([$with_pgsql]) USE_PGSQL=1 AC_DEFINE(USE_PGSQL,1,[Define to 1 if you want to compile with PostgreSQL support]) AC_SUBST([PGSQL_LIBS]) AC_SUBST([PGSQL_CFLAGS]) ]) AM_CONDITIONAL(USE_PGSQL, test x$with_pgsql != xno) AC_SUBST([USE_PGSQL]) # Check for libaio AC_CHECK_AIO AM_CONDITIONAL(USE_AIO, test x$enable_aio = xyes) # Check for advanced memory allocation libraries AC_CHECK_LIB([umem], [malloc], [EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lumem"], AC_CHECK_LIB([mtmalloc], [malloc], [EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lmtmalloc"]) ) # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([ \ errno.h \ fcntl.h \ math.h \ pthread.h \ sched.h \ signal.h \ stdlib.h \ string.h \ sys/aio.h \ sys/ipc.h \ sys/time.h \ sys/mman.h \ sys/shm.h \ thread.h \ unistd.h \ limits.h \ libgen.h \ ]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_OFF_T AC_HEADER_TIME AX_TLS([], AC_MSG_ERROR([thread-local storage is not suppored by the target platform!]) ) # Define HAVE_FUNC_ATTRIBUTE_FORMAT if compiler supports the # __attribute__((format...)) function attribute AX_GCC_FUNC_ATTRIBUTE(format) # Define HAVE_FUNC_ATTRIBUTE_UNUSED if compiler supports the # __attribute__((unused)) function attribute AX_GCC_FUNC_ATTRIBUTE(unused) if test "$enable_largefile" = yes; then AC_SYS_LARGEFILE fi AC_CHECK_SIZEOF(size_t) AC_CHECK_SIZEOF(bool,, [ #include ]) # Checks for library functions. AC_FUNC_MMAP AC_FUNC_STRERROR_R AC_SEARCH_LIBS([clock_gettime], [rt]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_CHECK_FUNCS([ \ alarm \ clock_gettime \ directio \ fdatasync \ gettimeofday \ isatty \ memalign \ memset \ posix_memalign \ pthread_yield \ setvbuf \ sqrt \ strdup \ thr_setconcurrency \ valloc \ ]) AC_CHECK_FUNC(pthread_once, , AC_MSG_ERROR([*** pthread_once() is not available on this platform ***]) ) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_ARG_WITH([debug], [AS_HELP_STRING([--with-debug], [Add debug code/turns off optimizations (yes|no) @<:@default=no@:>@])], [with_debug=$withval], [with_debug=no]) AC_ARG_ENABLE([coverage], [AS_HELP_STRING([--enable-coverage], [Toggle coverage @<:@default=no@:>@])], [ac_coverage="$enableval"], [ac_coverage="no"]) AC_ARG_ENABLE([asan], [AS_HELP_STRING([--enable-asan], [Enable AddressSanitizer @<:@default=no@:>@])], [ac_asan="$enableval"], [ac_asan="no"]) AC_ARG_ENABLE([msan], [AS_HELP_STRING([--enable-msan], [Enable MemorySanitizer @<:@default=no@:>@])], [ac_msan="$enableval"], [ac_msan="no"]) AC_ARG_ENABLE([fail], [AS_HELP_STRING([--disable-fail], [Turn warnings into failures @<:@default=no@:>@])], [ac_warn_fail="$enableval"], [ac_warn_fail="no"]) if test "$with_debug" = "yes" then # Debugging. No optimization. CFLAGS="${DEBUG_CFLAGS} -DDEBUG ${CFLAGS}" elif test "$ac_coverage" = "yes" then # Gcov-enabled build. No optimization. CFLAGS="${GCOV_CFLAGS} ${CFLAGS}" LDFLAGS="${GCOV_LDFLAGS} ${LDFLAGS}" else # Optimized version. No debug CFLAGS="${OPTIMIZE_CFLAGS} ${CFLAGS}" fi if test "$ac_asan" = "yes" then # Add -fsanitize=address to CFLAGS/LDFLAGS if supported by the compiler AX_CHECK_COMPILE_FLAG([-fsanitize=address], [ CFLAGS="${ASAN_CFLAGS} ${CFLAGS}" LDFLAGS="${ASAN_LDFLAGS} ${LDFLAGS}" ]) fi if test "$ac_msan" = "yes" then # Add -fsanitize=memory to CFLAGS/LDFLAGS if supported by the compiler AX_CHECK_COMPILE_FLAG([-fsanitize=memory], [ CFLAGS="${MSAN_CFLAGS} ${CFLAGS}" LDFLAGS="${MSAN_CFLAGS} ${LDFLAGS}" ]) fi if test "$GCC" = "yes" then if test "$ac_warn_fail" = "yes" then W_FAIL="-Werror" fi CC_WARNINGS="-Wall -Wextra -Wpointer-arith -Wbad-function-cast \ -Wstrict-prototypes -Wnested-externs -Wno-format-zero-length \ -Wundef -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \ -Wredundant-decls -Wcast-align -Wvla ${W_FAIL}" fi if test "$ax_cv_c_compiler_vendor" = "sun" then CC_WARNINGS="-v -errtags=yes -errwarn=%all -erroff=E_INTEGER_OVERFLOW_DETECTED -erroff=E_STATEMENT_NOT_REACHED" fi AM_CFLAGS="${CC_WARNINGS} ${AM_CFLAGS} ${PTHREAD_CFLAGS}" AM_CPPFLAGS="${AM_CPPFLAGS} -I\$(top_srcdir)/src ${LUAJIT_CFLAGS} ${CK_CFLAGS}" AM_LDFLAGS="$PTHREAD_LIBS" AC_SUBST(AM_CFLAGS) AC_SUBST(AM_CPPFLAGS) AC_SUBST(AM_LDFLAGS) # Define SB_GIT_SHA git=$(which git) if test -n "$git" then SB_GIT_SHA=$(git rev-parse --short HEAD 2>/dev/null) if test -n "$SB_GIT_SHA" then SB_GIT_SHA="-$SB_GIT_SHA" fi fi AC_DEFINE_UNQUOTED([SB_GIT_SHA], ["$SB_GIT_SHA"], [Git commit hash, if available.]) AC_SUBST([SB_GIT_SHA]) AC_CONFIG_FILES([ Makefile doc/xsl/Makefile doc/xsl/catalog.xml doc/Makefile third_party/luajit/Makefile third_party/concurrency_kit/Makefile src/Makefile src/drivers/Makefile src/drivers/mysql/Makefile src/drivers/drizzle/Makefile src/drivers/oracle/Makefile src/drivers/pgsql/Makefile src/drivers/attachsql/Makefile src/tests/Makefile src/tests/cpu/Makefile src/tests/fileio/Makefile src/tests/memory/Makefile src/tests/threads/Makefile src/tests/mutex/Makefile src/lua/Makefile src/lua/internal/Makefile tests/Makefile tests/include/config.sh snap/snapcraft.yaml ]) AC_OUTPUT AC_MSG_RESULT([===============================================================================]) AC_MSG_RESULT([sysbench version : ${PACKAGE_VERSION}${SB_GIT_SHA}]) AC_MSG_RESULT([CC : ${CC}]) AC_MSG_RESULT([CFLAGS : ${CFLAGS} ${AM_CFLAGS}]) AC_MSG_RESULT([CPPFLAGS : ${CPPFLAGS} ${AM_CPPFLAGS}]) AC_MSG_RESULT([LDFLAGS : ${LDFLAGS} ${AM_LDFLAGS}]) AC_MSG_RESULT([LIBS : ${LIBS}]) AC_MSG_RESULT([EXTRA_LDFLAGS : ${EXTRA_LDFLAGS}]) AC_MSG_RESULT([]) AC_MSG_RESULT([prefix : $(eval echo ${prefix})]) AC_MSG_RESULT([bindir : $(eval echo ${bindir})]) AC_MSG_RESULT([libexecdir : $(eval echo ${libexecdir})]) AC_MSG_RESULT([mandir : $(eval echo ${mandir})]) AC_MSG_RESULT([datadir : $(eval echo ${datadir})]) AC_MSG_RESULT([]) AC_MSG_RESULT([MySQL support : ${mysql_support}]) AC_MSG_RESULT([Drizzle support : ${drizzle_support}]) AC_MSG_RESULT([AttachSQL support : ${attachsql_support}]) AC_MSG_RESULT([Oracle support : ${oracle_support}]) AC_MSG_RESULT([PostgreSQL support : ${pgsql_support}]) AC_MSG_RESULT([]) AC_MSG_RESULT([LuaJIT : ${sb_use_luajit}]) AC_MSG_RESULT([LUAJIT_CFLAGS : ${LUAJIT_CFLAGS}]) AC_MSG_RESULT([LUAJIT_LIBS : ${LUAJIT_LIBS}]) AC_MSG_RESULT([LUAJIT_LDFLAGS : ${LUAJIT_LDFLAGS}]) AC_MSG_RESULT([]) AC_MSG_RESULT([Concurrency Kit : ${sb_use_ck}]) if test "$sb_use_ck" = bundled; then AC_MSG_RESULT([CK_CFLAGS : ${CK_CFLAGS}]) AC_MSG_RESULT([CK_LIBS : ${CK_LIBS}]) AC_MSG_RESULT([configure flags : ${CK_CONFIGURE_FLAGS}]) fi AC_MSG_RESULT([===============================================================================]) sysbench-1.0.18/ChangeLog0000600000175000017500000003730413553247311013000 0ustar jpjp2019-10-21 Alexey Kopytov * version 1.0.18 * build/CI/packaging: add Ubuntu Eoan. * build/CI/packaging: remove Ubuntu Cosmic (EOL). * build/CI/packaging: add CentOS 8. * build/CI/packaging: add Ubuntu Disco. * build/CI/packaging: remove Ubuntu Trusty (EOL). * build/CI/packaging: remove Fedora 28 (EOL). * build/CI/packaging: add Fedora 30. * build/CI/packaging: cherry-pick fix for LuaJIT/LuaJIT#484 to fix builds on macOS Mojave. * build/CI/packaging: add Debian Buster 2019-03-15 Alexey Kopytov * version 1.0.17 * build/CI/packaging: update RPM spec to support RHEL8-beta (thanks to Alexey Bychko for the patch) * regression tests: remove unnecessary error leading to opt_rate.t instability. * --rate mode: return a non-zero exit code on event queue overflow. * --rate mode: fix a bogus error about eventgen thread termination 2018-12-16 Alexey Kopytov * version 1.0.16 * build/CI/packaging: add Ubuntu Cosmic. * build/CI/packaging: add Fedora 29. * build/CI/packaging: remove Fedora 27 (EOL). * SQL API: fix GH-282 (Mysql's fetch_row() is broken) * --rate mode: fix latency stats skew on low rates * Lua: Add /usr/share/lua/5.1 to LUA_PATH and /usr/lib/lua/5.1 to LUA_CPATH. * build/CI/packaging: add -Wvla to default compiler flags. * build/CI/packaging: fix debian/changelog format * build/CI/packaging: fix buildpack.sh to not push multiple file types to packagecloud. * build/CI/packaging: add libaio-dev to Debian/Ubuntu build dependencies. 2018-07-03 Alexey Kopytov * version 1.0.15 * CI/build/packaging: add Fedora 28 * CI/build/packaging: add Ubuntu Bionic * CI/build/packaging: remove Fedora 26 (EOL) * CI/build/packaging: remove Debian Wheezy (EOL) * fileio: fix GH-229 (--file-fsync-freq=0 seems to prevent fsync() at the end of the test) * command line: improve parsing of boolean command line options * tests: fix GH-220 (Testsuite api_sql_mysql.t failed ...) * tests: fix GH-223 (test failure on ppc64) * tests: fix opt_help.t to pass when the binary is not configured with MySQL support * MySQL driver: use it by default in DB benchmarks 2018-04-01 Alexey Kopytov * version 1.0.14 * reports: fix JSON stats reporter to produce valid JSON (GH-195) * Lua SQL API: don't crash when query_row() is called with a SELECT returning empty result set * Lua SQL API: don't crash when bulk insert API calls are used out of order * regression tests: make PostgreSQL tests compatible with the new dump format introduced in 10.3 * regression tests: minor stability and coverage improvements 2018-02-17 Alexey Kopytov * version 1.0.13 * remove Ubuntu Zesty from CI/build/packaging matrices (EOL) * minor cleanups in build scripts * improve report formatting for long latency values * fileio: --file-extra-flags now accepts a list of flags rather than just a single value * OLTP: re-prepare prepared statements after reconnects, i.e. in cases when a server connection is lost and sysbench is configured to ignore such errors 2018-01-17 Alexey Kopytov * version 1.0.12 * improve --rate mode precision for high argument values * add Fedora Rawhide and Debian Sid to CI matrix * fix compile-time architecture detection for some Broadwell CPUs which were incorrectly identified as Core 2. * remove build dependency on xxd (and vim-minimal package) * fix Lua API to correctly stop the benchmark when event() returns a value other than nil or false (thanks to caojiafeng for the patch) * fix the fileio benchmark when the specified file size is not a multiple of block size * fix the fileio benchmark to throw a descriptive error when the specified file size does not match the size of files created by 'prepare' * remove Fedora 25 from CI/build/packaging matrices (EOL) * minor improvements in tests and documentation. 2017-12-09 Alexey Kopytov * version 1.0.11 * add Debian Stretch to CI/build/packaging matrices * add Fedora 27 to CI/build/packaging matrices * make statistic counters usable from Lua scripts * fix the PostgreSQL driver to be compatible with CockroachDB (GH-180) * fix oltp_insert.lua to work correctly when both --tables and --threads are greater than 1 (GH-178) * fix FreeBSD builds by adding -rdynamic to the default linker flags (GH-174) * minor documentation updates 2017-10-25 Alexey Kopytov * version 1.0.10 * fixed PK conflicts in oltp_insert.lua by creating empty tables on 'prepare' * made sysbench.opt available to init()/done() by exporting it to the global Lua state * added Fedora 26 (both x86_64 and AArch64) to the list of supported and tested distributions * fixed GH-172: sysbench 1.0.9 doesn't build with mariadb 10.2.8 * add the /usr/local LuaRocks root directory to default LUA_PATH and LUA_CPATH * removed Fedora 24, Ubuntu Precise, Yakkety from default build matrices * added Ubuntu Artful to default build matrices 2017-09-05 Alexey Kopytov * version 1.0.9 * fixed oltp_delete.lua to not use INSERT statements for consistency with other oltp_* benchmarks (GH-168) * added a workaround for MySQL bug #87337 "8.0.2 reintroduces my_bool to client API" * fixed building on on Debian GNU/kFreeBSD (GH-161) * fixed building against MariaDB 10.2 (thanks to Xavier Bachelot for the patch, GH-160) 2017-07-04 Alexey Kopytov * version 1.0.8 * fixed api_report test for slow machines (thanks to @jcfp) * fileio: suggest to run prepare step on missing files (thanks to Heinrich Schuchardt) * JSON reports: removed an erroneous trailing comma (GH-139) * added events per second to the CPU benchmark report (GH-140) * fixed db_connect() in legacy SQL API to use the default value for --db-driver (GH-146) * removed busy-wait in the bounded event generation mode (--rate) to avoid CPU hogging 2017-05-15 Alexey Kopytov * version 1.0.7 * Ubuntu Zesty added to package build matrix * fixed GH-130: Mutex Benchmark Documentation * fixed latency reports in the --rate mode * fixed compiler warnings when building against MySQL 8.0 client libraries 2017-04-13 Alexey Kopytov * version 1.0.6 * no functional changes * many build- and packaging-related improvements * Linux packages are now automatically built using Travis CI and packpack, hosted by packagecloud.io 2017-04-02 Alexey Kopytov * version 1.0.5 * various build-related documentation updates * benchmark can now be specified by a module name on the command line * memory benchmark: performance and scalability improvements * fix ARMv6 builds with system ConcurrencyKit * fix GH-123: Table already exists error on prepare * fix GH-121: make buildhost cpudetection optional 2017-03-13 Alexey Kopytov * version 1.0.4 * fixed a number of compilation errors and warnings that were specific to 32-bit platforms * bundle cram (regression tests framework) and use it by default in 'make test' * bundled ConcurrencyKit updated to 0.6.0 2017-02-26 Alexey Kopytov * version 1.0.3 * LuaJIT scalability improvements for non-x86 architectures * performance optimizations in oltp_read_write.lua to avoid Lua string management * fixed Illumos builds (thanks to Dillon Amburgey) 2017-02-17 Alexey Kopytov * version 1.0.2 * improved scalability for --report-checkpoints mode * fix builds on CentoOS 6 and autoconf 2.63 * support for Snap (http://snapcraft.io) packages 2017-02-05 Alexey Kopytov * version 1.0.1 * fix clock_gettime runtime failure built with macOS 10.11 and Xcode 8.x 2017-02-04 Aleksei Kopytov * version 1.0.0 * too much time and too many changes since the previous formal release, so briefly: * Lua scripts instead of hard-coded C tests for database ("oltp") benchmarks + ability to create custom workloads * much better single-threaded performance * much better scalability * improvements and cleanups in command line syntax and options * latency histograms in cumulative statistic reports * report hooks to print statistics in custom formats (CSV/JSON/XML/etc.) * Dropped Windows support * Dropped support for Oracle, Drizzle and libattachsql drivers 2006-10-10 Alexey Kopytov * Removed the debugging code in OLTP test which got into 0.4.7 by mistake * Handle ER_CHECKREAD in the same way as deadlocks in the MySQL driver * version 0.4.8 2006-05-28 Alexey Kopytov * count fsync() time as request execution time in file-fsync-all mode 2006-05-24 Alexey Kopytov * Added --oltp-reconnect option 2006-05-18 Alexey Kopytov * Allow build with non-gcc compilers * Fixed random numbers generation on Solaris * Added --mysql-ssl option * version 0.4.7 2006-04-03 Alexey Kopytov * Added a warning for inaccurate gettimeofday() implementations * version 0.4.6 2006-03-10 Alexey Kopytov * Fixed crash at the end of OLTP test 2006-03-03 Alexey Kopytov * Made auto_increment id column optional * Use TYPE= or ENGINE= in MySQL driver depending on the version of client libraries 2006-01-17 Alexey Kopytov * version 0.4.5 * Added several hosts capability to MySQL driver * Fixed several memory leaks in OLTP test 2005-12-14 Alexey Kopytov * Renamed option 'mysql-table-type' to 'mysql-table-engine' * It's now possible to pass arbitrary engine names to MySQL driver * Transactions support must be explicitly specified with 'mysql-engine-trx' option for those engines, which are unknown to SysBench 2005-09-27 Alexey Kopytov * Changed 'thread fairness' calculation from percents to stddev * Added validation mode to OLTP test (--validate switch) * Remove auto_increment from the 'id' field before running OLTP tests * Print separate time for query execution and result fetching in --debug mode * version 0.4.3 2005-07-25 Alexey Kopytov * Minor cleanups in help messages * Several FreeBSD-related fixes * Fixed the Oracle driver * Version 0.4.1 2005-03-04 Alexey Kopytov * Fixed a lot of small bugs, including portability issues on Mac OS X, 64-bit platforms and old MySQL versions * Documentation added to the main tree * New validation mode in fileio test 2005-01-27 Alexey Kopytov * Fixed compilation on Solaris * Added call to thr_setconcurrency() on Solaris * Fixed an overflow bug in sb_timer_current() * Changed the default number of threads to 1 * Added non-transactional mode to the OLTP test * Fixed bug with excessive number of connections in OLTP test * Handle ER_LOCK_WAIT_TIMEOUT in the same way as ER_LOCK_DEADLOCK * Version 0.3.2 2004-07-27 Alexey Kopytov * Fixed MySQL driver to use new PS API in MySQL >= 4.1.2 2004-07-12 Alexey Kopytov * Fixed final fsync in random I/O requests * Fixed several race conditions 2004-07-09 Alexey Kopytov * Removed --oltp-time-limit option (obsoleted by --max-time) 2004-07-06 Alexey Kopytov * Changed statistics output to more human-readable format 2004-07-04 Alexey Kopytov * Added new logger interface to internal API * Modified all tests to use the new logger interface 2004-06-17 Alexey Kopytov * Fixed table type autodetection with MySQL >= 4.1 2004-06-06 Alexey Kopytov * Added preliminary support of prepared statements to DB API 2004-05-31 Alexey Kopytov * Added slow-mmap mode for 32-bit boxes in fileio test 2004-05-30 Alexey Kopytov * Fixed compilation with gcc >= 3.3 * Fixed 'prepare' command for sequential write test 2004-05-26 Alexey Kopytov * Changed formatting of file sizes in output * Fixed type cast warning on SuSE 8.1 2004-05-21 Alexey Kopytov * Added mutex performance benchmark 2004-05-12 Alexey Kopytov * Extended memory benchmark to calculate more useful results 2004-05-10 Alexey Kopytov * Split test file creation, test running and cleaning up into separate commands (prepare, run, cleanup) for fileio test 2004-05-05 Alexey Kopytov * Removed limit on maximum block size for fileio test 2004-05-04 Alexey Kopytov * added --max-time option to limit total test execution time 2004-05-03 Alexey Kopytov * Fixed compilation with --without-mysql option. 2004-04-13 Alexey Kopytov * Added mmaped I/O support to fileio test 2004-04-11 Alexey Kopytov * Changed default table size to a lower value in OLTP test 2004-04-07 Alexey Kopytov * Added automatic table type detection to MySQL driver * Changed the default table type for MySQL driver to InnoDB * Added support for BDB and NDB table types 2004-04-06 Alexey Kopytov * Added autoconf macro to handle older (incompatible) version of libaio.h 2004-04-05 Alexey Kopytov * Fixed compilation on 64-bit systems * Replaced Linux AIO calls with more portable equivalents 2004-04-04 Alexey Kopytov * Added parameter to specify maximum number of queued operations in fileio async mode (file-async-backlog) * Added parameter to specify extra open() flags (file-extra-flags) * Fixed memory allocation bug in command line parser 2004-04-02 Alexey Kopytov * Added Linux asynchronous I/O support to fileio test * Fixed bug with statistic counters 2004-04-01 Alexey Kopytov * Added test file creation to fileio test * Added read-only mode to OLTP test 2004-03-31 Alexey Kopytov * Close database connections in OLTP test * Added file-fsync-all mode for fileio test 2004-03-30 Alexey Kopytov * Added myisam-max-rows option for MySQL driver * Fixed configure.ac for cases when no MySQL libraries found 2004-03-10 Alexey Kopytov * Implement proper handling of table locks in OLTP test 2004-03-09 Alexey Kopytov * Recognize MySQL table type when creating test database * Fix driver-specific options * Now it's possible to pass MySQL root directory in --with-mysql option * Trim trailing '.libs' if user passed it in --with-mysql-libs option to configure 2004-03-08 Alexey Kopytov * Build drivers and tests as separate libraries (first step to dynamically loaded modules) * Display help when required arguments are missing in fileio test * Changed code formatting to match MySQL coding guidelines 2004-03-04 Alexey Kopytov * Generalized DB-dependent code * Added 'database capabilities' feature 2004-02-28 Alexey Kopytov * Fixed possible memory leak in sql request generator 2004-03-27 Alexey Kopytov * Split OLTP code into DB-independent part and MySQL driver 2004-02-23 Alexey Kopytov * Use libtool for linking with external libraries * Statically link external libraries when they are not installed 2004-02-19 Alexey Kopytov * Print more info when configure finds no MySQL development files * Added --with-mysql-includes and --with-mysql-libs to configure * Fixed compilation error when compiling without MySQL support * Combine several inserts into one query to speed up database creation sysbench-1.0.18/config/0000700000175000017500000000000013553247311012462 5ustar jpjpsysbench-1.0.18/config/config.rpath0000600000175000017500000004364713553247311015007 0ustar jpjp#! /bin/sh # Output a system dependent set of variables, describing how to set the # run time search path of shared libraries in an executable. # # Copyright 1996-2007 Free Software Foundation, Inc. # Taken from GNU libtool, 2001 # Originally by Gordon Matzigkeit , 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # # The first argument passed to this file is the canonical host specification, # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld # should be set by the caller. # # The set of defined variables is at the end of this script. # Known limitations: # - On IRIX 6.5 with CC="cc", the run time search patch must not be longer # than 256 bytes, otherwise the compiler driver will dump core. The only # known workaround is to choose shorter directory names for the build # directory and/or the installation directory. # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a shrext=.so host="$1" host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` # Code taken from libtool.m4's _LT_CC_BASENAME. for cc_temp in $CC""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` # Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. wl= if test "$GCC" = yes; then wl='-Wl,' else case "$host_os" in aix*) wl='-Wl,' ;; darwin*) case $cc_basename in xlc*) wl='-Wl,' ;; esac ;; mingw* | cygwin* | pw32* | os2*) ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' ;; irix5* | irix6* | nonstopux*) wl='-Wl,' ;; newsos6) ;; linux* | k*bsd*-gnu) case $cc_basename in icc* | ecc*) wl='-Wl,' ;; pgcc | pgf77 | pgf90) wl='-Wl,' ;; ccc*) wl='-Wl,' ;; como) wl='-lopt=' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) wl='-Wl,' ;; esac ;; esac ;; osf3* | osf4* | osf5*) wl='-Wl,' ;; rdos*) ;; solaris*) wl='-Wl,' ;; sunos4*) wl='-Qoption ld ' ;; sysv4 | sysv4.2uw2* | sysv4.3*) wl='-Wl,' ;; sysv4*MP*) ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) wl='-Wl,' ;; unicos*) wl='-Wl,' ;; uts4*) ;; esac fi # Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no case "$host_os" in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. # Unlike libtool, we use -rpath here, not --rpath, since the documented # option of GNU ld is called -rpath, not --rpath. hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' case "$host_os" in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no fi ;; amigaos*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we cannot use # them. ld_shlibs=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; cygwin* | mingw* | pw32*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then : else ld_shlibs=no fi ;; interix[3-9]*) hardcode_direct=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; gnu* | linux* | k*bsd*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; netbsd*) ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' else ld_shlibs=no fi ;; esac ;; sunos4*) hardcode_direct=yes ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then hardcode_libdir_flag_spec= fi else case "$host_os" in aix3*) # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac fi hardcode_direct=yes hardcode_libdir_separator=':' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac fi # Begin _LT_AC_SYS_LIBPATH_AIX. echo 'int main () { return 0; }' > conftest.c ${CC} ${LDFLAGS} conftest.c -o conftest aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` fi if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib" fi rm -f conftest.c conftest # End _LT_AC_SYS_LIBPATH_AIX. if test "$aix_use_runtimelinking" = yes; then hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' else hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" fi fi ;; amigaos*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # see comment about different semantics on the GNU ld section ld_shlibs=no ;; bsdi[45]*) ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' libext=lib ;; darwin* | rhapsody*) hardcode_direct=no if test "$GCC" = yes ; then : else case $cc_basename in xlc*) ;; *) ld_shlibs=no ;; esac fi ;; dgux*) hardcode_libdir_flag_spec='-L$libdir' ;; freebsd1*) ld_shlibs=no ;; freebsd2.2*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; freebsd2*) hardcode_direct=yes hardcode_minus_L=yes ;; freebsd* | dragonfly*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; hpux9*) hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; hpux10*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no ;; *) hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; netbsd*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; newsos6) hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then hardcode_libdir_flag_spec='${wl}-rpath,$libdir' else case "$host_os" in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) hardcode_libdir_flag_spec='-R$libdir' ;; *) hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; osf3*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) if test "$GCC" = yes; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else # Both cc and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi hardcode_libdir_separator=: ;; solaris*) hardcode_libdir_flag_spec='-R$libdir' ;; sunos4*) hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes ;; sysv4) case $host_vendor in sni) hardcode_direct=yes # is this really true??? ;; siemens) hardcode_direct=no ;; motorola) hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac ;; sysv4.3*) ;; sysv4*MP*) if test -d /usr/nec; then ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ;; sysv5* | sco3.2v5* | sco5v6*) hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator=':' ;; uts4*) hardcode_libdir_flag_spec='-L$libdir' ;; *) ld_shlibs=no ;; esac fi # Check dynamic linker characteristics # Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. # Unlike libtool.m4, here we don't care about _all_ names of the library, but # only about the one the linker finds when passed -lNAME. This is the last # element of library_names_spec in libtool.m4, or possibly two of them if the # linker has special search rules. library_names_spec= # the last element of library_names_spec in libtool.m4 libname_spec='lib$name' case "$host_os" in aix3*) library_names_spec='$libname.a' ;; aix4* | aix5*) library_names_spec='$libname$shrext' ;; amigaos*) library_names_spec='$libname.a' ;; beos*) library_names_spec='$libname$shrext' ;; bsdi[45]*) library_names_spec='$libname$shrext' ;; cygwin* | mingw* | pw32*) shrext=.dll library_names_spec='$libname.dll.a $libname.lib' ;; darwin* | rhapsody*) shrext=.dylib library_names_spec='$libname$shrext' ;; dgux*) library_names_spec='$libname$shrext' ;; freebsd1*) ;; freebsd* | dragonfly*) case "$host_os" in freebsd[123]*) library_names_spec='$libname$shrext$versuffix' ;; *) library_names_spec='$libname$shrext' ;; esac ;; gnu*) library_names_spec='$libname$shrext' ;; hpux9* | hpux10* | hpux11*) case $host_cpu in ia64*) shrext=.so ;; hppa*64*) shrext=.sl ;; *) shrext=.sl ;; esac library_names_spec='$libname$shrext' ;; interix[3-9]*) library_names_spec='$libname$shrext' ;; irix5* | irix6* | nonstopux*) library_names_spec='$libname$shrext' case "$host_os" in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; *) libsuff= shlibsuff= ;; esac ;; esac ;; linux*oldld* | linux*aout* | linux*coff*) ;; linux* | k*bsd*-gnu) library_names_spec='$libname$shrext' ;; knetbsd*-gnu) library_names_spec='$libname$shrext' ;; netbsd*) library_names_spec='$libname$shrext' ;; newsos6) library_names_spec='$libname$shrext' ;; nto-qnx*) library_names_spec='$libname$shrext' ;; openbsd*) library_names_spec='$libname$shrext$versuffix' ;; os2*) libname_spec='$name' shrext=.dll library_names_spec='$libname.a' ;; osf3* | osf4* | osf5*) library_names_spec='$libname$shrext' ;; rdos*) ;; solaris*) library_names_spec='$libname$shrext' ;; sunos4*) library_names_spec='$libname$shrext$versuffix' ;; sysv4 | sysv4.3*) library_names_spec='$libname$shrext' ;; sysv4*MP*) library_names_spec='$libname$shrext' ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) library_names_spec='$libname$shrext' ;; uts4*) library_names_spec='$libname$shrext' ;; esac sed_quote_subst='s/\(["`$\\]\)/\\\1/g' escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` shlibext=`echo "$shrext" | sed -e 's,^\.,,'` escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' < 7 BuildRequires: python2 %else BuildRequires: python %endif ExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64 %description sysbench is a scriptable multi-threaded benchmark tool based on LuaJIT. It is most frequently used for database benchmarks, but can also be used to create arbitrarily complex workloads that do not involve a database server. sysbench comes with the following bundled benchmarks: - oltp_*.lua: a collection of OLTP-like database benchmarks - fileio: a filesystem-level benchmark - cpu: a simple CPU benchmark - memory: a memory access benchmark - threads: a thread-based scheduler benchmark - mutex: a POSIX mutex benchmark %prep %setup -q %build export CFLAGS="%{optflags}" autoreconf -vif %configure --with-mysql \ --with-pgsql \ --without-gcc-arch %if 0%{?el6} make -j2 %else %make_build %endif %install %make_install rm -f %{buildroot}%{_docdir}/sysbench/manual.html %check make test %files %doc ChangeLog COPYING README.md %if 0%{?el6} %else %license COPYING %endif %{_bindir}/* %{_datadir}/%{name} %changelog * Fri Mar 15 2019 Alexey Bychko - 1.0.16-1 - Updated build dependencies for RHEL8-Beta. * Sat Jan 6 2018 Alexey Kopytov - 1.0.12-1 - Remove vim-common from build dependencies. * Sun Apr 09 2017 Alexey Kopytov - 1.0.5-1 - Add --without-gcc-arch to configure flags * Sat Apr 08 2017 Alexey Kopytov - 1.0.5-1 - Workarounds for make_build and license macros which are not available on EL 6. * Fri Apr 07 2017 Alexey Kopytov - 1.0.5-1 - Depend on mysql-devel rather than mariadb-devel on EL 6. - Use bundled cram for tests, because it's not available on EL 6. * Thu Apr 06 2017 Alexey Kopytov - 1.0.5-1 - Reuse downstream Fedora spec with modifications (prefer bundled libraries) * Mon Mar 13 2017 Xavier Bachelot 1.0.4-2 - Don't build aarch64 on el7. * Mon Mar 13 2017 Xavier Bachelot 1.0.4-1 - Fix build for i686. - Drop bundled cram. * Wed Mar 08 2017 Xavier Bachelot 1.0.3-1 - Update to 1.0.3 (RHBZ#1424670). - Restrict arches to the same ones as luajit. - Add --with-gcc-arch=native to configure for %%{arm} and aarch64. - Ignore test suite results for aarch64, it segfaults in koji. * Sat Feb 25 2017 Xavier Bachelot 1.0.2-2 - Run test suite. * Sat Feb 25 2017 Xavier Bachelot 1.0.2-1 - Update to 1.0.2 (RHBZ#1424670). * Sun Feb 12 2017 Honza Horak - 1.0.0-1 - Update to the first proper release 1.0.0 * Sat Feb 11 2017 Fedora Release Engineering - 0.4.12-15 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild * Fri Feb 05 2016 Fedora Release Engineering - 0.4.12-14 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild * Fri Jun 19 2015 Fedora Release Engineering - 0.4.12-13 - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild * Thu Sep 04 2014 Xavier Bachelot 0.4.12-12 - Modernize specfile. * Mon Aug 18 2014 Fedora Release Engineering - 0.4.12-11 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild * Sun Jun 08 2014 Fedora Release Engineering - 0.4.12-10 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild * Sun Aug 04 2013 Fedora Release Engineering - 0.4.12-9 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild * Fri Feb 15 2013 Fedora Release Engineering - 0.4.12-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild * Sat Jul 21 2012 Fedora Release Engineering - 0.4.12-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild * Sat Jan 14 2012 Fedora Release Engineering - 0.4.12-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild * Tue Sep 06 2011 Xavier Bachelot 0.4.12-5 - Add BR: libaio-devel (rhbz#735882). * Wed Mar 23 2011 Dan Horák - 0.4.12-4 - rebuilt for mysql 5.5.10 (soname bump in libmysqlclient) * Wed Feb 09 2011 Fedora Release Engineering - 0.4.12-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild * Fri Dec 24 2010 Xavier Bachelot 0.4.12-2 - Rebuild against new mysql. * Wed Jul 07 2010 Xavier Bachelot 0.4.12-1 - Update to 0.4.12. * Fri Aug 21 2009 Tomas Mraz - 0.4.10-5 - rebuilt with new openssl * Sun Jul 26 2009 Fedora Release Engineering - 0.4.10-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild * Wed Mar 18 2009 Xavier Bachelot 0.4.10-3 - License is GPLv2+, not GPLv2. * Sat Mar 14 2009 Xavier Bachelot 0.4.10-2 - Make postgres support optional, the version in rhel4 is too old. - Drop TODO and manual.html from %%doc, they are empty. * Thu Mar 05 2009 Xavier Bachelot 0.4.10-1 - Adapt original spec file taken from PLD. sysbench-1.0.18/scripts/0000700000175000017500000000000013553247311012704 5ustar jpjpsysbench-1.0.18/scripts/buildpack.sh0000700000175000017500000001417513553247311015211 0ustar jpjp#!/usr/bin/env bash # # Copyright (C) 2017-2019 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # Build packages for a specified architecture and upload them to packagecloud.io # Expects the following environment variables to be defined: # # ARCH - architecture. 'aarch64', 'x86_64 and 'i386' are currently supported # values. If not set, the script behaves as if it was sequentially # called with 'x86_64' and 'i386' values # # OS/DIST - distribution specification for packpack. When empty (the default) # use all disitributions available for ARCH # # PACKAGECLOUD_TOKEN - packagecloud.io API token # # PACKAGECLOUD_USER - packagecloud.io user name, defaults to 'akopytov' # # PACKAGECLOUD_REPO - packagecloud.io repository. The default is 'sysbench' # for releases (i.e. if git HEAD corresponds to a tag), # and 'sysbench-prereleases' otherwise. # # PACKAGECLOUD_EXTRA_ARGS - extra arguments to pass to the package_cloud # utility. Empty by default. Can be used to pass the # --skip-errors flag to ignore deploy errors. # # PACKPACK_REPO - packpack repository to use. Defaults to akopytov/packpack. set -eu PACKAGECLOUD_USER=${PACKAGECLOUD_USER:-"akopytov"} PACKAGECLOUD_EXTRA_ARGS=${PACKAGECLOUD_EXTRA_ARGS:-} PACKPACK_REPO=${PACKPACK_REPO:-akopytov/packpack} distros_x86_64=( "el 6 x86_64" "el 7 x86_64" "el 8 x86_64" "fedora 29 x86_64" "fedora 39 x86_64" "ubuntu xenial x86_64" "ubuntu bionic x86_64" "ubuntu disco x86_64" "ubuntu eoan x86_64" "debian jessie x86_64" "debian stretch x86_64" "debian buster x86_64" ) distros_i386=( "ubuntu xenial i386" "ubuntu bionic i386" "ubuntu disco i386" "ubuntu eoan i386" "debian jessie i386" "debian stretch i386" "debian buster i386" ) distros_aarch64=( "el 7 aarch64" "fedora 29 aarch64" "fedora 30 aarch64" "ubuntu bionic aarch64" "ubuntu disco aarch64" "ubuntu eoan aarch64" "ubuntu xenial aarch64" "debian jessie aarch64" "debian stretch aarch64" "debian buster aarch64" ) main() { if [ ! -r configure.ac ]; then echo "This script should be executed from the source root directory." exit 1 fi if [ -z "${PACKAGECLOUD_TOKEN+x}" ]; then echo "This script expects PACKAGECLOUD_TOKEN to be defined." exit 1 fi if [ ! which package_cloud >/dev/null 2>&1 ]; then echo "This script requires package_cloud. You can install it by running:" echo " gem install package_cloud" fi if [ ! -d packpack ]; then git clone https://github.com/${PACKPACK_REPO} packpack fi if [ -z "${PACKAGECLOUD_REPO+x}" ]; then # Upload builds corresponding to release tags to the 'sysbench' # repository, push other ones to 'sysbench-prereleases' if ! git describe --long --always >/dev/null 2>&1 ; then echo "Either run this script from a git repository, or specify " echo "the packagecloud repository explicitly with PACKAGECLOUD_REPO" exit 1 fi local commits=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\2/p') if [ ${commits:-0} = 0 ]; then export PACKAGECLOUD_REPO=sysbench # Use short version numbers for release builds export VERSION=$(git describe) else export PACKAGECLOUD_REPO=sysbench-prereleases fi fi declare -a distros OS=${OS:-} DIST=${DIST:-} if [ -n "${OS}" -a -n "${DIST}" ]; then distros=( "${OS} ${DIST} ${ARCH:-x86_64}" ) elif [ -z "${ARCH+x}" ]; then distros=("${distros_x86_64[@]}" "${distros_i386[@]}") else case "$ARCH" in x86_64) distros=( "${distros_x86_64[@]}" ) ;; i386) distros=( "${distros_i386[@]}" ) ;; aarch64) distros=( "${distros_aarch64[@]}" ) ;; *) echo "Invalid ARCH value: $ARCH" exit 1 ;; esac fi export PRODUCT=sysbench export CHANGELOG_NAME=sysbench export CHANGELOG_EMAIL=akopytov@gmail.com for d in "${distros[@]}"; do echo "*** Building package for $d ***" local t=( $d ) export OS=${t[0]} export DIST=${t[1]} export ARCH=${t[2]} # Replace "el" with "centos" for packpack, as there is no "el-*" docker # images for some architectures local PPOS=${OS/#el/centos} OS="$PPOS" packpack/packpack # To avoid name conflicts, deploy source packages only for # "default", i.e. x86_64 architecture if [ "${ARCH}" = "x86_64" ]; then files="$(ls build/*.{rpm,deb,dsc} 2>/dev/null || :)" else files="$(ls build/*{[^c].rpm,.deb} 2>/dev/null || :)" fi if [ -z "$files" ]; then echo "No package files to push" exit 1 fi echo "Pushing packages to ${PACKAGECLOUD_USER}/${PACKAGECLOUD_REPO}" for f in $files ; do echo $f package_cloud push ${PACKAGECLOUD_EXTRA_ARGS} \ ${PACKAGECLOUD_USER}/${PACKAGECLOUD_REPO}/${OS}/${DIST} \ $f done OS=${PPOS} packpack/packpack clean done } main sysbench-1.0.18/Makefile.am0000600000175000017500000000305713553247311013260 0ustar jpjp# Copyright (C) 2004 MySQL AB # Copyright (C) 2004-2017 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ACLOCAL_AMFLAGS = -I m4 AM_DISTCHECK_CONFIGURE_FLAGS = --without-mysql if USE_BUNDLED_LUAJIT LUAJIT_DIR = third_party/luajit endif if USE_BUNDLED_CK CK_DIR = third_party/concurrency_kit endif SUBDIRS = doc $(LUAJIT_DIR) $(CK_DIR) src tests EXTRA_DIST = autogen.sh README.md README-WIN.txt README-Oracle.md ChangeLog \ snap/snapcraft.yaml.in third_party/cram \ debian/changelog debian/compat debian/control debian/copyright \ debian/dirs debian/docs debian/install debian/rules \ debian/source/format \ rpm/sysbench.spec \ scripts/buildpack.sh dist-hook: $(MAKE) -C $(distdir)/third_party/cram clean test: cd tests && $(MAKE) test clean-local: $(MAKE) -C $(top_srcdir)/third_party/cram clean sysbench-1.0.18/tests/0000700000175000017500000000000013553247311012357 5ustar jpjpsysbench-1.0.18/tests/t/0000700000175000017500000000000013553247311012622 5ustar jpjpsysbench-1.0.18/tests/t/test_fileio.t0000600000175000017500000003153113553247311015322 0ustar jpjp######################################################################## fileio benchmark tests ######################################################################## $ fileio_args="fileio --file-num=4 --file-total-size=32M" $ sysbench $fileio_args prepare sysbench *.* * (glob) 4 files, 8192Kb each, 32Mb total Creating files for the test... Extra file open flags: (none) Creating file test_file.0 Creating file test_file.1 Creating file test_file.2 Creating file test_file.3 33554432 bytes written in * seconds (*.* MiB/sec). (glob) $ ls test_file.* test_file.0 test_file.1 test_file.2 test_file.3 $ for i in $(seq 0 3) > do > echo -n "test_file.$i: " > echo $(wc -c < test_file.$i) > done test_file.0: 8388608 test_file.1: 8388608 test_file.2: 8388608 test_file.3: 8388608 $ sysbench $fileio_args run | grep FATAL FATAL: Missing required argument: --file-test-mode $ sysbench $fileio_args --events=150 --file-test-mode=rndrw run sysbench *.* * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Extra file open flags: (none) 4 files, 8MiB each 32MiB total file size Block size 16KiB Number of IO requests: 150 Read/Write ratio for combined random IO test: 1.50 Periodic FSYNC enabled, calling fsync() each 100 requests. Calling fsync() at the end of test, Enabled. Using synchronous I/O mode Doing random r/w test Initializing worker threads... Threads started! File operations: reads/s: *.* (glob) writes/s: *.* (glob) fsyncs/s: *.* (glob) Throughput: read, MiB/s: *.* (glob) written, MiB/s: *.* (glob) General statistics: total time: *.*s (glob) total number of events: 150 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): 150.0000/0.00 execution time (avg/stddev): *.*/0.00 (glob) $ sysbench $fileio_args --events=150 --file-test-mode=rndrd run sysbench *.* * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Extra file open flags: (none) 4 files, 8MiB each 32MiB total file size Block size 16KiB Number of IO requests: 150 Read/Write ratio for combined random IO test: 1.50 Periodic FSYNC enabled, calling fsync() each 100 requests. Calling fsync() at the end of test, Enabled. Using synchronous I/O mode Doing random read test Initializing worker threads... Threads started! File operations: reads/s: *.* (glob) writes/s: 0.00 fsyncs/s: 0.00 Throughput: read, MiB/s: *.* (glob) written, MiB/s: 0.00 General statistics: total time: *.*s (glob) total number of events: 150 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): 150.0000/0.00 execution time (avg/stddev): *.*/0.00 (glob) $ sysbench $fileio_args --events=150 --file-test-mode=seqrd run sysbench *.* * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Extra file open flags: (none) 4 files, 8MiB each 32MiB total file size Block size 16KiB Periodic FSYNC enabled, calling fsync() each 100 requests. Calling fsync() at the end of test, Enabled. Using synchronous I/O mode Doing sequential read test Initializing worker threads... Threads started! File operations: reads/s: *.* (glob) writes/s: 0.00 fsyncs/s: 0.00 Throughput: read, MiB/s: *.* (glob) written, MiB/s: 0.00 General statistics: total time: *.*s (glob) total number of events: 150 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): 150.0000/0.00 execution time (avg/stddev): *.*/0.00 (glob) $ sysbench $fileio_args --events=150 --file-test-mode=rndwr run sysbench *.* * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Extra file open flags: (none) 4 files, 8MiB each 32MiB total file size Block size 16KiB Number of IO requests: 150 Read/Write ratio for combined random IO test: 1.50 Periodic FSYNC enabled, calling fsync() each 100 requests. Calling fsync() at the end of test, Enabled. Using synchronous I/O mode Doing random write test Initializing worker threads... Threads started! File operations: reads/s: 0.00 writes/s: *.* (glob) fsyncs/s: *.* (glob) Throughput: read, MiB/s: 0.00 written, MiB/s: *.* (glob) General statistics: total time: *.*s (glob) total number of events: 150 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): 150.0000/0.00 execution time (avg/stddev): *.*/0.00 (glob) $ sysbench $fileio_args --events=150 --file-test-mode=rndwr --validate run | grep Validation Validation checks: on. $ sysbench $fileio_args --events=150 --file-test-mode=foo run sysbench *.* * (glob) FATAL: Invalid IO operations mode: foo. [1] $ sysbench $fileio_args cleanup sysbench *.* * (glob) Removing test files... $ ls $ sysbench $fileio_args --file-test-mode=rndrw --verbosity=2 run FATAL: Cannot open file 'test_file.0' errno = 2 (No such file or directory) WARNING: Did you forget to run the prepare step? [1] ######################################################################## GH-196: fileio: validate file sizes on startup ######################################################################## $ args="$fileio_args --verbosity=2" $ sysbench $args --file-total-size=1M prepare $ sysbench $args --file-test-mode=rndwr --events=1 run FATAL: Size of file 'test_file.0' is 256KiB, but at least 8MiB is expected. WARNING: Did you run 'prepare' with different --file-total-size or --file-num values? [1] $ sysbench $args cleanup $ sysbench $args --file-num=8 prepare $ sysbench $args --file-test-mode=rndwr --events=1 run FATAL: Size of file 'test_file.0' is 4MiB, but at least 8MiB is expected. WARNING: Did you run 'prepare' with different --file-total-size or --file-num values? [1] $ sysbench $args --file-num=8 cleanup $ sysbench $args --file-total-size=1M prepare $ sysbench $args --file-test-mode=seqwr --events=1 run $ sysbench $args cleanup $ unset args ######################################################################## GH-198: Tolerate misaligned test_files. ######################################################################## $ args="$fileio_args --verbosity=2 --file-total-size=1M --file-num=128 --file-block-size=4097 --events=2" $ sysbench $args --file-total-size=1M prepare $ sysbench $args --file-test-mode=seqrd run $ sysbench $args --file-test-mode=rndrd run $ sysbench $args cleanup $ unset args ######################################################################## Extra file flags. Not testing 'direct' as that is not supported on all tested platforms ######################################################################## $ args="$fileio_args --file-total-size=16K --file-num=1" $ sysbench $args --file-extra-flags= prepare sysbench * (glob) 1 files, 16Kb each, 0Mb total Creating files for the test... Extra file open flags: (none) Creating file test_file.0 16384 bytes written in * seconds (* MiB/sec). (glob) $ sysbench $args --file-extra-flags=sync prepare sysbench * (glob) 1 files, 16Kb each, 0Mb total Creating files for the test... Extra file open flags: sync Reusing existing file test_file.0 No bytes written. $ sysbench $args --file-extra-flags=dsync prepare sysbench * (glob) 1 files, 16Kb each, 0Mb total Creating files for the test... Extra file open flags: dsync Reusing existing file test_file.0 No bytes written. $ sysbench $args --file-extra-flags=dsync,sync prepare sysbench * (glob) 1 files, 16Kb each, 0Mb total Creating files for the test... Extra file open flags: sync dsync Reusing existing file test_file.0 No bytes written. $ sysbench $args --file-extra-flags= cleanup sysbench * (glob) Removing test files... ######################################################################## GH-229: "--file-fsync-freq=0" seems to prevent fsync() at end of test ######################################################################## $ args="fileio --file-total-size=160K --file-num=10 --file-test-mode=seqwr" $ args="$args --file-fsync-freq=0 --file-fsync-end=1" $ args="$args --events=0 --time=1" $ sysbench $args prepare sysbench * (glob) 10 files, 16Kb each, 0Mb total Creating files for the test... Extra file open flags: (none) Creating file test_file.0 Creating file test_file.1 Creating file test_file.2 Creating file test_file.3 Creating file test_file.4 Creating file test_file.5 Creating file test_file.6 Creating file test_file.7 Creating file test_file.8 Creating file test_file.9 163840 bytes written in * seconds (* MiB/sec). (glob) $ sysbench $args run sysbench * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Extra file open flags: (none) 10 files, 16KiB each 160KiB total file size Block size 16KiB Calling fsync() at the end of test, Enabled. Using synchronous I/O mode Doing sequential write (creation) test Initializing worker threads... Threads started! File operations: reads/s: 0.00 writes/s: [^0].* (re) fsyncs/s: [^0].* (re) Throughput: read, MiB/s: 0.00 written, MiB/s: [^0].* (re) General statistics: total time: [^0].*s (re) total number of events: [^0].* (re) Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): *.*/0.00 (glob) execution time (avg/stddev): *.*/0.00 (glob) $ sysbench $args --file-fsync-end=off run sysbench * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Extra file open flags: (none) 10 files, 16KiB each 160KiB total file size Block size 16KiB Using synchronous I/O mode Doing sequential write (creation) test Initializing worker threads... Threads started! File operations: reads/s: 0.00 writes/s: [^0].* (re) fsyncs/s: 0.00 Throughput: read, MiB/s: 0.00 written, MiB/s: [^0].* (re) General statistics: total time: [^0].*s (re) total number of events: [^0].* (re) Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): *.*/0.00 (glob) execution time (avg/stddev): *.*/0.00 (glob) sysbench-1.0.18/tests/t/api_histogram.t0000600000175000017500000000127113553247311015640 0ustar jpjp######################################################################## Tests for histogram API ######################################################################## $ sysbench < h = sysbench.histogram.new(1000, 1, 10) > h:update(1) > h:update(2) > h:update(0) > h:update(10) > h:update(100) > h:update(5.001) > h:print() > EOF sysbench * (glob) value ------------- distribution ------------- count 1.000 |**************************************** 2 2.001 |******************** 1 4.997 |******************** 1 10.000 |**************************************** 2 sysbench-1.0.18/tests/t/api_basic.t0000600000175000017500000000704413553247311014730 0ustar jpjp######################################################################## Basic Lua API tests ######################################################################## $ SB_ARGS="--verbosity=0 --events=2 --db-driver=mysql $SBTEST_MYSQL_ARGS $CRAMTMP/api_basic.lua" $ cat >$CRAMTMP/api_basic.lua < function init(thread_id) > print("tid:" .. (thread_id or "(nil)") .. " init()") > end > > function prepare(thread_id) > print("tid:" .. (thread_id or "(nil)") .. " prepare()") > end > > function run(thread_id) > print("tid:" .. (thread_id or "(nil)") .. " run()") > end > > function cleanup(thread_id) > print("tid:" .. (thread_id or "(nil)") .. " cleanup()") > end > > function help(thread_id) > print("tid:" .. (thread_id or "(nil)") .. " help()") > end > > function thread_init(thread_id) > print(string.format("tid:%d thread_init()", thread_id)) > end > > function event(thread_id) > print(string.format("tid:%d event()", thread_id)) > end > > function thread_done(thread_id) > print(string.format("tid:%d thread_done()", thread_id)) > end > > function done(thread_id) > print("tid:" .. (thread_id or "(nil)") .. " done()") > end > > EOF $ sysbench $SB_ARGS prepare tid:(nil) prepare() $ sysbench $SB_ARGS run tid:(nil) init() tid:0 thread_init() tid:0 event() tid:0 event() tid:0 thread_done() tid:(nil) done() $ sysbench $SB_ARGS cleanup tid:(nil) cleanup() $ sysbench $SB_ARGS help tid:(nil) help() $ cat >$CRAMTMP/api_basic.lua < function event() > print(sysbench.version) > print(sysbench.version_string) > end > EOF $ sysbench $SB_ARGS --events=1 run | > sed -e "s/$SBTEST_VERSION_STRING/VERSION_STRING/" \ > -e "s/$SBTEST_VERSION/VERSION/" VERSION VERSION_STRING $ cat >$CRAMTMP/api_basic.lua < function event() > print(string.format("sysbench.cmdline.script_path = %s", sysbench.cmdline.script_path)) > end > EOF $ sysbench $SB_ARGS --events=1 run sysbench.cmdline.script_path = */api_basic.lua (glob) ######################################################################## Error handling ######################################################################## # Syntax errors in the script $ cat >$CRAMTMP/api_basic.lua < foo > EOF $ sysbench $SB_ARGS run FATAL: */api_basic.lua:2: '=' expected near '' (glob) [1] # Missing event function $ cat >$CRAMTMP/api_basic.lua < function foo() > end > EOF $ sysbench $SB_ARGS run FATAL: cannot find the event() function in *api_basic.lua (glob) [1] ######################################################################## event() return values ######################################################################## $ cat >$CRAMTMP/api_basic.lua < sysbench.cmdline.options = { param = {"param", 0} } > function event() > i = (i or 0) + 1 > local param = sysbench.opt.param > print(i) > if param == 1 then > return 0 > elseif param == 2 then > return 1 > elseif param == 3 then > return true > elseif param == 4 then > return {} > elseif param == 5 then > return false > elseif param == 6 then > return nil > else > error("Unknown param value") > end > end > EOF $ sysbench $SB_ARGS run --param=1 1 $ sysbench $SB_ARGS run --param=2 1 $ sysbench $SB_ARGS run --param=3 1 $ sysbench $SB_ARGS run --param=4 1 $ sysbench $SB_ARGS run --param=5 1 2 $ sysbench $SB_ARGS run --param=6 1 2 sysbench-1.0.18/tests/t/cmd_run.t0000600000175000017500000000050513553247311014440 0ustar jpjp $ sysbench run sysbench * (glob) FATAL: Cannot find benchmark 'run': no such built-in test, file or module [1] $ cat >cmd_run.lua < function thread_run() > print('function thread_run()') > end > function event() > end > EOF $ sysbench --verbosity=0 cmd_run.lua run function thread_run() sysbench-1.0.18/tests/t/opt_rate.t0000600000175000017500000000072313553247311014630 0ustar jpjp######################################################################## Tests for the --rate option (aka the limited rate mode) ######################################################################## # Failing to deliver the requested rate should result in a non-zero exit code $ sysbench --rate=2000000000 cpu run --verbosity=1 FATAL: The event queue is full. This means the worker threads are unable to keep up with the specified event generation rate [1] sysbench-1.0.18/tests/t/opt_help.t0000600000175000017500000001004113553247311014617 0ustar jpjp######################################################################## Skip everything between "Compiled-in database drivers:" and "Compiled-in tests:" as that part depends on available database drivers and thus, build options. Driver-specific options are tested separately. ######################################################################## $ sysbench --help | sed '/Compiled-in database drivers:/,/Compiled-in tests:/d' Usage: sysbench [options]... [testname] [command] Commands implemented by most tests: prepare run cleanup help General options: --threads=N number of threads to use [1] --events=N limit for total number of events [0] --time=N limit for total execution time in seconds [10] --forced-shutdown=STRING number of seconds to wait after the --time limit before forcing shutdown, or 'off' to disable [off] --thread-stack-size=SIZE size of stack per thread [64K] --rate=N average transactions rate. 0 for unlimited rate [0] --report-interval=N periodically report intermediate statistics with a specified interval in seconds. 0 disables intermediate reports [0] --report-checkpoints=[LIST,...] dump full statistics and reset all counters at specified points in time. The argument is a list of comma-separated values representing the amount of time in seconds elapsed from start of test when report checkpoint(s) must be performed. Report checkpoints are off by default. [] --debug[=on|off] print more debugging info [off] --validate[=on|off] perform validation checks where possible [off] --help[=on|off] print help and exit [off] --version[=on|off] print version and exit [off] --config-file=FILENAME File containing command line options --tx-rate=N deprecated alias for --rate [0] --max-requests=N deprecated alias for --events [0] --max-time=N deprecated alias for --time [0] --num-threads=N deprecated alias for --threads [1] Pseudo-Random Numbers Generator options: --rand-type=STRING random numbers distribution {uniform,gaussian,special,pareto} [special] --rand-spec-iter=N number of iterations used for numbers generation [12] --rand-spec-pct=N percentage of values to be treated as 'special' (for special distribution) [1] --rand-spec-res=N percentage of 'special' values to use (for special distribution) [75] --rand-seed=N seed for random number generator. When 0, the current time is used as a RNG seed. [0] --rand-pareto-h=N parameter h for pareto distribution [0.2] Log options: --verbosity=N verbosity level {5 - debug, 0 - only critical messages} [3] --percentile=N percentile to calculate in latency statistics (1-100). Use the special value of 0 to disable percentile calculations [95] --histogram[=on|off] print latency histogram in report [off] General database options: --db-driver=STRING specifies database driver to use \('help' to get list of available drivers\)( \[mysql\])? (re) --db-ps-mode=STRING prepared statements usage mode {auto, disable} [auto] --db-debug[=on|off] print database-specific debug information [off] fileio - File I/O test cpu - CPU performance test memory - Memory functions speed test threads - Threads subsystem performance test mutex - Mutex performance test See 'sysbench help' for a list of options for each test. ######################################################################## Test driver-specific options ######################################################################## $ drivers=$(sysbench --help | sed -n '/Compiled-in database drivers:/,/^$/p' | tail -n +2 | cut -d ' ' -f 3) $ for drv in $drivers > do > if [ ! -r ${SBTEST_SUITEDIR}/help_drv_${drv}.t ] > then > echo "Cannot find test(s) for $drv driver options!" > exit 1 > fi > done sysbench-1.0.18/tests/t/help_drv_pgsql.t0000600000175000017500000000074013553247311016023 0ustar jpjpSkip test if the PostgreSQL driver is not available. $ if [ -z "$SBTEST_HAS_PGSQL" ] > then > exit 80 > fi $ sysbench --help | sed -n '/pgsql options:/,/^$/p' pgsql options: --pgsql-host=STRING PostgreSQL server host [localhost] --pgsql-port=N PostgreSQL server port [5432] --pgsql-user=STRING PostgreSQL user [sbtest] --pgsql-password=STRING PostgreSQL password [] --pgsql-db=STRING PostgreSQL database name [sbtest] sysbench-1.0.18/tests/t/drivers.t0000600000175000017500000000144613553247311014474 0ustar jpjp######################################################################## Make sure all available DB drivers are covered ######################################################################## $ drivers=$(sysbench --help | sed -n '/Compiled-in database drivers:/,/^$/p' | tail -n +2 | cut -d ' ' -f 3) $ for drv in $drivers > do > if [ ! -r ${SBTEST_SUITEDIR}/drv_${drv}.t ] > then > echo "Cannot find test(s) for the $drv driver!" > exit 1 > fi > done # Try using a non-existing driver $ sysbench --db-driver=nonexisting ${SBTEST_SCRIPTDIR}/oltp_read_write.lua cleanup sysbench * (glob) (FATAL: invalid database driver name: 'nonexisting'|FATAL: No DB drivers available) (re) FATAL: `cleanup' function failed: * failed to initialize the DB driver (glob) [1] sysbench-1.0.18/tests/t/drv_mysql.t0000600000175000017500000000267613553247311015044 0ustar jpjp######################################################################## MySQL driver tests ######################################################################## $ . $SBTEST_INCDIR/mysql_common.sh $ . $SBTEST_INCDIR/drv_common.sh sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 10 write: 0 other: 0 total: 10 transactions: 10 (*.* per sec.) (glob) queries: 10 (*.* per sec.) (glob) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: *.*s (glob) total number of events: 10 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): *.*/*.* (glob) execution time (avg/stddev): *.*/*.* (glob) sysbench-1.0.18/tests/t/cmd_prepare.t0000600000175000017500000000047413553247311015277 0ustar jpjp $ sysbench prepare sysbench * (glob) FATAL: Cannot find benchmark 'prepare': no such built-in test, file or module [1] $ cat >cmd_prepare.lua < function prepare() > print('function prepare()') > end > EOF $ sysbench cmd_prepare.lua prepare sysbench * (glob) function prepare() sysbench-1.0.18/tests/t/cmd_help.t0000600000175000017500000000044413553247311014566 0ustar jpjp $ sysbench help sysbench * (glob) FATAL: Cannot find benchmark 'help': no such built-in test, file or module [1] $ cat >cmd_help.lua < function help() > print('function help()') > end > EOF $ sysbench cmd_help.lua help sysbench * (glob) function help() sysbench-1.0.18/tests/t/script_oltp_point_select_mysql.t0000600000175000017500000002452413553247311021357 0ustar jpjp######################################################################## oltp_point_select.lua + MySQL tests ######################################################################## $ . $SBTEST_INCDIR/mysql_common.sh $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_point_select.lua $ . $SBTEST_INCDIR/script_oltp_common.sh sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating a secondary index on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating a secondary index on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating a secondary index on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating a secondary index on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating a secondary index on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating a secondary index on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating a secondary index on 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist sysbench * (glob) Prewarming table sbtest1 Prewarming table sbtest2 Prewarming table sbtest3 Prewarming table sbtest4 Prewarming table sbtest5 Prewarming table sbtest6 Prewarming table sbtest7 Prewarming table sbtest8 sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 100 write: 0 other: 0 total: 100 transactions: 100 (* per sec.) (glob) queries: 100 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist # Test --create-secondary=off sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) sysbench * (glob) Dropping table 'sbtest1'... # Test --auto-inc=off Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Dropping table 'sbtest1'... sysbench-1.0.18/tests/t/script_oltp_delete_mysql.t0000600000175000017500000002452413553247311020131 0ustar jpjp######################################################################## oltp_delete.lua + MySQL tests ######################################################################## $ . $SBTEST_INCDIR/mysql_common.sh $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_delete.lua $ . $SBTEST_INCDIR/script_oltp_common.sh sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating a secondary index on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating a secondary index on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating a secondary index on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating a secondary index on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating a secondary index on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating a secondary index on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating a secondary index on 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist sysbench * (glob) Prewarming table sbtest1 Prewarming table sbtest2 Prewarming table sbtest3 Prewarming table sbtest4 Prewarming table sbtest5 Prewarming table sbtest6 Prewarming table sbtest7 Prewarming table sbtest8 sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 0 write: * (glob) other: * (glob) total: 100 transactions: 100 (* per sec.) (glob) queries: 100 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist # Test --create-secondary=off sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) sysbench * (glob) Dropping table 'sbtest1'... # Test --auto-inc=off Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Dropping table 'sbtest1'... sysbench-1.0.18/tests/t/api_rand.t0000600000175000017500000000315113553247311014566 0ustar jpjp######################################################################## PRNG Lua API tests ######################################################################## $ SB_ARGS="--verbosity=0 --events=1" $ cat >$CRAMTMP/api_rand.lua < function event() > print("sb_rand(0, 9) = " .. sb_rand(0, 9)) > print("sb_rand_uniq(0, 4294967295) = " .. sb_rand_uniq(0, 4294967295)) > print("sb_rnd() = " .. sb_rnd()) > print([[sb_rand_str("abc-###-@@@-xyz") = ]] .. sb_rand_str("abc-###-@@@-xyz")) > print("sb_rand_uniform(0, 9) = " .. sb_rand_uniform(0, 9)) > print("sb_rand_gaussian(0, 9) = " .. sb_rand_gaussian(0, 9)) > print("sb_rand_special(0, 9) = " .. sb_rand_special(0, 9)) > end > EOF $ sysbench $SB_ARGS $CRAMTMP/api_rand.lua run sb_rand\(0, 9\) = [0-9]{1} (re) sb_rand_uniq\(0, 4294967295\) = [0-9]{1,10} (re) sb_rnd\(\) = [0-9]+ (re) sb_rand_str\(".*"\) = abc-[0-9]{3}-[a-z]{3}-xyz (re) sb_rand_uniform\(0, 9\) = [0-9]{1} (re) sb_rand_gaussian\(0, 9\) = [0-9]{1} (re) sb_rand_special\(0, 9\) = [0-9]{1} (re) ######################################################################## issue #96: sb_rand_uniq(1, oltp_table_size) generate duplicate value ######################################################################## $ cat >$CRAMTMP/api_rand_uniq.lua < function event() > local max = 1000000000 > local n = sb_rand_uniq(1, max) > if n > max then > error("n is out of range") > end > print(n) > end > EOF $ sysbench $SB_ARGS --events=100000 $CRAMTMP/api_rand_uniq.lua run | > sort -n | uniq | wc -l | sed -e 's/ //g' 100000 sysbench-1.0.18/tests/t/opt_report_interval.t0000600000175000017500000000122213553247311017107 0ustar jpjp######################################################################## # --report-interval tests ######################################################################## $ if [ -z "$SBTEST_HAS_MYSQL" ] > then > exit 80 > fi $ sysbench ${SBTEST_SCRIPTDIR}/oltp_read_write.lua --db-driver=mysql --mysql-dry-run --time=3 --events=0 --report-interval=1 run | grep '\[ 2s \]' [ 2s ] thds: 1 tps: * qps: * (r/w/o: */*/*) lat (ms,95%): *.* err/s: 0.00 reconn/s: 0.00 (glob) # Run a test that does not support intermediate reports $ sysbench cpu --report-interval=1 --time=2 run | grep '\[ 1s \]' [ 1s ] thds: 1 eps: * lat (ms,95%): * (glob) sysbench-1.0.18/tests/t/test_mutex.t0000600000175000017500000000265413553247311015221 0ustar jpjp######################################################################## mutex benchmark tests ######################################################################## $ args="mutex --events=10 --threads=2" $ sysbench $args help sysbench *.* * (glob) mutex options: --mutex-num=N total size of mutex array [4096] --mutex-locks=N number of mutex locks to do per thread [50000] --mutex-loops=N number of empty loops to do outside mutex lock [10000] $ sysbench $args prepare sysbench *.* * (glob) 'mutex' test does not implement the 'prepare' command. [1] $ sysbench $args run sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! General statistics: total time: *s (glob) total number of events: 2 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) $ sysbench $args cleanup sysbench *.* * (glob) 'mutex' test does not implement the 'cleanup' command. [1] sysbench-1.0.18/tests/t/script_bulk_insert_pgsql.t0000600000175000017500000000513413553247311020127 0ustar jpjp######################################################################## bulk_insert.lua + PostgreSQL tests ######################################################################## $ . $SBTEST_INCDIR/pgsql_common.sh $ . $SBTEST_INCDIR/script_bulk_insert_common.sh Creating table 'sbtest1'... Creating table 'sbtest2'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+---------+--------------------+---------+--------------+------------- id | integer | not null | plain | | k | integer | not null default 0 | plain | | Indexes: CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Table "public.sbtest2" Column | Type | Modifiers | Storage | Stats target | Description --------+---------+--------------------+---------+--------------+------------- id | integer | not null | plain | | k | integer | not null default 0 | plain | | Indexes: CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id) Did not find any relation named "sbtest3". sysbench * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 0 write: [12] (re) other: 0 total: [12] (re) transactions: 100 (* per sec.) (glob) queries: [12] \(.* per sec.\) (re) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev):* (glob) execution time (avg/stddev):* (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Did not find any relation named "sbtest1". Did not find any relation named "sbtest2". Did not find any relation named "sbtest3". sysbench-1.0.18/tests/t/api_sql_pgsql.t0000600000175000017500000000734413553247311015657 0ustar jpjp######################################################################## SQL Lua API + PostgreSQL tests ######################################################################## $ . ${SBTEST_INCDIR}/pgsql_common.sh $ . ${SBTEST_INCDIR}/api_sql_common.sh drv:name() = pgsql SQL types: { BIGINT = 4, CHAR = 11, DATE = 8, DATETIME = 9, DOUBLE = 6, FLOAT = 5, INT = 3, NONE = 0, SMALLINT = 2, TIME = 7, TIMESTAMP = 10, TINYINT = 1, VARCHAR = 12 } -- SQL error codes: { FATAL = 2, IGNORABLE = 1, NONE = 0 } -- FATAL: invalid database driver name: 'non-existing' failed to initialize the DB driver 100 -- -- 1 foo 0.4 2 nil 0.3 nil bar 0.2 nil nil 0.1 -- bar nil -- FATAL: PQprepare() failed: ERROR: relation "nonexisting" does not exist LINE 1: SELECT * FROM nonexisting ^ SQL API error -- Unsupported argument type: 8 nil ALERT: attempt to free an invalid result set db_free_results() failed db_free_results() failed -- (last message repeated 1 times) ALERT: attempt to use an already closed connection */api_sql.lua:*: SQL API error (glob) ALERT: attempt to close an already closed connection -- 4 301 400 0123456789 0123456789 -- 1 ALERT: reconnect is not supported by the current driver 2 -- reconnects = 0 FATAL: Connection to database failed: could not translate host name "non-existing" to address: * (glob) connection creation failed -- FATAL: PQexec() failed: 7 null value in column "a" violates not-null constraint FATAL: failed query was: INSERT INTO t VALUES (NULL) Got an error descriptor: { connection = , query = "INSERT INTO t VALUES (NULL)", sql_errmsg = 'null value in column "a" violates not-null constraint', sql_errno = 0, sql_state = "23502" } */api_sql.lua:*: SQL error, errno = 0, state = '23502': null value in column "a" violates not-null constraint (glob) FATAL: PQexec() failed: 7 value too long for type character(1) FATAL: failed query was: INSERT INTO t VALUES ('test') Got an error descriptor: { connection = , query = "INSERT INTO t VALUES ('test')", sql_errmsg = "value too long for type character(1)", sql_errno = 0, sql_state = "22001" } */api_sql.lua:*: SQL error, errno = 0, state = '22001': value too long for type character(1) (glob) FATAL: PQexec() failed: 7 table "t" does not exist FATAL: failed query was: DROP TABLE t Got an error descriptor: { connection = , query = "DROP TABLE t", sql_errmsg = 'table "t" does not exist', sql_errno = 0, sql_state = "42P01" } */api_sql.lua:*: SQL error, errno = 0, state = '42P01': table "t" does not exist (glob) -- ######################################################################## # Multiple connections test ######################################################################## 1 2 3 4 5 6 7 8 9 10 ######################################################################## # Incorrect bulk API usage ######################################################################## ALERT: attempt to call bulk_insert_next() before bulk_insert_init() */api_sql.lua:*: db_bulk_insert_next() failed (glob) ######################################################################## # query_row() with an empty result set ######################################################################## nil ######################################################################## # GH-282: Mysql's fetch_row() is broken ######################################################################## 1 2 sysbench-1.0.18/tests/t/script_select_random_mysql.t0000600000175000017500000001340513553247311020444 0ustar jpjp######################################################################## select_random_*.lua + MySQL tests ######################################################################## $ . $SBTEST_INCDIR/mysql_common.sh $ . $SBTEST_INCDIR/script_select_random_common.sh sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist sysbench * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 100 write: 0 other: 0 total: 100 transactions: 100 (* per sec.) (glob) queries: 100 (* per sec.) (glob) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev):* (glob) execution time (avg/stddev):* (glob) sysbench * (glob) Dropping table 'sbtest1'... ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist sysbench * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 100 write: 0 other: 0 total: 100 transactions: 100 (* per sec.) (glob) queries: 100 (* per sec.) (glob) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev):* (glob) execution time (avg/stddev):* (glob) sysbench * (glob) Dropping table 'sbtest1'... ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist sysbench-1.0.18/tests/t/api_reports.t0000600000175000017500000000637013553247311015346 0ustar jpjp######################################################################## Tests for custom report hooks ######################################################################## # Trigger one intermediate and one cumulative report $ SB_ARGS="api_reports.lua --time=5 --report-interval=2 --verbosity=1" ######################################################################## # Default human-readable format via a custom hook ######################################################################## $ cat >api_reports.lua < ffi.cdef[[int usleep(unsigned int);]] > > function event() > ffi.C.usleep(1000) > end > > sysbench.hooks.report_intermediate = sysbench.report_default > sysbench.hooks.report_cumulative = sysbench.report_default > EOF $ sysbench $SB_ARGS run \[ 2s \] thds: 1 tps: [0-9]*\.[0-9]* qps: 0\.00 \(r\/w\/o: 0\.00\/0\.00\/0\.00\) lat \(ms,95%\): [1-9][0-9]*\.[0-9]* err\/s 0\.00 reconn\/s: 0\.00 (re) \[ 4s \] thds: 1 tps: [0-9]*\.[0-9]* qps: 0\.00 \(r\/w\/o: 0\.00\/0\.00\/0\.00\) lat \(ms,95%\): [1-9][0-9]*\.[0-9]* err\/s 0\.00 reconn\/s: 0\.00 (re) \[ 5s \] thds: 0 tps: [0-9]*\.[0-9]* qps: 0\.00 \(r\/w\/o: 0\.00\/0\.00\/0\.00\) lat \(ms,95%\): [1-9][0-9]*\.[0-9]* err\/s 0\.00 reconn\/s: 0\.00 (re) ######################################################################## # CSV format via a custom hook ######################################################################## $ cat >api_reports.lua < ffi.cdef[[int usleep(unsigned int);]] > > function event() > ffi.C.usleep(1000) > end > > sysbench.hooks.report_intermediate = sysbench.report_csv > sysbench.hooks.report_cumulative = sysbench.report_csv > EOF $ sysbench $SB_ARGS run 2,1,[0-9]*\.[0-9]*,0\.00,0\.00,0\.00,0\.00,[1-9][0-9]*\.[0-9]*,0\.00,0\.00 (re) 4,1,[0-9]*\.[0-9]*,0\.00,0\.00,0\.00,0\.00,[1-9][0-9]*\.[0-9]*,0\.00,0\.00 (re) 5,0,[0-9]*\.[0-9]*,0\.00,0\.00,0\.00,0\.00,[1-9][0-9]*\.[0-9]*,0\.00,0\.00 (re) ######################################################################## # JSON format via a custom hook ######################################################################## $ cat >api_reports.lua < ffi.cdef[[int usleep(unsigned int);]] > > function event() > ffi.C.usleep(1000) > end > > sysbench.hooks.report_intermediate = sysbench.report_json > sysbench.hooks.report_cumulative = sysbench.report_json > EOF $ sysbench $SB_ARGS run [ { "time": 2, "threads": 1, "tps": *.*, (glob) "qps": { "total": 0.00, "reads": 0.00, "writes": 0.00, "other": 0.00 }, "latency": [1-9][0-9]*\.[0-9]*, (re) "errors": 0.00, "reconnects": 0.00 }, { "time": 4, "threads": 1, "tps": *.*, (glob) "qps": { "total": 0.00, "reads": 0.00, "writes": 0.00, "other": 0.00 }, "latency": [1-9][0-9]*\.[0-9]*, (re) "errors": 0.00, "reconnects": 0.00 } ] [ { "time": 5, "threads": 0, "tps": *.*, (glob) "qps": { "total": 0.00, "reads": 0.00, "writes": 0.00, "other": 0.00 }, "latency": [1-9][0-9]*\.[0-9]*, (re) "errors": 0.00, "reconnects": 0.00 } ] sysbench-1.0.18/tests/t/tests.t0000600000175000017500000000072713553247311014161 0ustar jpjp######################################################################## Make sure all built-in tests are covered ######################################################################## $ tests=$(sysbench --help | sed -n '/Compiled-in tests:/,/^$/p' | tail -n +2 | cut -d ' ' -f 3) $ for t in $tests > do > if [ ! -r ${SBTEST_SUITEDIR}/test_${t}.t ] > then > echo "Cannot find regression test(s) for 'sysbench $t'!" > exit 1 > fi > done sysbench-1.0.18/tests/t/opt_histogram.t0000600000175000017500000000264513553247311015677 0ustar jpjp######################################################################## --histogram tests ######################################################################## $ cat >$CRAMTMP/histogram.lua < local ffi = require("ffi") > ffi.cdef[[ > int usleep(unsigned int); > ]] > function event() > if (sysbench.tid == 0) then > ffi.C.usleep(1000000) > else > ffi.C.usleep(2000000) > end > end > EOF $ sysbench --histogram $CRAMTMP/histogram.lua --events=2 --threads=2 run sysbench * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! Latency histogram (values are in milliseconds) value ------------- distribution ------------- count * |\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* 1 (glob) * |\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* 1 (glob) General statistics: total time: *s (glob) total number of events: 2 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): 1.0000/0.00 execution time (avg/stddev): */* (glob) sysbench-1.0.18/tests/t/test_memory.t0000600000175000017500000001462713553247311015372 0ustar jpjp######################################################################## memory benchmark tests ######################################################################## $ args="memory --memory-block-size=4K --memory-total-size=1G --events=1 --time=0 --threads=2" The --memory-hugetlb option is supported and printed by 'sysbench help' only on Linux. $ if [ "$(uname -s)" = "Linux" ] > then > sysbench $args help | grep hugetlb > else > echo " --memory-hugetlb[=on|off] allocate memory from HugeTLB pool [off]" > fi --memory-hugetlb[=on|off] allocate memory from HugeTLB pool [off] $ sysbench $args help | grep -v hugetlb sysbench * (glob) memory options: --memory-block-size=SIZE size of memory block for test [1K] --memory-total-size=SIZE total size of data to transfer [100G] --memory-scope=STRING memory access scope {global,local} [global] --memory-oper=STRING type of memory operations {read, write, none} [write] --memory-access-mode=STRING memory access mode {seq,rnd} [seq] $ sysbench $args prepare sysbench *.* * (glob) 'memory' test does not implement the 'prepare' command. [1] $ sysbench $args --memory-block-size=-1 run sysbench * (glob) FATAL: Invalid value for memory-block-size: -1 [1] $ sysbench $args --memory-block-size=0 run sysbench * (glob) FATAL: Invalid value for memory-block-size: 0 [1] $ sysbench $args --memory-block-size=3 run sysbench * (glob) FATAL: Invalid value for memory-block-size: 3 [1] $ sysbench $args --memory-block-size=9 run sysbench * (glob) FATAL: Invalid value for memory-block-size: 9 [1] ######################################################################## # Global reads ######################################################################## $ sysbench $args --memory-oper=read run sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Running memory speed test with the following options: block size: 4KiB total size: 1024MiB operation: read scope: global Initializing worker threads... Threads started! Total operations: 262144 (* per second) (glob) 1024.00 MiB transferred (* MiB/sec) (glob) General statistics: total time: *s (glob) total number of events: 262144 (glob) Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) ######################################################################## # Global writes ######################################################################## $ sysbench $args --memory-oper=write run sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Running memory speed test with the following options: block size: 4KiB total size: 1024MiB operation: write scope: global Initializing worker threads... Threads started! Total operations: 262144 (* per second) (glob) 1024.00 MiB transferred (* MiB/sec) (glob) General statistics: total time: *s (glob) total number of events: 262144 (glob) Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) ######################################################################## # Local reads ######################################################################## $ sysbench $args --memory-scope=local --memory-oper=read run sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Running memory speed test with the following options: block size: 4KiB total size: 1024MiB operation: read scope: local Initializing worker threads... Threads started! Total operations: 262144 (* per second) (glob) 1024.00 MiB transferred (* MiB/sec) (glob) General statistics: total time: *s (glob) total number of events: 262144 (glob) Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) ######################################################################## # Local writes ######################################################################## $ sysbench $args --memory-scope=local --memory-oper=write run sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Running memory speed test with the following options: block size: 4KiB total size: 1024MiB operation: write scope: local Initializing worker threads... Threads started! Total operations: 262144 (* per second) (glob) 1024.00 MiB transferred (* MiB/sec) (glob) General statistics: total time: *s (glob) total number of events: 262144 (glob) Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) $ sysbench $args cleanup sysbench *.* * (glob) 'memory' test does not implement the 'cleanup' command. [1] sysbench-1.0.18/tests/t/opt_report_checkpoints.t0000600000175000017500000000127013553247311017600 0ustar jpjp######################################################################## # --report-checkpoints tests ######################################################################## $ if [ -z "$SBTEST_HAS_MYSQL" ] > then > exit 80 > fi $ sysbench ${SBTEST_SCRIPTDIR}/oltp_read_write.lua --db-driver=mysql --mysql-dry-run --time=3 --events=0 --report-checkpoints=1,2 run | egrep '(Checkpoint report|SQL statistics)' [ 1s ] Checkpoint report: SQL statistics: [ 2s ] Checkpoint report: SQL statistics: SQL statistics: # Run a test that does not support checkpoint reports $ sysbench cpu --report-checkpoints=1 --time=2 run | grep 'Checkpoint report' [ 1s ] Checkpoint report: sysbench-1.0.18/tests/t/script_oltp_insert_mysql.t0000600000175000017500000002443613553247311020175 0ustar jpjp######################################################################## oltp_insert.lua + MySQL tests ######################################################################## $ . $SBTEST_INCDIR/mysql_common.sh $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_insert.lua $ . $SBTEST_INCDIR/script_oltp_common.sh sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating a secondary index on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating a secondary index on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating a secondary index on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating a secondary index on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating a secondary index on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating a secondary index on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating a secondary index on 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist sysbench * (glob) Prewarming table sbtest1 Prewarming table sbtest2 Prewarming table sbtest3 Prewarming table sbtest4 Prewarming table sbtest5 Prewarming table sbtest6 Prewarming table sbtest7 Prewarming table sbtest8 sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 0 write: 100 other: 0 total: 100 transactions: 100 (* per sec.) (glob) queries: 100 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist # Test --create-secondary=off sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) sysbench * (glob) Dropping table 'sbtest1'... # Test --auto-inc=off Creating table 'sbtest1'... Creating a secondary index on 'sbtest1'... Dropping table 'sbtest1'... sysbench-1.0.18/tests/t/test_threads.t0000600000175000017500000000255413553247311015510 0ustar jpjp######################################################################## threads benchmark tests ######################################################################## $ args="threads --events=100 --threads=2" $ sysbench $args help sysbench *.* * (glob) threads options: --thread-yields=N number of yields to do per request [1000] --thread-locks=N number of locks per thread [8] $ sysbench $args prepare sysbench *.* * (glob) 'threads' test does not implement the 'prepare' command. [1] $ sysbench $args run sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) $ sysbench $args cleanup sysbench *.* * (glob) 'threads' test does not implement the 'cleanup' command. [1] sysbench-1.0.18/tests/t/script_oltp_read_write_mysql.t0000600000175000017500000005130313553247311021007 0ustar jpjp######################################################################## oltp_read_write.lua + MySQL tests ######################################################################## $ . $SBTEST_INCDIR/mysql_common.sh $ DB_DRIVER_ARGS="--db-driver=mysql --mysql-storage-engine=myisam $SBTEST_MYSQL_ARGS" $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_read_write.lua # Override --threads to run read/write tests with a single thread for # deterministic results $ SB_EXTRA_ARGS="--threads=1" $ . $SBTEST_INCDIR/script_oltp_common.sh sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating a secondary index on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating a secondary index on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating a secondary index on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating a secondary index on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating a secondary index on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating a secondary index on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating a secondary index on 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist sysbench * (glob) Prewarming table sbtest1 Prewarming table sbtest2 Prewarming table sbtest3 Prewarming table sbtest4 Prewarming table sbtest5 Prewarming table sbtest6 Prewarming table sbtest7 Prewarming table sbtest8 sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist sysbench *.* * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 1400 write: 400 other: 200 total: 2000 transactions: 100 (* per sec.) (glob) queries: 2000 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist # Test --create-secondary=off sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) sysbench * (glob) Dropping table 'sbtest1'... # Test --auto-inc=off Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Dropping table 'sbtest1'... $ DB_DRIVER_ARGS="--db-driver=mysql --mysql-storage-engine=innodb $SBTEST_MYSQL_ARGS" $ . $SBTEST_INCDIR/script_oltp_common.sh sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating a secondary index on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating a secondary index on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating a secondary index on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating a secondary index on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating a secondary index on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating a secondary index on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating a secondary index on 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist sysbench * (glob) Prewarming table sbtest1 Prewarming table sbtest2 Prewarming table sbtest3 Prewarming table sbtest4 Prewarming table sbtest5 Prewarming table sbtest6 Prewarming table sbtest7 Prewarming table sbtest8 sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist sysbench *.* * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 1400 write: 400 other: 200 total: 2000 transactions: 100 (* per sec.) (glob) queries: 2000 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist # Test --create-secondary=off sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob) sysbench * (glob) Dropping table 'sbtest1'... # Test --auto-inc=off Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Dropping table 'sbtest1'... sysbench-1.0.18/tests/t/opt_version.t0000600000175000017500000000052313553247311015360 0ustar jpjp######################################################################## Test for the --version option ######################################################################## $ sysbench --version sysbench [.0-9]+(-[a-f0-9]+)? (re) $ version=$(sysbench --version | cut -d ' ' -f 1,2) $ test "$version" = "$SBTEST_VERSION_STRING" sysbench-1.0.18/tests/t/script_oltp_read_write_pgsql.t0000600000175000017500000004416413553247311020777 0ustar jpjp######################################################################## oltp_read_write.lua + PostgreSQL tests ######################################################################## $ . $SBTEST_INCDIR/pgsql_common.sh $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_read_write.lua # Override --threads to run read/write tests with a single thread for # deterministic results $ SB_EXTRA_ARGS="--threads=1" $ . $SBTEST_INCDIR/script_oltp_common.sh sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating a secondary index on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating a secondary index on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating a secondary index on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating a secondary index on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating a secondary index on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating a secondary index on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating a secondary index on 'sbtest8'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_1 ON sbtest1 USING btree (k) CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Table "public.sbtest2" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest2_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_2 ON sbtest2 USING btree (k) CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id) Table "public.sbtest3" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest3_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_3 ON sbtest3 USING btree (k) CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id) Table "public.sbtest4" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest4_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_4 ON sbtest4 USING btree (k) CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id) Table "public.sbtest5" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest5_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_5 ON sbtest5 USING btree (k) CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id) Table "public.sbtest6" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest6_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_6 ON sbtest6 USING btree (k) CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id) Table "public.sbtest7" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest7_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_7 ON sbtest7 USING btree (k) CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id) Table "public.sbtest8" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest8_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_8 ON sbtest8 USING btree (k) CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id) Did not find any relation named "sbtest9". sysbench *.* * (glob) FATAL: *: prewarm is currently MySQL only (glob) sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_1 ON sbtest1 USING btree (k) CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Table "public.sbtest2" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest2_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_2 ON sbtest2 USING btree (k) CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id) Table "public.sbtest3" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest3_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_3 ON sbtest3 USING btree (k) CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id) Table "public.sbtest4" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest4_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_4 ON sbtest4 USING btree (k) CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id) Table "public.sbtest5" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest5_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_5 ON sbtest5 USING btree (k) CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id) Table "public.sbtest6" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest6_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_6 ON sbtest6 USING btree (k) CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id) Table "public.sbtest7" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest7_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_7 ON sbtest7 USING btree (k) CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id) Table "public.sbtest8" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest8_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_8 ON sbtest8 USING btree (k) CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id) Did not find any relation named "sbtest9". sysbench *.* * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 1400 write: 400 other: 200 total: 2000 transactions: 100 (* per sec.) (glob) queries: 2000 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) Did not find any relation named "sbtest1". Did not find any relation named "sbtest2". Did not find any relation named "sbtest3". Did not find any relation named "sbtest4". Did not find any relation named "sbtest5". Did not find any relation named "sbtest6". Did not find any relation named "sbtest7". Did not find any relation named "sbtest8". # Test --create-secondary=off sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) sysbench * (glob) Dropping table 'sbtest1'... # Test --auto-inc=off Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Dropping table 'sbtest1'... sysbench-1.0.18/tests/t/script_select_random_pgsql.t0000600000175000017500000001400613553247311020423 0ustar jpjp######################################################################## select_random_*.lua + PostgreSQL tests ######################################################################## $ . $SBTEST_INCDIR/pgsql_common.sh $ . $SBTEST_INCDIR/script_select_random_common.sh sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_1 ON sbtest1 USING btree (k) CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Did not find any relation named "sbtest2". Did not find any relation named "sbtest3". Did not find any relation named "sbtest4". Did not find any relation named "sbtest5". Did not find any relation named "sbtest6". Did not find any relation named "sbtest7". Did not find any relation named "sbtest8". sysbench * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 100 write: 0 other: 0 total: 100 transactions: 100 (* per sec.) (glob) queries: 100 (* per sec.) (glob) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev):* (glob) execution time (avg/stddev):* (glob) sysbench * (glob) Dropping table 'sbtest1'... Did not find any relation named "sbtest1". Did not find any relation named "sbtest2". Did not find any relation named "sbtest3". Did not find any relation named "sbtest4". Did not find any relation named "sbtest5". Did not find any relation named "sbtest6". Did not find any relation named "sbtest7". Did not find any relation named "sbtest8". sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_1 ON sbtest1 USING btree (k) CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Did not find any relation named "sbtest2". Did not find any relation named "sbtest3". Did not find any relation named "sbtest4". Did not find any relation named "sbtest5". Did not find any relation named "sbtest6". Did not find any relation named "sbtest7". Did not find any relation named "sbtest8". sysbench * (glob) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 100 write: 0 other: 0 total: 100 transactions: 100 (* per sec.) (glob) queries: 100 (* per sec.) (glob) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev):* (glob) execution time (avg/stddev):* (glob) sysbench * (glob) Dropping table 'sbtest1'... Did not find any relation named "sbtest1". Did not find any relation named "sbtest2". Did not find any relation named "sbtest3". Did not find any relation named "sbtest4". Did not find any relation named "sbtest5". Did not find any relation named "sbtest6". Did not find any relation named "sbtest7". Did not find any relation named "sbtest8". sysbench-1.0.18/tests/t/cmd_cleanup.t0000600000175000017500000000047413553247311015270 0ustar jpjp $ sysbench cleanup sysbench * (glob) FATAL: Cannot find benchmark 'cleanup': no such built-in test, file or module [1] $ cat >cmd_cleanup.lua < function cleanup() > print('function cleanup()') > end > EOF $ sysbench cmd_cleanup.lua cleanup sysbench * (glob) function cleanup() sysbench-1.0.18/tests/t/cmdline.t0000600000175000017500000002724013553247311014431 0ustar jpjp######################################################################## # Command line syntax tests ######################################################################## $ sysbench foo bar sysbench * (glob) FATAL: Cannot find benchmark 'foo': no such built-in test, file or module [1] $ sysbench foo bar baz Unrecognized command line argument: baz [1] $ sysbench --unknown < EOF sysbench * (glob) $ sysbench fileio sysbench * (glob) The 'fileio' test requires a command argument. See 'sysbench fileio help' [1] $ sysbench --help foo | grep Usage: Usage: $ sysbench < print('test') > EOF sysbench * (glob) test $ sysbench run < print('script body') > function event() > print('event function') > end > EOF sysbench * (glob) FATAL: Cannot find benchmark 'run': no such built-in test, file or module [1] $ cat >$CRAMTMP/cmdline.lua < #!/usr/bin/env sysbench > print('script body') > function event() > print('event function') > end > EOF $ sysbench --events=1 $CRAMTMP/cmdline.lua sysbench * (glob) script body $ sysbench --events=1 $CRAMTMP/cmdline.lua run sysbench * (glob) script body Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... script body Threads started! event function General statistics: total time: *s (glob) total number of events: 1 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): 1.0000/0.00 execution time (avg/stddev): *.*/0.00 (glob) ######################################################################## Command line options tests ######################################################################## $ cat >cmdline.lua < sysbench.cmdline.options = { > str_opt1 = {"str_opt1 description"}, > str_opt2 = {"str_opt2 description", "opt2"}, > str_opt3 = {"str_opt3 description", "opt3", sysbench.cmdline.ARG_STRING}, > bool_opt1 = {"bool_opt1 description", false}, > bool_opt2 = {"bool_opt2 description", true}, > bool_opt3 = {"bool_opt3 description", nil, sysbench.cmdline.ARG_BOOL}, > int_opt1 = {"int_opt1 description", 10}, > int_opt2 = {"int_opt2 description", nil, sysbench.cmdline.ARG_INT}, > int_opt3 = {"int_opt3 description", 20, sysbench.cmdline.ARG_INT}, > float_opt1 = {"float_opt1 description", 3.14, sysbench.cmdline.ARG_DOUBLE}, > float_opt2 = {"float_opt2 description", 0.2}, > list_opt1 = {"list_opt1 description", {"foo", "bar"}}, > list_opt2 = {"list_opt2 description", nil, sysbench.cmdline.ARG_LIST}, > ["dash-opt"] = {"dash-opt desc", "dash-opt val"} > } > > function print_opt_table() > local o = sysbench.opt > print(o.str_opt1) > print(o.str_opt2) > print(o.str_opt3) > print(o.bool_opt1) > print(o.bool_opt2) > print(o.bool_opt3) > print(o.int_opt1) > print(o.int_opt2) > print(o.float_opt1) > print(o.float_opt2) > print(o.list_opt1) > print(o.list_opt2) > print(o.dash_opt) > print() > end > > function help() > print("function help()") > print("Available options:") > sysbench.cmdline.print_test_options() > print_opt_table() > end > > function init() > print("function init()") > print_opt_table() > end > > function thread_init() > print("function thread_init()") > print_opt_table() > end > > function event() > print("function event()") > print_opt_table() > end > > function thread_done() > print("function thread_done()") > print_opt_table() > end > > function done() > print("function done()") > print_opt_table() > end > EOF $ sysbench cmdline.lua sysbench * (glob) $ sysbench cmdline.lua help sysbench * (glob) function help() Available options: --bool_opt1[=on|off] bool_opt1 description [off] --bool_opt2[=on|off] bool_opt2 description [on] --bool_opt3[=on|off] bool_opt3 description --dash-opt=STRING dash-opt desc [dash-opt val] --float_opt1=N float_opt1 description [3.14] --float_opt2=N float_opt2 description [0.2] --int_opt1=N int_opt1 description [10] --int_opt2=N int_opt2 description --int_opt3=N int_opt3 description [20] --list_opt1=[LIST,...] list_opt1 description [foo,bar] --list_opt2=[LIST,...] list_opt2 description --str_opt1=STRING str_opt1 description --str_opt2=STRING str_opt2 description [opt2] --str_opt3=STRING str_opt3 description [opt3] opt2 opt3 false true true 10 0 3.14 0.2 table: 0x* (glob) table: 0x* (glob) dash-opt val $ sysbench cmdline.lua prepare sysbench * (glob) 'cmdline.lua' test does not implement the 'prepare' command. [1] $ sysbench --non-existing-option=3 cmdline.lua prepare sysbench * (glob) invalid option: --non-existing-option=3 [1] $ sysbench cmdline.lua --events=1 run sysbench * (glob) function init() opt2 opt3 false true true 10 0 3.14 0.2 table: 0x* (glob) table: 0x* (glob) dash-opt val Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... function thread_init() opt2 opt3 false true true 10 0 3.14 0.2 table: 0x* (glob) table: 0x* (glob) dash-opt val Threads started! function event() opt2 opt3 false true true 10 0 3.14 0.2 table: 0x* (glob) table: 0x* (glob) dash-opt val function thread_done() opt2 opt3 false true true 10 0 3.14 0.2 table: 0x* (glob) table: 0x* (glob) dash-opt val General statistics: total time: *s (glob) total number of events: 1 Latency (ms): min: * (glob) avg: * (glob) max: * (glob) 95th percentile: * (glob) sum: * (glob) Threads fairness: events (avg/stddev): 1.0000/0.00 execution time (avg/stddev): */0.00 (glob) function done() opt2 opt3 false true true 10 0 3.14 0.2 table: 0x* (glob) table: 0x* (glob) dash-opt val $ sysbench cmdline.lua cleanup sysbench * (glob) 'cmdline.lua' test does not implement the 'cleanup' command. [1] $ cat >cmdline.lua < > EOF $ sysbench cmdline.lua help sysbench * (glob) 'cmdline.lua' test does not implement the 'help' command. [1] $ cat >cmdline.lua < sysbench.cmdline.options = { > {}, > } > > function help() > end > EOF $ sysbench cmdline.lua help sysbench * (glob) FATAL: `sysbench.cmdline.read_cmdline_options' function failed: [string "sysbench.cmdline.lua"]:*: wrong table structure in sysbench.cmdline.options (glob) [1] $ sysbench fileio --invalid-option prepare sysbench * (glob) invalid option: --invalid-option [1] # Custom commands $ sysbench < sysbench.cmdline.commands = { > cmd1 = "wrong structure" > } > EOF sysbench * (glob) $ sysbench < sysbench.cmdline.commands = { > cmd1 = { non_existing_func } > } > EOF sysbench * (glob) $ cat >cmdline.lua < ffi.cdef "unsigned int sleep(unsigned int);" > function cmd1_func() > print("cmd1, sysbench.tid = " .. sysbench.tid) > end > function cmd2_func() > ffi.C.sleep(sysbench.tid % 2) > print("cmd2, sysbench.tid = " .. sysbench.tid) > end > function prepare_func() > ffi.C.sleep(sysbench.tid % 2) > print("prepare_func, sysbench.tid = " .. sysbench.tid) > end > sysbench.cmdline.commands = { > cmd1 = { cmd1_func }, > cmd2 = { cmd2_func, sysbench.cmdline.PARALLEL_COMMAND }, > prepare = { prepare_func, sysbench.cmdline.PARALLEL_COMMAND } > } > EOF $ sysbench --threads=2 cmdline.lua cmd1 sysbench * (glob) cmd1, sysbench.tid = 0 $ sysbench --threads=2 cmdline.lua cmd2 sysbench * (glob) Initializing worker threads... cmd2, sysbench.tid = [01] (re) cmd2, sysbench.tid = [01] (re) $ sysbench --threads=2 cmdline.lua prepare sysbench * (glob) Initializing worker threads... prepare_func, sysbench.tid = [01] (re) prepare_func, sysbench.tid = [01] (re) $ sysbench --threads=2 cmdline.lua cmd3 sysbench * (glob) Unknown command: cmd3 [1] $ cat >cmdline.lua < function print_cmd() > print("argv = " .. require("inspect")(sysbench.cmdline.argv)) > print(string.format("sysbench.cmdline.command = %s",sysbench.cmdline.command)) > end > function prepare() > print_cmd() > end > print_cmd() > EOF $ sysbench --opt1 --opt2=val cmdline.lua sysbench * (glob) argv = { "--opt1", "--opt2=val", "cmdline.lua", [0] = "sysbench" } sysbench.cmdline.command = nil $ sysbench --opt1 --opt2=val cmdline.lua prepare sysbench * (glob) argv = { "--opt1", "--opt2=val", "cmdline.lua", "prepare", [0] = "sysbench" } sysbench.cmdline.command = prepare argv = { "--opt1", "--opt2=val", "cmdline.lua", "prepare", [0] = "sysbench" } sysbench.cmdline.command = prepare $ sysbench - < print("hello") > EOF sysbench * (glob) hello $ sysbench - prepare < function prepare() > print("prepare") > end > print("global") > EOF sysbench * (glob) global # Test benchmark specification as a module $ cat > cmdline_module.lua < print("cmdline_module loaded") > function event() > print("cmdline_module event") > end > EOF $ LUA_PATH="$PWD/?.lua;$LUA_PATH" sysbench cmdline_module --verbosity=0 cmdline_module loaded $ LUA_PATH="$PWD/?.lua;$LUA_PATH" sysbench cmdline_module --events=1 --verbosity=0 run cmdline_module loaded cmdline_module loaded cmdline_module event # Test that errors thrown by the script itself are reported properly $ cat >> cmdline_module.lua < error("test error") > EOF $ LUA_PATH="$PWD/?.lua;$LUA_PATH" sysbench cmdline_module --verbosity=0 cmdline_module loaded FATAL: */cmdline_module.lua:5: test error (glob) [1] $ LUA_PATH="$PWD/?.lua;$LUA_PATH" sysbench cmdline_module --events=1 --verbosity=0 run cmdline_module loaded FATAL: */cmdline_module.lua:5: test error (glob) [1] ########################################################################## # Test boolean option validation ########################################################################## $ cat > cmdline.lua < sysbench.cmdline.options = { > bool_opt = {"Flag", false} > } > > function prepare() > print("bool_opt = " .. tostring(sysbench.opt.bool_opt)) > end > EOF $ SB_ARGS=--verbosity=0 $ sysbench $SB_ARGS cmdline.lua --bool-opt=on prepare bool_opt = true $ sysbench $SB_ARGS cmdline.lua --bool-opt=off prepare bool_opt = false $ sysbench $SB_ARGS cmdline.lua --bool-opt=true prepare bool_opt = true $ sysbench $SB_ARGS cmdline.lua --bool-opt=false prepare bool_opt = false $ sysbench $SB_ARGS cmdline.lua --bool-opt=1 prepare bool_opt = true $ sysbench $SB_ARGS cmdline.lua --bool-opt=0 prepare bool_opt = false $ sysbench $SB_ARGS cmdline.lua --bool-opt=5 prepare invalid option: --bool-opt=5 [1] $ sysbench $SB_ARGS cmdline.lua --bool-opt=foo prepare invalid option: --bool-opt=foo [1] sysbench-1.0.18/tests/t/test_cpu.t0000600000175000017500000000261413553247311014642 0ustar jpjp######################################################################## cpu benchmark tests ######################################################################## $ args="cpu --cpu-max-prime=1000 --events=100 --threads=2" $ sysbench $args help sysbench *.* * (glob) cpu options: --cpu-max-prime=N upper limit for primes generator [10000] $ sysbench $args prepare sysbench *.* * (glob) 'cpu' test does not implement the 'prepare' command. [1] $ sysbench $args run sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Prime numbers limit: 1000 Initializing worker threads... Threads started! CPU speed: events per second: *.* (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): 50.0000/* (glob) execution time (avg/stddev): */* (glob) $ sysbench $args cleanup sysbench *.* * (glob) 'cpu' test does not implement the 'cleanup' command. [1] sysbench-1.0.18/tests/t/api_legacy_rand.t0000600000175000017500000000372713553247311016123 0ustar jpjp######################################################################## Legacy PRNG Lua API tests ######################################################################## $ SB_ARGS="--verbosity=0 --max-requests=1" $ cat >$CRAMTMP/api_legacy_rand.lua < function event() > print("sb_rand(0, 9) = " .. sb_rand(0, 9)) > print("sb_rand_uniq(0, 4294967295) = " .. sb_rand_uniq(0, 4294967295)) > print("sb_rnd() = " .. sb_rnd()) > print([[sb_rand_str("abc-###-@@@-xyz") = ]] .. sb_rand_str("abc-###-@@@-xyz")) > print("sb_rand_uniform(0, 9) = " .. sb_rand_uniform(0, 9)) > print("sb_rand_gaussian(0, 9) = " .. sb_rand_gaussian(0, 9)) > print("sb_rand_special(0, 9) = " .. sb_rand_special(0, 9)) > end > EOF $ sysbench $SB_ARGS --test=$CRAMTMP/api_legacy_rand.lua run WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. WARNING: --max-requests is deprecated, use --events instead sb_rand\(0, 9\) = [0-9]{1} (re) sb_rand_uniq\(0, 4294967295\) = [0-9]{1,10} (re) sb_rnd\(\) = [0-9]+ (re) sb_rand_str\(".*"\) = abc-[0-9]{3}-[a-z]{3}-xyz (re) sb_rand_uniform\(0, 9\) = [0-9]{1} (re) sb_rand_gaussian\(0, 9\) = [0-9]{1} (re) sb_rand_special\(0, 9\) = [0-9]{1} (re) ######################################################################## issue #96: sb_rand_uniq(1, oltp_table_size) generate duplicate value ######################################################################## $ cat >$CRAMTMP/api_rand_uniq.lua < function event() > local max = 1000000000 > local n = sb_rand_uniq(1, max) > if n > max then > error("n is out of range") > end > print(n) > end > EOF $ sysbench $SB_ARGS --max-requests=100000 --test=$CRAMTMP/api_rand_uniq.lua run | > grep -v WARNING | sort -n | uniq | wc -l | sed -e 's/ //g' WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. 100000 sysbench-1.0.18/tests/t/1st.t0000600000175000017500000000014313553247311013516 0ustar jpjp# Ensure the sysbench binary exists in PATH and is executable $ sysbench --help >/dev/null 2>&1 sysbench-1.0.18/tests/t/api_sql_mysql.t0000600000175000017500000000717713553247311015702 0ustar jpjp######################################################################## SQL Lua API + MySQL tests ######################################################################## $ . ${SBTEST_INCDIR}/mysql_common.sh $ . ${SBTEST_INCDIR}/api_sql_common.sh drv:name() = mysql SQL types: { BIGINT = 4, CHAR = 11, DATE = 8, DATETIME = 9, DOUBLE = 6, FLOAT = 5, INT = 3, NONE = 0, SMALLINT = 2, TIME = 7, TIMESTAMP = 10, TINYINT = 1, VARCHAR = 12 } -- SQL error codes: { FATAL = 2, IGNORABLE = 1, NONE = 0 } -- FATAL: invalid database driver name: 'non-existing' failed to initialize the DB driver 100 -- -- nil bar 0.2 nil nil 0.1 1 foo 0.4 2 nil 0.3 -- nil 2 -- FATAL: mysql_stmt_prepare() failed FATAL: MySQL error: 1146 "Table 'sbtest.nonexisting' doesn't exist" SQL API error -- Unsupported argument type: 8 nil ALERT: attempt to free an invalid result set db_free_results() failed db_free_results() failed -- (last message repeated 1 times) ALERT: attempt to use an already closed connection */api_sql.lua:*: SQL API error (glob) ALERT: attempt to close an already closed connection -- 4 301 400 0123456789 0123456789 -- 1 2 -- reconnects = 1 FATAL: unable to connect to MySQL server on host 'non-existing', port 3306, aborting... FATAL: error 2005: Unknown MySQL server host 'non-existing' (0) connection creation failed -- FATAL: mysql_drv_query() returned error 1048 (Column 'a' cannot be null) for query 'INSERT INTO t VALUES (NULL)' Got an error descriptor: { connection = , query = "INSERT INTO t VALUES (NULL)", sql_errmsg = "Column 'a' cannot be null", sql_errno = 1048, sql_state = "23000" } */api_sql.lua:*: SQL error, errno = 1048, state = '23000': Column 'a' cannot be null (glob) FATAL: mysql_drv_query() returned error 1406 (Data too long for column 'a' at row 1) for query 'INSERT INTO t VALUES ('test')' Got an error descriptor: { connection = , query = "INSERT INTO t VALUES ('test')", sql_errmsg = "Data too long for column 'a' at row 1", sql_errno = 1406, sql_state = "22001" } */api_sql.lua:*: SQL error, errno = 1406, state = '22001': Data too long for column 'a' at row 1 (glob) FATAL: mysql_drv_query() returned error 1051 (Unknown table '*t') for query 'DROP TABLE t' (glob) Got an error descriptor: { connection = , query = "DROP TABLE t", sql_errmsg = "Unknown table 'sbtest.t'", sql_errno = 1051, sql_state = "42S02" } */api_sql.lua:*: SQL error, errno = 1051, state = '42S02': Unknown table '*t' (glob) -- ######################################################################## # Multiple connections test ######################################################################## 1 2 3 4 5 6 7 8 9 10 ######################################################################## # Incorrect bulk API usage ######################################################################## ALERT: attempt to call bulk_insert_next() before bulk_insert_init() */api_sql.lua:*: db_bulk_insert_next() failed (glob) ######################################################################## # query_row() with an empty result set ######################################################################## nil ######################################################################## # GH-282: Mysql's fetch_row() is broken ######################################################################## 1 2 sysbench-1.0.18/tests/t/script_oltp_insert_pgsql.t0000600000175000017500000004367613553247311020165 0ustar jpjp######################################################################## oltp_insert.lua + PostgreSQL tests ######################################################################## $ . $SBTEST_INCDIR/pgsql_common.sh $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_insert.lua $ . $SBTEST_INCDIR/script_oltp_common.sh sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating a secondary index on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating a secondary index on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating a secondary index on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating a secondary index on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating a secondary index on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating a secondary index on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating a secondary index on 'sbtest8'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_1 ON sbtest1 USING btree (k) CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Table "public.sbtest2" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest2_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_2 ON sbtest2 USING btree (k) CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id) Table "public.sbtest3" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest3_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_3 ON sbtest3 USING btree (k) CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id) Table "public.sbtest4" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest4_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_4 ON sbtest4 USING btree (k) CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id) Table "public.sbtest5" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest5_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_5 ON sbtest5 USING btree (k) CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id) Table "public.sbtest6" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest6_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_6 ON sbtest6 USING btree (k) CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id) Table "public.sbtest7" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest7_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_7 ON sbtest7 USING btree (k) CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id) Table "public.sbtest8" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest8_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_8 ON sbtest8 USING btree (k) CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id) Did not find any relation named "sbtest9". sysbench *.* * (glob) FATAL: *: prewarm is currently MySQL only (glob) sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_1 ON sbtest1 USING btree (k) CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Table "public.sbtest2" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest2_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_2 ON sbtest2 USING btree (k) CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id) Table "public.sbtest3" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest3_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_3 ON sbtest3 USING btree (k) CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id) Table "public.sbtest4" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest4_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_4 ON sbtest4 USING btree (k) CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id) Table "public.sbtest5" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest5_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_5 ON sbtest5 USING btree (k) CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id) Table "public.sbtest6" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest6_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_6 ON sbtest6 USING btree (k) CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id) Table "public.sbtest7" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest7_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_7 ON sbtest7 USING btree (k) CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id) Table "public.sbtest8" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest8_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_8 ON sbtest8 USING btree (k) CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id) Did not find any relation named "sbtest9". sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 0 write: 100 other: 0 total: 100 transactions: 100 (* per sec.) (glob) queries: 100 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) Did not find any relation named "sbtest1". Did not find any relation named "sbtest2". Did not find any relation named "sbtest3". Did not find any relation named "sbtest4". Did not find any relation named "sbtest5". Did not find any relation named "sbtest6". Did not find any relation named "sbtest7". Did not find any relation named "sbtest8". # Test --create-secondary=off sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) sysbench * (glob) Dropping table 'sbtest1'... # Test --auto-inc=off Creating table 'sbtest1'... Creating a secondary index on 'sbtest1'... Dropping table 'sbtest1'... sysbench-1.0.18/tests/t/help_drv_mysql.t0000600000175000017500000000236013553247311016042 0ustar jpjpSkip test if the MySQL driver is not available. $ if [ -z "$SBTEST_HAS_MYSQL" ] > then > exit 80 > fi $ sysbench --help | grep -- '--db-driver' --db-driver=STRING specifies database driver to use ('help' to get list of available drivers) [mysql] $ sysbench --help | sed -n '/mysql options:/,/^$/p' mysql options: --mysql-host=[LIST,...] MySQL server host [localhost] --mysql-port=[LIST,...] MySQL server port [3306] --mysql-socket=[LIST,...] MySQL socket --mysql-user=STRING MySQL user [sbtest] --mysql-password=STRING MySQL password [] --mysql-db=STRING MySQL database name [sbtest] --mysql-ssl[=on|off] use SSL connections, if available in the client library [off] --mysql-ssl-cipher=STRING use specific cipher for SSL connections [] --mysql-compression[=on|off] use compression, if available in the client library [off] --mysql-debug[=on|off] trace all client library calls [off] --mysql-ignore-errors=[LIST,...] list of errors to ignore, or "all" [1213,1020,1205] --mysql-dry-run[=on|off] Dry run, pretend that all MySQL client API calls are successful without executing them [off] sysbench-1.0.18/tests/t/commands.t0000600000175000017500000000035613553247311014616 0ustar jpjp $ commands=$(sysbench --help | grep 'Commands' | cut -d ' ' -f 6-) $ for cmd in $commands; do > if [ ! -r ${SBTEST_SUITEDIR}/cmd_${cmd}.t ] > then > echo "Cannot find test(s) for 'sysbench $cmd'!" > exit 1 > fi > done sysbench-1.0.18/tests/t/api_legacy_basic.t0000600000175000017500000000464613553247311016261 0ustar jpjp######################################################################## Legacy basic Lua API tests ######################################################################## $ if [ -z "${SBTEST_MYSQL_ARGS:-}" ] > then > exit 80 > fi $ SB_ARGS="--verbosity=0 --max-requests=2 --db-driver=mysql $SBTEST_MYSQL_ARGS --test=$CRAMTMP/api_legacy_basic.lua" $ cat >$CRAMTMP/api_legacy_basic.lua < function prepare(thread_id) > print("tid:" .. (thread_id or "(nil)") .. " prepare()") > end > > function run(thread_id) > print("tid:" .. (thread_id or "(nil)") .. " run()") > end > > function cleanup(thread_id) > print("tid:" .. (thread_id or "(nil)") .. " cleanup()") > end > > function help() > print("tid:" .. (thread_id or "(nil)") .. " help()") > end > > function thread_init(thread_id) > print(string.format("tid:%d thread_init()", thread_id)) > end > > function event(thread_id) > print(string.format("tid:%d event()", thread_id)) > end > > function thread_done(thread_id) > print(string.format("tid:%d thread_done()", thread_id)) > end > > EOF $ sysbench $SB_ARGS prepare WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. WARNING: --max-requests is deprecated, use --events instead tid:(nil) prepare() $ sysbench $SB_ARGS run WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. WARNING: --max-requests is deprecated, use --events instead tid:0 thread_init() tid:0 event() tid:0 event() tid:0 thread_done() $ sysbench $SB_ARGS cleanup WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. WARNING: --max-requests is deprecated, use --events instead tid:(nil) cleanup() $ sysbench $SB_ARGS help WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. WARNING: --max-requests is deprecated, use --events instead tid:0 help() $ cat >$CRAMTMP/api_legacy_basic.lua < function prepare() > print(test) > end > EOF $ sysbench $SB_ARGS prepare WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. WARNING: --max-requests is deprecated, use --events instead */api_legacy_basic.lua (glob) sysbench-1.0.18/tests/t/drv_pgsql.t0000600000175000017500000000270313553247311015014 0ustar jpjp######################################################################## PostgreSQL driver tests ######################################################################## $ . $SBTEST_INCDIR/pgsql_common.sh $ . $SBTEST_INCDIR/drv_common.sh sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 10 write: 0 other: 0 total: 10 transactions: 10 (*.* per sec.) (glob) queries: 10 (*.* per sec.) (glob) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: *.*s (glob) total number of events: 10 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): *.*/*.* (glob) execution time (avg/stddev): *.*/*.* (glob) sysbench-1.0.18/tests/t/script_bulk_insert_mysql.t0000600000175000017500000000440513553247311020146 0ustar jpjp######################################################################## bulk_insert.lua + MySQL tests ######################################################################## $ . $SBTEST_INCDIR/mysql_common.sh $ . $SBTEST_INCDIR/script_bulk_insert_common.sh Creating table 'sbtest1'... Creating table 'sbtest2'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL, `k` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB * (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(11) NOT NULL, `k` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB * (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist sysbench * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 0 write: [12] (re) other: 0 total: [12] (re) transactions: 100 (* per sec.) (glob) queries: [12] \(.* per sec.\) (re) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev):* (glob) execution time (avg/stddev):* (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist sysbench-1.0.18/tests/t/api_legacy_sql.t0000600000175000017500000004253113553247311015772 0ustar jpjp######################################################################## Legacy SQL Lua API tests ######################################################################## $ if [ -z "${SBTEST_MYSQL_ARGS:-}" ] > then > exit 80 > fi $ SB_ARGS="--verbosity=1 --max-requests=1 --db-driver=mysql $SBTEST_MYSQL_ARGS --test=$CRAMTMP/api_legacy_sql.lua" $ cat >$CRAMTMP/api_legacy_sql.lua < function event(thread_id) > db_query("CREATE TABLE t(a INT)") > > db_bulk_insert_init("INSERT INTO t VALUES") > for i = 1,100 do > db_bulk_insert_next(string.format("(%d)", i)) > end > db_bulk_insert_done() > > db_connect() > db_query("SELECT 1") > db_disconnect() > db_query("SELECT 1") > db_connect() > > local stmt = db_prepare("UPDATE t SET a = a + ?") > db_bind_param(stmt, {100}) > rs = db_execute(stmt) > db_store_results(rs) > db_free_results(rs) > db_close(stmt) > > print("DB_ERROR_NONE = " .. DB_ERROR_NONE) > print("DB_ERROR_RESTART_TRANSACTION = " .. DB_ERROR_RESTART_TRANSACTION) > print("DB_ERROR_FAILED = " .. DB_ERROR_FAILED) > end > EOF $ mysql -uroot sbtest -Nse "DROP TABLE IF EXISTS t" $ sysbench $SB_ARGS run WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. WARNING: --max-requests is deprecated, use --events instead DB_ERROR_NONE = [0-9] (re) DB_ERROR_RESTART_TRANSACTION = [0-9] (re) DB_ERROR_FAILED = [0-9] (re) $ mysql -uroot sbtest -Nse "SHOW CREATE TABLE t\G" *************************** 1. row *************************** t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL ) * (glob) $ mysql -uroot sbtest -Nse "SELECT COUNT(DISTINCT a) FROM t" 100 $ mysql -uroot sbtest -Nse "SELECT MIN(a), MAX(a) FROM t\G" *************************** 1. row *************************** 101 200 $ mysql -uroot sbtest -Nse "DROP TABLE t" $ function db_show_table() { > mysql -uroot sbtest -Nse "SHOW CREATE TABLE $1\G" > } $ DB_DRIVER_ARGS="--db-driver=mysql --mysql-table-engine=myisam $SBTEST_MYSQL_ARGS" $ . $SBTEST_INCDIR/script_oltp_legacy_common.sh WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating secondary indexes on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating secondary indexes on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating secondary indexes on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating secondary indexes on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating secondary indexes on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating secondary indexes on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating secondary indexes on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating secondary indexes on 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. WARNING: --num-threads is deprecated, use --threads instead WARNING: --max-requests is deprecated, use --events instead sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 1400 write: 400 other: 200 total: 2000 transactions: 100 (* per sec.) (glob) queries: 2000 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. sysbench * (glob) Dropping table 'sbtest1'... $ DB_DRIVER_ARGS="--db-driver=mysql --mysql-table-engine=innodb $SBTEST_MYSQL_ARGS" $ . $SBTEST_INCDIR/script_oltp_legacy_common.sh WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating secondary indexes on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating secondary indexes on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating secondary indexes on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating secondary indexes on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating secondary indexes on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating secondary indexes on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating secondary indexes on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating secondary indexes on 'sbtest8'... *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest2 CREATE TABLE `sbtest2` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_2` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest3 CREATE TABLE `sbtest3` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_3` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest4 CREATE TABLE `sbtest4` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_4` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest5 CREATE TABLE `sbtest5` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_5` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest6 CREATE TABLE `sbtest6` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_6` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest7 CREATE TABLE `sbtest7` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_7` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) *************************** 1. row *************************** sbtest8 CREATE TABLE `sbtest8` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`), KEY `k_8` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. WARNING: --num-threads is deprecated, use --threads instead WARNING: --max-requests is deprecated, use --events instead sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 1400 write: 400 other: 200 total: 2000 transactions: 100 (* per sec.) (glob) queries: 2000 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' *************************** 1. row *************************** sbtest1 CREATE TABLE `sbtest1` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120)* NOT NULL DEFAULT '', (glob) `pad` char(60)* NOT NULL DEFAULT '', (glob) PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* MAX_ROWS=1000000 (glob) WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options. sysbench * (glob) Dropping table 'sbtest1'... sysbench-1.0.18/tests/t/script_oltp_help.t0000600000175000017500000000401713553247311016365 0ustar jpjp######################################################################## OLTP usage information test ######################################################################## $ sysbench $SBTEST_SCRIPTDIR/oltp_read_write.lua help sysbench * (glob) oltp_read_write.lua options: --auto_inc[=on|off] Use AUTO_INCREMENT column as Primary Key (for MySQL), or its alternatives in other DBMS. When disabled, use client-generated IDs [on] --create_secondary[=on|off] Create a secondary index in addition to the PRIMARY KEY [on] --delete_inserts=N Number of DELETE/INSERT combinations per transaction [1] --distinct_ranges=N Number of SELECT DISTINCT queries per transaction [1] --index_updates=N Number of UPDATE index queries per transaction [1] --mysql_storage_engine=STRING Storage engine, if MySQL is used [innodb] --non_index_updates=N Number of UPDATE non-index queries per transaction [1] --order_ranges=N Number of SELECT ORDER BY queries per transaction [1] --pgsql_variant=STRING Use this PostgreSQL variant when running with the PostgreSQL driver. The only currently supported variant is 'redshift'. When enabled, create_secondary is automatically disabled, and delete_inserts is set to 0 --point_selects=N Number of point SELECT queries per transaction [10] --range_selects[=on|off] Enable/disable all range SELECT queries [on] --range_size=N Range size for range SELECT queries [100] --secondary[=on|off] Use a secondary index in place of the PRIMARY KEY [off] --simple_ranges=N Number of simple range SELECT queries per transaction [1] --skip_trx[=on|off] Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off] --sum_ranges=N Number of SELECT SUM() queries per transaction [1] --table_size=N Number of rows per table [10000] --tables=N Number of tables [1] sysbench-1.0.18/tests/t/script_oltp_delete_pgsql.t0000600000175000017500000004376413553247311020121 0ustar jpjp######################################################################## oltp_delete.lua + PostgreSQL tests ######################################################################## $ . $SBTEST_INCDIR/pgsql_common.sh $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_delete.lua $ . $SBTEST_INCDIR/script_oltp_common.sh sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating a secondary index on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating a secondary index on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating a secondary index on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating a secondary index on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating a secondary index on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating a secondary index on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating a secondary index on 'sbtest8'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_1 ON sbtest1 USING btree (k) CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Table "public.sbtest2" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest2_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_2 ON sbtest2 USING btree (k) CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id) Table "public.sbtest3" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest3_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_3 ON sbtest3 USING btree (k) CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id) Table "public.sbtest4" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest4_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_4 ON sbtest4 USING btree (k) CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id) Table "public.sbtest5" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest5_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_5 ON sbtest5 USING btree (k) CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id) Table "public.sbtest6" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest6_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_6 ON sbtest6 USING btree (k) CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id) Table "public.sbtest7" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest7_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_7 ON sbtest7 USING btree (k) CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id) Table "public.sbtest8" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest8_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_8 ON sbtest8 USING btree (k) CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id) Did not find any relation named "sbtest9". sysbench *.* * (glob) FATAL: *: prewarm is currently MySQL only (glob) sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_1 ON sbtest1 USING btree (k) CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Table "public.sbtest2" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest2_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_2 ON sbtest2 USING btree (k) CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id) Table "public.sbtest3" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest3_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_3 ON sbtest3 USING btree (k) CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id) Table "public.sbtest4" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest4_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_4 ON sbtest4 USING btree (k) CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id) Table "public.sbtest5" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest5_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_5 ON sbtest5 USING btree (k) CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id) Table "public.sbtest6" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest6_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_6 ON sbtest6 USING btree (k) CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id) Table "public.sbtest7" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest7_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_7 ON sbtest7 USING btree (k) CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id) Table "public.sbtest8" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest8_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_8 ON sbtest8 USING btree (k) CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id) Did not find any relation named "sbtest9". sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 0 write: * (glob) other: * (glob) total: 100 transactions: 100 (* per sec.) (glob) queries: 100 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) Did not find any relation named "sbtest1". Did not find any relation named "sbtest2". Did not find any relation named "sbtest3". Did not find any relation named "sbtest4". Did not find any relation named "sbtest5". Did not find any relation named "sbtest6". Did not find any relation named "sbtest7". Did not find any relation named "sbtest8". # Test --create-secondary=off sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) sysbench * (glob) Dropping table 'sbtest1'... # Test --auto-inc=off Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Dropping table 'sbtest1'... sysbench-1.0.18/tests/t/script_oltp_point_select_pgsql.t0000600000175000017500000004376413553247311021347 0ustar jpjp######################################################################## oltp_point_select.lua + PostgreSQL tests ######################################################################## $ . $SBTEST_INCDIR/pgsql_common.sh $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_point_select.lua $ . $SBTEST_INCDIR/script_oltp_common.sh sysbench *.* * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Creating table 'sbtest2'... Inserting 10000 records into 'sbtest2' Creating a secondary index on 'sbtest2'... Creating table 'sbtest3'... Inserting 10000 records into 'sbtest3' Creating a secondary index on 'sbtest3'... Creating table 'sbtest4'... Inserting 10000 records into 'sbtest4' Creating a secondary index on 'sbtest4'... Creating table 'sbtest5'... Inserting 10000 records into 'sbtest5' Creating a secondary index on 'sbtest5'... Creating table 'sbtest6'... Inserting 10000 records into 'sbtest6' Creating a secondary index on 'sbtest6'... Creating table 'sbtest7'... Inserting 10000 records into 'sbtest7' Creating a secondary index on 'sbtest7'... Creating table 'sbtest8'... Inserting 10000 records into 'sbtest8' Creating a secondary index on 'sbtest8'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_1 ON sbtest1 USING btree (k) CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Table "public.sbtest2" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest2_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_2 ON sbtest2 USING btree (k) CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id) Table "public.sbtest3" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest3_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_3 ON sbtest3 USING btree (k) CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id) Table "public.sbtest4" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest4_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_4 ON sbtest4 USING btree (k) CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id) Table "public.sbtest5" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest5_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_5 ON sbtest5 USING btree (k) CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id) Table "public.sbtest6" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest6_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_6 ON sbtest6 USING btree (k) CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id) Table "public.sbtest7" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest7_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_7 ON sbtest7 USING btree (k) CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id) Table "public.sbtest8" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest8_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_8 ON sbtest8 USING btree (k) CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id) Did not find any relation named "sbtest9". sysbench *.* * (glob) FATAL: *: prewarm is currently MySQL only (glob) sysbench *.* * (glob) Dropping table 'sbtest1'... Dropping table 'sbtest2'... Dropping table 'sbtest3'... Dropping table 'sbtest4'... Dropping table 'sbtest5'... Dropping table 'sbtest6'... Dropping table 'sbtest7'... Dropping table 'sbtest8'... Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_1 ON sbtest1 USING btree (k) CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) Table "public.sbtest2" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest2_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_2 ON sbtest2 USING btree (k) CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id) Table "public.sbtest3" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest3_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_3 ON sbtest3 USING btree (k) CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id) Table "public.sbtest4" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest4_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_4 ON sbtest4 USING btree (k) CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id) Table "public.sbtest5" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest5_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_5 ON sbtest5 USING btree (k) CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id) Table "public.sbtest6" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest6_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_6 ON sbtest6 USING btree (k) CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id) Table "public.sbtest7" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest7_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_7 ON sbtest7 USING btree (k) CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id) Table "public.sbtest8" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest8_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE INDEX k_8 ON sbtest8 USING btree (k) CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id) Did not find any relation named "sbtest9". sysbench *.* * (glob) Running the test with following options: Number of threads: 2 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 100 write: 0 other: 0 total: 100 transactions: 100 (* per sec.) (glob) queries: 100 (* per sec.) (glob) ignored errors: 0 (* per sec.) (glob) reconnects: 0 (* per sec.) (glob) General statistics: total time: *s (glob) total number of events: 100 Latency (ms): min: *.* (glob) avg: *.* (glob) max: *.* (glob) 95th percentile: *.* (glob) sum: *.* (glob) Threads fairness: events (avg/stddev): */* (glob) execution time (avg/stddev): */* (glob) Did not find any relation named "sbtest1". Did not find any relation named "sbtest2". Did not find any relation named "sbtest3". Did not find any relation named "sbtest4". Did not find any relation named "sbtest5". Did not find any relation named "sbtest6". Did not find any relation named "sbtest7". Did not find any relation named "sbtest8". # Test --create-secondary=off sysbench * (glob) Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Table "public.sbtest1" Column | Type | Modifiers | Storage | Stats target | Description --------+----------------+------------------------------------------------------+----------+--------------+------------- id | integer | not null default nextval('sbtest1_id_seq'::regclass) | plain | | k | integer | not null default 0 | plain | | c | character(120) | not null default ''::bpchar | extended | | pad | character(60) | not null default ''::bpchar | extended | | Indexes: CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id) sysbench * (glob) Dropping table 'sbtest1'... # Test --auto-inc=off Creating table 'sbtest1'... Inserting 10000 records into 'sbtest1' Creating a secondary index on 'sbtest1'... Dropping table 'sbtest1'... sysbench-1.0.18/tests/README.md0000600000175000017500000000371513553247311013646 0ustar jpjpsysbench Test Suite =================== sysbench uses the [Cram](https://bitheap.org/cram/) framework for functional and regression testing. If your system has Python 2.7.9 or later, or Python 3.4 or later, installing Cram is as simple as executing `pip install cram`. If you use an older Python version, you may need to [install pip](https://pip.pypa.io/en/latest/installing/) first: ``` {.example} curl https://bootstrap.pypa.io/get-pip.py | python ``` To run the sysbench test suite, invoke the `test_run.sh` script in the `tests` directory as follows: ``` {.example} ./test_run.sh [test_name]... ``` Each `test_name` argument is a name of a test case file. Functional and regression tests are located in the `t` subdirectory in files with the `.t` suffix. If no tests are named on the `test_run.sh` command line, it will execute all files with the `.t` suffix in the `t` subdirectory. Some tests require external servers (MySQL, PostgreSQL, etc). One should use environment variables to specify connection related arguments that sysbench can use to connect to such external server(s). The currently recognized variables are: - `SBTEST_MYSQL_ARGS` -- MySQL connection options: `--mysql-host`, `--mysql-port`, `--mysql-socket` `--mysql-user`, `--mysql-password` and `--mysql-db`; - `SBTEST_PGSQL_ARGS` -- PostgreSQL connection options: `--pgsql-host`, `--pgsql-port`, `--pgsql-user`, `--pgsql-password` and `--pgsql-db`. For example: ``` {.example} export SBTEST_MYSQL_ARGS="--mysql-host=localhost --mysql-user=sbtest --mysql-password=secret --mysql-db=sbtest" export SBTEST_PGSQL_ARGS="--pgsql-host=localhost --pgsql-user=postgres --pgsql-password=secret --pgsql-db=sbtest" ./test_run.sh ``` sysbench assumes that server(s) are pre-configured so that the specified database exists and the user connecting with the specified credentials has all privileges on the database. In particular, sysbench must have enough privileges to create/drop/read/modify tables in that database. sysbench-1.0.18/tests/include/0000700000175000017500000000000013553247311014002 5ustar jpjpsysbench-1.0.18/tests/include/script_oltp_legacy_common.sh0000600000175000017500000000315313553247311021600 0ustar jpjp#!/usr/bin/env bash # ################################################################################ # Common code for legacy OLTP tests # # Expects the following variables and callback functions to be defined by the # caller: # # DB_DRIVER_ARGS -- extra driver-specific arguments to pass to sysbench # # db_show_table() -- called with a single argument to dump a specified table # schema ################################################################################ set -eu ARGS="--test=${SBTEST_INCDIR}/oltp_legacy/oltp.lua $DB_DRIVER_ARGS --oltp-tables-count=8" sysbench $ARGS prepare db_show_table sbtest1 db_show_table sbtest2 db_show_table sbtest3 db_show_table sbtest4 db_show_table sbtest5 db_show_table sbtest6 db_show_table sbtest7 db_show_table sbtest8 db_show_table sbtest9 || true # Error on non-existing table sysbench $ARGS --max-requests=100 --num-threads=2 run sysbench $ARGS cleanup db_show_table sbtest1 || true # Error on non-existing table db_show_table sbtest2 || true # Error on non-existing table db_show_table sbtest3 || true # Error on non-existing table db_show_table sbtest4 || true # Error on non-existing table db_show_table sbtest5 || true # Error on non-existing table db_show_table sbtest6 || true # Error on non-existing table db_show_table sbtest7 || true # Error on non-existing table db_show_table sbtest8 || true # Error on non-existing table # Test --oltp-create-secondary=off ARGS="--test=${SBTEST_INCDIR}/oltp_legacy/oltp.lua $DB_DRIVER_ARGS --oltp-tables-count=1" sysbench $ARGS --oltp-create-secondary=off prepare db_show_table sbtest1 sysbench $ARGS cleanup sysbench-1.0.18/tests/include/api_sql_common.sh0000600000175000017500000001456113553247311017347 0ustar jpjp######################################################################## # Common code for SQL API tests # # Expects the following variables and callback functions to be defined by the # caller: # # DB_DRIVER_ARGS -- extra driver-specific arguments to pass to sysbench # ######################################################################## set -eu SB_ARGS="--verbosity=1 --events=1 $DB_DRIVER_ARGS $CRAMTMP/api_sql.lua" cat >$CRAMTMP/api_sql.lua <$CRAMTMP/api_sql.lua <$CRAMTMP/api_sql.lua <$CRAMTMP/api_sql.lua <$CRAMTMP/api_sql.lua <$CRAMTMP/api_sql.lua <$CRAMTMP/api_sql.lua <$CRAMTMP/api_sql.lua </dev/null db_show_table sbtest1 db_show_table sbtest2 db_show_table sbtest3 db_show_table sbtest4 db_show_table sbtest5 db_show_table sbtest6 db_show_table sbtest7 db_show_table sbtest8 db_show_table sbtest9 || true # Error on non-existing table sysbench $ARGS prewarm >/dev/null || true # MySQL only sysbench --events=100 $ARGS run sysbench $ARGS cleanup >/dev/null db_show_table sbtest1 || true # Error on non-existing table db_show_table sbtest2 || true # Error on non-existing table db_show_table sbtest3 || true # Error on non-existing table db_show_table sbtest4 || true # Error on non-existing table db_show_table sbtest5 || true # Error on non-existing table db_show_table sbtest6 || true # Error on non-existing table db_show_table sbtest7 || true # Error on non-existing table db_show_table sbtest8 || true # Error on non-existing table echo "# Test --create-secondary=off" ARGS="${OLTP_SCRIPT_PATH} ${DB_DRIVER_ARGS} ${SB_EXTRA_ARGS} --tables=1" sysbench --create-secondary=off $ARGS prepare db_show_table sbtest1 sysbench $ARGS cleanup echo "# Test --auto-inc=off" ARGS="$ARGS --auto-inc=off --verbosity=1" sysbench $ARGS prepare sysbench $ARGS run sysbench $ARGS cleanup sysbench-1.0.18/tests/include/script_select_random_common.sh0000600000175000017500000000205713553247311022117 0ustar jpjp#!/usr/bin/env bash # ################################################################################ # Common code for select_random_* tests # # Expects the following variables and callback functions to be defined by the # caller: # # DB_DRIVER_ARGS -- extra driver-specific arguments to pass to sysbench # # db_show_table() -- called with a single argument to dump a specified table # schema ################################################################################ set -eu for test in select_random_points select_random_ranges do ARGS="${SBTEST_SCRIPTDIR}/${test}.lua $DB_DRIVER_ARGS --tables=1" sysbench $ARGS prepare db_show_table sbtest1 for i in $(seq 2 8) do db_show_table sbtest${i} || true # Error on non-existing table done sysbench $ARGS --events=100 run sysbench $ARGS cleanup for i in $(seq 1 8) do db_show_table sbtest${i} || true # Error on non-existing table done ARGS="${SBTEST_SCRIPTDIR}/select_random_points.lua $DB_DRIVER_ARGS --tables=8" done sysbench-1.0.18/tests/include/inspect.lua0000600000175000017500000002307313553247311016161 0ustar jpjplocal inspect ={ _VERSION = 'inspect.lua 3.1.0', _URL = 'http://github.com/kikito/inspect.lua', _DESCRIPTION = 'human-readable representations of tables', _LICENSE = [[ MIT LICENSE Copyright (c) 2013 Enrique García Cota Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] } local tostring = tostring inspect.KEY = setmetatable({}, {__tostring = function() return 'inspect.KEY' end}) inspect.METATABLE = setmetatable({}, {__tostring = function() return 'inspect.METATABLE' end}) -- Apostrophizes the string if it has quotes, but not aphostrophes -- Otherwise, it returns a regular quoted string local function smartQuote(str) if str:match('"') and not str:match("'") then return "'" .. str .. "'" end return '"' .. str:gsub('"', '\\"') .. '"' end -- \a => '\\a', \0 => '\\0', 31 => '\31' local shortControlCharEscapes = { ["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v" } local longControlCharEscapes = {} -- \a => nil, \0 => \000, 31 => \031 for i=0, 31 do local ch = string.char(i) if not shortControlCharEscapes[ch] then shortControlCharEscapes[ch] = "\\"..i longControlCharEscapes[ch] = string.format("\\%03d", i) end end local function escape(str) return (str:gsub("\\", "\\\\") :gsub("(%c)%f[0-9]", longControlCharEscapes) :gsub("%c", shortControlCharEscapes)) end local function isIdentifier(str) return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" ) end local function isSequenceKey(k, sequenceLength) return type(k) == 'number' and 1 <= k and k <= sequenceLength and math.floor(k) == k end local defaultTypeOrders = { ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4, ['function'] = 5, ['userdata'] = 6, ['thread'] = 7 } local function sortKeys(a, b) local ta, tb = type(a), type(b) -- strings and numbers are sorted numerically/alphabetically if ta == tb and (ta == 'string' or ta == 'number') then return a < b end local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb] -- Two default types are compared according to the defaultTypeOrders table if dta and dtb then return defaultTypeOrders[ta] < defaultTypeOrders[tb] elseif dta then return true -- default types before custom ones elseif dtb then return false -- custom types after default ones end -- custom types are sorted out alphabetically return ta < tb end -- For implementation reasons, the behavior of rawlen & # is "undefined" when -- tables aren't pure sequences. So we implement our own # operator. local function getSequenceLength(t) local len = 1 local v = rawget(t,len) while v ~= nil do len = len + 1 v = rawget(t,len) end return len - 1 end local function getNonSequentialKeys(t) local keys = {} local sequenceLength = getSequenceLength(t) for k,_ in pairs(t) do if not isSequenceKey(k, sequenceLength) then table.insert(keys, k) end end table.sort(keys, sortKeys) return keys, sequenceLength end local function getToStringResultSafely(t, mt) local __tostring = type(mt) == 'table' and rawget(mt, '__tostring') local str, ok if type(__tostring) == 'function' then ok, str = pcall(__tostring, t) str = ok and str or 'error: ' .. tostring(str) end if type(str) == 'string' and #str > 0 then return str end end local function countTableAppearances(t, tableAppearances) tableAppearances = tableAppearances or {} if type(t) == 'table' then if not tableAppearances[t] then tableAppearances[t] = 1 for k,v in pairs(t) do countTableAppearances(k, tableAppearances) countTableAppearances(v, tableAppearances) end countTableAppearances(getmetatable(t), tableAppearances) else tableAppearances[t] = tableAppearances[t] + 1 end end return tableAppearances end local copySequence = function(s) local copy, len = {}, #s for i=1, len do copy[i] = s[i] end return copy, len end local function makePath(path, ...) local keys = {...} local newPath, len = copySequence(path) for i=1, #keys do newPath[len + i] = keys[i] end return newPath end local function processRecursive(process, item, path, visited) if item == nil then return nil end if visited[item] then return visited[item] end local processed = process(item, path) if type(processed) == 'table' then local processedCopy = {} visited[item] = processedCopy local processedKey for k,v in pairs(processed) do processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY), visited) if processedKey ~= nil then processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey), visited) end end local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited) setmetatable(processedCopy, mt) processed = processedCopy end return processed end ------------------------------------------------------------------- local Inspector = {} local Inspector_mt = {__index = Inspector} function Inspector:puts(...) local args = {...} local buffer = self.buffer local len = #buffer for i=1, #args do len = len + 1 buffer[len] = args[i] end end function Inspector:down(f) self.level = self.level + 1 f() self.level = self.level - 1 end function Inspector:tabify() self:puts(self.newline, string.rep(self.indent, self.level)) end function Inspector:alreadyVisited(v) return self.ids[v] ~= nil end function Inspector:getId(v) local id = self.ids[v] if not id then local tv = type(v) id = (self.maxIds[tv] or 0) + 1 self.maxIds[tv] = id self.ids[v] = id end return tostring(id) end function Inspector:putKey(k) if isIdentifier(k) then return self:puts(k) end self:puts("[") self:putValue(k) self:puts("]") end function Inspector:putTable(t) if t == inspect.KEY or t == inspect.METATABLE then self:puts(tostring(t)) elseif self:alreadyVisited(t) then self:puts('') elseif self.level >= self.depth then self:puts('{...}') else if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end local nonSequentialKeys, sequenceLength = getNonSequentialKeys(t) local mt = getmetatable(t) local toStringResult = getToStringResultSafely(t, mt) self:puts('{') self:down(function() if toStringResult then self:puts(' -- ', escape(toStringResult)) if sequenceLength >= 1 then self:tabify() end end local count = 0 for i=1, sequenceLength do if count > 0 then self:puts(',') end self:puts(' ') self:putValue(t[i]) count = count + 1 end for _,k in ipairs(nonSequentialKeys) do if count > 0 then self:puts(',') end self:tabify() self:putKey(k) self:puts(' = ') self:putValue(t[k]) count = count + 1 end if mt then if count > 0 then self:puts(',') end self:tabify() self:puts(' = ') self:putValue(mt) end end) if #nonSequentialKeys > 0 or mt then -- result is multi-lined. Justify closing } self:tabify() elseif sequenceLength > 0 then -- array tables have one extra space before closing } self:puts(' ') end self:puts('}') end end function Inspector:putValue(v) local tv = type(v) if tv == 'string' then self:puts(smartQuote(escape(v))) elseif tv == 'number' or tv == 'boolean' or tv == 'nil' or tv == 'cdata' or tv == 'ctype' then self:puts(tostring(v)) elseif tv == 'table' then self:putTable(v) else self:puts('<',tv,' ',self:getId(v),'>') end end ------------------------------------------------------------------- function inspect.inspect(root, options) options = options or {} local depth = options.depth or math.huge local newline = options.newline or '\n' local indent = options.indent or ' ' local process = options.process if process then root = processRecursive(process, root, {}, {}) end local inspector = setmetatable({ depth = depth, level = 0, buffer = {}, ids = {}, maxIds = {}, newline = newline, indent = indent, tableAppearances = countTableAppearances(root) }, Inspector_mt) inspector:putValue(root) return table.concat(inspector.buffer) end setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end }) return inspect sysbench-1.0.18/tests/include/config.sh.in0000600000175000017500000000177713553247311016226 0ustar jpjp#!/usr/bin/env bash # Configuration file used by the sysbench test suite. # Copyright (C) 2016 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA export SBTEST_VERSION_STRING="sysbench @PACKAGE_VERSION@@SB_GIT_SHA@" export SBTEST_VERSION="@PACKAGE_VERSION@" export SBTEST_HAS_MYSQL=@USE_MYSQL@ export SBTEST_HAS_PGSQL=@USE_PGSQL@ sysbench-1.0.18/tests/include/pgsql_common.sh0000600000175000017500000000343513553247311017043 0ustar jpjp######################################################################## # Common code for PostgreSQL-specific tests ######################################################################## set -eu if [ -z "${SBTEST_PGSQL_ARGS:-}" ] then exit 80 fi # Emulate "\d+" output since it is not portable across PostgreSQL major versions function db_show_table() { if ! psql -c "\d+ $1" sbtest > /dev/null then return fi echo " Table \"public.$1\"" psql -q sbtest < 0 EOF echo "Indexes:" psql -qt sbtest <test.lua < # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA AM_TESTS_ENVIRONMENT = \ PATH="$(top_srcdir)/third_party/cram/scripts:$$PATH" \ PYTHONPATH="$(top_srcdir)/third_party/cram:$$PYTHONPATH" TESTS = test_run.sh test_SCRIPTS = test_run.sh EXTRA_DIST = $(test_SCRIPTS) \ README.md testroot = $(datadir) testdir = $(testroot)/sysbench/tests test_dirs= t include include/oltp_legacy # Used by dist-hook and install-data-local to copy all # test files into either dist or install directory install_test_files: @if test -z "$(INSTALL_TO_DIR)"; then \ echo "Set INSTALL_TO_DIR!" && exit 1; \ fi @for dir in $(test_dirs); do \ from_dir="$(srcdir)/$$dir"; \ to_dir="$(INSTALL_TO_DIR)/$$dir"; \ $(mkinstalldirs) "$$to_dir"; \ for f in `(cd $$from_dir && ls *.t *.sh *.lua) 2>/dev/null`; do \ if test -f "$$from_dir/$$f"; then \ $(INSTALL_DATA) "$$from_dir/$$f" "$$to_dir/$$f" ; \ fi; \ done \ done dist-hook: $(MAKE) INSTALL_TO_DIR="$(distdir)" install_test_files install-data-local: $(MAKE) INSTALL_TO_DIR="$(DESTDIR)$(testdir)" install_test_files uninstall-local: rm -f -r $(DESTDIR)$(testdir) test: ./test_run.sh sysbench-1.0.18/tests/test_run.sh0000700000175000017500000000530613553247311014565 0ustar jpjp#!/usr/bin/env bash # Copyright (C) 2016-2017 Alexey Kopytov # # 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; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA set -eu testroot=$(cd $(dirname "$0"); echo $PWD) # Find the sysbench binary to use dirlist=( "$testroot/../src" # source directory "$testroot/../bin" # standalone install root directory "$testroot/../../../bin" # system-wide install (e.g. /usr/local/share/sysbench/tests) "$PWD/../src" ) # build directory by 'make distcheck' for dir in ${dirlist[@]} do if [ -x "$dir/sysbench" ] then sysbench_dir="$dir" break fi done if [ -z ${sysbench_dir+x} ] then echo "Cannot find sysbench in the following list of directories: \ ${dirlist[@]}" exit 1 fi if [ -z ${srcdir+x} ] then SBTEST_INCDIR="$PWD/include" SBTEST_CONFIG="$SBTEST_INCDIR/config.sh" if [ $# -lt 1 ] then tests="t/*.t" fi else # SBTEST_INCDIR must be an absolute path, because cram changes CWD to a # temporary directory when executing tests. That's why we can just use # $srcdir here SBTEST_INCDIR="$(cd $srcdir; echo $PWD)/include" SBTEST_CONFIG="$PWD/include/config.sh" if [ $# -lt 1 ] then tests="$srcdir/t/*.t" fi fi if [ -z ${tests+x} ] then tests="$*" fi export SBTEST_ROOTDIR="$testroot" export SBTEST_SCRIPTDIR="$testroot/../src/lua" export SBTEST_SUITEDIR="$testroot/t" export SBTEST_CONFIG export SBTEST_INCDIR # Add directories containing sysbench and cram to PATH export PATH="${sysbench_dir}:${SBTEST_ROOTDIR}/../third_party/cram/scripts:$PATH" export PYTHONPATH="${SBTEST_ROOTDIR}/../third_party/cram:${PYTHONPATH:-}" LUA_PATH="$SBTEST_SCRIPTDIR/?;$SBTEST_SCRIPTDIR/?.lua" LUA_PATH="$LUA_PATH;$SBTEST_INCDIR/?;$SBTEST_INCDIR/?.lua" export LUA_PATH . $SBTEST_CONFIG if $(command -v python >/dev/null 2>&1) then PYTHON=python elif $(command -v python2 >/dev/null 2>&1) then PYTHON=python2 else echo "Cannot find python interpreter in PATH" exit 1 fi $PYTHON $(command -v cram) --shell=/bin/bash --verbose $tests