diff --git a/.bzrignore b/.bzrignore index c91df60c99f..2e6193b6368 100644 --- a/.bzrignore +++ b/.bzrignore @@ -352,8 +352,11 @@ client/.libs/mysqltest client/completion_hash.cpp client/decimal.c client/insert_test +client/link_sources client/log_event.cc client/log_event.h +client/log_event_old.cc +client/log_event_old.h client/mf_iocache.c client/mf_iocache.cc client/my_decimal.cc @@ -379,6 +382,9 @@ client/mysqltestmanager-pwgen client/mysqltestmanagerc client/mysys_priv.h client/readline.cpp +client/rpl_constants.h +client/rpl_record_old.cc +client/rpl_record_old.h client/select_test client/sql_string.cpp client/ssl_test @@ -574,6 +580,7 @@ help help.c help.h include/check_abi +include/link_sources include/my_config.h include/my_global.h include/mysql_h.ic @@ -749,6 +756,7 @@ libmysql/.libs/libmysqlclient.so.15.0.0 libmysql/conf_to_src libmysql/debug/libmysql.exp libmysql/libmysql.ver +libmysql/link_sources libmysql/my_static.h libmysql/my_time.c libmysql/mysys_priv.h @@ -1084,9 +1092,11 @@ libmysqld/item_uniq.cc libmysqld/key.cc libmysqld/lib_sql.cpp libmysqld/libmysql.c +libmysqld/link_sources libmysqld/lock.cc libmysqld/log.cc libmysqld/log_event.cc +libmysqld/log_event_old.cc libmysqld/md5.c libmysqld/mf_iocache.cc libmysqld/mini_client.cc @@ -1109,6 +1119,8 @@ libmysqld/records.cc libmysqld/repl_failsafe.cc libmysqld/rpl_filter.cc libmysqld/rpl_injector.cc +libmysqld/rpl_record.cc +libmysqld/rpl_record_old.cc libmysqld/set_var.cc libmysqld/simple-test libmysqld/slave.cc @@ -1347,10 +1359,15 @@ mysql-test/suite/funcs_1/r/myisam_trig_03e.warnings mysql-test/suite/funcs_1/r/myisam_views.warnings mysql-test/suite/funcs_1/r/ndb_trig_03e.warnings mysql-test/suite/funcs_1/r/ndb_views.warnings +mysql-test/suite/partitions/r/dif mysql-test/suite/partitions/r/diff +mysql-test/suite/partitions/r/partition.result mysql-test/suite/partitions/r/partition_bit_ndb.warnings mysql-test/suite/partitions/r/partition_special_innodb.warnings mysql-test/suite/partitions/r/partition_special_myisam.warnings +mysql-test/suite/partitions/r/partition_t55.out +mysql-test/suite/partitions/r/partition_t55.refout +mysql-test/suite/partitions/t/partition.test mysql-test/t/index_merge.load mysql-test/t/tmp.test mysql-test/var @@ -1763,7 +1780,9 @@ netware/.deps/my_manage.Po netware/.deps/mysql_install_db.Po netware/.deps/mysql_test_run.Po netware/.deps/mysqld_safe.Po +netware/init_db.sql netware/libmysql.imp +netware/test_db.sql pack_isam/*.ds? perror/*.ds? perror/*.vcproj @@ -1798,6 +1817,7 @@ repl-tests/test-repl/sum-wlen-slave.master.re repl-tests/test-repl/sum-wlen-slave.master.reje replace/*.ds? replace/*.vcproj +scripts/comp_sql scripts/fill_func_tables scripts/fill_func_tables.sql scripts/fill_help_tables @@ -1815,6 +1835,7 @@ scripts/mysql_find_rows scripts/mysql_fix_extensions scripts/mysql_fix_privilege_tables scripts/mysql_fix_privilege_tables.sql +scripts/mysql_fix_privilege_tables_sql.c scripts/mysql_install_db scripts/mysql_secure_installation scripts/mysql_setpermission diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh index 6f0600c9de3..142ff7eb08e 100644 --- a/BUILD/FINISH.sh +++ b/BUILD/FINISH.sh @@ -4,7 +4,7 @@ extra_configs="$extra_configs $local_infile_configs" configure="./configure $base_configs $extra_configs" commands="\ -$make -k distclean || true +$make -k maintainer-clean || true /bin/rm -rf */.deps/*.P configure config.cache storage/*/configure storage/*/config.cache autom4te.cache storage/*/autom4te.cache; path=`dirname $0` diff --git a/BUILD/check-cpu b/BUILD/check-cpu index 9edde51402f..2852aa98ef3 100755 --- a/BUILD/check-cpu +++ b/BUILD/check-cpu @@ -64,10 +64,11 @@ check_cpu () { ;; # Intel ia32 - *X[eE][oO][nN]*) + *Intel*Core*|*X[eE][oO][nN]*) # a Xeon is just another pentium4 ... # ... unless it has the "lm" (long-mode) flag set, - # in that case it's a Xeon with EM64T support + # in that case it's a Xeon with EM64T support + # So is Intel Core. if [ -z "$cpu_flag_lm" ]; then cpu_arg="pentium4"; else @@ -114,6 +115,10 @@ check_cpu () { *i386*i486*) cpu_arg="pentium-m"; ;; + #Core 2 Duo + *Intel*Core\(TM\)2*) + cpu_arg="nocona"; + ;; # Intel ia64 *Itanium*) @@ -160,26 +165,34 @@ check_cpu () { cc_ver=`$cc --version | sed 1q` cc_verno=`echo $cc_ver | sed -e 's/^.*gcc/gcc/g; s/[^0-9. ]//g; s/^ *//g; s/ .*//g'` + set -- `echo $cc_verno | tr '.' ' '` + cc_major=$1 + cc_minor=$2 + cc_patch=$3 + cc_comp=`expr $cc_major '*' 100 '+' $cc_minor` case "$cc_ver--$cc_verno" in *GCC*) # different gcc backends (and versions) have different CPU flags case `gcc -dumpmachine` in i?86-*) - case "$cc_verno" in - 3.4*|3.5*|4.*) - check_cpu_args='-mtune=$cpu_arg -march=$cpu_arg' - ;; - *) - check_cpu_args='-mcpu=$cpu_arg -march=$cpu_arg' - ;; - esac + if test "$cc_comp" -lt 304 + then + check_cpu_args='-mcpu=$cpu_arg' + else + check_cpu_args='-mtune=$cpu_arg' + fi ;; ppc-*) check_cpu_args='-mcpu=$cpu_arg -mtune=$cpu_arg' ;; x86_64-*) - check_cpu_args='-mtune=$cpu_arg' + if test "$cc_comp" -lt 304 + then + check_cpu_args='-mcpu=$cpu_arg' + else + check_cpu_args='-mtune=$cpu_arg' + fi ;; *) check_cpu_cflags="" diff --git a/BUILD/compile-alpha-ccc b/BUILD/compile-alpha-ccc index 889592295b5..59ed241d51c 100755 --- a/BUILD/compile-alpha-ccc +++ b/BUILD/compile-alpha-ccc @@ -1,5 +1,7 @@ +#! /bin/sh + /bin/rm -f */.deps/*.P */*.o -make -k clean +make -k maintainer-clean /bin/rm -f */.deps/*.P */*.o /bin/rm -f config.cache mysql-*.tar.gz diff --git a/BUILD/compile-alpha-cxx b/BUILD/compile-alpha-cxx index 1624f4ed622..a1b5605ac5e 100755 --- a/BUILD/compile-alpha-cxx +++ b/BUILD/compile-alpha-cxx @@ -1,5 +1,7 @@ +#! /bin/sh + /bin/rm -f */.deps/*.P */*.o -make -k clean +make -k maintainer-clean /bin/rm -f */.deps/*.P */*.o /bin/rm -f */.deps/*.P config.cache storage/innobase/config.cache mysql-*.tar.gz diff --git a/BUILD/compile-alpha-debug b/BUILD/compile-alpha-debug index b565a18272f..94fe8a2b414 100755 --- a/BUILD/compile-alpha-debug +++ b/BUILD/compile-alpha-debug @@ -1,5 +1,7 @@ +#! /bin/sh + /bin/rm -f */.deps/*.P */*.o -make -k clean +make -k maintainer-clean /bin/rm -f */.deps/*.P */*.o /bin/rm -f */.deps/*.P config.cache storage/innobase/config.cache mysql-*.tar.gz diff --git a/BUILD/compile-dist b/BUILD/compile-dist index 0504b308ceb..0ecb386bf71 100755 --- a/BUILD/compile-dist +++ b/BUILD/compile-dist @@ -6,7 +6,7 @@ # tree can then be picked up by "make dist" to create the "pristine source # package" that is used as the basis for all other binary builds. # -test -f Makefile && make distclean +test -f Makefile && make maintainer-clean (cd storage/innobase && aclocal && autoheader && \ libtoolize --automake --force --copy && \ automake --force --add-missing --copy && autoconf) diff --git a/BUILD/compile-hpux11-parisc2-aCC b/BUILD/compile-hpux11-parisc2-aCC index c286488bb26..0e825715663 100755 --- a/BUILD/compile-hpux11-parisc2-aCC +++ b/BUILD/compile-hpux11-parisc2-aCC @@ -61,7 +61,7 @@ done set -x -make distclean +make maintainer-clean path=`dirname $0` . "$path/autorun.sh" diff --git a/BUILD/compile-ia64-debug-max b/BUILD/compile-ia64-debug-max index d1017ad506b..123bfb06300 100755 --- a/BUILD/compile-ia64-debug-max +++ b/BUILD/compile-ia64-debug-max @@ -1,4 +1,4 @@ -gmake -k clean || true +gmake -k maintainer-clean || true /bin/rm -f */.deps/*.P config.cache storage/innobase/config.cache path=`dirname $0` diff --git a/BUILD/compile-irix-mips64-mipspro b/BUILD/compile-irix-mips64-mipspro index 0cebb4b9f5b..5e34df20c28 100755 --- a/BUILD/compile-irix-mips64-mipspro +++ b/BUILD/compile-irix-mips64-mipspro @@ -33,7 +33,7 @@ else fi set -x -make distclean +make maintainer-clean path=`dirname $0` . "$path/autorun.sh" diff --git a/BUILD/compile-pentium-debug-max b/BUILD/compile-pentium-debug-max index adb9b7899a5..b2c8b4d9331 100755 --- a/BUILD/compile-pentium-debug-max +++ b/BUILD/compile-pentium-debug-max @@ -4,6 +4,6 @@ path=`dirname $0` . "$path/SETUP.sh" "$@" --with-debug=full extra_flags="$pentium_cflags $debug_cflags" -extra_configs="$pentium_configs $debug_configs $max_configs $error_inject" +extra_configs="$pentium_configs $debug_configs $max_configs $error_inject --with-experimental-collations" . "$path/FINISH.sh" diff --git a/BUILD/compile-pentium-pgcc b/BUILD/compile-pentium-pgcc index 411241451cf..c13a6ff14f7 100755 --- a/BUILD/compile-pentium-pgcc +++ b/BUILD/compile-pentium-pgcc @@ -1,5 +1,7 @@ +#! /bin/sh + AM_MAKEFLAGS="-j 2" -gmake -k clean || true +gmake -k maintainer-clean || true /bin/rm -f */.deps/*.P config.cache path=`dirname $0` diff --git a/BUILD/compile-solaris-amd64 b/BUILD/compile-solaris-amd64 new file mode 100755 index 00000000000..f128fb12973 --- /dev/null +++ b/BUILD/compile-solaris-amd64 @@ -0,0 +1,55 @@ +#!/usr/bin/bash + +function _find_mysql_root () ( + while [ "x$PWD" != "x/" ]; do + # Check if some directories are present + if [ -d BUILD -a -d sql -a -d mysys ]; then + echo "$PWD" + return 0 + fi + cd .. + done + return 1 +) + +make -k clean || true +/bin/rm -f */.deps/*.P config.cache + +path=`dirname $0` +. "$path/autorun.sh" + +warning_flags="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused" +compiler_flags="-g -O3 -fno-omit-frame-pointer" + +export CC CXX CFLAGS CXXFLAGS LDFLAGS LIBS +CC="gcc" +CXX="gcc" +CFLAGS="$warning_flags $compiler_flags" +CXXFLAGS="" +LDFLAGS="-O3 -g -static-libgcc" +LIBS=-lmtmalloc +root=$(_find_mysql_root) + +$root/configure \ + --prefix=/usr/local/mysql \ + --localstatedir=/usr/local/mysql/data \ + --libexecdir=/usr/local/mysql/bin \ + --with-extra-charsets=complex \ + --enable-thread-safe-client \ + --enable-local-infile \ + --with-zlib-dir=bundled \ + --with-big-tables \ + --with-readline \ + --with-archive-storage-engine \ + --with-named-curses=-lcurses \ + --with-big-tables \ + --with-innodb \ + --with-berkeley-db \ + --with-example-storage-engine \ + --with-blackhole-storage-engine \ + --with-ndbcluster \ + --with-federated-storage-engine \ + --with-csv-storage-engine \ + --with-ssl \ + --with-embedded-server \ + --disable-shared diff --git a/BUILD/compile-solaris-sparc-forte b/BUILD/compile-solaris-sparc-forte index 936266670d9..2a8b7dbae48 100755 --- a/BUILD/compile-solaris-sparc-forte +++ b/BUILD/compile-solaris-sparc-forte @@ -5,7 +5,7 @@ PATH=/opt/SUNWspro/bin/:/usr/ccs/bin:$PATH -make -k clean || true +make -k maintainer-clean || true /bin/rm -f */.deps/*.P config.cache path=`dirname $0` diff --git a/BUILD/compile-solaris-sparc-purify b/BUILD/compile-solaris-sparc-purify index d7473230607..08308f05f4e 100755 --- a/BUILD/compile-solaris-sparc-purify +++ b/BUILD/compile-solaris-sparc-purify @@ -31,7 +31,7 @@ do shift done -make -k clean || true +make -k maintainer-clean || true /bin/rm -f */.deps/*.P config.cache path=`dirname $0` diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit index 86f3db012ee..b4dcb311dde 100755 --- a/BitKeeper/triggers/post-commit +++ b/BitKeeper/triggers/post-commit @@ -72,7 +72,7 @@ X-CSetKey: <$CSETKEY> $BH EOF bk changes -v -r+ - bk cset -r+ -d + bk rset -r+ -ah | bk gnupatch -h -dup -T ) > $BKROOT/BitKeeper/tmp/dev_public.txt $SENDMAIL -t < $BKROOT/BitKeeper/tmp/dev_public.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index eb4d77db73f..a46022566d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,14 @@ IF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO + ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}) + STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO + ${CMAKE_C_FLAGS_RELWITHDEBINFO}) + + # generate .map files + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MAP /MAPINFO:EXPORTS") + # remove support for Exception handling STRING(REPLACE "/GX" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) @@ -131,10 +139,11 @@ ADD_SUBDIRECTORY(dbug) ADD_SUBDIRECTORY(strings) ADD_SUBDIRECTORY(regex) ADD_SUBDIRECTORY(mysys) +ADD_SUBDIRECTORY(scripts) +ADD_SUBDIRECTORY(zlib) ADD_SUBDIRECTORY(extra/yassl) ADD_SUBDIRECTORY(extra/yassl/taocrypt) ADD_SUBDIRECTORY(extra) -ADD_SUBDIRECTORY(zlib) ADD_SUBDIRECTORY(storage/heap) ADD_SUBDIRECTORY(storage/myisam) ADD_SUBDIRECTORY(storage/myisammrg) diff --git a/Docs/.cvsignore b/Docs/.cvsignore index 777efb1eb7b..6a00212535b 100644 --- a/Docs/.cvsignore +++ b/Docs/.cvsignore @@ -1,40 +1,5 @@ -COPYING -COPYING.LIB +INSTALL-SOURCE INSTALL-BINARY Makefile Makefile.in -Manual-updates -before-gpl-changes-manual.texi -include.texi -manual-before-gpl.texi -manual-tmp.aux -manual-tmp.cp -manual-tmp.fn -manual-tmp.ky -manual-tmp.log -manual-tmp.pdf -manual-tmp.pg -manual-tmp.texi -manual-tmp.toc -manual-tmp.tp -manual-tmp.vr -manual.aux -manual.cp -manual.cps -manual.fn -manual.fns -manual.html -manual.ky -manual.log -manual.pdf -manual.pg -manual.toc -manual.tp -manual.txt -manual.vr -manual_a4.ps -manual_a4.ps.gz -manual_letter.ps -manual_letter.ps.gz -manual_toc.html mysql.info diff --git a/Docs/internals.texi b/Docs/internals.texi deleted file mode 100644 index e1462531270..00000000000 --- a/Docs/internals.texi +++ /dev/null @@ -1,101 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c -@c ********************************************************* -@c -@c This is a dummy placeholder file for internals.texi in the -@c MySQL source trees. -@c -@c Note, that the internals documentation has been moved into a separate -@c BitKeeper source tree named "mysqldoc" - do not attempt to edit this -@c file! All changes to internals.texi should be done in the mysqldoc tree. -@c -@c See http://www.mysql.com/doc/en/Installing_source_tree.html -@c for information about how to work with BitKeeper source trees. -@c -@c This dummy file is being replaced with the actual file from the -@c mysqldoc tree when building the official source distribution. -@c -@c Please e-mail docs@mysql.com for more information or if -@c you are interested in doing a translation. -@c -@c ********************************************************* -@c -@c %**start of header - -@setfilename internals.info - -@c We want the types in the same index -@syncodeindex tp fn - -@ifclear tex-debug -@c This removes the black squares in the right margin -@finalout -@end ifclear - -@c Set background for HTML -@set _body_tags BGCOLOR=silver TEXT=#000000 LINK=#101090 VLINK=#7030B0 -@c Set some style elements for the manual in HTML form. 'suggested' -@c natural language colors: aqua, black, blue, fuchsia, gray, green, -@c lime, maroon, navy, olive, purple, red, silver, teal, white, and -@c yellow. From Steeve Buehler -@set _extra_head - -@settitle Dummy MySQL internals documentation for version @value{mysql_version}. - -@c We want single-sided heading format, with chapters on new pages. To -@c get double-sided format change 'on' below to 'odd' -@setchapternewpage on - -@paragraphindent 0 - -@c %**end of header - -@ifinfo -@format -START-INFO-DIR-ENTRY -* mysql: (mysql). MySQL documentation. -END-INFO-DIR-ENTRY -@end format -@end ifinfo - -@titlepage -@sp 10 -@center @titlefont{Empty placeholder for the MySQL Internals Documentation} -@sp 10 -@center Copyright @copyright{} 1995-2003 MySQL AB -@c blank page after title page makes page 1 be a page front. -@c also makes the back of the title page blank. -@page -@end titlepage - -@c This should be added. The HTML conversion also needs a MySQL version -@c number somewhere. - -@iftex -@c change this to double if you want formatting for double-sided -@c printing -@headings single - -@oddheading @thischapter @| @| @thispage -@evenheading @thispage @| @| MySQL Internal Reference for Version @value{mysql_version} - -@end iftex - -@node Top, (dir), (dir), (dir) - -@ifinfo -This is an empty placeholder file for the MySQL internals documentation. - -The real version of this file is now maintained in a separate BitKeeper -source tree! Please see -@url{http://www.mysql.com/doc/en/Installing_source_tree.html} for more info -on how to work with BitKeeper. - -Please do not attempt to edit this file directly - use the one in the -@code{mysqldoc} BK tree instead. - -This file will be replaced with the current @code{internals.texi} when -building the official source distribution. -@end ifinfo - -@bye diff --git a/Docs/linuxthreads.txt b/Docs/linuxthreads.txt index 30270125c0d..552415fe794 100644 --- a/Docs/linuxthreads.txt +++ b/Docs/linuxthreads.txt @@ -1,3 +1,5 @@ +[Note this information is obsolete] + Notes on compiling glibc for the standard MySQL binary: - make sure you have gcc 2.95 and gmake 3.79 or newer diff --git a/Docs/my_sys.txt b/Docs/my_sys.txt deleted file mode 100644 index 85ffc13ecb4..00000000000 --- a/Docs/my_sys.txt +++ /dev/null @@ -1,140 +0,0 @@ -Functions i mysys: (For flags se my_sys.h) - - int my_copy _A((const char *from,const char *to,myf MyFlags)); - - Copy file - - int my_delete _A((const char *name,myf MyFlags)); - - Delete file - - int my_getwd _A((string buf,uint size,myf MyFlags)); - int my_setwd _A((const char *dir,myf MyFlags)); - - Get and set working directory - - string my_tempnam _A((const char *pfx,myf MyFlags)); - - Make a uniq temp file name by using dir and adding something after - pfx to make name uniq. Name is made by adding a uniq 6 length-string - and TMP_EXT after pfx. - Returns pointer to malloced area for filename. Should be freed by - free(). - - File my_open _A((const char *FileName,int Flags,myf MyFlags)); - File my_create _A((const char *FileName,int CreateFlags, - int AccsesFlags, myf MyFlags)); - int my_close _A((File Filedes,myf MyFlags)); - uint my_read _A((File Filedes,byte *Buffer,uint Count,myf MyFlags)); - uint my_write _A((File Filedes,const byte *Buffer,uint Count, - myf MyFlags)); - ulong my_seek _A((File fd,ulong pos,int whence,myf MyFlags)); - ulong my_tell _A((File fd,myf MyFlags)); - - Use instead of open,open-with-create-flag, close read and write - to get automatic error-messages (flag: MYF_WME) and only have - to test for != 0 if error (flag: MY_NABP). - - int my_rename _A((const char *from,const char *to,myf MyFlags)); - - Rename file - - FILE *my_fopen _A((const char *FileName,int Flags,myf MyFlags)); - FILE *my_fdopen _A((File Filedes,int Flags,myf MyFlags)); - int my_fclose _A((FILE *fd,myf MyFlags)); - uint my_fread _A((FILE *stream,byte *Buffer,uint Count,myf MyFlags)); - uint my_fwrite _A((FILE *stream,const byte *Buffer,uint Count, - myf MyFlags)); - ulong my_fseek _A((FILE *stream,ulong pos,int whence,myf MyFlags)); - ulong my_ftell _A((FILE *stream,myf MyFlags)); - - Same read-interface for streams as for files - - gptr _mymalloc _A((uint uSize,const char *sFile, - uint uLine, myf MyFlag)); - gptr _myrealloc _A((string pPtr,uint uSize,const char *sFile, - uint uLine, myf MyFlag)); - void _myfree _A((gptr pPtr,const char *sFile,uint uLine)); - int _sanity _A((const char *sFile,unsigned int uLine)); - gptr _myget_copy_of_memory _A((const byte *from,uint length, - const char *sFile, uint uLine, - myf MyFlag)); - - malloc(size,myflag) is mapped to this functions if not compiled - with -DSAFEMALLOC - - void TERMINATE _A((void)); - - Writes malloc-info on stdout if compiled with -DSAFEMALLOC. - - int my_chsize _A((File fd,ulong newlength,myf MyFlags)); - - Change size of file - - void my_error _D((int nr,myf MyFlags, ...)); - - Writes message using error number (se mysys/errors.h) on - stdout or curses if MYSYS_PROGRAM_USES_CURSES() is called. - - void my_message _A((const char *str,myf MyFlags)); - - Writes message-string on - stdout or curses if MYSYS_PROGRAM_USES_CURSES() is called. - - void my_init _A((void )); - - Start each program (in main) with this. - void my_end _A((int infoflag)); - - Gives info about program. - - If infoflag & MY_CHECK_ERROR prints if some files are left open - - If infoflag & MY_GIVE_INFO prints timing info and malloc info - about prog. - - int my_redel _A((const char *from, const char *to, int MyFlags)); - - Delete from before rename of to to from. Copyes state from old - file to new file. If MY_COPY_TIME is set sets old time. - - int my_copystat _A((const char *from, const char *to, int MyFlags)); - - Copye state from old file to new file. - If MY_COPY_TIME is set sets copy also time. - - string my_filename _A((File fd)); - - Give filename of open file. - - int dirname _A((string to,const char *name)); - - Copy name of directory from filename. - - int test_if_hard_path _A((const char *dir_name)); - - Test if dirname is a hard path (Starts from root) - - void convert_dirname _A((string name)); - - Convert dirname acording to system. - - In MSDOS changes all caracters to capitals and changes '/' to - '\' - string fn_ext _A((const char *name)); - - Returns pointer to extension in filename - string fn_format _A((string to,const char *name,const char *dsk, - const char *form,int flag)); - format a filename with replace of library and extension and - converts between different systems. - params to and name may be identicall - function dosn't change name if name != to - Flag may be: 1 force replace filnames library with 'dsk' - 2 force replace extension with 'form' */ - 4 force Unpack filename (replace ~ with home) - 8 Pack filename as short as possibly for output to - user. - All open requests should allways use at least: - "open(fn_format(temp_buffe,name,"","",4),...)" to unpack home and - convert filename to system-form. - - string fn_same _A((string toname,const char *name,int flag)); - - Copys directory and extension from name to toname if neaded. - copy can be forced by same flags that in fn_format. - - int wild_compare _A((const char *str,const char *wildstr)); - - Compare if str matches wildstr. Wildstr can contain "*" and "?" - as match-characters. - Returns 0 if match. - - void get_date _A((string to,int timeflag)); - - Get current date in a form ready for printing. - - void soundex _A((string out_pntr, string in_pntr)) - - Makes in_pntr to a 5 chars long string. All words that sounds - alike have the same string. - - int init_key_cache _A((ulong use_mem,ulong leave_this_much_mem)); - - Use cacheing of keys in MISAM, PISAM, and ISAM. - KEY_CACHE_SIZE is a good size. - - Remember to lock databases for optimal cacheing - - void end_key_cache _A((void)); - - End key-cacheing. diff --git a/Docs/net_doc.txt b/Docs/net_doc.txt deleted file mode 100644 index 4f21383c06d..00000000000 --- a/Docs/net_doc.txt +++ /dev/null @@ -1,943 +0,0 @@ - MySQL Client/Server Protocol Documentation - - - -Introduction ------------- - - -This paper has the objective of presenting a through description -of the client/server protocol that is embodied in MySQL. Particularly, -this paper aims to document and describe: - -- manner in which MySQL server detects client connection requests and - creates connection -- manner in which MySQL client C API call connects to server - the - entire protocol of sending/receiving data by MySQL server and C API - code -- manner in which queries are sent by client C API calls to server -- manner in which query results are sent by server -- manner in which query results are resolved by server -- sending and receiving of error messages - - -This paper does not have the goal or describing nor documenting other -related MySQL issues, like usage of thread libraries, MySQL standard -library set, MySQL strings library and other MySQL specific libraries, -type definitions and utilities. - -Issues that are covered by this paper are contained in the following -source code files: - -- libmysql/net.c and sql/net_serv.cc, the two being identical -- client/libmysql.c (not entire file is covered) -- include/mysql_com.h -- include/mysql.h -- sql/mysqld.cc (not entire file is covered) -- sql/net_pkg.cc -- sql/sql_base.cc (not entire file is covered) -- sql/sql_select.cc (not entire file is covered) -- sql/sql_parse.cc (not entire file is covered) - -Note: libmysql/net.c was client/net.c prior to MySQL 3.23.11. -sql/net_serv.cc was sql/net_serv.c prior to MySQL 3.23.16. - -Beside this introduction this paper presents basic definitions, -constants, structures and global variables, all related functions in -server and in C API. Textual description of the entire protocol -functioning is described in the last chapter of this paper. - - -Constants, structures and global variables ------------------------------------------- - -This chapter will describe all constants, structures and -global variables relevant to client/server protocol. - -Constants - -They are important as they contain default values, the ones -that are valid if options are not set in any other way. Beside that -MySQL source code does not contain a single non-defined constant in -its code. This description of constants does not include -configuration and conditional compilation #defines. - -NAME_LEN - field and table name length, current value 64 -HOSTNAME_LENGTH - length of the hostname, current value 64 -USERNAME_LENGTH - username length, current value 16 -MYSQL_PORT - default TCP/IP port number, current value 3306 -MYSQL_UNIX_ADDR - full path of the default Unix socket file, current value - "/tmp/mysql.sock" -MYSQL_NAMEDPIPE - full path of the default NT pipe file, current value - "MySQL" -MYSQL_SERVICENAME - name of the MySQL Service on NT, current value "MySQL" -NET_HEADER_SIZE - size of the network header, when no - compression is used, current value 4 -COMP_HEADER_SIZE - additional size of network header when - compression is used, current value 3 - -What follows are set of constants, defined in source only, which -define capabilities of the client built with that version of C -API. Simply, when some new feature is added in client, that client -feature is defined, so that server can detect what capabilities a -client program has. - -CLIENT_LONG_PASSWORD - client supports new more secure passwords -CLIENT_LONG_FLAG - client uses longer flags -CLIENT_CONNECT_WITH_DB - client can specify db on connect -CLIENT_COMPRESS - client can use compression protocol -CLIENT_ODBC - ODBC client -CLIENT_LOCAL_FILES - client can use LOAD DATA INFILE LOCAL -CLIENT_IGNORE_SPACE - client can ignore spaces before '(' -CLIENT_CHANGE_USER - client supports the mysql_change_user() - -What follows are other constants, pertaining to timeouts and sizes - -MYSQL_ERRMSG_SIZE - maximum size of error message string, current value 200 -NET_READ_TIMEOUT - read timeout, current value 30 seconds -NET_WRITE_TIMEOUT - write timeout, current value 60 seconds -NET_WAIT_TIMEOUT - wait for new query timeout, current value 8*60*60 - seconds, that is, 8 hours -packet_error - value returned in case of socket errors, current - value -1 -TES_BLOCKING - used in debug mode for setting up blocking testing -RETRY COUNT - number of times network read and write will be - retried, current value 1 - -There are also error messages for last_errno, which depict system -errors, and are used on the server only. - -ER_NET_PACKAGE_TOO_LARGE - packet is larger than max_allowed_packet -ER_OUT_OF_RESOURCES - practically no more memory -ER_NET_ERROR_ON_WRITE - error in writing to NT Named Pipe -ER_NET_WRITE_INTERRUPTED - some signal or interrupt happened - during write -ER_NET_READ_ERROR_FROM_PIPE - error in reading from NT Named Pipe -ER_NET_FCNTL_ERROR - error in trying to set fcntl on socket - descriptor -ER_NET_PACKETS_OUT_OF_ORDER - packet numbers on client and - server side differ -ER_NET_UNCOMPRESS_ERROR - error in uncompress of compressed packet - - - Structs and enums - - -struct NET - -This is MySQL's network handle structure, used in all client/server -read/write functions. On the server, it is initialized and preserved -in each thread. On the client, it is a part of the MYSQL struct, -which is the MySQL handle used in all C API functions. This structure -uniquely identifies a connection, either on the server or client -side. It consists of the following fields: - - Vio* vio - explained above - HANDLE hPipe - Handle for NT Named Pipe file - my_socket fd - file descriptor used for both TCP/IP socket and - Unix socket file - int fcntl - contains info on fcntl options used on fd. Mostly - used for saving info if blocking is used or not - unsigned char *buff - network buffer used for storing data for - reading from/writing to socket - unsigned char,*buff_end - points to the end of buff - unsigned char *write_pos - present writing position in buff - unsigned char *read_pos - present reading position in buff. This - pointer is used for reading data after - calling my_net_read function and function - that are just its wrappers - char last_error[MYSQL_ERRMSG_SIZE] - holds last error message - unsigned int last_errno - holds last error code of the network - protocol. Its possible values are listed - in above constants. It is used only on - the server side - unsigned int max_packet - holds current value of buff size - unsigned int timeout - stores read timeout value for that connection - unsigned int pkt_nr - stores the value of the current packet number in - a batch of packets. Used primarily for - detection of protocol errors resulting in a - mismatch - my_bool error - holds either 1 or 0 depending on the error condition - my_bool return_errno - if its value != 0 then there is an error in - protocol mismatch between client and server - my_bool compress - if true compression is used in the protocol - unsigned long remain_in_buf - used only in reading compressed packets. - Explained in my_net_read - unsigned long length - used only for storing the length of the read - packet. Explained in my_net_read - unsigned long buf_length - used only in reading compressed packets. - Explained in my_net_read - unsigned long where_b - used only in reading compressed packets. - Explained in my_net_read - short int more - used for reporting in mysql_list_processes - char save_char - used in reading compressed packets for saving chars - in order to make zero-delimited strings. Explained - in my_net_read - -A few typedefs will be defined for easier understanding of the text that -follows. - -typedef char **MYSQL_ROW - data containing one row of values - -typedef unsigned int MYSQL_FIELD_OFFSET - offset in bytes of the current field - -typedef MYSQL_ROWS *MYSQL_ROW_OFFSET - offset in bytes of the current row - -struct MYSQL_FIELD - contains all info on the attributes of a -specific column in a result set, plus info on lengths of the column in -a result set. This struct is tagged as st_mysql_field. This structure -consists of the following fields: - - char *name - name of column - char *table - table of column if column was a field and not - an expression or constant - char *def - default value (set by mysql_list_fields) - enum enum_field_types type - see above - unsigned int length - width of column in the current row - unsigned int max_length - maximum width of that column in entire - result set - unsigned int flags - corresponding to Extra in DESCRIBE - unsigned int decimals - number of decimals in field - - -struct MYSQL_ROWS - a node for each row in the single linked -list forming entire result set. This struct is tagged as -st_mysql_rows, and has two fields: - - struct st_mysql_rows *next - pointer to the next one - MYSQL_ROW data - see above - - -struct MYSQL_DATA - contains all rows from result set. It is -tagged as st_mysql_data and has following fields: - - my_ulonglong rows - how many rows - unsigned int fields - how many columns - MYSQL_ROWS *data - see above. This is the first node of the linked list - MEM_ROOT alloc - MEM_ROOT is MySQL memory allocation structure, and - this field is used to store all fields and rows. - - -struct st_mysql_options - holds various client options, and -contains following fields: - - unsigned int connect_timeout - time in seconds for connection - unsigned int client_flag - used to hold client capabilities - my_bool compress - boolean for compression - my_bool named_pipe - is Named Pipe used? (on NT) - unsigned int port - what TCP port is used - char *host - host to connect to - char *init_command - command to be executed upon connection - char *user - account name on MySQL server - char *password - password for the above - char *unix_socket - full path for Unix socket file - char *db - default database - char *my_cnf_file - optional configuration file - char *my_cnf_group - optional header for options - - -struct MYSQL - MySQL client's handle. Required for any -operation issued from client to server. Tagged as st_mysql and having -following fields: - - NET net - see above - char *host - host on which MySQL server is running - char *user - MySQL username - char *passwd - password for above - char *unix_socket- full path of Unix socket file - char *server_version - version of the server - char *host_info - contains info on how has connection been - established, TCP port, socket or Named Pipe - char *info - used to store information on the query results, - like number of rows affected etc. - char *db - current database - unsigned int port - TCP port in use - unsigned int client_flag - client capabilities - unsigned int server_capabilities - server capabilities - unsigned int protocol_version - version of the protocol - unsigned int field_count - used for storing number of fields - immediately upon execution of a query, - but before fetching rows - unsigned long thread_id - server thread to which this connection - is attached - my_ulonglong affected_rows - used for storing number of rows - immediately upon execution of a query, - but before fetching rows - my_ulonglong insert_id - fetching LAST_INSERT_ID() through client C API - my_ulonglong extra_info - used by mysqlshow -unsigned long packet_length - saving size of the first packet upon - execution of a query - enum mysql_status status - see above - MYSQL_FIELD *fields - see above - MEM_ROOT field_alloc - memory used for storing previous field (fields) - my_bool free_me - boolean that flags if MYSQL was allocated in mysql_init - my_bool reconnect - used to automatically reconnect - struct st_mysql_options options - see above - char scramble_buff[9] - key for scrambling password before sending it - to server - - -struct MYSQL_RES - tagged as st_mysql_res and used to store -entire result set from a single query. Contains following fields: - - my_ulonglong row_count - number of rows - unsigned int field_count - number of columns - unsigned int current_field - cursor for fetching fields - MYSQL_FIELD *fields - see above - MYSQL_DATA *data - see above, and used in buffered reads, that is, - mysql_store_result only - MYSQL_ROWS *data_cursor - pointing to the field of above "data" - MEM_ROOT field_alloc - memory allocation for above "fields" - MYSQL_ROW row - used for storing row by row in unbuffered reads, - that is, in mysql_use_result - MYSQL_ROW current_row - cursor to the current row for buffered reads - unsigned long *lengths - column lengths of current row - MYSQL *handle - see above, used in unbuffered reads, that is, in - mysql_use_result - my_bool eof - used by mysql_fetch_row as a marker for end of data - - - - Global variables - - -unsigned long max_allowed_packet - maximum allowable value of network - buffer. Default value - 1MB - -unsigned long net_buffer_length - default, starting value of network - buffer - 8KB - -unsigned long bytes_sent - total number of bytes written since startup - of the server - -unsigned long bytes_received - total number of bytes read since startup - of the server - - -Synopsis of the basic client/server protocol --------------------------------------------- - -Purpose of this chapter is to provide a complete picture of -the basic client/server protocol implemented in MySQL. It was felt -it is necessary after writing descriptions for all of the functions -involved in basic protocol. There are at present 11 functions -involved, with several structures, many constants etc, which are all -described in detail. But as a forest could not be seen from the trees, -so the concept of the protocol could not be deciphered easily from a -thorough documentation of minutiae. - -Although the concept of the protocol was not changed with the -introduction of vio system, embodied in violate.cc source file and VIO -system, the introduction of these has changed the code substantially. Before -VIO was introduced, functions for reading from/writing to network -connection had to deal with various network standards. So, these functions -depended on whether TCP port or Unix socket file or NT Named Pipe file is -used. This is all changed now and single vio_ functions are called, while -all this diversity is covered by vio_ functions. - -In MySQL a specific buffered network input/output transport model -has been implemented. Although each operating system may have its -own buffering for network connections, MySQL has added its own -buffering model. This same for each of the three transport protocol -types that are used in MySQL client/server communications, which -are TCP/IP sockets (on all systems), Unix socket files on Unix and -Unix-like operating systems and Named Pipe files on NT. Although -TCP/IP sockets are omnipresent, the latter two types have been added -for local connections. Those two connection types can be used in -local mode only, that is, when both client and server reside on the -same host, and are introduced because they enable better speeds for -local connections. This is especially useful for WWW type of -applications. Startup options of MySQL server allow that either -TCP/IP sockets or local connection (OS dependent) can be disallowed. - -In order to implement buffered input/output, MySQL allocates a -buffer. The starting size of this buffer is determined by the value -of the global variable net_buffer_length, which can be changed at -MySQL server startup. This is, as explained, only the startup length -of MySQL network buffer. Because a single item that has to be read -or written can be larger than that value, MySQL will increase buffer -size as long as that size reaches value of the global variable -max_allowed_packet, which is also settable at server startup. Maximum -value of this variable is limited by the way MySQL stores/reads -sizes of packets to be sent/read, which means by the way MySQL -formats packages. - -Basically each packet consists of two parts, a header and data. In -the case when compression is not used, header consists of 4 bytes -of which 3 contain the length of the packet to be sent and one holds -the packet number. When compression is used there are onother 3 -bytes which store the size of uncompressed data. Because of the way -MySQL packs length into 3 bytes, plus due to the usage of some -special values in the most significant byte, maximum size of -max_allowed_packet is limited to 24MB at present. So, if compression -is not used, at first 4 bytes are written to the buffer and then -data itself. As MySQL buffers I/O logical packets are packet together -until packets fill up entire size of the buffer. That size no less -than net_buffer_size, but no greater than max_allowed_packet. So, -actual writing to the network is done when this buffer is filled -up. As frequently sequence of buffers make a logical unit, like a -result set, then at the end of sending data, even if buffer is not -full, data is written (flushed to the connection) with a call of -the net_flush function. So that no single packet can be larger than -this value, checks are made throughout the code to make sure that -no single field or command could exceed that value. - -In order to maintain coherency in consecutive packets, each packet -is numbered and their number stored as a part of a header, as -explained above. Packets start with 0, so whenever a logical packet -is written, that number is incremented. On the other side when -packets are read, value that is fetched is compared with the value -stored and if there is no mismatch that value is incremented, too. -Packet number is reset on the client side when unwanted connections -are removed from the connection and on the server side when a new -command has been started. - - -So, before writing, the buffer contains a sequence of logical -packets, consisting of header plus data consecutively. If compression -is used, packet numbers are not stored in each header of the logical -packets, but a whole buffer, or a part of it if flushing is done, -containing one or more logical packets are compressed. In that case -a new larger header, is formed, and all logical packets contained -in the buffer are compressed together. This way only one packet is -formed which makes several logical packets, which improves both -speed and compression ratio. On the other side, when this large -compressed packet is read, it is first uncompressed, and then logical -packets are sent, one by one, to the calling functions. - - -All this functionality is described in detail in the following -chapter. It does not contain functions that form logical packets, or -that read and write to connections but also functions that are used -for initialization, clearing of connections. There are functions at -higher level dealing with sending fields, rows, establishing -connections, sending commands, but those are not explained in the -following chapter. - - -Functions utilized in client/server protocol --------------------------------------------- - -First of all, functions are described that are involved in preparing, -reading, or writing data over TCP port, Unix socket file, or named -pipe, and functions directly related to those. All of these functions -are used both in server and client. Server and client specific code -segments are documented in each function description. - -Each MySQL function checks for errors in memory allocation and -freeing, as well as in every OS call, like the one dealing with -files and sockets, and for errors in indigenous MySQL function -calls. This is expected, but has to be said here so as not to repeat -it in every function description. - -Older versions of MySQL have utilized the following macros for -reading from or writing to a socket. - -raw_net_read - calls OS function recv function that reads N bytes -from a socket into a buffer. Number of bytes read is returned. - -raw_net_write - calls OS function send to write N bytes from a -buffer to socket. Number of bytes written is returned. - -These macros are replaced with VIO (Virtual I/O) functions. - - -Function name: my_net_init - -Parameters: struct NET *, enum_net_type, struct Vio - -Return value: 1 for error, 0 for success - -Function purpose: To initialize properly all NET fields, - allocate memory and set socket options - -Function description - -First of all, buff field of NET struct is allocated to the size of -net_buffer_length, and on failure function exits with 0. All fields -in NET are set to their default or starting values. As net_buffer_length -and max_allowed_packet are configurable, max_allowed_packet is set -equal to net_buffer_length if the latter one is greater. max_packet -is set for that NET to net_buffer_length, and buff_end points to -buff end. vio field is set to the second parameter. If it is a -real connection, which is the case when second parameter is not -null, then fd field is set by calling vio_fd function. read_pos and -write_pos to buff, while remaining integers are set to 0. If function -is run on the MySQL server on Unix and server is started in a test -mode that would require testing of blocking, then vio_blocking -function is called. Last, fast throughput mode is set by a call to -vio_fastsend function. - - -Function name: net_end - -Parameters: struct NET * - -Return value: void - -Function purpose: To release memory allocated to buff - - - -Function name: net_realloc (private, static function) - -Parameters: struct NET, ulong (unsigned long) - -Return value: 1 for error, 0 for success - -Function purpose: To change memory allocated to buff - -Function description - -New length of buff field of NET struct is passed as second parameter. -It is first checked versus max_allowed_packet and if greater, an -error is returned. New length is aligned to 4096-byte boundary. Then, -buff is reallocated, buff_end, max_packet, and write_pas reset to -the same values as in my_net_init. - - - -Function name: net_clear (used on client side only) - -Parameters: struct NET * - -Return value: void - -Function purpose: To read unread packets - -Function description - -This function is used on client side only, and is executed -only if a program is not started in test mode. This function reads -unread packets without processing them. First, non-blocking mode is -set on systems that do not have non-blocking mode defined. This is -performed by checking the mode with vio_is_blocking function. and -setting non-blocking mode by vio_blocking function. If this operation -was successful, then packets are read by vio_read function, to which -vio field of NET is passed together with buff and max_packet field -values. field of the same struct at a length of max_packet. If -blocking was active before reading is performed, blocking is set with -vio_blocking function. After reading has been performed, pkt_nr is -reset to 0 and write_pos reset to buff. In order to clarify some -matters non-blocking mode enables executing program to dissociate from -a connection, so that error in connection would not hang entire -program or its thread. - -Function name: net_flush - -Parameters: struct NET * - -Return value: 1 for error, 0 for success - -Function purpose: To write remaining bytes in buff to socket - -Function description - -net_real_write (described below) is performed is write_pos -differs from buff, both being fields of the only parameter. write_pos -is reset to buff. This function has to be used, as MySQL uses buffered -writes (as will be explained more in the function net_write_buff). - - -Function name: my_net_write - -Parameters: struct NET *, const char *, ulong - -Return value: 1 for error, 0 for success - -Function purpose: Write a logical packet in the second parameter - of third parameter length - -Function description - -The purpose of this function is to prepare a logical packet such -that entire content of data, pointed to by second parameter and in -length of third parameter is sent to the other side. In case of -server, it is used for sending result sets, and in case of client -it is used for sending local data. This function foremost prepares -a header for the packet. Normally, the header consists of 4 bytes, -of which the first 3 bytes contain the length of the packet, thereby -limiting a maximum allowable length of a packet to 16MB, while the -fourth byte contains the packet number, which is used when one large -packet has to be divided into sequence of packets. This way each -sub-packet gets its number which should be matched on the other -side. When compression is used another three bytes are added to -packet header, thus packet header is in that case increased to 7 -bytes. Additional three bytes are used to save the length of -compressed data. As in connection that uses compression option, -code packs packets together,, a header prepared by this function -is later not used in writing to / reading from network, but only -to distinguish logical packets within a buffered read operation. - - -This function, first stores the value of the third parameter into the -first 3 bytes of local char variable of NET_HEADER_SIZE size by usage -of function int3store. Then, at this point, if compression is not -used, pkt_nr is increased, and its value stored in the last byte of -the said local char[] variable. If compression is used, 0 is stored in -both values. Then those four bytes are sent to other side by the usage -of the function net_write_buff(to be explained later on), and if -successful, entire packet in second parameter of the length described -in third parameter is sent by the usage of the same function. - - -Function name: net_write_command - -Parameters: struct NET *, char, const char *, ulong - -Return value: 1 for error, 0 for success - -Function purpose: Send a command with a packet as in previous function - -Function description - -This function is very similar to the previous one. The only -difference is that first packet is enlarged by one byte, so that the -command precedes the packet to be sent. This is implemented by -increasing first packet by one byte, which contains a command code. As -command codes do not use the range of values that are used by character -sets, so when the other side receives a packet, first byte after -header contains a command code. This function is used by client for -sending all commands and queries, and by server in connection process -and for sending errors. - - -Function name: net_write_buff (private, static function) - -Parameters: struct NET *, const char *, uint - -Return value: 1 for error, 0 for success - -Function purpose: To write a packet of any size by cutting it -and using next function for writing it - -Function description - -This function was created after compression feature has been -added to MySQL. This function supposes that packets have already been -properly formatted, regarding packet header etc. The principal reason for -this function to exist is because a packet that is sent by client or -server does not have to be less than max_packet. So this function -first calculates how much data has been left in a buff, by getting a -difference between buff_end and write_pos and storing it to local -variable left_length. Then a loop is run as long as the length to be -sent is greater than length of left bytes (left_length). In a loop -data from second parameter is copied to buff at write_pos, as much as -it can be, that is, by left_length. Then net_real_write function is called -(see below) with NET, buff, and max_packet parameters. This function -is the lowest level function that writes data over established -connection. In the loop, write_pos is reset to buff, the pointer to data -(second parameter) is moved by the amount of data sent (left_length), -length of data to be sent (third parameter) is decreased by the amount -sent (left_length) and left_length is reset to max_packet value, which -ends the loop. This logic was necessary, as there could have been some -data yet unsent (write_pos != buf), while data to be sent could be as -large as necessary, thus requiring many loops. At the end of function, -remaining data in second parameter are copied to buff at write_pos, by -the remaining length of data to be sent (third parameter). So, in the -next call of this function remaining data will be sent, as buff is -used in the call to net_real_write. It is very important to note that if -a packet to be sent is less than the number of bytes that are still -available in buff, then there will be no writing over network, but -only logical packets will be added one after another. This will -accelerate network traffic, plus if compression is used, the -expected compression rate would be higher. That is why server or -client functions that sends data uses at the end of data net_flush -function described above. - - -Function name: net_real_write - -Parameters: struct NET *, const char *, ulong - -Return value: 1 for error, 0 for success - -Function purpose: To write data to a socket or pipe, with -compression if used - -Function description - -First, more field is set to 2, to enable reporting in -mysql_list_processes. Then if compression is enabled on that -connection, a new local buffer (variable b) is initialized to the -length of total header (normal header + compression header) and if no -memory is available, an error is returned. This buffer (b) is used for -holding the final, compressed packet to be written over the -connection. Furthermore in compression initialization, second -parameter at length of third parameter is copied to the local buffer -b, and MySQL's wrapped zlib's compression function is run at total -header offset of the local buffer. Please, do note that this function -does not test effectiveness of compression. If compression is turned -on in some connection, it is used all of the time. Also, it is very -important to be cognizant of the fact that this algorithm makes -possible that a single compressed packet contains several logical -packets. In this way compression rate is increased and network -throughput is increased as well. However, this algorithm has -consequences on the other side, that reads compressed packet, which -is covered in my_net_read function. After compression is done, the full -compression header is properly formed with the packet number, -compressed and uncompressed lengths. At the end of compression code, -third parameter is increased by total header length, as the original -header is not used (see above), and second parameter, pointer to data, -is set to point to local buffer b, in order that the further flow of -function is independent of compression. If a function is executed -on server side, a thread alarm initialized and if non-blocking is -active set at NET_WRITE_TIMEOUT. Two local (char *) pointers are -initialized, pos at beginning of second parameter, and end at end of -data. Then the loop is run as long as all data is written, which means -as long as pos != end. First vio_write function is called, with -parameters of vio field, pos and size of data (end - pos). Number of -bytes written over connection is saved in local variable (length). If -error is returned local bool variable (interrupted) is set according -to the return value of the vio_should_retry called with vio field as -parameter. This bool variable indicates whether writing was -interrupted in some way or not. - -Further, error from vio_write is treated differently on Unix versus -other OS's (Win32 or OS/2). On Unix an alarm is set if one is not -in use, no bytes have been written and there has been no interruption. -Also, in that case, if connection is not in blocking mode, a sub-loop -is run as long as blocking is not set with vio_blocking function. -Within the loop another run of above vio_write is run based on -return value of vio_is_retry function, provided number of repeated -writes is less than RETRY_COUNT. If that is not the case, error -field of struct NET is set to 1 and function exits. At the exit -of sub-loop number of reruns already executed is reset to zero and -another run of above vio_write function is attempted. If the function -is run on Win32 and OS/2, and in the case that function flow was -not interrupted and thread alarm is not in use, again the main loop -is continued until pos != end. In the case that this function is -executed on thread safe client program, a communication flow is -tested on EINTR, caused by context switching, by use of vio_errno -function, in which case the loop is continued. At the end of -processing of the error from vio_write, error field of struct NET -is set, and if on server last_errno field is set to -ER_NET_WRITE_INTERRUPTED in the case that local bool variable -(interrupted) is true or to ER_NET_ERROR_ON_WRITE. Before the end -of loop, in order to make possible evaluation of the loop condition, -pos is increased by the value written in last iteration (length). -Also global variable bytes_sent is increased by the same value, for -status purposes. At the end of the functions more fields is reset, -in case of compression, compression buffer (b) memory is released -and if thread is still in use, it is ended and blocking state is -reset to its original state, and function returns error is all bytes -are not written. - - - -Function name: my_real_read (private, static function) - -Parameters: struct NET *, ulong * - -Return value: length of bytes read - -Function purpose: low level network connection read function - -Function description - -This function has made as a separate one when compression was -introduced in MySQL client/server protocol . It contains basic, low -level network reading functionality, while all dealings with -compressed packets are handled in next function. Compression in this -function is only handled in as much to unfold the length of uncompressed -data. First blocking state of connection is saved in local bool -variable net_blocking, and field more is set 1 for detailed reporting -in mysqld_list_processes. A new thread alarm is initialized, in order -to enable read timeout handling, and if on server and a connection can -block a program, the alarm is set at a value of timeout field. Local -pointer is set to the position of the next logical packet, with its -header skipped, which is at field where_b offset from buff. Next, a -two time run code is entered. A loop is run exactly two times because -first time number of bytes to be fetched (remain) are set to the -header size, which is different when compression is used or not used -on the connection. After first fetch has been done, number of packets -that will be received in second iteration is well known, as fetched -header contains the size of packet, packet number, and in the case of -compression, the size of the uncompressed packet. Then, as long as there are -bytes to read the loop is entered with first reading data from network -connection with vio_read function, called with parameters of field -vio, current position and remaining number of bytes, which value is -hold by local variable (remain) initialized at the value of header size, -which differs if compression is used. Number of bytes read are -returned in local length variable. If error is returned local bool -variable (interrupted) is set according to the return value of the -vio_should_retry called with vio field as parameter. This bool -variable indicates whether reading was interrupted in some way or not. - -Further, error from vio_read is treated differently on Unix versus -other OS's (Win32 or OS/2). On Unix an alarm is set if one is not -in use, no bytes have been read and there has been no interruption. -Also, in that case, if connection is not in blocking mode, a sub-loop -is run as long as blocking is not set with vio_blocking function. -Within the loop another run of above vio_read is run based on return -value of vio_is_retry function, provided number of repeated writes -is less than RETRY_COUNT. If that is not the case, error field of -struct NET is set to 1 and function exits. At the exit of sub-loop -number of reruns already executed is reset to zero and another run -of above vio_read function is attempted. If the function is run on -Win32 and OS/2, and in the case that function flow was not interrupted -and thread alarm is not in use, again the main loop is continued -as long as there are bytes remaining. In the case that this function -is executed on thread safe client program, then if another run -should be made, which is decided by the output of vio_should_retry -function, in which case the loop is continued. At the end of -processing of the error from vio_read, error field of struct NET -is set, and if on server last_errno field is set to ER_NET_READ_INTERRUPTED -in the case that local bool variable (interrupted) is true or to -ER_NET_ERROR_ON_READ. In case of such an error this function exits -and returns error. In the case when there is no error, number of -remaining bytes (remain) is decreased by the number of bytes read, -which should be zero, but in case it is not the entire code is still -in while (remain > 0) loop, which will be exited immediately if it -is. This has been done to accommodate errors in the traffic level -and for the very slow connections. Current position in field buff -is also moved by the amount of bytes read by vio_read function, and -global variable bytes_received is increased by the same value in a -thread safe manner. When the loop that is run until necessary bytes -are read (remain) is finished, then if external loop is in its first -run, of the two, packet sequencing is tested for consistency by -comparing the number contained at 4th byte in header with pkt_nr -field. Header location is found at where_b offset to field_b. Usage -of where_b is obligatory due to the possible compression usage. If -there is no compression on a connection, then where_b is always 0. -If there is a discrepancy, then first byte of the header is checked -whether it is equal to 255, because when error is sent by the server, -or by a client if it is sending data (like in LOAD DATA INFILE -LOCAL...), then first byte in header is set to 255. If it is not -255, then an error on packets being out of order is printed. In any -case, on server, last_errno field is set to ER_NET_PACKETS_OUT_OF_ORDER -and the function returns with an error, that is, the value returned is -packet_error. If a check on serial number of packet is successful, -pkt_nr field is incremented in order to enable checking packet order -with next packet and if compression is used, uncompressed length -is extracted from a proper position in header and returned in the -second parameter of this function. Length of the packet is saved, -for the purpose of a proper return value from this function. Still -in the first iteration of the main loop, a check must be made if -field buff could accommodate entire package that comes, in its -compressed or uncompressed form. This is done in such a way, because -zlib's compress and uncompress functions use the same memory area -for compression and uncompression. Necessary field buff length is -equal to current offset where data are (where_b which is zero for -non-compression), plus the larger value of compressed or uncompressed -package to be read in a second run. If this value is larger than -the current length of field buff, which is read from field max_packet, -then field buff has to be reallocated. If reallocation with net_realloc -function fails, the function returns an error. Before a second -loop is started, length to be read is set to the length of expected -data and current position (pos) is set at where_b offset from field -buff. At the end of function, if alarm is set, which is the case -if it is run on server or on a client if a function is interrupted -and another run of vio_read is attempted, alarm is ended and blocking -state is restored from the saved local bool variable net_blocking. -Function returns number of bytes read or the error (packet_error). - - -Function name: my_net_read - -Parameters: struct NET * - -Return value: length of bytes read - -Function purpose: Highest level general purpose reading function - -Function description - -First, if compression is not used, my_real_read is called, with -struct NET * a first parameter, and pointer to local ulong complen -as a second parameter, but its value is not used here. Number of -bytes read is returned in local ulong variable len. read_pos field -is set to an offset of value of where_b field from field buff. -where_b field actually denotes where in field buff is the current -packet. If returned number of bytes read (local variable len) does -not signal that an error in packet transmission occurred (that is, -it is not set to packet_error), then the string contained in read_pos -is zero terminated. Simply, the end of the string starting at -read_pos, and ending at read_pos + len, is set to zero. This is -done in that way, because mysql_use_result expects a zero terminated -string, and function returns with a value local variable len. This -ends this function in the case that compression is not used and the -remaining code is executed only if compression is enabled on the -connection. - -In order to explain how a compressed packet logically is cut into -meningful packets, the full meaning of several NET fields should -be explained. First of all, fields in NET are used and not local -variables, as all values should be saved between consecutive calls -of this function. Simply, this function is called in order to return -logical packets, but this function does not need to call my_real_read -function everytime, because when a large packet is uncompressed, -it may, but not necessarily so, contain several logical packets. -Therefore, in order to preserve data on logical packets local -variables are not used. Instead fields in NET struct are used. Field -remain_in_buf denotes how many bytes of entire uncompressed packets -is still contained within buff. field buf_length saves the value -of the length of entire uncompressed packet. field save_char is -used to save the character at the position where the packet ends, -which character has to be replaced with a zero, '\0', in order to -make a logical packet zero delimited, for mysql_use_result. Field -length stores the value of the length of compressed packet. Field -read_pos as usual, points to the current reading position. This -char * pointer is used by all functions that call this function in -order to fetch their data. Field buff is not used for that purpose, -but read_pos is used instead. This change was introduced with -compression, when algorithm accommodated grouping of several packets -together. - -Now that meanings of all relevant NET fields are explained, -we can proceed with the flow of this function for the case when -compression is active. First, if there are remaining portions of -compressed packet in a field buff, saved character value is set at -the position where zero char '\0' was inserted to enable the string -to be zero delimited for mysql_use_result. Then a loop is started. -In the first part of the loop, if there are remaining bytes, local -uchar *pos variable is set at the current position in field buff -where a new packet starts. This position is an (buf_length - -remain_in_buf) offset in field buff. As it is possible that next -logical packet is not read to the full length in the remaining of -the field buf, several things had to be inspected. It should be -noted that data that is read from net_real_read contains only logical -packets containing 4 byte headers only, being 4 byte headers prepared -by my_net_write or net_write_command. But, when written, logical -packet could be so divided that only a part of header is read in. -Therefore after pointer to the start of the next packet has been -saved, a check is made whether number of remaining bytes in buffer -is less than 4, being 3 bytes for length and one byte for packet -number. If it is greater, then the length of the logical packet is -extracted and saved a length field. Then a check is made whether -entire packet is contained within a buf, that is, a check is made -that the logical packet is fully contained in the buffer. In that -case, number of bytes remaining in buffer is decreased by the full -length of logical packet (4 + length field), read_pos is moved -forward by 4 bytes to skip header and be set at a beginning of data -in logical packet, length field is saved for the value to be returned -in function and the loop is exited. In the case that the entire -logical packet is not contained within the buffer, then if length of -the entire buffer differs from remaining length of logical packet, -it (logical packet) is moved to the beginning of the field buff. -If length of the entire buffer equals the remaining length of logical -packet, where_b and buf_length fields are set to 0. This is done -so that in both cases buffer is ready to accept next part of packet. - -In order to get a next part of a packet, still within a loop, -my_real_read function is called and length of compressed packet is -returned to a local len variable, and length of compressed data is -returned in complen variable. In the case of non-compression value -of complen is zero. If packet_error is from my_real_read function, -this function returns also with packet_error. If it is not a -packet_error, my_uncompress function is called to uncompress data. -It is called with offset of where_b data from field buff, as it is -the position where compressed packet starts, and with len and complen -values, being lengths of compressed and uncompressed data. If there -is no compression, 0 is returned for uncompressed size from -my_real_read function, and my_uncompress wrapper function is made -to skip zlib uncompress in that case. If error is returned from -my_uncompress, error field is set to 1, if on server last_errno is -set to ER_NET_UNCOMPRESS_ERROR and loop is exited and function -returns with packet_error. If not, buf_length and remain_in_buf -fields are set to the uncompressed size of buffer and the loop is -continued. When the loop is exited save_char field is used to save -the char at end of a logical packet, which is an offset of field -len from position in field buff pointed by field read_pos, in order -that zero char is set at the same position, for mysql_use_result. -Function returns the length of the logical packet without its header. diff --git a/EXCEPTIONS-CLIENT b/EXCEPTIONS-CLIENT index 19b86cab32b..c570ff7ba24 100644 --- a/EXCEPTIONS-CLIENT +++ b/EXCEPTIONS-CLIENT @@ -4,7 +4,7 @@ The MySQL AB Exception for Free/Libre and Open Source Software-only Applications Using MySQL Client Libraries (the "FLOSS Exception"). -Version 0.5, 30 August 2006 +Version 0.6, 7 March 2007 Exception Intent @@ -59,10 +59,12 @@ Apache Software License 1.0/1.1/2.0 Apple Public Source License 2.0 Artistic license From Perl 5.8.0 BSD license "July 22 1999" +Common Development and Distribution License (CDDL) 1.0 Common Public License 1.0 +Eclipse Public License 1.0 GNU Library or "Lesser" General Public License (LGPL) 2.0/2.1 Jabber Open Source License 1.0 -MIT license --- +MIT license (As listed in file MIT-License.txt) --- Mozilla Public License (MPL) 1.0/1.1 Open Software License 2.0 OpenSSL license (with original SSLeay license) "2003" ("1998") diff --git a/Makefile.am b/Makefile.am index 6d435bff85a..c9f86f76058 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,58 +21,18 @@ AUTOMAKE_OPTIONS = foreign EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \ README COPYING EXCEPTIONS-CLIENT CMakeLists.txt SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ - @readline_topdir@ sql-common \ + @readline_topdir@ sql-common scripts \ @thread_dirs@ pstack \ @sql_union_dirs@ unittest storage plugin \ - @sql_server@ scripts @man_dirs@ tests \ + @sql_server@ @man_dirs@ tests \ netware @libmysqld_dirs@ \ mysql-test support-files sql-bench @tools_dirs@ \ win -DIST_SUBDIRS = $(SUBDIRS) BUILD +DIST_SUBDIRS = $(SUBDIRS) BUILD debian -# Run these targets before any others, also make part of clean target, -# to make sure we create new links after a clean. -BUILT_SOURCES = linked_client_sources linked_server_sources \ - @linked_client_targets@ \ - @linked_libmysqld_targets@ \ - linked_include_sources @linked_netware_sources@ - -CLEANFILES = $(BUILT_SOURCES) DISTCLEANFILES = ac_available_languages_fragment -linked_include_sources: - cd include; $(MAKE) link_sources - echo timestamp > linked_include_sources - -linked_client_sources: @linked_client_targets@ - cd client; $(MAKE) link_sources - echo timestamp > linked_client_sources - -linked_libmysql_sources: - cd libmysql; $(MAKE) link_sources - echo timestamp > linked_libmysql_sources - -linked_libmysql_r_sources: linked_libmysql_sources - cd libmysql_r; $(MAKE) link_sources - echo timestamp > linked_libmysql_r_sources - -linked_libmysqld_sources: - cd libmysqld; $(MAKE) link_sources - echo timestamp > linked_libmysqld_sources - -linked_libmysqldex_sources: - cd libmysqld/examples; $(MAKE) link_sources - echo timestamp > linked_libmysqldex_sources - -linked_netware_sources: - cd @netware_dir@; $(MAKE) link_sources - echo timestamp > linked_netware_sources - -linked_server_sources: - cd sql; $(MAKE) link_sources - echo timestamp > linked_server_sources - # Create permission databases init-db: all $(top_builddir)/scripts/mysql_install_db @@ -97,7 +57,10 @@ tags: .PHONY: init-db bin-dist \ test test-force test-full test-force-full test-force-mem \ test-pl test-force-pl test-full-pl test-force-full-pl test-force-pl-mem \ - test-unit test-ps test-nr test-pr test-ns test-binlog-statement + test-unit test-ps test-nr test-pr test-ns test-binlog-statement \ + test-ext-funcs test-ext-rpl test-ext-partitions test-ext \ + test-fast test-fast-cursor test-fast-view test-fast-prepare \ + test-full-qa # Target 'test' will run the regression test suite using the built server. # @@ -120,11 +83,11 @@ test-nr: test-pr: cd mysql-test ; \ - @PERL@ ./mysql-test-run.pl $(force) --ps-protocol --mysqld=--binlog-format=row + @PERL@ ./mysql-test-run.pl $(force) $(mem) --ps-protocol --mysqld=--binlog-format=row test-ns: cd mysql-test ; \ - @PERL@ ./mysql-test-run.pl $(force) --mysqld=--binlog-format=mixed + @PERL@ ./mysql-test-run.pl $(force) $(mem) --mysqld=--binlog-format=mixed test-binlog-statement: cd mysql-test ; \ @@ -142,7 +105,29 @@ test-force-full: #used by autopush.pl to run memory based tests test-force-mem: - $(MAKE) 'force=--force --mem' test + $(MAKE) force=--force mem=--mem test + +test-bt: + -cd mysql-test ; MTR_BUILD_THREAD=auto \ + @PERL@ ./mysql-test-run.pl --comment=normal --force --timer \ + --skip-ndbcluster --report-features + -cd mysql-test ; MTR_BUILD_THREAD=auto \ + @PERL@ ./mysql-test-run.pl --comment=ps --force --timer \ + --skip-ndbcluster --ps-protocol + -cd mysql-test ; MTR_BUILD_THREAD=auto \ + @PERL@ ./mysql-test-run.pl --comment=normal+rowrepl --force --timer \ + --skip-ndbcluster --mysqld=--binlog-format=row + -cd mysql-test ; MTR_BUILD_THREAD=auto \ + @PERL@ ./mysql-test-run.pl --comment=ps+rowrepl+NDB --force --timer \ + --ps-protocol --mysqld=--binlog-format=row + -cd mysql-test ; MTR_BUILD_THREAD=auto \ + @PERL@ ./mysql-test-run.pl --comment=NDB --force --timer \ + --with-ndbcluster-only + +test-bt-debug: + -cd mysql-test ; MTR_BUILD_THREAD=auto \ + @PERL@ ./mysql-test-run.pl --comment=debug --force --timer \ + --skip-ndbcluster --skip-rpl --report-features # Keep these for a while test-pl: test @@ -151,5 +136,43 @@ test-force-pl: test-force test-force-pl-mem: test-force-mem test-force-full-pl: test-force-full +test-ext-funcs: + cd mysql-test ; \ + @PERL@ ./mysql-test-run.pl --force --suite=funcs_1 ; \ + @PERL@ ./mysql-test-run.pl --force --suite=funcs_2 + +test-ext-rpl: + cd mysql-test ; \ + @PERL@ ./mysql-test-run.pl --force --suite=rpl + +test-ext-partitions: + cd mysql-test ; \ + @PERL@ ./mysql-test-run.pl --force --suite=partitions + +test-ext-jp: + cd mysql-test ; \ + @PERL@ ./mysql-test-run.pl --force --suite=jp + +test-ext: test-ext-funcs test-ext-rpl test-ext-partitions test-ext-jp + +test-fast: + cd mysql-test ; \ + @PERL@ ./mysql-test-run.pl $(subset) --force --skip-ndb --skip-innodb --skip-im --skip-rpl ; \ + @PERL@ ./mysql-test-run.pl $(subset) --force --suite=funcs_1 --do-test=myisam + +test-fast-view: + $(MAKE) subset=--view-protocol test-fast + +test-fast-cursor: + $(MAKE) subset=--cursor-protocol test-fast + +test-fast-prepare: + $(MAKE) subset=--ps-protocol test-fast + +test-full-qa: + $(MAKE) force=--force test-pr \ + test-binlog-statement test-ext test-fast-view \ + test-fast-cursor test-unit + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index d492c49a6b2..4c41dc263b0 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -82,6 +82,7 @@ TARGET_LINK_LIBRARIES(mysqlimport mysqlclient mysys dbug yassl taocrypt zlib wso ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c) TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient dbug yassl taocrypt zlib wsock32) +ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs) ADD_EXECUTABLE(mysqlshow mysqlshow.c) TARGET_LINK_LIBRARIES(mysqlshow mysqlclient mysys dbug yassl taocrypt zlib wsock32) @@ -95,6 +96,7 @@ ADD_EXECUTABLE(mysqladmin mysqladmin.cc) TARGET_LINK_LIBRARIES(mysqladmin mysqlclient mysys dbug yassl taocrypt zlib wsock32) ADD_EXECUTABLE(mysqlslap mysqlslap.c) +SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS") TARGET_LINK_LIBRARIES(mysqlslap mysqlclient mysys yassl taocrypt zlib wsock32 dbug) ADD_EXECUTABLE(echo echo.c) diff --git a/client/Makefile.am b/client/Makefile.am index 1c908ea715e..d482512e411 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -34,7 +34,11 @@ LDADD= @CLIENT_EXTRA_LDFLAGS@ $(CLIENT_THREAD_LIBS) \ noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \ client_priv.h -EXTRA_DIST = get_password.c CMakeLists.txt +EXTRA_DIST = get_password.c CMakeLists.txt echo.c + +BUILT_SOURCES = link_sources + +CLEANFILES = $(BUILT_SOURCES) bin_PROGRAMS = mysql \ mysqladmin \ @@ -76,6 +80,7 @@ mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ mysqlshow_SOURCES= mysqlshow.c mysqlslap_SOURCES= mysqlslap.c +mysqlslap_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ $(LIBMYSQLCLIENT_LA) \ @@ -94,9 +99,11 @@ DEFS = -DUNDEF_THREADS_HACK \ -DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \ -DDATADIR="\"$(localstatedir)\"" -sql_src=log_event.h mysql_priv.h log_event.cc my_decimal.h my_decimal.cc +sql_src=log_event.h mysql_priv.h rpl_constants.h \ + log_event.cc my_decimal.h my_decimal.cc \ + log_event_old.h log_event_old.cc \ + rpl_record_old.h rpl_record_old.cc strings_src=decimal.c -EXTRA_DIST = get_password.c CMakeLists.txt echo.c link_sources: for f in $(sql_src) ; do \ @@ -109,6 +116,7 @@ link_sources: done; \ rm -f $(srcdir)/my_user.c; \ @LN_CP_F@ $(top_srcdir)/sql-common/my_user.c my_user.c; + echo timestamp > link_sources; # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/client/client_priv.h b/client/client_priv.h index 646619f62b1..25241cc8c59 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -23,6 +23,14 @@ #include #include +#ifndef WEXITSTATUS +# ifdef __WIN__ +# define WEXITSTATUS(stat_val) (stat_val) +# else +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +# endif +#endif + enum options_client { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, @@ -49,7 +57,6 @@ enum options_client OPT_TRIGGERS, OPT_MYSQL_ONLY_PRINT, OPT_MYSQL_LOCK_DIRECTORY, - OPT_MYSQL_SLAP_SLAVE, OPT_USE_THREADS, OPT_IMPORT_USE_THREADS, OPT_MYSQL_NUMBER_OF_QUERY, @@ -58,7 +65,16 @@ enum options_client OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA, OPT_SLAP_CSV, OPT_SLAP_CREATE_STRING, OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, OPT_SLAP_AUTO_GENERATE_WRITE_NUM, + OPT_SLAP_AUTO_GENERATE_ADD_AUTO, + OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY, + OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES, + OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES, + OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM, + OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM, + OPT_SLAP_PRE_QUERY, + OPT_SLAP_POST_QUERY, OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID, OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT, - OPT_DEBUG_INFO, OPT_COLUMN_TYPES + OPT_DEBUG_INFO, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, OPT_WRITE_BINLOG, + OPT_MAX_CLIENT_OPTION }; diff --git a/client/echo.c b/client/echo.c index 4483eaad293..e3d22edb3ae 100644 --- a/client/echo.c +++ b/client/echo.c @@ -2,8 +2,7 @@ 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. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/client/mysql.cc b/client/mysql.cc index 48172d97f56..49d5ae4f449 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -818,7 +818,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; #endif case OPT_CHARSETS_DIR: - strmov(mysql_charsets_dir, argument); + strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir) - 1); charsets_dir = mysql_charsets_dir; break; case OPT_DEFAULT_CHARSET: @@ -871,7 +871,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), if (argument && strlen(argument)) { default_pager_set= 1; - strmov(pager, argument); + strmake(pager, argument, sizeof(pager) - 1); strmov(default_pager, pager); } else if (default_pager_set) @@ -885,14 +885,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_nopager= 1; break; case OPT_MYSQL_PROTOCOL: - { - if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0) - { - fprintf(stderr, "Unknown option to protocol: %s\n", argument); - exit(1); - } + opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, + opt->name); break; - } break; case 'A': opt_rehash= 0; @@ -2104,6 +2099,17 @@ com_go(String *buffer,char *line __attribute__((unused))) if (!mysql_num_rows(result) && ! quick && !column_types_flag) { strmov(buff, "Empty set"); + if (opt_xml) + { + /* + We must print XML header and footer + to produce a well-formed XML even if + the result set is empty (Bug#27608). + */ + init_pager(); + print_table_data_xml(result); + end_pager(); + } } else { @@ -2517,7 +2523,8 @@ print_table_data_xml(MYSQL_RES *result) tee_fputs("\n\n", PAGER); + tee_fputs("\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">", + PAGER); fields = mysql_fetch_fields(result); while ((cur = mysql_fetch_row(result))) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index e6870c23129..64de3d19882 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -14,57 +14,51 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "client_priv.h" -#include -#include #include +#include "../scripts/mysql_fix_privilege_tables_sql.c" -#define UPGRADE_DEFAULTS_NAME "mysql_upgrade_defaults" -#define MYSQL_UPGRADE_INFO_NAME "mysql_upgrade_info" -#define MYSQL_FIX_PRIV_TABLES_NAME "mysql_fix_privilege_tables.sql" - -#define MY_PARENT (1 << 0) -#define MY_ISDIR (1 << 1) -#define MY_SEARCH_SELF (1 << 2) - -#ifdef __WIN__ -const char *mysqlcheck_name= "mysqlcheck.exe"; -const char *mysql_name= "mysql.exe"; -const char *mysqld_name= "mysqld.exe"; -#define EXTRA_CLIENT_PATHS "client/release", "client/debug" -#else -const char *mysqlcheck_name= "mysqlcheck"; -const char *mysql_name= "mysql"; -const char *mysqld_name= "mysqld"; -#define EXTRA_CLIENT_PATHS "client" -#endif /*__WIN__*/ - -extern TYPELIB sql_protocol_typelib; - -static my_bool opt_force= 0, opt_verbose= 0, opt_compress= 0; -static char *user= (char*) "root", *basedir= 0, *datadir= 0, *opt_password= 0; -static char *current_host= 0; -static char *opt_default_charset= 0, *opt_charsets_dir= 0; -#ifdef HAVE_SMEM -static char *shared_memory_base_name= 0; +#ifdef HAVE_SYS_WAIT_H +#include #endif -static char *opt_protocol= 0; -static my_string opt_mysql_port= 0, opt_mysql_unix_port= 0; + +#ifndef WEXITSTATUS +# ifdef __WIN__ +# define WEXITSTATUS(stat_val) (stat_val) +# else +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +# endif +#endif + +static char mysql_path[FN_REFLEN]; +static char mysqlcheck_path[FN_REFLEN]; + +static my_bool opt_force, opt_verbose; +static char *opt_user= (char*)"root"; + +static DYNAMIC_STRING ds_args; + +static char *opt_password= 0; +static my_bool tty_password= 0; + #ifndef DBUG_OFF static char *default_dbug_option= (char*) "d:t:O,/tmp/mysql_upgrade.trace"; #endif -static my_bool info_flag= 0, tty_password= 0; static char **defaults_argv; +static my_bool not_used; /* Can't use GET_BOOL without a value pointer */ + +#include + static struct my_option my_long_options[]= { {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"basedir", 'b', "Specifies the directory where MySQL is installed", - (gptr*) &basedir, - (gptr*) &basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"datadir", 'd', "Specifies the data directory", (gptr*) &datadir, - (gptr*) &datadir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"basedir", 'b', "Not used by mysql_upgrade. Only for backward compatibilty", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"datadir", 'd', + "Not used by mysql_upgrade. Only for backward compatibilty", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef DBUG_OFF {"debug", '#', "This is a non-debug version. Catch this and exit", 0, 0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -72,629 +66,720 @@ static struct my_option my_long_options[]= {"debug", '#', "Output debug log", (gptr *) & default_dbug_option, (gptr *) & default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-info", 'T', "Print some debug info at exit.", (gptr *) & info_flag, - (gptr *) & info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, - "Set the default character set.", (gptr*) &opt_default_charset, - (gptr*) &opt_default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"force", 'f', "Force execution of mysqlcheck even if mysql_upgrade " - "has already been executed for the current version of MySQL.", - (gptr*) &opt_force, (gptr*) &opt_force, 0, GET_BOOL, NO_ARG, 0, 0, - 0, 0, 0, 0}, + "Set the default character set.", 0, + 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory where character sets are.", (gptr*) &opt_charsets_dir, - (gptr*) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Directory where character sets are.", 0, + 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"compress", OPT_COMPRESS, "Use compression in server/client protocol.", - (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, - 0, 0, 0}, - {"host",'h', "Connect to host.", (gptr*) ¤t_host, - (gptr*) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + (gptr*)¬_used, (gptr*)¬_used, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"force", 'f', "Force execution of mysqlcheck even if mysql_upgrade " + "has already been executed for the current version of MySQL.", + (gptr*)&opt_force, (gptr*)&opt_force, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"host",'h', "Connect to host.", 0, + 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server. If password is not given" - " it's solicited on the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + " it's solicited on the tty.", (gptr*) &opt_password,(gptr*) &opt_password, + 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __WIN__ - {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, + {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port, - (gptr*) &opt_mysql_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"port", 'P', "Port number to use for connection.", 0, + 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_SMEM {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME, - "Base name of shared memory.", (gptr*) &shared_memory_base_name, - (gptr*) &shared_memory_base_name, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Base name of shared memory.", 0, + 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif {"socket", 'S', "Socket file to use for connection.", - (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"user", 'u', "User for login if not current user.", (gptr*) &user, - (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"user", 'u', "User for login if not current user.", (gptr*) &opt_user, + (gptr*) &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include - {"verbose", 'v', "Display more output about the process", - (gptr*) &opt_verbose, (gptr*) &opt_verbose, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"verbose", 'v', "Display more output about the process", + (gptr*) &opt_verbose, (gptr*) &opt_verbose, 0, + GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; -static const char *load_default_groups[]= -{ - "mysql_upgrade", 0 -}; - #include -static LIST *extra_defaults= NULL; -typedef struct _extra_default +static void free_used_memory(void) { - int id; - const char *name; - int n_len; - const char *value; - int v_len; -} extra_default_t; + /* Free memory allocated by 'load_defaults' */ + free_defaults(defaults_argv); -static inline -void set_extra_default(int id, const struct my_option *opt) + dynstr_free(&ds_args); +} + + +static void die(const char *fmt, ...) { - switch (id) { - case 'b': case 'd': /* these are ours */ - case 'f': /* --force is ours */ - case 'u': /* --user passed on cmdline */ - case 'T': /* --debug-info is not accepted by mysqlcheck */ - case 'p': /* --password may change yet */ - /* so, do nothing */ - break; - default: - { - LIST *l; - extra_default_t *d; + va_list args; + DBUG_ENTER("die"); - /* - Remove any earlier duplicates: they can - refer to invalid memory addresses (stale pointers) - */ - l= extra_defaults; - while (l) - { - LIST *n= l->next; + /* Print the error message */ + va_start(args, fmt); + if (fmt) + { + fprintf(stderr, "FATAL ERROR: "); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + fflush(stderr); + } + va_end(args); - d= l->data; - if (d->id == id) - { - extra_defaults= list_delete(extra_defaults, l); - my_free((gptr)l, MYF(0)); - my_free((gptr)d, MYF(0)); - } - l= n; - } + free_used_memory(); + my_end(MY_CHECK_ERROR); + exit(1); +} - d= (extra_default_t *)my_malloc(sizeof(extra_default_t), - MYF(MY_FAE|MY_ZEROFILL)); - d->id= id; - d->name= opt->name; - d->n_len= strlen(opt->name); - if (opt->arg_type != NO_ARG && opt->value) - switch (opt->var_type & GET_TYPE_MASK) { - case GET_BOOL: - if (*((int *)opt->value)) - { - d->value= "true"; - d->v_len= 4; - } - break; - case GET_STR: - case GET_STR_ALLOC: - d->value= *opt->value; - d->v_len= strlen(d->value); - break; - default: - my_printf_error(0, "Error: internal error at %s:%d", MYF(0), - __FILE__, __LINE__); - exit(1); - } - list_push(extra_defaults, d); + +static void verbose(const char *fmt, ...) +{ + va_list args; + + if (!opt_verbose) + return; + + /* Print the verbose message */ + va_start(args, fmt); + if (fmt) + { + vfprintf(stdout, fmt, args); + fprintf(stdout, "\n"); + fflush(stdout); + } + va_end(args); +} + + +/* + Add one option - passed to mysql_upgrade on command line + or by defaults file(my.cnf) - to a dynamic string, in + this way we pass the same arguments on to mysql and mysql_check +*/ + +static void add_one_option(DYNAMIC_STRING* ds, + const struct my_option *opt, + const char* argument) + +{ + const char* eq= NullS; + const char* arg= NullS; + if (opt->arg_type != NO_ARG) + { + eq= "="; + switch (opt->var_type & GET_TYPE_MASK) { + case GET_STR: + arg= argument; + break; + default: + die("internal error at %s: %d",__FILE__, __LINE__); } } + dynstr_append_os_quoted(ds, "--", opt->name, eq, arg, NullS); + dynstr_append(&ds_args, " "); } static my_bool -get_one_option(int optid, const struct my_option *opt __attribute__ ((unused)), +get_one_option(int optid, const struct my_option *opt, char *argument) { + my_bool add_option= TRUE; + switch (optid) { + case '?': - puts - ("MySQL utility to upgrade database to the current server version"); - puts(""); + printf("MySQL utility for upgrading database to MySQL version %s\n", + MYSQL_SERVER_VERSION); my_print_help(my_long_options); exit(0); + break; + case '#': DBUG_PUSH(argument ? argument : default_dbug_option); + add_option= FALSE; break; + case 'p': tty_password= 1; + add_option= FALSE; if (argument) { - char *start= argument; - my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR)); - opt_password= my_strdup(argument, MYF(MY_FAE)); + /* Add password to ds_args before overwriting the arg with x's */ + add_one_option(&ds_args, opt, argument); while (*argument) *argument++= 'x'; /* Destroy argument */ - if (*start) - start[1]= 0; /* Cut length of argument */ tty_password= 0; } break; -#ifdef __WIN__ - case 'W': - my_free(opt_protocol, MYF(MY_ALLOW_ZERO_PTR)); - opt_protocol= my_strdup("pipe", MYF(MY_FAE)); + + case 'b': /* --basedir */ + case 'v': /* --verbose */ + case 'd': /* --datadir */ + case 'f': /* --force */ + add_option= FALSE; break; -#endif - case OPT_MYSQL_PROTOCOL: - if (find_type(argument, &sql_protocol_typelib, 0) > 0) - { - my_free(opt_protocol, MYF(MY_ALLOW_ZERO_PTR)); - opt_protocol= my_strdup(argument, MYF(MY_FAE)); - } - else - { - fprintf(stderr, "Unknown option to protocol: %s\n", argument); - exit(1); - } - break; -#include - default:; } - set_extra_default(opt->id, opt); + + if (add_option) + { + /* + This is an option that is accpted by mysql_upgrade just so + it can be passed on to "mysql" and "mysqlcheck" + Save it in the ds_args string + */ + add_one_option(&ds_args, opt, argument); + } return 0; } -static int create_check_file(const char *path) +static int run_command(char* cmd, + DYNAMIC_STRING *ds_res) { - int ret; - File fd; - - fd= my_open(path, O_CREAT | O_WRONLY, MYF(MY_FAE | MY_WME)); - if (fd < 0) { - ret= 1; - goto error; + char buf[512]= {0}; + FILE *res_file; + int error; + + if (!(res_file= popen(cmd, "r"))) + die("popen(\"%s\", \"r\") failed", cmd); + + while (fgets(buf, sizeof(buf), res_file)) + { + DBUG_PRINT("info", ("buf: %s", buf)); + if(ds_res) + { + /* Save the output of this command in the supplied string */ + dynstr_append(ds_res, buf); + } + else + { + /* Print it directly on screen */ + fprintf(stdout, "%s", buf); + } } - ret= my_write(fd, MYSQL_SERVER_VERSION, - sizeof(MYSQL_SERVER_VERSION) - 1, - MYF(MY_WME | MY_FNABP)); - ret|= my_close(fd, MYF(MY_FAE | MY_WME)); -error: - return ret; + + error= pclose(res_file); + return WEXITSTATUS(error); } -static int create_defaults_file(const char *path, const char *forced_path) +static int run_tool(char *tool_path, DYNAMIC_STRING *ds_res, ...) { int ret; - uint cnt; - File forced_file, defaults_file; - - DYNAMIC_STRING buf; - extra_default_t *d; + const char* arg; + va_list args; + DYNAMIC_STRING ds_cmdline; - DBUG_ENTER("create_defaults_file"); - DBUG_PRINT("enter", ("path: %s, forced_path: %s", path, forced_path)); + DBUG_ENTER("run_tool"); + DBUG_PRINT("enter", ("tool_path: %s", tool_path)); - /* Delete any previous defaults file generated by mysql_upgrade */ - my_delete(path, MYF(0)); - - defaults_file= my_open(path, O_BINARY | O_CREAT | O_WRONLY | O_EXCL, - MYF(MY_FAE | MY_WME)); - if (defaults_file < 0) + if (init_dynamic_string(&ds_cmdline, IF_WIN("\"", ""), FN_REFLEN, FN_REFLEN)) + die("Out of memory"); + + dynstr_append_os_quoted(&ds_cmdline, tool_path, NullS); + dynstr_append(&ds_cmdline, " "); + + va_start(args, ds_res); + + while ((arg= va_arg(args, char *))) { - ret= 1; - goto out; + /* Options should be os quoted */ + if (strncmp(arg, "--", 2) == 0) + dynstr_append_os_quoted(&ds_cmdline, arg, NullS); + else + dynstr_append(&ds_cmdline, arg); + dynstr_append(&ds_cmdline, " "); } - if (init_dynamic_string(&buf, NULL, my_getpagesize(), FN_REFLEN)) - { - ret= 1; - goto error; - } + va_end(args); - /* Copy forced_path file into the defaults_file being generated */ - if (forced_path) - { - forced_file= my_open(forced_path, O_RDONLY, MYF(MY_FAE | MY_WME)); - if (forced_file < 0) - { - ret= 1; - goto error; - } - DBUG_PRINT("info", ("Copying from %s to %s", forced_path, path)); - do - { - cnt= my_read(forced_file, buf.str, buf.max_length, MYF(MY_WME)); - if ((cnt == MY_FILE_ERROR) - || my_write(defaults_file, buf.str, cnt, MYF(MY_FNABP | MY_WME))) - { - ret= 1; - my_close(forced_file, MYF(0)); - goto error; - } - DBUG_PRINT("info", ("%s", buf.str)); - } while (cnt == buf.max_length); - my_close(forced_file, MYF(0)); - } +#ifdef __WIN__ + dynstr_append(&ds_cmdline, "\""); +#endif - /* Write all extra_default options into the [client] section */ - dynstr_set(&buf, "\n[client]"); - if (opt_password) - { - if (dynstr_append(&buf, "\npassword=") - || dynstr_append(&buf, opt_password)) - { - ret = 1; - goto error; - } - } - DBUG_PRINT("info", ("Writing extra_defaults to file")); - while (extra_defaults) - { - int len; - - d= extra_defaults->data; - len= d->n_len + d->v_len + 1; - if (buf.length + len >= buf.max_length) /* to avoid realloc() */ - { - - if (my_write(defaults_file, buf.str, buf.length, MYF(MY_FNABP | MY_WME))) - { - ret= 1; - goto error; - } - dynstr_set(&buf, NULL); - } - if (dynstr_append_mem(&buf, "\n", 1) || - dynstr_append_mem(&buf, d->name, d->n_len) || - (d->v_len && (dynstr_append_mem(&buf, "=", 1) || - dynstr_append_mem(&buf, d->value, d->v_len)))) - { - ret= 1; - goto error; - } - DBUG_PRINT("info", ("%s", buf.str)); - my_free((gptr)d, MYF(0)); - list_pop(extra_defaults); /* pop off the head */ - } - if (my_write(defaults_file, buf.str, buf.length, MYF(MY_FNABP | MY_WME))) - { - ret= 1; - goto error; - } - /* everything's all right */ - ret= 0; -error: - dynstr_free(&buf); - - if (defaults_file >= 0) - ret|= my_close(defaults_file, MYF(MY_WME)); - - if (ret) - my_delete(path, MYF(0)); - -out: + DBUG_PRINT("info", ("Running: %s", ds_cmdline.str)); + ret= run_command(ds_cmdline.str, ds_res); + DBUG_PRINT("exit", ("ret: %d", ret)); + dynstr_free(&ds_cmdline); DBUG_RETURN(ret); } -/* Compare filenames */ -static int comp_names(struct fileinfo *a, struct fileinfo *b) +/* + Try to get the full path to this exceutable + + Return 0 if path found + +*/ + +static my_bool get_full_path_to_executable(char* path) { - return (strcmp(a->name,b->name)); + my_bool ret; + DBUG_ENTER("get_full_path_to_executable"); +#ifdef __WIN__ + ret= (GetModuleFileName(NULL, path, FN_REFLEN) == 0); +#else + /* my_readlink returns 0 if a symlink was read */ + ret= (my_readlink(path, "/proc/self/exe", MYF(0)) != 0); + /* Might also want to try with /proc/$$/exe if the above fails */ +#endif + DBUG_PRINT("exit", ("path: %s", path)); + DBUG_RETURN(ret); } -static int find_file(const char *name, const char *root, - uint flags, char *result, size_t len, ...) +/* + Look for the tool in the same directory as mysql_upgrade. + + When running in a not yet installed build the the program + will exist but it need to be invoked via it's libtool wrapper. + Check if the found tool can executed and if not look in the + directory one step higher up where the libtool wrapper normally + is found +*/ + +static void find_tool(char *tool_path, const char *tool_name) { - int ret= 1; - va_list va; - const char *subdir; - char *cp; - FILEINFO key; + char path[FN_REFLEN]; + DYNAMIC_STRING ds_tmp; + DBUG_ENTER("find_tool"); + DBUG_PRINT("enter", ("progname: %s", my_progname)); - /* Init key with name of the file to look for */ - key.name= (char*)name; + if (init_dynamic_string(&ds_tmp, "", 32, 32)) + die("Out of memory"); - DBUG_ASSERT(root != NULL); - - cp= strmake(result, root, len); - if (cp[-1] != FN_LIBCHAR) - *cp++= FN_LIBCHAR; - - va_start(va, len); - subdir= (!(flags & MY_SEARCH_SELF)) ? va_arg(va, char *) : ""; - while (subdir) + /* Initialize path with the full path to this program */ + if (get_full_path_to_executable(path)) { - MY_DIR *dir; - FILEINFO *match; - char *cp1; - - cp1= strnmov(cp, subdir, len - (cp - result) - 1); - - dir= my_dir(result, (flags & MY_ISDIR) ? MY_WANT_STAT : MYF(0)); - if (dir) - { - match= bsearch(&key, dir->dir_entry, dir->number_off_files, - sizeof(FILEINFO), (qsort_cmp)comp_names); - if (match) - { - ret= (flags & MY_ISDIR) ? !MY_S_ISDIR(match->mystat->st_mode) : 0; - if (!ret) - { - if (cp1[-1] != FN_LIBCHAR) - *cp1++= FN_LIBCHAR; - - if (!(flags & MY_PARENT)) - strnmov(cp1, name, len - (cp1 - result)); - else - *cp1= '\0'; - - my_dirend(dir); - break; - } - } - my_dirend(dir); + /* + Easy way to get full executable path failed, try + other methods + */ + if (my_progname[0] == FN_LIBCHAR) + { + /* 1. my_progname contains full path */ + strmake(path, my_progname, FN_REFLEN); + } + else if (my_progname[0] == '.') + { + /* 2. my_progname contains relative path, prepend wd */ + char buf[FN_REFLEN]; + my_getwd(buf, FN_REFLEN, MYF(0)); + my_snprintf(path, FN_REFLEN, "%s%s", buf, my_progname); + } + else + { + /* 3. Just go for it and hope tool is in path */ + path[0]= 0; } - subdir= va_arg(va, char *); } - va_end(va); - return ret; + do + { + DBUG_PRINT("enter", ("path: %s", path)); + + /* Chop off last char(since it might be a /) */ + path[max((strlen(path)-1), 0)]= 0; + + /* Chop off last dir part */ + dirname_part(path, path); + + /* Format name of the tool to search for */ + fn_format(tool_path, tool_name, + path, "", MYF(MY_REPLACE_DIR)); + + verbose("Looking for '%s' in: %s", tool_name, tool_path); + + /* Make sure the tool exists */ + if (my_access(tool_path, F_OK) != 0) + die("Can't find '%s'", tool_path); + + /* + Make sure it can be executed, otherwise try again + in higher level directory + */ + } + while(run_tool(tool_path, + &ds_tmp, /* Get output from command, discard*/ + "--help", + "2>&1", + IF_WIN("> NUL", "> /dev/null"), + NULL)); + + dynstr_free(&ds_tmp); + + DBUG_VOID_RETURN; } +/* + Run query using "mysql" +*/ + +static int run_query(const char *query, DYNAMIC_STRING *ds_res, + my_bool force) +{ + int ret; + File fd; + char query_file_path[FN_REFLEN]; + DBUG_ENTER("run_query"); + DBUG_PRINT("enter", ("query: %s", query)); + if ((fd= create_temp_file(query_file_path, NULL, + "sql", O_CREAT | O_SHARE | O_RDWR, + MYF(MY_WME))) < 0) + die("Failed to create temporary file for defaults"); + + if (my_write(fd, query, strlen(query), + MYF(MY_FNABP | MY_WME))) + die("Failed to write to '%s'", query_file_path); + + ret= run_tool(mysql_path, + ds_res, + ds_args.str, + "--database=mysql", + "--batch", /* Turns off pager etc. */ + force ? "--force": "--skip-force", + ds_res ? "--silent": "", + "<", + query_file_path, + "2>&1", + NULL); + + my_close(fd, MYF(0)); + + DBUG_RETURN(ret); +} + + +/* + Extract the value returned from result of "show variable like ..." +*/ + +static int extract_variable_from_show(DYNAMIC_STRING* ds, char* value) +{ + char *value_start, *value_end; + /* + The query returns "datadir\t\n", skip past + the tab + */ + if ((value_start= strchr(ds->str, '\t')) == NULL) + return 1; /* Unexpected result */ + value_start++; + + /* Don't copy the ending newline */ + if ((value_end= strchr(value_start, '\n')) == NULL) + return 1; /* Unexpected result */ + + strncpy(value, value_start, min(FN_REFLEN, value_end-value_start)); + return 0; +} + + +static int get_upgrade_info_file_name(char* name) +{ + DYNAMIC_STRING ds_datadir; + DBUG_ENTER("get_upgrade_info_file_name"); + + if (init_dynamic_string(&ds_datadir, NULL, 32, 32)) + die("Out of memory"); + + if (run_query("show variables like 'datadir'", + &ds_datadir, FALSE) || + extract_variable_from_show(&ds_datadir, name)) + { + dynstr_free(&ds_datadir); + DBUG_RETURN(1); /* Query failed */ + } + + dynstr_free(&ds_datadir); + + fn_format(name, "mysql_upgrade_info", name, "", MYF(0)); + DBUG_PRINT("exit", ("name: %s", name)); + DBUG_RETURN(0); +} + + +/* + Read the content of mysql_upgrade_info file and + compare the version number form file against + version number wich mysql_upgrade was compiled for + + NOTE + This is an optimization to avoid running mysql_upgrade + when it's already been performed for the particular + version of MySQL. + + In case the MySQL server can't return the upgrade info + file it's always better to report that the upgrade hasn't + been performed. + +*/ + +static int upgrade_already_done(void) +{ + FILE *in; + char upgrade_info_file[FN_REFLEN]= {0}; + char buf[sizeof(MYSQL_SERVER_VERSION)+1]; + + if (get_upgrade_info_file_name(upgrade_info_file)) + return 0; /* Could not get filename => not sure */ + + if (!(in= my_fopen(upgrade_info_file, O_RDONLY, MYF(0)))) + return 0; /* Could not open file => not sure */ + + /* + Read from file, don't care if it fails since it + will be detected by the strncmp + */ + bzero(buf, sizeof(buf)); + fgets(buf, sizeof(buf), in); + + my_fclose(in, MYF(0)); + + return (strncmp(buf, MYSQL_SERVER_VERSION, + sizeof(MYSQL_SERVER_VERSION)-1)==0); +} + + +/* + Write mysql_upgrade_info file in servers data dir indicating that + upgrade has been done for this version + + NOTE + This might very well fail but since it's just an optimization + to run mysql_upgrade only when necessary the error can be + ignored. + +*/ + +static void create_mysql_upgrade_info_file(void) +{ + FILE *out; + char upgrade_info_file[FN_REFLEN]= {0}; + + if (get_upgrade_info_file_name(upgrade_info_file)) + return; /* Could not get filename => skip */ + + if (!(out= my_fopen(upgrade_info_file, O_TRUNC | O_WRONLY, MYF(0)))) + { + fprintf(stderr, + "Could not create the upgrade info file '%s' in " + "the MySQL Servers datadir, errno: %d\n", + upgrade_info_file, errno); + return; + } + + /* Write new version to file */ + fputs(MYSQL_SERVER_VERSION, out); + my_fclose(out, MYF(0)); + + /* + Check if the upgrad_info_file was properly created/updated + It's not a fatal error -> just print a message if it fails + */ + if (!upgrade_already_done()) + fprintf(stderr, + "Could not write to the upgrade info file '%s' in " + "the MySQL Servers datadir, errno: %d\n", + upgrade_info_file, errno); + return; +} + + +/* + Check and upgrade(if neccessary) all tables + in the server using "mysqlcheck --check-upgrade .." +*/ + +static int run_mysqlcheck_upgrade(void) +{ + verbose("Running 'mysqlcheck'..."); + return run_tool(mysqlcheck_path, + NULL, /* Send output from mysqlcheck directly to screen */ + ds_args.str, + "--check-upgrade", + "--all-databases", + "--auto-repair", + NULL); +} + + +static const char *expected_errors[]= +{ + "ERROR 1060", /* Duplicate column name */ + "ERROR 1061", /* Duplicate key name */ + "ERROR 1054", /* Unknown column */ + 0 +}; + + +static my_bool is_expected_error(const char* line) +{ + const char** error= expected_errors; + while (*error) + { + /* + Check if lines starting with ERROR + are in the list of expected errors + */ + if (strncmp(line, "ERROR", 5) != 0 || + strncmp(line, *error, strlen(*error)) == 0) + return 1; /* Found expected error */ + error++; + } + return 0; +} + + +static char* get_line(char* line) +{ + while (*line && *line != '\n') + line++; + if (*line) + line++; + return line; +} + + +/* Print the current line to stderr */ +static void print_line(char* line) +{ + while (*line && *line != '\n') + { + fputc(*line, stderr); + line++; + } + fputc('\n', stderr); +} + + +/* + Update all system tables in MySQL Server to current + version using "mysql" to execute all the SQL commands + compiled into the mysql_fix_privilege_tables array +*/ + +static int run_sql_fix_privilege_tables(void) +{ + int found_real_errors= 0; + DYNAMIC_STRING ds_result; + DBUG_ENTER("run_sql_fix_privilege_tables"); + + if (init_dynamic_string(&ds_result, "", 512, 512)) + die("Out of memory"); + + verbose("Running 'mysql_fix_privilege_tables'..."); + run_query(mysql_fix_privilege_tables, + &ds_result, /* Collect result */ + TRUE); + + { + /* + Scan each line of the result for real errors + and ignore the expected one(s) like "Duplicate column name", + "Unknown column" and "Duplicate key name" since they just + indicate the system tables are already up to date + */ + char *line= ds_result.str; + do + { + if (!is_expected_error(line)) + { + /* Something unexpected failed, dump error line to screen */ + found_real_errors++; + print_line(line); + } + } while ((line= get_line(line)) && *line); + } + + dynstr_free(&ds_result); + return found_real_errors; +} + + +static const char *load_default_groups[]= +{ + "client", /* Read settings how to connect to server */ + "mysql_upgrade", /* Read special settings for mysql_upgrade*/ + 0 +}; + + int main(int argc, char **argv) { - int ret; - - char *forced_defaults_file; - char *forced_extra_defaults; - char *local_defaults_group_suffix; - - char path[FN_REFLEN], upgrade_defaults_path[FN_REFLEN]; - DYNAMIC_STRING cmdline; - MY_INIT(argv[0]); #ifdef __NETWARE__ setscreenmode(SCR_AUTOCLOSE_ON_EXIT); #endif - /* Check if we are forced to use specific defaults */ - get_defaults_options(argc, argv, - &forced_defaults_file, &forced_extra_defaults, - &local_defaults_group_suffix); - + if (init_dynamic_string(&ds_args, "", 512, 256)) + die("Out of memory"); + load_defaults("my", load_default_groups, &argc, &argv); - defaults_argv= argv; + defaults_argv= argv; /* Must be freed by 'free_defaults' */ + + if (handle_options(&argc, &argv, my_long_options, get_one_option)) + die(NULL); - /* - Must init_dynamic_string before handle_options because string is freed - at error label. - */ - if (init_dynamic_string(&cmdline, NULL, 2 * FN_REFLEN + 128, FN_REFLEN) || - handle_options(&argc, &argv, my_long_options, get_one_option)) - { - ret= 1; - goto error; - } if (tty_password) + { opt_password= get_tty_password(NullS); - - if (!basedir) - { - my_getwd(path, sizeof(path), MYF(0)); - basedir= my_strdup(path, MYF(0)); - if (find_file("errmsg.sys", basedir, MYF(0), path, sizeof(path), - "share/mysql/english", NullS) - || find_file(mysqld_name, basedir, MYF(0), path, sizeof(path), - "bin", "libexec", NullS)) - { - my_free((gptr)basedir, MYF(0)); - basedir= (char *)DEFAULT_MYSQL_HOME; - } + /* add password to defaults file */ + dynstr_append_os_quoted(&ds_args, "--password=", opt_password, NullS); + dynstr_append(&ds_args, " "); } + /* add user to defaults file */ + dynstr_append_os_quoted(&ds_args, "--user=", opt_user, NullS); + dynstr_append(&ds_args, " "); - if (!datadir) - { - if (!find_file("mysql", basedir, MYF(MY_ISDIR|MY_PARENT), - path, sizeof(path), - "data", "var", NullS)) - datadir= my_strdup(path, MYF(0)); - else - datadir= (char *)DATADIR; - } - if (find_file("user.frm", datadir, MYF(0), path, sizeof(path), - "mysql", NullS)) - { - ret= 1; - fprintf(stderr, - "Can't find data directory. Please restart with" - " --datadir=path-to-writable-data-dir"); - goto error; - } - - /* - Create the modified defaults file to be used by mysqlcheck - and mysql command line client - */ - fn_format(upgrade_defaults_path, UPGRADE_DEFAULTS_NAME, datadir, "", MYF(0)); - create_defaults_file(upgrade_defaults_path, forced_extra_defaults); + /* Find mysql */ + find_tool(mysql_path, IF_WIN("mysql.exe", "mysql")); + /* Find mysqlcheck */ + find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck")); /* Read the mysql_upgrade_info file to check if mysql_upgrade - already has been done - Maybe this could be done a little earlier? + already has been run for this installation of MySQL */ - if (!find_file(MYSQL_UPGRADE_INFO_NAME, datadir, MY_SEARCH_SELF, - path, sizeof(path), NULL, NullS) - && !opt_force) + if (!opt_force && upgrade_already_done()) { - char buf[sizeof(MYSQL_SERVER_VERSION)]; - int fd, cnt; - - fd= my_open(path, O_RDONLY, MYF(0)); - cnt= my_read(fd, buf, sizeof(buf) - 1, MYF(0)); - my_close(fd, MYF(0)); - buf[cnt]= 0; - if (!strcmp(buf, MYSQL_SERVER_VERSION)) - { - if (opt_verbose) - puts("mysql_upgrade has already been done for this version"); - goto fix_priv_tables; - } - } - - - /* Find mysqlcheck */ - if (find_file(mysqlcheck_name, basedir, MYF(0), path, sizeof(path), - "bin", EXTRA_CLIENT_PATHS, NullS)) - { - ret= 1; - fprintf(stderr, - "Can't find program '%s'\n" - "Please restart with --basedir=mysql-install-directory", - mysqlcheck_name); - goto error; - } - else - { -#ifdef __WIN__ - /* Windows requires an extra pair of quotes around the entire string. */ - dynstr_set(&cmdline, "\""); -#else - dynstr_set(&cmdline, ""); -#endif /* __WIN__ */ - dynstr_append_os_quoted(&cmdline, path, NullS); + printf("This installation of MySQL is already upgraded to %s, " + "use --force if you still need to run mysql_upgrade\n", + MYSQL_SERVER_VERSION); + die(NULL); } /* - All settings have been written to the "upgrade_defaults_path" - instruct mysqlcheck to only read options from that file + Run "mysqlcheck" and "mysql_fix_privilege_tables.sql" */ - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--defaults-file=", - upgrade_defaults_path, NullS); - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--check-upgrade", NullS); - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--all-databases", NullS); - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--auto-repair", NullS); - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--user=", user, NullS); -#ifdef __WIN__ - dynstr_append(&cmdline, "\""); -#endif /* __WIN__ */ - - /* Execute mysqlcheck */ - if (opt_verbose) - printf("Running %s\n", cmdline.str); - DBUG_PRINT("info", ("Running: %s", cmdline.str)); - ret= system(cmdline.str); - if (ret) + if (run_mysqlcheck_upgrade() || + run_sql_fix_privilege_tables()) { - fprintf(stderr, "Error executing '%s'\n", cmdline.str); - goto error; + /* + The upgrade failed to complete in some way or another, + significant error message should have been printed to the screen + */ + die("Upgrade failed" ); } + verbose("OK"); - fn_format(path, MYSQL_UPGRADE_INFO_NAME, datadir, "", MYF(0)); - ret= create_check_file(path); - if (ret) - goto error; + /* Create a file indicating upgrade has been performed */ + create_mysql_upgrade_info_file(); -fix_priv_tables: - /* Find mysql */ - if (find_file(mysql_name, basedir, MYF(0), path, sizeof(path), - "bin", EXTRA_CLIENT_PATHS, NullS)) - { - ret= 1; - fprintf(stderr, - "Could not find MySQL command-line client (mysql).\n" - "Please use --basedir to specify the directory" - " where MySQL is installed."); - goto error; - } - else - { -#ifdef __WIN__ - /* Windows requires an extra pair of quotes around the entire string. */ - dynstr_set(&cmdline, "\""); -#else - dynstr_set(&cmdline, ""); -#endif /* __WIN__ */ - dynstr_append_os_quoted(&cmdline, path, NullS); - } - - /* Find mysql_fix_privililege_tables.sql */ - if (find_file(MYSQL_FIX_PRIV_TABLES_NAME, basedir, MYF(0), - path, sizeof(path), - "support_files", "share", "share/mysql", "scripts", - NullS) - && find_file(MYSQL_FIX_PRIV_TABLES_NAME, "/usr/local/mysql", MYF(0), - path, sizeof(path), - "share/mysql", NullS)) - { - ret= 1; - fprintf(stderr, - "Could not find file " MYSQL_FIX_PRIV_TABLES_NAME "\n" - "Please use --basedir to specify the directory" - " where MySQL is installed"); - goto error; - } - - /* - All settings have been written to the "upgrade_defaults_path", - instruct mysql to only read options from that file - */ - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--defaults-file=", - upgrade_defaults_path, NullS); - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--force", NullS); - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--no-auto-rehash", NullS); - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--batch", NullS); - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--user=", user, NullS); - dynstr_append(&cmdline, " "); - dynstr_append_os_quoted(&cmdline, "--database=mysql", NullS); - dynstr_append(&cmdline, " < "); - dynstr_append_os_quoted(&cmdline, path, NullS); -#ifdef __WIN__ - dynstr_append(&cmdline, "\""); -#endif /* __WIN__ */ - - /* Execute "mysql --force < mysql_fix_privilege_tables.sql" */ - if (opt_verbose) - printf("Running %s\n", cmdline.str); - DBUG_PRINT("info", ("Running: %s", cmdline.str)); - ret= system(cmdline.str); - if (ret) - fprintf(stderr, "Error executing '%s'\n", cmdline.str); - -error: - dynstr_free(&cmdline); - - /* Delete the generated defaults file */ - my_delete(upgrade_defaults_path, MYF(0)); - - free_defaults(defaults_argv); - my_end(info_flag ? MY_CHECK_ERROR : 0); - return ret; + free_used_memory(); + my_end(MY_CHECK_ERROR); + exit(0); } diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index ccfff4d7a03..03b37f2ba3a 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -40,7 +40,7 @@ ulonglong last_values[MAX_MYSQL_VAR]; static int interval=0; static my_bool option_force=0,interrupted=0,new_line=0, opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0, - tty_password= 0, info_flag= 0; + tty_password= 0, info_flag= 0, opt_nobeep; static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations, opt_count_iterations= 0; static ulong opt_connect_timeout, opt_shutdown_timeout; @@ -54,6 +54,7 @@ static char *opt_ndb_connectstring=0; static char *shared_memory_base_name=0; #endif static uint opt_protocol=0; +static myf error_flags; /* flags to pass to my_printf_error, like ME_BELL */ /* When using extended-status relatively, ex_val_max_len is the estimated @@ -154,6 +155,8 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"no-beep", 'b', "Turn off beep on error.", (gptr*) &opt_nobeep, + (gptr*) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server. If password is not given it's asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -284,15 +287,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #endif break; case OPT_MYSQL_PROTOCOL: - { - if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0) - { - fprintf(stderr, "Unknown option to protocol: %s\n", argument); - exit(1); - } + opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, + opt->name); break; } - } if (error) { usage(); @@ -352,6 +350,8 @@ int main(int argc,char *argv[]) #endif if (default_charset) mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); + error_flags= (myf)(opt_nobeep ? 0 : ME_BELL); + if (sql_connect(&mysql, option_wait)) { unsigned int err= mysql_errno(&mysql); @@ -450,7 +450,7 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) if (!host) host= (char*) LOCAL_HOST; my_printf_error(0,"connect to server at '%s' failed\nerror: '%s'", - MYF(ME_BELL), host, mysql_error(mysql)); + error_flags, host, mysql_error(mysql)); if (mysql_errno(mysql) == CR_CONNECTION_ERROR) { fprintf(stderr, @@ -525,14 +525,14 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) char buff[FN_REFLEN+20]; if (argc < 2) { - my_printf_error(0,"Too few arguments to create",MYF(ME_BELL)); + my_printf_error(0, "Too few arguments to create", error_flags); return 1; } sprintf(buff,"create database `%.*s`",FN_REFLEN,argv[1]); if (mysql_query(mysql,buff)) { my_printf_error(0,"CREATE DATABASE failed; error: '%-.200s'", - MYF(ME_BELL), mysql_error(mysql)); + error_flags, mysql_error(mysql)); return -1; } argc--; argv++; @@ -542,7 +542,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (argc < 2) { - my_printf_error(0,"Too few arguments to drop",MYF(ME_BELL)); + my_printf_error(0, "Too few arguments to drop", error_flags); return 1; } if (drop_db(mysql,argv[1])) @@ -567,7 +567,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (mysql_shutdown(mysql, SHUTDOWN_DEFAULT)) { - my_printf_error(0,"shutdown failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "shutdown failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -588,7 +588,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_RELOAD: if (mysql_query(mysql,"flush privileges")) { - my_printf_error(0,"reload failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "reload failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -599,7 +599,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) REFRESH_READ_LOCK | REFRESH_SLAVE | REFRESH_MASTER))) { - my_printf_error(0,"refresh failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "refresh failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -607,7 +607,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_FLUSH_THREADS: if (mysql_refresh(mysql,(uint) REFRESH_THREADS)) { - my_printf_error(0,"refresh failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "refresh failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -651,7 +651,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) "show processlist")) || !(result = mysql_store_result(mysql))) { - my_printf_error(0,"process list failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "process list failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -674,7 +674,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) char *pos; if (argc < 2) { - my_printf_error(0,"Too few arguments to 'kill'",MYF(ME_BELL)); + my_printf_error(0, "Too few arguments to 'kill'", error_flags); return 1; } pos=argv[1]; @@ -682,7 +682,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_kill(mysql,(ulong) atol(pos))) { - my_printf_error(0,"kill failed on %ld; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "kill failed on %ld; error: '%s'", error_flags, atol(pos), mysql_error(mysql)); error=1; } @@ -698,7 +698,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_DEBUG: if (mysql_dump_debug_info(mysql)) { - my_printf_error(0,"debug failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "debug failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -712,7 +712,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (mysql_query(mysql,"show /*!40003 GLOBAL */ variables") || !(res=mysql_store_result(mysql))) { - my_printf_error(0,"unable to show variables; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "unable to show variables; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -734,7 +734,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (mysql_query(mysql, "show /*!50002 GLOBAL */ status") || !(res = mysql_store_result(mysql))) { - my_printf_error(0, "unable to show status; error: '%s'", MYF(ME_BELL), + my_printf_error(0, "unable to show status; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -784,7 +784,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_refresh(mysql,REFRESH_LOG)) { - my_printf_error(0,"refresh failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "refresh failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -794,7 +794,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_query(mysql,"flush hosts")) { - my_printf_error(0,"refresh failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "refresh failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -804,7 +804,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_query(mysql,"flush tables")) { - my_printf_error(0,"refresh failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "refresh failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -814,7 +814,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_query(mysql,"flush status")) { - my_printf_error(0,"refresh failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "refresh failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -831,7 +831,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (argc < 2) { - my_printf_error(0,"Too few arguments to change password",MYF(ME_BELL)); + my_printf_error(0, "Too few arguments to change password", error_flags); return 1; } if (argv[1][0]) @@ -854,7 +854,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'")) { my_printf_error(0, "Could not determine old_passwords setting from server; error: '%s'", - MYF(ME_BELL),mysql_error(mysql)); + error_flags, mysql_error(mysql)); return -1; } else @@ -865,7 +865,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) my_printf_error(0, "Could not get old_passwords setting from " "server; error: '%s'", - MYF(ME_BELL),mysql_error(mysql)); + error_flags, mysql_error(mysql)); return -1; } if (!mysql_num_rows(res)) @@ -890,7 +890,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (mysql_query(mysql,"set sql_log_off=1")) { my_printf_error(0, "Can't turn off logging; error: '%s'", - MYF(ME_BELL),mysql_error(mysql)); + error_flags, mysql_error(mysql)); return -1; } if (mysql_query(mysql,buff)) @@ -898,7 +898,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (mysql_errno(mysql)!=1290) { my_printf_error(0,"unable to change password; error: '%s'", - MYF(ME_BELL),mysql_error(mysql)); + error_flags, mysql_error(mysql)); return -1; } else @@ -912,7 +912,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) " with grant tables disabled (was started with" " --skip-grant-tables).\n" "Use: \"mysqladmin flush-privileges password '*'\"" - " instead", MYF(ME_BELL)); + " instead", error_flags); return -1; } } @@ -923,7 +923,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_START_SLAVE: if (mysql_query(mysql, "START SLAVE")) { - my_printf_error(0, "Error starting slave: %s", MYF(ME_BELL), + my_printf_error(0, "Error starting slave: %s", error_flags, mysql_error(mysql)); return -1; } @@ -933,7 +933,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_STOP_SLAVE: if (mysql_query(mysql, "STOP SLAVE")) { - my_printf_error(0, "Error stopping slave: %s", MYF(ME_BELL), + my_printf_error(0, "Error stopping slave: %s", error_flags, mysql_error(mysql)); return -1; } @@ -959,7 +959,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) else { my_printf_error(0,"mysqld doesn't answer to ping, error: '%s'", - MYF(ME_BELL),mysql_error(mysql)); + error_flags, mysql_error(mysql)); return -1; } } @@ -970,7 +970,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (argc < 2) { - my_printf_error(0,"Too few arguments to ndb-mgm",MYF(ME_BELL)); + my_printf_error(0, "Too few arguments to ndb-mgm", error_flags); return 1; } { @@ -984,7 +984,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) break; #endif default: - my_printf_error(0,"Unknown command: '%-.60s'",MYF(ME_BELL),argv[0]); + my_printf_error(0, "Unknown command: '%-.60s'", error_flags, argv[0]); return 1; } } @@ -1062,7 +1062,7 @@ static int drop_db(MYSQL *mysql, const char *db) sprintf(name_buff,"drop database `%.*s`",FN_REFLEN,db); if (mysql_query(mysql,name_buff)) { - my_printf_error(0,"DROP DATABASE %s failed;\nerror: '%s'",MYF(ME_BELL), + my_printf_error(0, "DROP DATABASE %s failed;\nerror: '%s'", error_flags, db,mysql_error(mysql)); return 1; } @@ -1287,7 +1287,7 @@ static my_bool get_pidfile(MYSQL *mysql, char *pidfile) if (mysql_query(mysql, "SHOW VARIABLES LIKE 'pid_file'")) { - my_printf_error(0,"query failed; error: '%s'",MYF(ME_BELL), + my_printf_error(0, "query failed; error: '%s'", error_flags, mysql_error(mysql)); } result = mysql_store_result(mysql); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 940fac6da38..033c55707fc 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -158,11 +158,7 @@ class Load_log_processor public: Load_log_processor() {} - ~Load_log_processor() - { - destroy(); - delete_dynamic(&file_names); - } + ~Load_log_processor() {} int init() { @@ -182,20 +178,22 @@ public: target_dir_name_len= strlen(target_dir_name); } void destroy() + { + File_name_record *ptr= (File_name_record *)file_names.buffer; + File_name_record *end= ptr + file_names.elements; + for (; ptr < end; ptr++) { - File_name_record *ptr= (File_name_record *)file_names.buffer; - File_name_record *end= ptr + file_names.elements; - for (; ptrfname) { - if (ptr->fname) - { - my_free(ptr->fname, MYF(MY_WME)); - delete ptr->event; - bzero((char *)ptr, sizeof(File_name_record)); - } + my_free(ptr->fname, MYF(MY_WME)); + delete ptr->event; + bzero((char *)ptr, sizeof(File_name_record)); } } + delete_dynamic(&file_names); + } + /* Obtain Create_file event for LOAD DATA statement by its file_id. @@ -483,19 +481,17 @@ static int write_event_header_and_base64(Log_event *ev, FILE *result_file, PRINT_EVENT_INFO *print_event_info) { + IO_CACHE *head= &print_event_info->head_cache; + IO_CACHE *body= &print_event_info->body_cache; DBUG_ENTER("write_event_header_and_base64"); - /* Write header and base64 output to cache */ - IO_CACHE result_cache; - if (open_cached_file(&result_cache, NULL, NULL, 0, MYF(MY_WME | MY_NABP))) - return 1; - ev->print_header(&result_cache, print_event_info, FALSE); - ev->print_base64(&result_cache, print_event_info, FALSE); + /* Write header and base64 output to cache */ + ev->print_header(head, print_event_info, FALSE); + ev->print_base64(body, print_event_info, FALSE); /* Read data from cache and write to result file */ - my_b_copy_to_file(&result_cache, result_file); - close_cached_file(&result_cache); - DBUG_RETURN(0); + DBUG_RETURN(copy_event_cache_to_file_and_reinit(head, result_file) || + copy_event_cache_to_file_and_reinit(body, result_file)); } @@ -948,14 +944,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), remote_opt= 1; break; case OPT_MYSQL_PROTOCOL: - { - if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0) - { - fprintf(stderr, "Unknown option to protocol: %s\n", argument); - exit(1); - } + opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, + opt->name); break; - } case OPT_START_DATETIME: start_datetime= convert_str_to_timestamp(start_datetime_str); break; @@ -1171,7 +1162,7 @@ could be out of memory"); } if (len < 8 && net->read_pos[0] == 254) break; // end of data - DBUG_PRINT("info",( "len: %lu, net->read_pos[5]: %d\n", + DBUG_PRINT("info",( "len: %lu net->read_pos[5]: %d\n", len, net->read_pos[5])); if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 , len - 1, &error_msg, @@ -1226,6 +1217,18 @@ could be out of memory"); len= 1; // fake Rotate, so don't increment old_off } } + else if (type == FORMAT_DESCRIPTION_EVENT) + { + /* + This could be an fake Format_description_log_event that server + (5.0+) automatically sends to a slave on connect, before sending + a first event at the requested position. If this is the case, + don't increment old_off. Real Format_description_log_event always + starts from BIN_LOG_HEADER_SIZE position. + */ + if (old_off != BIN_LOG_HEADER_SIZE) + len= 1; // fake event, don't increment old_off + } if ((error= process_event(print_event_info, ev, old_off))) { error= ((error < 0) ? 0 : 1); @@ -1238,16 +1241,16 @@ could be out of memory"); const char *old_fname= le->fname; uint old_len= le->fname_len; File file; - + if ((file= load_processor.prepare_new_file_for_old_format(le,fname)) < 0) { error= 1; goto err; } - + if ((error= process_event(print_event_info, ev, old_off))) { - my_close(file,MYF(MY_WME)); + my_close(file,MYF(MY_WME)); error= ((error < 0) ? 0 : 1); goto err; } @@ -1260,8 +1263,8 @@ could be out of memory"); } } /* - Let's adjust offset for remote log as for local log to produce - similar text. + Let's adjust offset for remote log as for local log to produce + similar text and to have --stop-position to work identically. */ old_off+= len-1; } @@ -1577,6 +1580,7 @@ int main(int argc, char** argv) cleanup(); free_defaults(defaults_argv); my_free_open_file_info(); + load_processor.destroy(); /* We cannot free DBUG, it is used in global destructors after exit(). */ my_end((info_flag ? MY_CHECK_ERROR : 0) | MY_DONT_FREE_DBUG); @@ -1603,10 +1607,12 @@ int main(int argc, char** argv) #include "decimal.c" #include "my_decimal.cpp" #include "log_event.cpp" +#include "log_event_old.cpp" #else #include "my_decimal.h" #include "decimal.c" #include "my_decimal.cc" #include "log_event.cc" +#include "log_event_old.cc" #endif diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 1a9d07804b4..43a938badbe 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -34,7 +34,8 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0, opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0, opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0, tty_password= 0, opt_frm= 0, info_flag= 0, - opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0; + opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0, + opt_write_binlog= 1; static uint verbose = 0, opt_mysql_port=0; static my_string opt_mysql_unix_port = 0; static char *opt_password = 0, *current_user = 0, @@ -123,6 +124,10 @@ static struct my_option my_long_options[] = {"medium-check", 'm', "Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"write-binlog", OPT_WRITE_BINLOG, + "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Enabled by default; use --skip-write-binlog when commands should not be sent to replication slaves.", + (gptr*) &opt_write_binlog, (gptr*) &opt_write_binlog, 0, GET_BOOL, NO_ARG, + 1, 0, 0, 0, 0, 0}, {"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', @@ -310,15 +315,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case 'V': print_version(); exit(0); case OPT_MYSQL_PROTOCOL: - { - if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0) - { - fprintf(stderr, "Unknown option to protocol: %s\n", argument); - exit(1); - } + opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, + opt->name); break; } - } return 0; } @@ -598,16 +598,16 @@ static int handle_request_for_tables(char *tables, uint length) if (opt_upgrade) end = strmov(end, " FOR UPGRADE"); break; case DO_REPAIR: - op = "REPAIR"; + op= (opt_write_binlog) ? "REPAIR" : "REPAIR NO_WRITE_TO_BINLOG"; if (opt_quick) end = strmov(end, " QUICK"); if (opt_extended) end = strmov(end, " EXTENDED"); if (opt_frm) end = strmov(end, " USE_FRM"); break; case DO_ANALYZE: - op = "ANALYZE"; + op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG"; break; case DO_OPTIMIZE: - op = "OPTIMIZE"; + op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG"; break; case DO_UPGRADE: return fix_object_name("TABLE", tables); diff --git a/client/mysqldump.c b/client/mysqldump.c index 5f2749eef77..d556e0136df 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -77,13 +77,13 @@ #define IGNORE_DATA 0x01 /* don't dump data for this table */ #define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */ -static char *add_load_option(char *ptr, const char *object, - const char *statement); +static void add_load_option(DYNAMIC_STRING *str, const char *option, + const char *option_value); static ulong find_set(TYPELIB *lib, const char *x, uint length, char **err_pos, uint *err_len); static char *alloc_query_str(ulong size); -static char *field_escape(char *to,const char *from,uint length); +static void field_escape(DYNAMIC_STRING* in, const char *from); static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, quick= 1, extended_insert= 1, lock_tables=1,ignore_errors=0,flush_logs=0,flush_privileges=0, @@ -109,7 +109,8 @@ static char *opt_password=0,*current_user=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0, *where=0, *order_by=0, *opt_compatible_mode_str= 0, - *err_ptr= 0; + *err_ptr= 0, + *log_error_file= NULL; static char **defaults_argv= 0; static char compatible_mode_normal_str[255]; static ulong opt_compatible_mode= 0; @@ -120,11 +121,26 @@ static my_string opt_mysql_unix_port=0; static int first_error=0; static DYNAMIC_STRING extended_row; #include -FILE *md_result_file= 0; +FILE *md_result_file= 0; +FILE *stderror_file=0; + #ifdef HAVE_SMEM static char *shared_memory_base_name=0; #endif static uint opt_protocol= 0; + +/* +Dynamic_string wrapper functions. In this file use these +wrappers, they will terminate the process if there is +an allocation failure. +*/ +static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str, + uint init_alloc, uint alloc_increment); +static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src); +static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str); +static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append, + uint length); +static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size); /* Constant for detection of default value of default_charset. If default_charset is equal to mysql_universal_client_charset, then @@ -307,6 +323,9 @@ static struct my_option my_long_options[] = 0, 0, 0, 0, 0, 0}, {"lock-tables", 'l', "Lock all tables for read.", (gptr*) &lock_tables, (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"log-error", OPT_ERROR_LOG_FILE, "Append warnings and errors to given file.", + (gptr*) &log_error_file, (gptr*) &log_error_file, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"master-data", OPT_MASTER_DATA, "This causes the binary log position and filename to be appended to the " "output. If equal to 1, will print it as a CHANGE MASTER command; if equal" @@ -436,7 +455,9 @@ static struct my_option my_long_options[] = static const char *load_default_groups[]= { "mysqldump","client",0 }; -static void safe_exit(int error); +static void maybe_exit(int error); +static void die(int error, const char* reason, ...); +static void maybe_die(int error, const char* reason, ...); static void write_header(FILE *sql_file, char *db_name); static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, const char *prefix,const char *name, @@ -495,11 +516,7 @@ static void verbose_msg(const char *fmt, ...) void check_io(FILE *file) { if (ferror(file)) - { - fprintf(stderr, "%s: Got errno %d on write\n", my_progname, errno); - ignore_errors= 0; /* We can't ignore this error */ - safe_exit(EX_EOF); - } + die(EX_EOF, "Got errno %d on write", errno); } static void print_version(void) @@ -790,14 +807,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; } case (int) OPT_MYSQL_PROTOCOL: - { - if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0) - { - fprintf(stderr, "Unknown option to protocol: %s\n", argument); - exit(1); - } - break; - } + opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, + opt->name); + break; } return 0; } @@ -818,11 +830,15 @@ static int get_options(int *argc, char ***argv) (hash_get_key) get_table_key, (hash_free_key) free_table_ent, 0)) return(EX_EOM); - /* Don't copy cluster internal log tables */ + /* Don't copy internal log tables */ if (my_hash_insert(&ignore_table, (byte*) my_strdup("mysql.apply_status", MYF(MY_WME))) || my_hash_insert(&ignore_table, - (byte*) my_strdup("mysql.schema", MYF(MY_WME)))) + (byte*) my_strdup("mysql.schema", MYF(MY_WME))) || + my_hash_insert(&ignore_table, + (byte*) my_strdup("mysql.general_log", MYF(MY_WME))) || + my_hash_insert(&ignore_table, + (byte*) my_strdup("mysql.slow_log", MYF(MY_WME)))) return(EX_EOM); if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option))) @@ -887,12 +903,74 @@ static int get_options(int *argc, char ***argv) static void DB_error(MYSQL *mysql_arg, const char *when) { DBUG_ENTER("DB_error"); - fprintf(stderr, "%s: Got error: %d: %s %s\n", my_progname, + maybe_die(EX_MYSQLERR, "Got error: %d: %s %s", mysql_errno(mysql_arg), mysql_error(mysql_arg), when); - fflush(stderr); - safe_exit(EX_MYSQLERR); DBUG_VOID_RETURN; -} /* DB_error */ +} + + + +/* + Prints out an error message and kills the process. + + SYNOPSIS + die() + error_num - process return value + fmt_reason - a format string for use by my_vsnprintf. + ... - variable arguments for above fmt_reason string + + DESCRIPTION + This call prints out the formatted error message to stderr and then + terminates the process. +*/ +static void die(int error_num, const char* fmt_reason, ...) +{ + char buffer[1000]; + va_list args; + va_start(args,fmt_reason); + my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args); + va_end(args); + + fprintf(stderr, "%s: %s\n", my_progname, buffer); + fflush(stderr); + + ignore_errors= 0; /* force the exit */ + maybe_exit(error_num); +} + + +/* + Prints out an error message and maybe kills the process. + + SYNOPSIS + maybe_die() + error_num - process return value + fmt_reason - a format string for use by my_vsnprintf. + ... - variable arguments for above fmt_reason string + + DESCRIPTION + This call prints out the formatted error message to stderr and then + terminates the process, unless the --force command line option is used. + + This call should be used for non-fatal errors (such as database + errors) that the code may still be able to continue to the next unit + of work. + +*/ +static void maybe_die(int error_num, const char* fmt_reason, ...) +{ + char buffer[1000]; + va_list args; + va_start(args,fmt_reason); + my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args); + va_end(args); + + fprintf(stderr, "%s: %s\n", my_progname, buffer); + fflush(stderr); + + maybe_exit(error_num); +} + /* @@ -917,10 +995,8 @@ static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res, if (mysql_query(mysql_con, query) || (res && !((*res)= mysql_store_result(mysql_con)))) { - fprintf(stderr, "%s: Couldn't execute '%s': %s (%d)\n", - my_progname, query, - mysql_error(mysql_con), mysql_errno(mysql_con)); - safe_exit(EX_MYSQLERR); + maybe_die(EX_MYSQLERR, "Couldn't execute '%s': %s (%d)", + query, mysql_error(mysql_con), mysql_errno(mysql_con)); return 1; } return 0; @@ -965,7 +1041,7 @@ static void free_resources() } -static void safe_exit(int error) +static void maybe_exit(int error) { if (!first_error) first_error= error; @@ -1025,10 +1101,7 @@ static int connect_to_db(char *host, char *user,char *passwd) my_snprintf(buff, sizeof(buff), "/*!40100 SET @@SQL_MODE='%s' */", compatible_mode_normal_str); if (mysql_query_with_error_report(mysql, 0, buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(1); - } /* set time_zone to UTC to allow dumping date types between servers with different time zone settings @@ -1037,10 +1110,7 @@ static int connect_to_db(char *host, char *user,char *passwd) { my_snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */"); if (mysql_query_with_error_report(mysql, 0, buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(1); - } } DBUG_RETURN(0); } /* connect_to_db */ @@ -1061,10 +1131,8 @@ static void unescape(FILE *file,char *pos,uint length) char *tmp; DBUG_ENTER("unescape"); if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME)))) - { - ignore_errors=0; /* Fatal error */ - safe_exit(EX_MYSQLERR); /* Force exit */ - } + die(EX_MYSQLERR, "Couldn't allocate memory"); + mysql_real_escape_string(&mysql_connection, tmp, pos, length); fputc('\'', file); fputs(tmp, file); @@ -1423,14 +1491,13 @@ static uint dump_events_for_db(char *db) mysql_query(mysql, "LOCK TABLES mysql.event READ"); if (mysql_query_with_error_report(mysql, &event_list_res, "show events")) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } strcpy(delimiter, ";"); if (mysql_num_rows(event_list_res) > 0) { + fprintf(sql_file, "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;\n"); + while ((event_list_row= mysql_fetch_row(event_list_res)) != NULL) { event_name= quote_name(event_list_row[1], name_buff, 0); @@ -1447,13 +1514,13 @@ static uint dump_events_for_db(char *db) if the user has EXECUTE privilege he can see event names, but not the event body! */ - if (strlen(row[2]) != 0) + if (strlen(row[3]) != 0) { if (opt_drop) fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n", event_name, delimiter); - delimit_test= create_delimiter(row[2], delimiter, sizeof(delimiter)); + delimit_test= create_delimiter(row[3], delimiter, sizeof(delimiter)); if (delimit_test == NULL) { fprintf(stderr, "%s: Warning: Can't dump event '%s'\n", event_name, my_progname); @@ -1461,12 +1528,16 @@ static uint dump_events_for_db(char *db) } fprintf(sql_file, "DELIMITER %s\n", delimiter); - fprintf(sql_file, "/*!50106 %s */ %s\n", row[2], delimiter); + fprintf(sql_file, "/*!50106 SET TIME_ZONE= '%s' */ %s\n", + row[2], delimiter); + fprintf(sql_file, "/*!50106 %s */ %s\n", row[3], delimiter); } } /* end of event printing */ + mysql_free_result(event_res); + } /* end of list of events */ fprintf(sql_file, "DELIMITER ;\n"); - mysql_free_result(event_res); + fprintf(sql_file, "/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n"); } mysql_free_result(event_list_res); @@ -1633,8 +1704,9 @@ static uint dump_routines_for_db(char *db) my_free(query_str, MYF(MY_ALLOW_ZERO_PTR)); } } /* end of routine printing */ + mysql_free_result(routine_res); + } /* end of list of routines */ - mysql_free_result(routine_res); } mysql_free_result(routine_list_res); } /* end of for i (0 .. 1) */ @@ -1695,11 +1767,10 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (!insert_pat_inited) { insert_pat_inited= 1; - if (init_dynamic_string(&insert_pat, "", 1024, 1024)) - safe_exit(EX_MYSQLERR); + init_dynamic_string_checked(&insert_pat, "", 1024, 1024); } else - dynstr_set(&insert_pat, ""); + dynstr_set_checked(&insert_pat, ""); } insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " : @@ -1731,18 +1802,13 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_snprintf(buff, sizeof(buff), "show create table %s", result_table); if (mysql_query_with_error_report(mysql, 0, buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } if (path) { if (!(sql_file= open_sql_file_for_table(table))) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } + write_header(sql_file, db); } if (!opt_xml && opt_comments) @@ -1806,7 +1872,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR)); - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } else @@ -1869,7 +1934,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (path) my_fclose(sql_file, MYF(MY_WME)); - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -1882,21 +1946,21 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (write_data) { if (opt_replace_into) - dynstr_append_mem(&insert_pat, "REPLACE ", 8); + dynstr_append_checked(&insert_pat, "REPLACE "); else - dynstr_append_mem(&insert_pat, "INSERT ", 7); - dynstr_append(&insert_pat, insert_option); - dynstr_append_mem(&insert_pat, "INTO ", 5); - dynstr_append(&insert_pat, opt_quoted_table); + dynstr_append_checked(&insert_pat, "INSERT "); + dynstr_append_checked(&insert_pat, insert_option); + dynstr_append_checked(&insert_pat, "INTO "); + dynstr_append_checked(&insert_pat, opt_quoted_table); if (complete_insert) { - dynstr_append_mem(&insert_pat, " (", 2); + dynstr_append_checked(&insert_pat, " ("); } else { - dynstr_append_mem(&insert_pat, " VALUES ", 8); + dynstr_append_checked(&insert_pat, " VALUES "); if (!extended_insert) - dynstr_append_mem(&insert_pat, "(", 1); + dynstr_append_checked(&insert_pat, "("); } } @@ -1906,10 +1970,10 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (init) { - dynstr_append_mem(&insert_pat, ", ", 2); + dynstr_append_checked(&insert_pat, ", "); } init=1; - dynstr_append(&insert_pat, + dynstr_append_checked(&insert_pat, quote_name(row[SHOW_FIELDNAME], name_buff, 0)); } } @@ -1924,10 +1988,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_snprintf(query_buff, sizeof(query_buff), "show fields from %s", result_table); if (mysql_query_with_error_report(mysql, &result, query_buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } /* Make an sql-file, if path was given iow. option -T was given */ if (!opt_no_create_info) @@ -1935,10 +1996,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (path) { if (!(sql_file= open_sql_file_for_table(table))) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } write_header(sql_file, db); } if (!opt_xml && opt_comments) @@ -1957,19 +2015,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (write_data) { if (opt_replace_into) - dynstr_append_mem(&insert_pat, "REPLACE ", 8); + dynstr_append_checked(&insert_pat, "REPLACE "); else - dynstr_append_mem(&insert_pat, "INSERT ", 7); - dynstr_append(&insert_pat, insert_option); - dynstr_append_mem(&insert_pat, "INTO ", 5); - dynstr_append(&insert_pat, result_table); - if (opt_complete_insert) - dynstr_append_mem(&insert_pat, " (", 2); + dynstr_append_checked(&insert_pat, "INSERT "); + dynstr_append_checked(&insert_pat, insert_option); + dynstr_append_checked(&insert_pat, "INTO "); + dynstr_append_checked(&insert_pat, result_table); + if (complete_insert) + dynstr_append_checked(&insert_pat, " ("); else { - dynstr_append_mem(&insert_pat, " VALUES ", 8); + dynstr_append_checked(&insert_pat, " VALUES "); if (!extended_insert) - dynstr_append_mem(&insert_pat, "(", 1); + dynstr_append_checked(&insert_pat, "("); } } @@ -1984,11 +2042,11 @@ static uint get_table_structure(char *table, char *db, char *table_type, check_io(sql_file); } if (complete_insert) - dynstr_append_mem(&insert_pat, ", ", 2); + dynstr_append_checked(&insert_pat, ", "); } init=1; - if (opt_complete_insert) - dynstr_append(&insert_pat, + if (complete_insert) + dynstr_append_checked(&insert_pat, quote_name(row[SHOW_FIELDNAME], name_buff, 0)); if (!opt_no_create_info) { @@ -2038,7 +2096,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_progname, result_table, mysql_error(mysql)); if (path) my_fclose(sql_file, MYF(MY_WME)); - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -2146,11 +2203,11 @@ continue_xml: check_io(sql_file); } } - if (opt_complete_insert) + if (complete_insert) { - dynstr_append_mem(&insert_pat, ") VALUES ", 9); + dynstr_append_checked(&insert_pat, ") VALUES "); if (!extended_insert) - dynstr_append_mem(&insert_pat, "(", 1); + dynstr_append_checked(&insert_pat, "("); } if (sql_file != md_result_file) { @@ -2197,7 +2254,6 @@ static void dump_triggers_for_table(char *table, { if (path) my_fclose(sql_file, MYF(MY_WME)); - safe_exit(EX_MYSQLERR); DBUG_VOID_RETURN; } if (mysql_num_rows(result)) @@ -2256,24 +2312,28 @@ DELIMITER ;;\n"); DBUG_VOID_RETURN; } -static char *add_load_option(char *ptr,const char *object, - const char *statement) +static void add_load_option(DYNAMIC_STRING *str, const char *option, + const char *option_value) { - if (object) + if (!option_value) { - /* Don't escape hex constants */ - if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X')) - ptr= strxmov(ptr," ",statement," ",object,NullS); - else - { - /* char constant; escape */ - ptr= strxmov(ptr," ",statement," '",NullS); - ptr= field_escape(ptr,object,(uint) strlen(object)); - *ptr++= '\''; - } + /* Null value means we don't add this option. */ + return; } - return ptr; -} /* add_load_option */ + + dynstr_append_checked(str, option); + + if (strncmp(option_value, "0x", sizeof("0x")-1) == 0) + { + /* It's a hex constant, don't escape */ + dynstr_append_checked(str, option_value); + } + else + { + /* char constant; escape */ + field_escape(str, option_value); + } +} /* @@ -2283,28 +2343,36 @@ static char *add_load_option(char *ptr,const char *object, syntax errors from the SQL parser. */ -static char *field_escape(char *to,const char *from,uint length) +static void field_escape(DYNAMIC_STRING* in, const char *from) { - const char *end; - uint end_backslashes=0; + uint end_backslashes= 0; - for (end= from+length; from != end; from++) + dynstr_append_checked(in, "'"); + + while (*from) { - *to++= *from; + dynstr_append_mem_checked(in, from, 1); + if (*from == '\\') end_backslashes^=1; /* find odd number of backslashes */ else { if (*from == '\'' && !end_backslashes) - *to++= *from; /* We want a duplicate of "'" for MySQL */ + { + /* We want a duplicate of "'" for MySQL */ + dynstr_append_checked(in, "\'"); + } end_backslashes=0; } + from++; } /* Add missing backslashes if user has specified odd number of backs.*/ if (end_backslashes) - *to++= '\\'; - return to; -} /* field_escape */ + dynstr_append_checked(in, "\\"); + + dynstr_append_checked(in, "'"); +} + static char *alloc_query_str(ulong size) @@ -2312,10 +2380,8 @@ static char *alloc_query_str(ulong size) char *query; if (!(query= (char*) my_malloc(size, MYF(MY_WME)))) - { - ignore_errors= 0; /* Fatal error */ - safe_exit(EX_MYSQLERR); /* Force exit */ - } + die(EX_MYSQLERR, "Couldn't allocate a query string."); + return query; } @@ -2335,13 +2401,14 @@ static char *alloc_query_str(ulong size) void */ + static void dump_table(char *table, char *db) { char ignore_flag; - char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3]; + char buf[200], table_buff[NAME_LEN+3]; + DYNAMIC_STRING query_string; char table_type[NAME_LEN]; char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table; - char *query= query_buf; int error= 0; ulong rownr, row_break, total_length, init_length; uint num_fields; @@ -2395,44 +2462,69 @@ static void dump_table(char *table, char *db) opt_quoted_table= quote_name(table, table_buff2, 0); verbose_msg("-- Sending SELECT query...\n"); + + init_dynamic_string_checked(&query_string, "", 1024, 1024); + if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; - convert_dirname(tmp_path,path,NullS); + + if (strlen(path) >= FN_REFLEN) + { + /* + This check is made because the some the file functions below + have FN_REFLEN sized stack allocated buffers and will cause + a crash even if the input destination buffer is large enough + to hold the output. + */ + die(EX_USAGE, "Input filename or options too long: %s", path); + } + + /* + Convert the path to native os format + and resolve to the full filepath. + */ + convert_dirname(tmp_path,path,NullS); my_load_path(tmp_path, tmp_path, NULL); - fn_format(filename, table, tmp_path, ".txt", 4); - my_delete(filename, MYF(0)); /* 'INTO OUTFILE' doesn't work, if - filename wasn't deleted */ + fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME)); + + /* Must delete the file that 'INTO OUTFILE' will write to */ + my_delete(filename, MYF(0)); + + /* convert to a unix path name to stick into the query */ to_unix_path(filename); - my_snprintf(query, QUERY_LENGTH, - "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '%s'", - filename); - end= strend(query); + + /* now build the query string */ + + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '"); + dynstr_append_checked(&query_string, filename); + dynstr_append_checked(&query_string, "'"); if (fields_terminated || enclosed || opt_enclosed || escaped) - end= strmov(end, " FIELDS"); - end= add_load_option(end, fields_terminated, " TERMINATED BY"); - end= add_load_option(end, enclosed, " ENCLOSED BY"); - end= add_load_option(end, opt_enclosed, " OPTIONALLY ENCLOSED BY"); - end= add_load_option(end, escaped, " ESCAPED BY"); - end= add_load_option(end, lines_terminated, " LINES TERMINATED BY"); - *end= '\0'; + dynstr_append_checked(&query_string, " FIELDS"); + + add_load_option(&query_string, " TERMINATED BY ", fields_terminated); + add_load_option(&query_string, " ENCLOSED BY ", enclosed); + add_load_option(&query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed); + add_load_option(&query_string, " ESCAPED BY ", escaped); + add_load_option(&query_string, " LINES TERMINATED BY ", lines_terminated); - my_snprintf(buff, sizeof(buff), " FROM %s", result_table); - end= strmov(end,buff); - if (where || order_by) + dynstr_append_checked(&query_string, " FROM "); + dynstr_append_checked(&query_string, result_table); + + if (where) { - query= alloc_query_str((ulong) ((end - query) + 1 + - (where ? strlen(where) + 7 : 0) + - (order_by ? strlen(order_by) + 10 : 0))); - end= strmov(query, query_buf); - - if (where) - end= strxmov(end, " WHERE ", where, NullS); - if (order_by) - end= strxmov(end, " ORDER BY ", order_by, NullS); + dynstr_append_checked(&query_string, " WHERE "); + dynstr_append_checked(&query_string, where); } - if (mysql_real_query(mysql, query, (uint) (end - query))) + + if (order_by) + { + dynstr_append_checked(&query_string, " ORDER BY "); + dynstr_append_checked(&query_string, order_by); + } + + if (mysql_real_query(mysql, query_string.str, query_string.length)) { DB_error(mysql, "when executing 'SELECT INTO OUTFILE'"); DBUG_VOID_RETURN; @@ -2446,41 +2538,38 @@ static void dump_table(char *table, char *db) result_table); check_io(md_result_file); } - my_snprintf(query, QUERY_LENGTH, - "SELECT /*!40001 SQL_NO_CACHE */ * FROM %s", - result_table); - if (where || order_by) - { - query= alloc_query_str((ulong) (strlen(query) + 1 + - (where ? strlen(where) + 7 : 0) + - (order_by ? strlen(order_by) + 10 : 0))); - end= strmov(query, query_buf); + + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM "); + dynstr_append_checked(&query_string, result_table); - if (where) + if (where) + { + if (!opt_xml && opt_comments) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file, "-- WHERE: %s\n", where); - check_io(md_result_file); - } - end= strxmov(end, " WHERE ", where, NullS); - } - if (order_by) - { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file, "-- ORDER BY: %s\n", order_by); - check_io(md_result_file); - } - end= strxmov(end, " ORDER BY ", order_by, NullS); + fprintf(md_result_file, "-- WHERE: %s\n", where); + check_io(md_result_file); } + + dynstr_append_checked(&query_string, " WHERE "); + dynstr_append_checked(&query_string, where); } + if (order_by) + { + if (!opt_xml && opt_comments) + { + fprintf(md_result_file, "-- ORDER BY: %s\n", order_by); + check_io(md_result_file); + } + dynstr_append_checked(&query_string, " ORDER BY "); + dynstr_append_checked(&query_string, order_by); + } + if (!opt_xml && !opt_compact) { fputs("\n", md_result_file); check_io(md_result_file); } - if (mysql_query_with_error_report(mysql, 0, query)) + if (mysql_query_with_error_report(mysql, 0, query_string.str)) { DB_error(mysql, "when retrieving data from server"); goto err; @@ -2554,14 +2643,9 @@ static void dump_table(char *table, char *db) ulong length= lengths[i]; if (!(field= mysql_fetch_field(res))) - { - my_snprintf(query, QUERY_LENGTH, - "%s: Not enough fields from table %s! Aborting.\n", - my_progname, result_table); - fputs(query,stderr); - error= EX_CONSCHECK; - goto err; - } + die(EX_CONSCHECK, + "Not enough fields from table %s! Aborting.\n", + result_table); /* 63 is my_charset_bin. If charsetnr is not 63, @@ -2580,9 +2664,9 @@ static void dump_table(char *table, char *db) if (extended_insert && !opt_xml) { if (i == 0) - dynstr_set(&extended_row,"("); + dynstr_set_checked(&extended_row,"("); else - dynstr_append(&extended_row,","); + dynstr_append_checked(&extended_row,","); if (row[i]) { @@ -2597,15 +2681,10 @@ static void dump_table(char *table, char *db) - In non-HEX mode we need up to 2 bytes per character, plus 2 bytes for leading and trailing '\'' characters. */ - if (dynstr_realloc(&extended_row,length * 2+2)) - { - fputs("Aborting dump (out of memory)",stderr); - error= EX_EOM; - goto err; - } + dynstr_realloc_checked(&extended_row,length * 2+2); if (opt_hex_blob && is_blob) { - dynstr_append(&extended_row, "0x"); + dynstr_append_checked(&extended_row, "0x"); extended_row.length+= mysql_hex_string(extended_row.str + extended_row.length, row[i], length); @@ -2613,13 +2692,13 @@ static void dump_table(char *table, char *db) } else { - dynstr_append(&extended_row,"'"); + dynstr_append_checked(&extended_row,"'"); extended_row.length += mysql_real_escape_string(&mysql_connection, &extended_row.str[extended_row.length], row[i],length); extended_row.str[extended_row.length]='\0'; - dynstr_append(&extended_row,"'"); + dynstr_append_checked(&extended_row,"'"); } } else @@ -2628,30 +2707,26 @@ static void dump_table(char *table, char *db) char *ptr= row[i]; if (my_isalpha(charset_info, *ptr) || (*ptr == '-' && my_isalpha(charset_info, ptr[1]))) - dynstr_append(&extended_row, "NULL"); + dynstr_append_checked(&extended_row, "NULL"); else { if (field->type == MYSQL_TYPE_DECIMAL) { /* add " signs around */ - dynstr_append(&extended_row, "'"); - dynstr_append(&extended_row, ptr); - dynstr_append(&extended_row, "'"); + dynstr_append_checked(&extended_row, "'"); + dynstr_append_checked(&extended_row, ptr); + dynstr_append_checked(&extended_row, "'"); } else - dynstr_append(&extended_row, ptr); + dynstr_append_checked(&extended_row, ptr); } } } else - dynstr_append(&extended_row,"''"); - } - else if (dynstr_append(&extended_row,"NULL")) - { - fputs("Aborting dump (out of memory)",stderr); - error= EX_EOM; - goto err; + dynstr_append_checked(&extended_row,"''"); } + else + dynstr_append_checked(&extended_row,"NULL"); } else { @@ -2737,7 +2812,7 @@ static void dump_table(char *table, char *db) if (extended_insert) { ulong row_length; - dynstr_append(&extended_row,")"); + dynstr_append_checked(&extended_row,")"); row_length= 2 + extended_row.length; if (total_length + row_length < opt_net_buffer_length) { @@ -2773,14 +2848,14 @@ static void dump_table(char *table, char *db) check_io(md_result_file); if (mysql_errno(mysql)) { - my_snprintf(query, QUERY_LENGTH, + my_snprintf(buf, sizeof(buf), "%s: Error %d: %s when dumping table %s at row: %ld\n", my_progname, mysql_errno(mysql), mysql_error(mysql), result_table, rownr); - fputs(query,stderr); + fputs(buf,stderr); error= EX_CONSCHECK; goto err; } @@ -2803,15 +2878,13 @@ static void dump_table(char *table, char *db) check_io(md_result_file); } mysql_free_result(res); - if (query != query_buf) - my_free(query, MYF(MY_ALLOW_ZERO_PTR)); + dynstr_free(&query_string); } DBUG_VOID_RETURN; err: - if (query != query_buf) - my_free(query, MYF(MY_ALLOW_ZERO_PTR)); - safe_exit(error); + dynstr_free(&query_string); + maybe_exit(error); DBUG_VOID_RETURN; } /* dump_table */ @@ -2858,25 +2931,25 @@ static int dump_tablespaces_for_tables(char *db, char **table_names, int tables) mysql_real_escape_string(mysql, name_buff, db, strlen(db)); - init_dynamic_string(&where, " AND TABLESPACE_NAME IN (" + init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN (" "SELECT DISTINCT TABLESPACE_NAME FROM" " INFORMATION_SCHEMA.PARTITIONS" " WHERE" " TABLE_SCHEMA='", 256, 1024); - dynstr_append(&where, name_buff); - dynstr_append(&where, "' AND TABLE_NAME IN ("); + dynstr_append_checked(&where, name_buff); + dynstr_append_checked(&where, "' AND TABLE_NAME IN ("); for (i=0 ; i 0 ; tables-- , table_names++) { /* the table name passed on commandline may be wrong case */ @@ -3470,16 +3545,14 @@ static int dump_selected_tables(char *db, char **table_names, int tables) /* Add found table name to lock_tables_query */ if (lock_tables) { - dynstr_append(&lock_tables_query, quote_name(*pos, table_buff, 1)); - dynstr_append(&lock_tables_query, " READ /*!32311 LOCAL */,"); + dynstr_append_checked(&lock_tables_query, quote_name(*pos, table_buff, 1)); + dynstr_append_checked(&lock_tables_query, " READ /*!32311 LOCAL */,"); } pos++; } else { - my_printf_error(0,"Couldn't find table: \"%s\"\n", MYF(0), - *table_names); - safe_exit(EX_ILLEGAL_TABLE); + maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names); /* We shall countinue here, if --force was given */ } } @@ -3731,7 +3804,7 @@ char check_if_ignore_table(const char *table_name, char *table_type) { char result= IGNORE_NONE; char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN]; - MYSQL_RES *res; + MYSQL_RES *res= NULL; MYSQL_ROW row; DBUG_ENTER("check_if_ignore_table"); @@ -3900,12 +3973,12 @@ static int replace(DYNAMIC_STRING *ds_str, const char *start= strstr(ds_str->str, search_str); if (!start) return 1; - init_dynamic_string(&ds_tmp, "", + init_dynamic_string_checked(&ds_tmp, "", ds_str->length + replace_len, 256); - dynstr_append_mem(&ds_tmp, ds_str->str, start - ds_str->str); - dynstr_append_mem(&ds_tmp, replace_str, replace_len); - dynstr_append(&ds_tmp, start + search_len); - dynstr_set(ds_str, ds_tmp.str); + dynstr_append_mem_checked(&ds_tmp, ds_str->str, start - ds_str->str); + dynstr_append_mem_checked(&ds_tmp, replace_str, replace_len); + dynstr_append_checked(&ds_tmp, start + search_len); + dynstr_set_checked(ds_str, ds_tmp.str); dynstr_free(&ds_tmp); return 0; } @@ -3951,10 +4024,7 @@ static my_bool get_view_structure(char *table, char* db) my_snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table); if (mysql_query_with_error_report(mysql, &table_res, query)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } /* Check if this is a view */ field= mysql_fetch_field_direct(table_res, 0); @@ -3968,10 +4038,8 @@ static my_bool get_view_structure(char *table, char* db) if (path) { if (!(sql_file= open_sql_file_for_table(table))) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(1); - } + write_header(sql_file, db); } @@ -4017,14 +4085,14 @@ static my_bool get_view_structure(char *table, char* db) /* Save the result of SHOW CREATE TABLE in ds_view */ row= mysql_fetch_row(table_res); lengths= mysql_fetch_lengths(table_res); - init_dynamic_string(&ds_view, row[1], lengths[1] + 1, 1024); + init_dynamic_string_checked(&ds_view, row[1], lengths[1] + 1, 1024); mysql_free_result(table_res); /* Get the result from "select ... information_schema" */ if (!(table_res= mysql_store_result(mysql)) || !(row= mysql_fetch_row(table_res))) { - safe_exit(EX_MYSQLERR); + DB_error(mysql, "when trying to save the result of SHOW CREATE TABLE in ds_view."); DBUG_RETURN(1); } @@ -4096,6 +4164,45 @@ static my_bool get_view_structure(char *table, char* db) DBUG_RETURN(0); } +/* + The following functions are wrappers for the dynamic string functions + and if they fail, the wrappers will terminate the current process. +*/ + +#define DYNAMIC_STR_ERROR_MSG "Couldn't perform DYNAMIC_STRING operation" + +static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str, + uint init_alloc, uint alloc_increment) +{ + if (init_dynamic_string(str, init_str, init_alloc, alloc_increment)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src) +{ + if (dynstr_append(dest, src)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str) +{ + if (dynstr_set(str, init_str)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append, + uint length) +{ + if (dynstr_append_mem(str, append, length)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size) +{ + if (dynstr_realloc(str, additional_size)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + int main(int argc, char **argv) { @@ -4112,6 +4219,16 @@ int main(int argc, char **argv) free_resources(0); exit(exit_code); } + + if (log_error_file) + { + if(!(stderror_file= freopen(log_error_file, "a+", stderr))) + { + free_resources(0); + exit(EX_MYSQLERR); + } + } + if (connect_to_db(current_host, current_user, opt_password)) { free_resources(0); @@ -4175,5 +4292,9 @@ err: if (!path) write_footer(md_result_file); free_resources(); + + if (stderror_file) + fclose(stderror_file); + return(first_error); } /* main */ diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 3e054fba308..c037da9c0b9 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -231,14 +231,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; #endif case OPT_MYSQL_PROTOCOL: - { - if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0) - { - fprintf(stderr, "Unknown option to protocol: %s\n", argument); - exit(1); - } + opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, + opt->name); break; - } case '#': DBUG_PUSH(argument ? argument : "d:t:o"); break; diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 1c714cc640f..0c6a6229964 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -287,14 +287,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #endif break; case OPT_MYSQL_PROTOCOL: - { - if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0) - { - fprintf(stderr, "Unknown option to protocol: %s\n", argument); - exit(1); - } + opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, + opt->name); break; - } case '#': DBUG_PUSH(argument ? argument : "d:t:o"); break; diff --git a/client/mysqlslap.c b/client/mysqlslap.c index ad2c8685ba1..0335922881a 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -62,7 +62,6 @@ TODO: Add language for better tests String length for files and those put on the command line are not setup to handle binary data. - Report results of each thread into the lock file we use. More stats Break up tests and run them on multiple hosts at once. Allow output to be fed into a database directly. @@ -71,16 +70,18 @@ TODO: #define SHOW_VERSION "0.9" -#define HUGE_STRING_LENGTH 8096 +#define HUGE_STRING_LENGTH 8196 #define RAND_STRING_SIZE 126 +/* Types */ +#define SELECT_TYPE 0 +#define UPDATE_TYPE 1 +#define INSERT_TYPE 2 +#define UPDATE_TYPE_REQUIRES_PREFIX 3 +#define CREATE_TABLE_TYPE 4 +#define SELECT_TYPE_REQUIRES_PREFIX 5 + #include "client_priv.h" -#ifdef HAVE_LIBPTHREAD -#include -#endif -#include -#include -#include #include #include #include @@ -92,9 +93,6 @@ TODO: #endif #include -#define MYSLAPLOCK "/myslaplock.lck" -#define MYSLAPLOCK_DIR "/tmp" - #ifdef __WIN__ #define srandom srand #define random rand @@ -105,10 +103,23 @@ TODO: static char *shared_memory_base_name=0; #endif +/* Global Thread counter */ +uint thread_counter; +pthread_mutex_t counter_mutex; +pthread_cond_t count_threshhold; +uint master_wakeup; +pthread_mutex_t sleeper_mutex; +pthread_cond_t sleep_threshhold; + static char **defaults_argv; +char **primary_keys; +unsigned long long primary_keys_number_of; + static char *host= NULL, *opt_password= NULL, *user= NULL, *user_supplied_query= NULL, + *user_supplied_pre_statements= NULL, + *user_supplied_post_statements= NULL, *default_engine= NULL, *opt_mysql_unix_port= NULL; @@ -116,26 +127,35 @@ const char *delimiter= "\n"; const char *create_schema_string= "mysqlslap"; -const char *lock_directory; -char lock_file_str[FN_REFLEN]; - static my_bool opt_preserve; static my_bool opt_only_print= FALSE; -static my_bool opt_slave; - static my_bool opt_compress= FALSE, tty_password= FALSE, opt_silent= FALSE, + auto_generate_sql_autoincrement= FALSE, + auto_generate_sql_guid_primary= FALSE, auto_generate_sql= FALSE; const char *auto_generate_sql_type= "mixed"; static unsigned long connect_flags= CLIENT_MULTI_RESULTS; -static int verbose, num_int_cols, num_char_cols, delimiter_length; -static int iterations; +static int verbose, delimiter_length; +const char *num_int_cols_opt; +const char *num_char_cols_opt; +/* Yes, we do set defaults here */ +static unsigned int num_int_cols= 1; +static unsigned int num_char_cols= 1; +static unsigned int num_int_cols_index= 0; +static unsigned int num_char_cols_index= 0; + +static unsigned int iterations; static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME; static ulonglong actual_queries= 0; +static ulonglong auto_actual_queries; +static ulonglong auto_generate_sql_unique_write_number; +static ulonglong auto_generate_sql_unique_query_number; +static unsigned int auto_generate_sql_secondary_indexes; static ulonglong num_of_query; static ulonglong auto_generate_sql_number; const char *concurrency_str= NULL; @@ -150,7 +170,6 @@ static uint opt_protocol= 0; static int get_options(int *argc,char ***argv); static uint opt_mysql_port= 0; -static uint opt_use_threads; static const char *load_default_groups[]= { "mysqlslap","client",0 }; @@ -159,9 +178,22 @@ typedef struct statement statement; struct statement { char *string; size_t length; + unsigned char type; + char *option; + size_t option_length; statement *next; }; +typedef struct option_string option_string; + +struct option_string { + char *string; + size_t length; + char *option; + size_t option_length; + option_string *next; +}; + typedef struct stats stats; struct stats { @@ -175,7 +207,6 @@ typedef struct thread_context thread_context; struct thread_context { statement *stmt; ulonglong limit; - bool thread; }; typedef struct conclusions conclusions; @@ -192,27 +223,36 @@ struct conclusions { unsigned long long min_rows; }; +static option_string *engine_options= NULL; +static statement *pre_statements= NULL; +static statement *post_statements= NULL; static statement *create_statements= NULL, - *engine_statements= NULL, *query_statements= NULL; /* Prototypes */ void print_conclusions(conclusions *con); void print_conclusions_csv(conclusions *con); -void generate_stats(conclusions *con, statement *eng, stats *sptr); +void generate_stats(conclusions *con, option_string *eng, stats *sptr); uint parse_comma(const char *string, uint **range); uint parse_delimiter(const char *script, statement **stmt, char delm); +uint parse_option(const char *origin, option_string **stmt, char delm); static int drop_schema(MYSQL *mysql, const char *db); uint get_random_string(char *buf); static statement *build_table_string(void); static statement *build_insert_string(void); -static statement *build_query_string(void); +static statement *build_update_string(void); +static statement * build_select_string(my_bool key); +static int generate_primary_key_list(MYSQL *mysql, option_string *engine_stmt); +static int drop_primary_key_list(void); static int create_schema(MYSQL *mysql, const char *db, statement *stmt, - statement *engine_stmt); + option_string *engine_stmt); static int run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit); -int run_task(thread_context *con); +pthread_handler_t run_task(void *p); void statement_cleanup(statement *stmt); +void option_cleanup(option_string *stmt); +void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr); +static int run_statements(MYSQL *mysql, statement *stmt); static const char ALPHANUMERICS[]= "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz"; @@ -246,13 +286,7 @@ static int gettimeofday(struct timeval *tp, void *tzp) int main(int argc, char **argv) { MYSQL mysql; - int x; - unsigned long long client_limit; - statement *eptr; - -#ifdef __WIN__ - opt_use_threads= 1; -#endif + option_string *eptr; MY_INIT(argv[0]); @@ -309,78 +343,63 @@ int main(int argc, char **argv) } } + VOID(pthread_mutex_init(&counter_mutex, NULL)); + VOID(pthread_cond_init(&count_threshhold, NULL)); + VOID(pthread_mutex_init(&sleeper_mutex, NULL)); + VOID(pthread_cond_init(&sleep_threshhold, NULL)); + /* Main iterations loop */ - eptr= engine_statements; + eptr= engine_options; do { /* For the final stage we run whatever queries we were asked to run */ uint *current; - conclusions conclusion; - for (current= concurrency; current && *current; current++) + if (verbose >= 2) + printf("Starting Concurrency Test\n"); + + if (*concurrency) { - stats *head_sptr; - stats *sptr; - - head_sptr= (stats *)my_malloc(sizeof(stats) * iterations, MYF(MY_ZEROFILL)); - - bzero(&conclusion, sizeof(conclusions)); - - if (num_of_query) - client_limit= num_of_query / *current; - else - client_limit= actual_queries; - - for (x= 0, sptr= head_sptr; x < iterations; x++, sptr++) - { - /* - We might not want to load any data, such as when we are calling - a stored_procedure that doesn't use data, or we know we already have - data in the table. - */ - if (!opt_preserve) - drop_schema(&mysql, create_schema_string); - /* First we create */ - if (create_statements) - create_schema(&mysql, create_schema_string, create_statements, eptr); - - run_scheduler(sptr, query_statements, *current, client_limit); + for (current= concurrency; current && *current; current++) + concurrency_loop(&mysql, *current, eptr); + } + else + { + uint infinite= 1; + do { + concurrency_loop(&mysql, infinite, eptr); } - - generate_stats(&conclusion, eptr, head_sptr); - - if (!opt_silent) - print_conclusions(&conclusion); - if (opt_csv_str) - print_conclusions_csv(&conclusion); - - my_free((byte *)head_sptr, MYF(0)); + while (infinite++); } if (!opt_preserve) drop_schema(&mysql, create_schema_string); + } while (eptr ? (eptr= eptr->next) : 0); + VOID(pthread_mutex_destroy(&counter_mutex)); + VOID(pthread_cond_destroy(&count_threshhold)); + VOID(pthread_mutex_destroy(&sleeper_mutex)); + VOID(pthread_cond_destroy(&sleep_threshhold)); + if (!opt_only_print) mysql_close(&mysql); /* Close & free connection */ - - /* Remove lock file */ - my_delete(lock_file_str, MYF(0)); - /* now free all the strings we created */ if (opt_password) - my_free(opt_password, MYF(0)); + my_free((gptr)opt_password, MYF(0)); - my_free((byte *)concurrency, MYF(0)); + my_free((gptr)concurrency, MYF(0)); statement_cleanup(create_statements); - statement_cleanup(engine_statements); statement_cleanup(query_statements); + statement_cleanup(pre_statements); + statement_cleanup(post_statements); + option_cleanup(engine_options); #ifdef HAVE_SMEM if (shared_memory_base_name) - my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); + my_free((gptr)shared_memory_base_name, MYF(MY_ALLOW_ZERO_PTR)); #endif free_defaults(defaults_argv); my_end(0); @@ -388,6 +407,76 @@ int main(int argc, char **argv) return 0; } +void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr) +{ + unsigned int x; + stats *head_sptr; + stats *sptr; + conclusions conclusion; + unsigned long long client_limit; + + head_sptr= (stats *)my_malloc(sizeof(stats) * iterations, + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + + bzero(&conclusion, sizeof(conclusions)); + + if (auto_actual_queries) + client_limit= auto_actual_queries; + else if (num_of_query) + client_limit= num_of_query / current; + else + client_limit= actual_queries; + + for (x= 0, sptr= head_sptr; x < iterations; x++, sptr++) + { + /* + We might not want to load any data, such as when we are calling + a stored_procedure that doesn't use data, or we know we already have + data in the table. + */ + if (!opt_preserve) + drop_schema(mysql, create_schema_string); + + /* First we create */ + if (create_statements) + create_schema(mysql, create_schema_string, create_statements, eptr); + + /* + If we generated GUID we need to build a list of them from creation that + we can later use. + */ + if (verbose >= 2) + printf("Generating primary key list\n"); + if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary) + generate_primary_key_list(mysql, eptr); + + if (pre_statements) + run_statements(mysql, pre_statements); + + run_scheduler(sptr, query_statements, current, client_limit); + + if (post_statements) + run_statements(mysql, post_statements); + + /* We are finished with this run */ + if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary) + drop_primary_key_list(); + } + + if (verbose >= 2) + printf("Generating stats\n"); + + generate_stats(&conclusion, eptr, head_sptr); + + if (!opt_silent) + print_conclusions(&conclusion); + if (opt_csv_str) + print_conclusions_csv(&conclusion); + + my_free((gptr)head_sptr, MYF(0)); + +} + static struct my_option my_long_options[] = { @@ -397,10 +486,42 @@ static struct my_option my_long_options[] = "Generate SQL where not supplied by file or command line.", (gptr*) &auto_generate_sql, (gptr*) &auto_generate_sql, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO, + "Add autoincrement to auto-generated tables.", + (gptr*) &auto_generate_sql_autoincrement, + (gptr*) &auto_generate_sql_autoincrement, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES, + "Set this number to generate a set number of queries to run.\n", + (gptr*) &auto_actual_queries, (gptr*) &auto_actual_queries, + 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY, + "Add GUID based primary keys to auto-generated tables.", + (gptr*) &auto_generate_sql_guid_primary, + (gptr*) &auto_generate_sql_guid_primary, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, - "Load types are mixed, write, or read. Default is mixed\n", + "Load types are mixed, update, write, key, or read. Default is mixed\n", (gptr*) &auto_generate_sql_type, (gptr*) &auto_generate_sql_type, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"auto-generate-sql-secondary-indexes", + OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES, + "Number of secondary indexes to add auto-generated tables.", + (gptr*) &auto_generate_sql_secondary_indexes, + (gptr*) &auto_generate_sql_secondary_indexes, 0, + GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"auto-generate-sql-unique-query-number", + OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM, + "Number of unique queries auto tests", + (gptr*) &auto_generate_sql_unique_query_number, + (gptr*) &auto_generate_sql_unique_query_number, + 0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0}, + {"auto-generate-sql-unique-write-number", + OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM, + "Number of unique queries for auto-generate-sql-write-number", + (gptr*) &auto_generate_sql_unique_write_number, + (gptr*) &auto_generate_sql_unique_write_number, + 0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0}, {"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM, "Number of rows to insert to used in read and write loads (default is 100).\n", (gptr*) &auto_generate_sql_number, (gptr*) &auto_generate_sql_number, @@ -435,17 +556,14 @@ static struct my_option my_long_options[] = REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"iterations", 'i', "Number of times too run the tests.", (gptr*) &iterations, (gptr*) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0}, - {"lock-directory", OPT_MYSQL_LOCK_DIRECTORY, "Directory to use to keep locks.", - (gptr*) &lock_directory, (gptr*) &lock_directory, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"number-char-cols", 'x', "Number of VARCHAR columns to create table with if specifying --auto-generate-sql ", - (gptr*) &num_char_cols, (gptr*) &num_char_cols, 0, GET_UINT, REQUIRED_ARG, - 1, 0, 0, 0, 0, 0}, + (gptr*) &num_char_cols_opt, (gptr*) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, {"number-int-cols", 'y', "Number of INT columns to create table with if specifying --auto-generate-sql.", - (gptr*) &num_int_cols, (gptr*) &num_int_cols, 0, GET_UINT, REQUIRED_ARG, - 1, 0, 0, 0, 0, 0}, + (gptr*) &num_int_cols_opt, (gptr*) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, {"number-of-queries", OPT_MYSQL_NUMBER_OF_QUERY, "Limit each client to this number of queries (this is not exact).", (gptr*) &num_of_query, (gptr*) &num_of_query, 0, @@ -465,6 +583,16 @@ static struct my_option my_long_options[] = {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port, (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0}, + {"post-query", OPT_SLAP_POST_QUERY, + "Query to run or file containing query to run after executing.", + (gptr*) &user_supplied_post_statements, + (gptr*) &user_supplied_post_statements, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"pre-query", OPT_SLAP_PRE_QUERY, + "Query to run or file containing query to run before executing.", + (gptr*) &user_supplied_pre_statements, + (gptr*) &user_supplied_pre_statements, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"preserve-schema", OPT_MYSQL_PRESERVE_SCHEMA, "Preserve the schema from the mysqlslap run, this happens unless " "--auto-generate-sql or --create are used.", @@ -485,17 +613,10 @@ static struct my_option my_long_options[] = {"silent", 's', "Run program in silent mode - no output.", (gptr*) &opt_silent, (gptr*) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"slave", OPT_MYSQL_SLAP_SLAVE, "Follow master locks for other slap clients", - (gptr*) &opt_slave, (gptr*) &opt_slave, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection.", (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include - {"use-threads", OPT_USE_THREADS, - "Use pthread calls instead of fork() calls (default on Windows)", - (gptr*) &opt_use_threads, (gptr*) &opt_use_threads, 0, - GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DONT_ALLOW_USER_CHANGE {"user", 'u', "User for login if not current user.", (gptr*) &user, (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -552,7 +673,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), if (argument) { char *start= argument; - my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); + my_free((gptr)opt_password, MYF(MY_ALLOW_ZERO_PTR)); opt_password= my_strdup(argument,MYF(MY_FAE)); while (*argument) *argument++= 'x'; /* Destroy argument */ if (*start) @@ -568,14 +689,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #endif break; case OPT_MYSQL_PROTOCOL: - { - if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0) - { - fprintf(stderr, "Unknown option to protocol: %s\n", argument); - exit(1); - } - break; - } + opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, + opt->name); + break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); break; @@ -614,43 +730,196 @@ get_random_string(char *buf) static statement * build_table_string(void) { - char buf[512]; - int col_count; + char buf[HUGE_STRING_LENGTH]; + unsigned int col_count; statement *ptr; DYNAMIC_STRING table_string; DBUG_ENTER("build_table_string"); - DBUG_PRINT("info", ("num int cols %d num char cols %d", + DBUG_PRINT("info", ("num int cols %u num char cols %u", num_int_cols, num_char_cols)); init_dynamic_string(&table_string, "", 1024, 1024); dynstr_append(&table_string, "CREATE TABLE `t1` ("); - for (col_count= 1; col_count <= num_int_cols; col_count++) - { - sprintf(buf, "intcol%d INT(32)", col_count); - dynstr_append(&table_string, buf); - if (col_count < num_int_cols || num_char_cols > 0) + if (auto_generate_sql_autoincrement) + { + dynstr_append(&table_string, "id serial"); + + if (num_int_cols || num_char_cols) dynstr_append(&table_string, ","); } - for (col_count= 1; col_count <= num_char_cols; col_count++) - { - sprintf(buf, "charcol%d VARCHAR(128)", col_count); - dynstr_append(&table_string, buf); - if (col_count < num_char_cols) + if (auto_generate_sql_guid_primary) + { + dynstr_append(&table_string, "id varchar(32) primary key"); + + if (num_int_cols || num_char_cols || auto_generate_sql_guid_primary) dynstr_append(&table_string, ","); } + + if (auto_generate_sql_secondary_indexes) + { + unsigned int count; + + for (count= 0; count < auto_generate_sql_secondary_indexes; count++) + { + if (count) /* Except for the first pass we add a comma */ + dynstr_append(&table_string, ","); + + if (snprintf(buf, HUGE_STRING_LENGTH, "id%d varchar(32) unique key", count) + > HUGE_STRING_LENGTH) + { + fprintf(stderr, "Memory Allocation error in create table\n"); + exit(1); + } + dynstr_append(&table_string, buf); + } + + if (num_int_cols || num_char_cols) + dynstr_append(&table_string, ","); + } + + if (num_int_cols) + for (col_count= 1; col_count <= num_int_cols; col_count++) + { + if (num_int_cols_index) + { + if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT(32), INDEX(intcol%d)", + col_count, col_count) > HUGE_STRING_LENGTH) + { + fprintf(stderr, "Memory Allocation error in create table\n"); + exit(1); + } + } + else + { + if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT(32) ", col_count) + > HUGE_STRING_LENGTH) + { + fprintf(stderr, "Memory Allocation error in create table\n"); + exit(1); + } + } + dynstr_append(&table_string, buf); + + if (col_count < num_int_cols || num_char_cols > 0) + dynstr_append(&table_string, ","); + } + + if (num_char_cols) + for (col_count= 1; col_count <= num_char_cols; col_count++) + { + if (num_char_cols_index) + { + if (snprintf(buf, HUGE_STRING_LENGTH, + "charcol%d VARCHAR(128), INDEX(charcol%d) ", + col_count, col_count) > HUGE_STRING_LENGTH) + { + fprintf(stderr, "Memory Allocation error in creating table\n"); + exit(1); + } + } + else + { + if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d VARCHAR(128)", + col_count) > HUGE_STRING_LENGTH) + { + fprintf(stderr, "Memory Allocation error in creating table\n"); + exit(1); + } + } + dynstr_append(&table_string, buf); + + if (col_count < num_char_cols) + dynstr_append(&table_string, ","); + } + dynstr_append(&table_string, ")"); - ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL)); - ptr->string = (char *)my_malloc(table_string.length+1, MYF(MY_WME)); + ptr= (statement *)my_malloc(sizeof(statement), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + ptr->string = (char *)my_malloc(table_string.length+1, + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); ptr->length= table_string.length+1; + ptr->type= CREATE_TABLE_TYPE; strmov(ptr->string, table_string.str); dynstr_free(&table_string); DBUG_RETURN(ptr); } +/* + build_update_string() + + This function builds insert statements when the user opts to not supply + an insert file or string containing insert data +*/ +static statement * +build_update_string(void) +{ + char buf[HUGE_STRING_LENGTH]; + unsigned int col_count; + statement *ptr; + DYNAMIC_STRING update_string; + DBUG_ENTER("build_update_string"); + + init_dynamic_string(&update_string, "", 1024, 1024); + + dynstr_append(&update_string, "UPDATE t1 SET "); + + if (num_int_cols) + for (col_count= 1; col_count <= num_int_cols; col_count++) + { + if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d = %ld", col_count, + random()) > HUGE_STRING_LENGTH) + { + fprintf(stderr, "Memory Allocation error in creating update\n"); + exit(1); + } + dynstr_append(&update_string, buf); + + if (col_count < num_int_cols || num_char_cols > 0) + dynstr_append_mem(&update_string, ",", 1); + } + + if (num_char_cols) + for (col_count= 1; col_count <= num_char_cols; col_count++) + { + char rand_buffer[RAND_STRING_SIZE]; + int buf_len= get_random_string(rand_buffer); + + if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d = '%.*s'", col_count, + buf_len, rand_buffer) + > HUGE_STRING_LENGTH) + { + fprintf(stderr, "Memory Allocation error in creating update\n"); + exit(1); + } + dynstr_append(&update_string, buf); + + if (col_count < num_char_cols) + dynstr_append_mem(&update_string, ",", 1); + } + + if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary) + dynstr_append(&update_string, " WHERE id = "); + + + ptr= (statement *)my_malloc(sizeof(statement), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + + ptr->string= (char *)my_malloc(update_string.length + 1, + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + ptr->length= update_string.length+1; + if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary) + ptr->type= UPDATE_TYPE_REQUIRES_PREFIX ; + else + ptr->type= UPDATE_TYPE; + strmov(ptr->string, update_string.str); + dynstr_free(&update_string); + DBUG_RETURN(ptr); +} + /* build_insert_string() @@ -661,38 +930,82 @@ build_table_string(void) static statement * build_insert_string(void) { - char buf[RAND_STRING_SIZE]; - int col_count; + char buf[HUGE_STRING_LENGTH]; + unsigned int col_count; statement *ptr; DYNAMIC_STRING insert_string; DBUG_ENTER("build_insert_string"); init_dynamic_string(&insert_string, "", 1024, 1024); - dynstr_append_mem(&insert_string, "INSERT INTO t1 VALUES (", 23); - for (col_count= 1; col_count <= num_int_cols; col_count++) - { - sprintf(buf, "%ld", random()); - dynstr_append(&insert_string, buf); + dynstr_append(&insert_string, "INSERT INTO t1 VALUES ("); - if (col_count < num_int_cols || num_char_cols > 0) - dynstr_append_mem(&insert_string, ",", 1); - } - for (col_count= 1; col_count <= num_char_cols; col_count++) + if (auto_generate_sql_autoincrement) { - int buf_len= get_random_string(buf); - dynstr_append_mem(&insert_string, "'", 1); - dynstr_append_mem(&insert_string, buf, buf_len); - dynstr_append_mem(&insert_string, "'", 1); + dynstr_append(&insert_string, "NULL"); - if (col_count < num_char_cols) - dynstr_append_mem(&insert_string, ",", 1); + if (num_int_cols || num_char_cols) + dynstr_append(&insert_string, ","); } + + if (auto_generate_sql_guid_primary) + { + dynstr_append(&insert_string, "uuid()"); + + if (num_int_cols || num_char_cols) + dynstr_append(&insert_string, ","); + } + + if (auto_generate_sql_secondary_indexes) + { + unsigned int count; + + for (count= 0; count < auto_generate_sql_secondary_indexes; count++) + { + if (count) /* Except for the first pass we add a comma */ + dynstr_append(&insert_string, ","); + + dynstr_append(&insert_string, "uuid()"); + } + + if (num_int_cols || num_char_cols) + dynstr_append(&insert_string, ","); + } + + if (num_int_cols) + for (col_count= 1; col_count <= num_int_cols; col_count++) + { + if (snprintf(buf, HUGE_STRING_LENGTH, "%ld", random()) > HUGE_STRING_LENGTH) + { + fprintf(stderr, "Memory Allocation error in creating insert\n"); + exit(1); + } + dynstr_append(&insert_string, buf); + + if (col_count < num_int_cols || num_char_cols > 0) + dynstr_append_mem(&insert_string, ",", 1); + } + + if (num_char_cols) + for (col_count= 1; col_count <= num_char_cols; col_count++) + { + int buf_len= get_random_string(buf); + dynstr_append_mem(&insert_string, "'", 1); + dynstr_append_mem(&insert_string, buf, buf_len); + dynstr_append_mem(&insert_string, "'", 1); + + if (col_count < num_char_cols) + dynstr_append_mem(&insert_string, ",", 1); + } + dynstr_append_mem(&insert_string, ")", 1); - ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL)); - ptr->string= (char *)my_malloc(insert_string.length+1, MYF(MY_WME)); + ptr= (statement *)my_malloc(sizeof(statement), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + ptr->string= (char *)my_malloc(insert_string.length + 1, + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); ptr->length= insert_string.length+1; + ptr->type= INSERT_TYPE; strmov(ptr->string, insert_string.str); dynstr_free(&insert_string); DBUG_RETURN(ptr); @@ -700,26 +1013,31 @@ build_insert_string(void) /* - build_query_string() + build_select_string() This function builds a query if the user opts to not supply a query statement or file containing a query statement */ static statement * -build_query_string(void) +build_select_string(my_bool key) { - char buf[512]; - int col_count; + char buf[HUGE_STRING_LENGTH]; + unsigned int col_count; statement *ptr; static DYNAMIC_STRING query_string; - DBUG_ENTER("build_query_string"); + DBUG_ENTER("build_select_string"); init_dynamic_string(&query_string, "", 1024, 1024); dynstr_append_mem(&query_string, "SELECT ", 7); for (col_count= 1; col_count <= num_int_cols; col_count++) { - sprintf(buf, "intcol%d", col_count); + if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d", col_count) + > HUGE_STRING_LENGTH) + { + fprintf(stderr, "Memory Allocation error in creating select\n"); + exit(1); + } dynstr_append(&query_string, buf); if (col_count < num_int_cols || num_char_cols > 0) @@ -728,17 +1046,34 @@ build_query_string(void) } for (col_count= 1; col_count <= num_char_cols; col_count++) { - sprintf(buf, "charcol%d", col_count); + if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d", col_count) + > HUGE_STRING_LENGTH) + { + fprintf(stderr, "Memory Allocation error in creating select\n"); + exit(1); + } dynstr_append(&query_string, buf); if (col_count < num_char_cols) dynstr_append_mem(&query_string, ",", 1); } - dynstr_append_mem(&query_string, " FROM t1", 8); - ptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL)); - ptr->string= (char *)my_malloc(query_string.length+1, MYF(MY_WME)); + dynstr_append(&query_string, " FROM t1"); + + if ((key) && + (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)) + dynstr_append(&query_string, " WHERE id = "); + + ptr= (statement *)my_malloc(sizeof(statement), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + ptr->string= (char *)my_malloc(query_string.length + 1, + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); ptr->length= query_string.length+1; + if ((key) && + (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)) + ptr->type= SELECT_TYPE_REQUIRES_PREFIX; + else + ptr->type= SELECT_TYPE; strmov(ptr->string, query_string.str); dynstr_free(&query_string); DBUG_RETURN(ptr); @@ -773,12 +1108,40 @@ get_options(int *argc,char ***argv) exit(1); } - parse_comma(concurrency_str ? concurrency_str : "1", &concurrency); + if (auto_generate_sql && auto_generate_sql_guid_primary && + auto_generate_sql_autoincrement) + { + fprintf(stderr, + "%s: Either auto-generate-sql-guid-primary or auto-generate-sql-add-autoincrement can be used!\n", + my_progname); + exit(1); + } - if (lock_directory) - snprintf(lock_file_str, FN_REFLEN, "%s/%s", lock_directory, MYSLAPLOCK); - else - snprintf(lock_file_str, FN_REFLEN, "%s/%s", MYSLAPLOCK_DIR, MYSLAPLOCK); + /* + We are testing to make sure that if someone specified a key search + that we actually added a key! + */ + if (auto_generate_sql && auto_generate_sql_type[0] == 'k') + if ( auto_generate_sql_autoincrement == FALSE && + auto_generate_sql_guid_primary == FALSE) + { + fprintf(stderr, + "%s: Can't perform key test without a primary key!\n", + my_progname); + exit(1); + } + + + + if (auto_generate_sql && num_of_query && auto_actual_queries) + { + fprintf(stderr, + "%s: Either auto-generate-sql-execute-number or number-of-queries can be used!\n", + my_progname); + exit(1); + } + + parse_comma(concurrency_str ? concurrency_str : "1", &concurrency); if (opt_csv_str) { @@ -803,23 +1166,76 @@ get_options(int *argc,char ***argv) if (opt_only_print) opt_silent= TRUE; + if (num_int_cols_opt) + { + option_string *str; + parse_option(num_int_cols_opt, &str, ','); + num_int_cols= atoi(str->string); + if (str->option) + num_int_cols_index= atoi(str->option); + option_cleanup(str); + } + + if (num_char_cols_opt) + { + option_string *str; + parse_option(num_char_cols_opt, &str, ','); + num_char_cols= atoi(str->string); + if (str->option) + num_char_cols_index= atoi(str->option); + else + num_char_cols_index= 0; + option_cleanup(str); + } + + if (auto_generate_sql) { unsigned long long x= 0; statement *ptr_statement; + if (verbose >= 2) + printf("Building Create Statements for Auto\n"); + create_statements= build_table_string(); + /* + Pre-populate table + */ + for (ptr_statement= create_statements, x= 0; + x < auto_generate_sql_unique_write_number; + x++, ptr_statement= ptr_statement->next) + { + ptr_statement->next= build_insert_string(); + } + + if (verbose >= 2) + printf("Building Query Statements for Auto\n"); if (auto_generate_sql_type[0] == 'r') { - for (ptr_statement= create_statements, x= 0; - x < auto_generate_sql_number; + if (verbose >= 2) + printf("Generating SELECT Statements for Auto\n"); + + query_statements= build_select_string(FALSE); + for (ptr_statement= query_statements, x= 0; + x < auto_generate_sql_unique_query_number; x++, ptr_statement= ptr_statement->next) { - ptr_statement->next= build_insert_string(); + ptr_statement->next= build_select_string(FALSE); } + } + else if (auto_generate_sql_type[0] == 'k') + { + if (verbose >= 2) + printf("Generating SELECT for keys Statements for Auto\n"); - query_statements= build_query_string(); + query_statements= build_select_string(TRUE); + for (ptr_statement= query_statements, x= 0; + x < auto_generate_sql_unique_query_number; + x++, ptr_statement= ptr_statement->next) + { + ptr_statement->next= build_select_string(TRUE); + } } else if (auto_generate_sql_type[0] == 'w') { @@ -828,14 +1244,26 @@ get_options(int *argc,char ***argv) Archive (since strings which were identical one after another would be too easily optimized). */ + if (verbose >= 2) + printf("Generating INSERT Statements for Auto\n"); query_statements= build_insert_string(); for (ptr_statement= query_statements, x= 0; - x < auto_generate_sql_number; + x < auto_generate_sql_unique_query_number; x++, ptr_statement= ptr_statement->next) { ptr_statement->next= build_insert_string(); } } + else if (auto_generate_sql_type[0] == 'u') + { + query_statements= build_update_string(); + for (ptr_statement= query_statements, x= 0; + x < auto_generate_sql_unique_query_number; + x++, ptr_statement= ptr_statement->next) + { + ptr_statement->next= build_update_string(); + } + } else /* Mixed mode is default */ { int coin= 0; @@ -846,7 +1274,7 @@ get_options(int *argc,char ***argv) at the moment it results in "every other". */ for (ptr_statement= query_statements, x= 0; - x < 4; + x < auto_generate_sql_unique_query_number; x++, ptr_statement= ptr_statement->next) { if (coin) @@ -856,7 +1284,7 @@ get_options(int *argc,char ***argv) } else { - ptr_statement->next= build_query_string(); + ptr_statement->next= build_select_string(TRUE); coin= 1; } } @@ -878,12 +1306,13 @@ get_options(int *argc,char ***argv) fprintf(stderr,"%s: Could not open create file\n", my_progname); exit(1); } - tmp_string= (char *)my_malloc(sbuf.st_size+1, MYF(MY_WME)); + tmp_string= (char *)my_malloc(sbuf.st_size + 1, + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); my_read(data_file, tmp_string, sbuf.st_size, MYF(0)); tmp_string[sbuf.st_size]= '\0'; my_close(data_file,MYF(0)); parse_delimiter(tmp_string, &create_statements, delimiter[0]); - my_free(tmp_string, MYF(0)); + my_free((gptr)tmp_string, MYF(0)); } else if (create_string) { @@ -904,14 +1333,15 @@ get_options(int *argc,char ***argv) fprintf(stderr,"%s: Could not open query supplied file\n", my_progname); exit(1); } - tmp_string= (char *)my_malloc(sbuf.st_size+1, MYF(MY_WME)); + tmp_string= (char *)my_malloc(sbuf.st_size + 1, + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); my_read(data_file, tmp_string, sbuf.st_size, MYF(0)); tmp_string[sbuf.st_size]= '\0'; my_close(data_file,MYF(0)); if (user_supplied_query) actual_queries= parse_delimiter(tmp_string, &query_statements, delimiter[0]); - my_free(tmp_string, MYF(0)); + my_free((gptr)tmp_string, MYF(0)); } else if (user_supplied_query) { @@ -920,8 +1350,71 @@ get_options(int *argc,char ***argv) } } + if (user_supplied_pre_statements && my_stat(user_supplied_pre_statements, &sbuf, MYF(0))) + { + File data_file; + if (!MY_S_ISREG(sbuf.st_mode)) + { + fprintf(stderr,"%s: User query supplied file was not a regular file\n", + my_progname); + exit(1); + } + if ((data_file= my_open(user_supplied_pre_statements, O_RDWR, MYF(0))) == -1) + { + fprintf(stderr,"%s: Could not open query supplied file\n", my_progname); + exit(1); + } + tmp_string= (char *)my_malloc(sbuf.st_size + 1, + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + my_read(data_file, tmp_string, sbuf.st_size, MYF(0)); + tmp_string[sbuf.st_size]= '\0'; + my_close(data_file,MYF(0)); + if (user_supplied_pre_statements) + actual_queries= parse_delimiter(tmp_string, &pre_statements, + delimiter[0]); + my_free((gptr)tmp_string, MYF(0)); + } + else if (user_supplied_pre_statements) + { + actual_queries= parse_delimiter(user_supplied_pre_statements, &pre_statements, + delimiter[0]); + } + + if (user_supplied_post_statements && my_stat(user_supplied_post_statements, &sbuf, MYF(0))) + { + File data_file; + if (!MY_S_ISREG(sbuf.st_mode)) + { + fprintf(stderr,"%s: User query supplied file was not a regular file\n", + my_progname); + exit(1); + } + if ((data_file= my_open(user_supplied_post_statements, O_RDWR, MYF(0))) == -1) + { + fprintf(stderr,"%s: Could not open query supplied file\n", my_progname); + exit(1); + } + tmp_string= (char *)my_malloc(sbuf.st_size + 1, + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + my_read(data_file, tmp_string, sbuf.st_size, MYF(0)); + tmp_string[sbuf.st_size]= '\0'; + my_close(data_file,MYF(0)); + if (user_supplied_post_statements) + parse_delimiter(tmp_string, &post_statements, + delimiter[0]); + my_free((gptr)tmp_string, MYF(0)); + } + else if (user_supplied_post_statements) + { + parse_delimiter(user_supplied_post_statements, &post_statements, + delimiter[0]); + } + + if (verbose >= 2) + printf("Parsing engines to use.\n"); + if (default_engine) - parse_delimiter(default_engine, &engine_statements, ','); + parse_option(default_engine, &engine_options, ','); if (tty_password) opt_password= get_tty_password(NullS); @@ -937,24 +1430,99 @@ static int run_query(MYSQL *mysql, const char *query, int len) return 0; } - if (verbose >= 2) + if (verbose >= 3) printf("%.*s;\n", len, query); return mysql_real_query(mysql, query, len); } +static int +generate_primary_key_list(MYSQL *mysql, option_string *engine_stmt) +{ + MYSQL_RES *result; + MYSQL_ROW row; + unsigned long long counter; + DBUG_ENTER("generate_primary_key_list"); + + /* + Blackhole is a special case, this allows us to test the upper end + of the server during load runs. + */ + if (opt_only_print || (engine_stmt && + strstr(engine_stmt->string, "blackhole"))) + { + primary_keys_number_of= 1; + primary_keys= (char **)my_malloc((uint)(sizeof(char *) * + primary_keys_number_of), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + /* Yes, we strdup a const string to simplify the interface */ + primary_keys[0]= my_strdup("796c4422-1d94-102a-9d6d-00e0812d", MYF(0)); + } + else + { + if (run_query(mysql, "SELECT id from t1", strlen("SELECT id from t1"))) + { + fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", my_progname, + mysql_error(mysql)); + exit(1); + } + + result= mysql_store_result(mysql); + primary_keys_number_of= mysql_num_rows(result); + + /* So why check this? Blackhole :) */ + if (primary_keys_number_of) + { + /* + We create the structure and loop and create the items. + */ + primary_keys= (char **)my_malloc((uint)(sizeof(char *) * + primary_keys_number_of), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + row= mysql_fetch_row(result); + for (counter= 0; counter < primary_keys_number_of; + counter++, row= mysql_fetch_row(result)) + primary_keys[counter]= my_strdup(row[0], MYF(0)); + } + + mysql_free_result(result); + } + + DBUG_RETURN(0); +} + +static int +drop_primary_key_list(void) +{ + unsigned long long counter; + + if (primary_keys_number_of) + { + for (counter= 0; counter < primary_keys_number_of; counter++) + my_free((gptr)primary_keys[counter], MYF(0)); + + my_free((gptr)primary_keys, MYF(0)); + } + + return 0; +} static int create_schema(MYSQL *mysql, const char *db, statement *stmt, - statement *engine_stmt) + option_string *engine_stmt) { char query[HUGE_STRING_LENGTH]; statement *ptr; + statement *after_create; int len; + ulonglong count; DBUG_ENTER("create_schema"); len= snprintf(query, HUGE_STRING_LENGTH, "CREATE SCHEMA `%s`", db); + if (verbose >= 2) + printf("Loading Pre-data\n"); + if (run_query(mysql, query, len)) { fprintf(stderr,"%s: Cannot create schema %s : %s\n", my_progname, db, @@ -968,8 +1536,9 @@ create_schema(MYSQL *mysql, const char *db, statement *stmt, } else { - if (verbose >= 2) + if (verbose >= 3) printf("%s;\n", query); + if (mysql_select_db(mysql, db)) { fprintf(stderr,"%s: Cannot select schema '%s': %s\n",my_progname, db, @@ -990,14 +1559,44 @@ create_schema(MYSQL *mysql, const char *db, statement *stmt, } } - for (ptr= stmt; ptr && ptr->length; ptr= ptr->next) + count= 0; + after_create= stmt; + +limit_not_met: + for (ptr= after_create; ptr && ptr->length; ptr= ptr->next, count++) { - if (run_query(mysql, ptr->string, ptr->length)) + if (auto_generate_sql && ( auto_generate_sql_number == count)) + break; + + if (engine_stmt && engine_stmt->option && ptr->type == CREATE_TABLE_TYPE) { - fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n", - my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql)); - exit(1); + char buffer[HUGE_STRING_LENGTH]; + + snprintf(buffer, HUGE_STRING_LENGTH, "%s %s", ptr->string, + engine_stmt->option); + if (run_query(mysql, buffer, strlen(buffer))) + { + fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n", + my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql)); + exit(1); + } } + else + { + if (run_query(mysql, ptr->string, ptr->length)) + { + fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n", + my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql)); + exit(1); + } + } + } + + if (auto_generate_sql && (auto_generate_sql_number > count )) + { + /* Special case for auto create, we don't want to create tables twice */ + after_create= stmt->next; + goto limit_not_met; } DBUG_RETURN(0); @@ -1023,137 +1622,85 @@ drop_schema(MYSQL *mysql, const char *db) DBUG_RETURN(0); } +static int +run_statements(MYSQL *mysql, statement *stmt) +{ + statement *ptr; + DBUG_ENTER("run_statements"); + + for (ptr= stmt; ptr && ptr->length; ptr= ptr->next) + { + if (run_query(mysql, ptr->string, ptr->length)) + { + fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n", + my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql)); + exit(1); + } + } + + DBUG_RETURN(0); +} + static int run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit) { -#ifndef __WIN__ uint x; -#endif - File lock_file; struct timeval start_time, end_time; thread_context con; + pthread_t mainthread; /* Thread descriptor */ + pthread_attr_t attr; /* Thread attributes */ DBUG_ENTER("run_scheduler"); con.stmt= stmts; con.limit= limit; - con.thread= opt_use_threads ? 1 :0; - lock_file= my_open(lock_file_str, O_CREAT|O_WRONLY|O_TRUNC, MYF(0)); + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, + PTHREAD_CREATE_DETACHED); - if (!opt_slave) - if (my_lock(lock_file, F_WRLCK, 0, F_TO_EOF, MYF(0))) + pthread_mutex_lock(&counter_mutex); + thread_counter= 0; + + pthread_mutex_lock(&sleeper_mutex); + master_wakeup= 1; + pthread_mutex_unlock(&sleeper_mutex); + for (x= 0; x < concur; x++) + { + /* now you create the thread */ + if (pthread_create(&mainthread, &attr, run_task, + (void *)&con) != 0) { - fprintf(stderr,"%s: Could not get lockfile\n", + fprintf(stderr,"%s: Could not create thread\n", my_progname); exit(0); } - -#ifdef HAVE_LIBPTHREAD - if (opt_use_threads) - { - pthread_t mainthread; /* Thread descriptor */ - pthread_attr_t attr; /* Thread attributes */ - - for (x= 0; x < concur; x++) - { - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, - PTHREAD_CREATE_DETACHED); - - /* now create the thread */ - if (pthread_create(&mainthread, &attr, (void *)run_task, - (void *)&con) != 0) - { - fprintf(stderr,"%s: Could not create thread\n", - my_progname); - exit(0); - } - } + thread_counter++; } -#endif -#if !(defined(__WIN__) || defined(__NETWARE__)) -#ifdef HAVE_LIBPTHREAD - else -#endif - { - fflush(NULL); - for (x= 0; x < concur; x++) - { - int pid; - DBUG_PRINT("info", ("x: %d concurrency: %u", x, *concurrency)); - pid= fork(); - switch(pid) - { - case 0: - /* child */ - DBUG_PRINT("info", ("fork returned 0, calling task(\"%s\"), pid %d gid %d", - stmts ? stmts->string : "", pid, getgid())); - if (verbose >= 2) - fprintf(stderr, - "%s: fork returned 0, calling task pid %d gid %d\n", - my_progname, pid, getgid()); - run_task(&con); - exit(0); - break; - case -1: - /* error */ - DBUG_PRINT("info", - ("fork returned -1, failing pid %d gid %d", pid, getgid())); - fprintf(stderr, - "%s: Failed on fork: -1, max procs per parent exceeded.\n", - my_progname); - /*exit(1);*/ - goto WAIT; - default: - /* parent, forked */ - DBUG_PRINT("info", ("default, break: pid %d gid %d", pid, getgid())); - if (verbose >= 2) - fprintf(stderr,"%s: fork returned %d, gid %d\n", - my_progname, pid, getgid()); - break; - } - } - } -#endif + pthread_mutex_unlock(&counter_mutex); + pthread_attr_destroy(&attr); - /* Lets release use some clients! */ - if (!opt_slave) - my_lock(lock_file, F_UNLCK, 0, F_TO_EOF, MYF(0)); + pthread_mutex_lock(&sleeper_mutex); + master_wakeup= 0; + pthread_mutex_unlock(&sleeper_mutex); + pthread_cond_broadcast(&sleep_threshhold); gettimeofday(&start_time, NULL); /* - We look to grab a write lock at this point. Once we get it we know that - all clients have completed their work. + We loop until we know that all children have cleaned up. */ - if (opt_use_threads) + pthread_mutex_lock(&counter_mutex); + while (thread_counter) { - if (my_lock(lock_file, F_WRLCK, 0, F_TO_EOF, MYF(0))) - { - fprintf(stderr,"%s: Could not get lockfile\n", - my_progname); - exit(0); - } - my_lock(lock_file, F_UNLCK, 0, F_TO_EOF, MYF(0)); + struct timespec abstime; + + set_timespec(abstime, 3); + pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime); } -#ifndef __WIN__ - else - { -WAIT: - while (x--) - { - int status, pid; - pid= wait(&status); - DBUG_PRINT("info", ("Parent: child %d status %d", pid, status)); - if (status != 0) - printf("%s: Child %d died with the status %d\n", - my_progname, pid, status); - } - } -#endif + pthread_mutex_unlock(&counter_mutex); + gettimeofday(&end_time, NULL); - my_close(lock_file, MYF(0)); sptr->timing= timedif(end_time, start_time); sptr->users= concur; @@ -1163,28 +1710,41 @@ WAIT: } -int -run_task(thread_context *con) +pthread_handler_t run_task(void *p) { ulonglong counter= 0, queries; - File lock_file= -1; MYSQL *mysql; MYSQL_RES *result; MYSQL_ROW row; statement *ptr; + thread_context *con= (thread_context *)p; DBUG_ENTER("run_task"); DBUG_PRINT("info", ("task script \"%s\"", con->stmt ? con->stmt->string : "")); - if (!(mysql= mysql_init(NULL))) - goto end; + pthread_mutex_lock(&sleeper_mutex); + while (master_wakeup) + { + pthread_cond_wait(&sleep_threshhold, &sleeper_mutex); + } + pthread_mutex_unlock(&sleeper_mutex); - if (con->thread && mysql_thread_init()) - goto end; + if (!(mysql= mysql_init(NULL))) + { + fprintf(stderr,"%s: mysql_init() failed ERROR : %s\n", + my_progname, mysql_error(mysql)); + exit(0); + } + + if (mysql_thread_init()) + { + fprintf(stderr,"%s: mysql_thread_init() failed ERROR : %s\n", + my_progname, mysql_error(mysql)); + exit(0); + } DBUG_PRINT("info", ("trying to connect to host %s as user %s", host, user)); - lock_file= my_open(lock_file_str, O_RDWR, MYF(0)); - my_lock(lock_file, F_RDLCK, 0, F_TO_EOF, MYF(0)); + if (!opt_only_print) { /* Connect to server */ @@ -1213,18 +1773,59 @@ run_task(thread_context *con) } DBUG_PRINT("info", ("connected.")); if (verbose >= 3) - fprintf(stderr, "connected!\n"); + printf("connected!\n"); queries= 0; limit_not_met: for (ptr= con->stmt; ptr && ptr->length; ptr= ptr->next) { - if (run_query(mysql, ptr->string, ptr->length)) + /* + We have to execute differently based on query type. This should become a function. + */ + if ((ptr->type == UPDATE_TYPE_REQUIRES_PREFIX) || + (ptr->type == SELECT_TYPE_REQUIRES_PREFIX)) { - fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n", - my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql)); - goto end; + int length; + unsigned int key_val; + char *key; + char buffer[HUGE_STRING_LENGTH]; + + /* + This should only happen if some sort of new engine was + implemented that didn't properly handle UPDATEs. + + Just in case someone runs this under an experimental engine we don't + want a crash so the if() is placed here. + */ + DBUG_ASSERT(primary_keys_number_of); + if (primary_keys_number_of) + { + key_val= (unsigned int)(random() % primary_keys_number_of); + key= primary_keys[key_val]; + + DBUG_ASSERT(key); + + length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'", + (int)ptr->length, ptr->string, key); + + if (run_query(mysql, buffer, length)) + { + fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n", + my_progname, (uint)length, buffer, mysql_error(mysql)); + exit(0); + } + } } + else + { + if (run_query(mysql, ptr->string, ptr->length)) + { + fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n", + my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql)); + exit(0); + } + } + if (mysql_field_count(mysql)) { result= mysql_store_result(mysql); @@ -1243,20 +1844,97 @@ limit_not_met: end: - if (lock_file != -1) - { - my_lock(lock_file, F_UNLCK, 0, F_TO_EOF, MYF(0)); - my_close(lock_file, MYF(0)); - } - if (!opt_only_print) mysql_close(mysql); - if (con->thread) - my_thread_end(); + my_thread_end(); + + pthread_mutex_lock(&counter_mutex); + thread_counter--; + pthread_cond_signal(&count_threshhold); + pthread_mutex_unlock(&counter_mutex); + DBUG_RETURN(0); } +uint +parse_option(const char *origin, option_string **stmt, char delm) +{ + char *retstr; + char *ptr= (char *)origin; + option_string **sptr= stmt; + option_string *tmp; + uint length= strlen(origin); + uint count= 0; /* We know that there is always one */ + + for (tmp= *sptr= (option_string *)my_malloc(sizeof(option_string), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + (retstr= strchr(ptr, delm)); + tmp->next= (option_string *)my_malloc(sizeof(option_string), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)), + tmp= tmp->next) + { + char buffer[HUGE_STRING_LENGTH]; + char *buffer_ptr; + + count++; + strncpy(buffer, ptr, (size_t)(retstr - ptr)); + if ((buffer_ptr= strchr(buffer, ':'))) + { + char *option_ptr; + + tmp->length= (size_t)(buffer_ptr - buffer); + tmp->string= my_strndup(ptr, (uint)tmp->length, MYF(MY_FAE)); + + option_ptr= ptr + 1 + tmp->length; + + /* Move past the : and the first string */ + tmp->option_length= (size_t)(retstr - option_ptr); + tmp->option= my_strndup(option_ptr, (uint)tmp->option_length, + MYF(MY_FAE)); + } + else + { + tmp->string= my_strndup(ptr, (size_t)(retstr - ptr), MYF(MY_FAE)); + tmp->length= (size_t)(retstr - ptr); + } + + ptr+= retstr - ptr + 1; + if (isspace(*ptr)) + ptr++; + count++; + } + + if (ptr != origin+length) + { + char *origin_ptr; + + if ((origin_ptr= strchr(ptr, ':'))) + { + char *option_ptr; + + tmp->length= (size_t)(origin_ptr - ptr); + tmp->string= my_strndup(origin, tmp->length, MYF(MY_FAE)); + + option_ptr= (char *)ptr + 1 + tmp->length; + + /* Move past the : and the first string */ + tmp->option_length= (size_t)((ptr + length) - option_ptr); + tmp->option= my_strndup(option_ptr, tmp->option_length, + MYF(MY_FAE)); + } + else + { + tmp->length= (size_t)((ptr + length) - ptr); + tmp->string= my_strndup(ptr, tmp->length, MYF(MY_FAE)); + } + + count++; + } + + return count; +} + uint parse_delimiter(const char *script, statement **stmt, char delm) @@ -1268,13 +1946,15 @@ parse_delimiter(const char *script, statement **stmt, char delm) uint length= strlen(script); uint count= 0; /* We know that there is always one */ - for (tmp= *sptr= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL)); + for (tmp= *sptr= (statement *)my_malloc(sizeof(statement), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); (retstr= strchr(ptr, delm)); - tmp->next= (statement *)my_malloc(sizeof(statement), MYF(MY_ZEROFILL)), + tmp->next= (statement *)my_malloc(sizeof(statement), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)), tmp= tmp->next) { count++; - tmp->string= my_strndup(ptr, (size_t)(retstr - ptr), MYF(MY_FAE)); + tmp->string= my_strndup(ptr, (uint)(retstr - ptr), MYF(MY_FAE)); tmp->length= (size_t)(retstr - ptr); ptr+= retstr - ptr + 1; if (isspace(*ptr)) @@ -1284,7 +1964,7 @@ parse_delimiter(const char *script, statement **stmt, char delm) if (ptr != script+length) { - tmp->string= my_strndup(ptr, (size_t)((script + length) - ptr), + tmp->string= my_strndup(ptr, (uint)((script + length) - ptr), MYF(MY_FAE)); tmp->length= (size_t)((script + length) - ptr); count++; @@ -1306,7 +1986,8 @@ parse_comma(const char *string, uint **range) if (*ptr == ',') count++; /* One extra spot for the NULL */ - nptr= *range= (uint *)my_malloc(sizeof(uint) * (count + 1), MYF(MY_ZEROFILL)); + nptr= *range= (uint *)my_malloc(sizeof(uint) * (count + 1), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); ptr= (char *)string; x= 0; @@ -1341,23 +2022,25 @@ void print_conclusions_csv(conclusions *con) { char buffer[HUGE_STRING_LENGTH]; + const char *ptr= auto_generate_sql_type ? auto_generate_sql_type : "query"; snprintf(buffer, HUGE_STRING_LENGTH, - "%s,query,%ld.%03ld,%ld.%03ld,%ld.%03ld,%d,%llu\n", + "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%d,%llu\n", con->engine ? con->engine : "", /* Storage engine we ran against */ + ptr, /* Load type */ con->avg_timing / 1000, con->avg_timing % 1000, /* Time to load */ con->min_timing / 1000, con->min_timing % 1000, /* Min time */ con->max_timing / 1000, con->max_timing % 1000, /* Max time */ con->users, /* Children used */ con->avg_rows /* Queries run */ ); - my_write(csv_file, buffer, strlen(buffer), MYF(0)); + my_write(csv_file, buffer, (uint)strlen(buffer), MYF(0)); } void -generate_stats(conclusions *con, statement *eng, stats *sptr) +generate_stats(conclusions *con, option_string *eng, stats *sptr) { stats *ptr; - int x; + unsigned int x; con->min_timing= sptr->timing; con->max_timing= sptr->timing; @@ -1386,6 +2069,24 @@ generate_stats(conclusions *con, statement *eng, stats *sptr) con->engine= NULL; } +void +option_cleanup(option_string *stmt) +{ + option_string *ptr, *nptr; + if (!stmt) + return; + + for (ptr= stmt; ptr; ptr= nptr) + { + nptr= ptr->next; + if (ptr->string) + my_free((gptr)ptr->string, MYF(0)); + if (ptr->option) + my_free((gptr)ptr->option, MYF(0)); + my_free((gptr)(byte *)ptr, MYF(0)); + } +} + void statement_cleanup(statement *stmt) { @@ -1397,7 +2098,7 @@ statement_cleanup(statement *stmt) { nptr= ptr->next; if (ptr->string) - my_free(ptr->string, MYF(0)); - my_free((byte *)ptr, MYF(0)); + my_free((gptr)ptr->string, MYF(0)); + my_free((gptr)(byte *)ptr, MYF(0)); } } diff --git a/client/mysqltest.c b/client/mysqltest.c index 528e169f471..8dc70249f60 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -33,18 +33,12 @@ #define MTEST_VERSION "3.2" -#include -#include -#include -#include -#include +#include "client_priv.h" #include #include -#include #include #include #include -#include #include #include #include "my_regex.h" /* Our own version of regex */ @@ -52,14 +46,6 @@ #include #endif -#ifndef WEXITSTATUS -# ifdef __WIN__ -# define WEXITSTATUS(stat_val) (stat_val) -# else -# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -# endif -#endif - /* Use cygwin for --exec and --system before 5.0 */ #if MYSQL_VERSION_ID < 50000 #define USE_CYGWIN @@ -81,11 +67,9 @@ }; enum { - OPT_SKIP_SAFEMALLOC=256, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, - OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_PS_PROTOCOL, - OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, - OPT_SSL_VERIFY_SERVER_CERT, OPT_MAX_CONNECT_RETRIES, - OPT_MARK_PROGRESS, OPT_CHARSETS_DIR, OPT_LOG_DIR, OPT_DEBUG_INFO + OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION, + OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, + OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR }; static int record= 0, opt_sleep= -1; @@ -103,10 +87,10 @@ static my_bool sp_protocol= 0, sp_protocol_enabled= 0; static my_bool view_protocol= 0, view_protocol_enabled= 0; static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0; static my_bool parsing_disabled= 0; -static my_bool info_flag; -static my_bool display_result_vertically= FALSE, display_metadata= FALSE; +static my_bool display_result_vertically= FALSE, + display_metadata= FALSE, display_result_sorted= FALSE; static my_bool disable_query_log= 0, disable_result_log= 0; -static my_bool disable_warnings= 0, disable_ps_warnings= 0; +static my_bool disable_warnings= 0; static my_bool disable_info= 1; static my_bool abort_on_error= 1; static my_bool server_initialized= 0; @@ -266,20 +250,19 @@ enum enum_commands { Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, Q_WAIT_FOR_SLAVE_TO_STOP, Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, - Q_ENABLE_PS_WARNINGS, Q_DISABLE_PS_WARNINGS, Q_ENABLE_INFO, Q_DISABLE_INFO, Q_ENABLE_METADATA, Q_DISABLE_METADATA, Q_EXEC, Q_DELIMITER, Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR, Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS, - Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, + Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_QUERY_SORTED, Q_START_TIMER, Q_END_TIMER, Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL, Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT, Q_IF, Q_DISABLE_PARSING, Q_ENABLE_PARSING, Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, - Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, + Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES, Q_UNKNOWN, /* Unknown command. */ @@ -330,8 +313,6 @@ const char *command_names[]= "wait_for_slave_to_stop", "enable_warnings", "disable_warnings", - "enable_ps_warnings", - "disable_ps_warnings", "enable_info", "disable_info", "enable_metadata", @@ -344,6 +325,7 @@ const char *command_names[]= "horizontal_results", "query_vertical", "query_horizontal", + "query_sorted", "start_timer", "end_timer", "character_set", @@ -361,8 +343,10 @@ const char *command_names[]= "copy_file", "perl", "die", + /* Don't execute any more commands, compare result */ "exit", + "skip", "chmod", "append_file", "cat_file", @@ -415,12 +399,10 @@ struct st_command TYPELIB command_typelib= {array_elements(command_names),"", command_names, 0}; -static DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages; -static DYNAMIC_STRING global_ds_warnings, global_eval_query; +DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages; char builtin_echo[FN_REFLEN]; - void die(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2); void abort_not_supported_test(const char *fmt, ...) @@ -490,6 +472,7 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, int len); void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val); void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val); +void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input); void handle_error(struct st_command*, unsigned int err_errno, const char *err_error, @@ -797,9 +780,6 @@ void free_used_memory() dynstr_free(&ds_res); dynstr_free(&ds_progress); dynstr_free(&ds_warning_messages); - dynstr_free(&global_ds_warnings); - dynstr_free(&global_eval_query); - free_all_replace(); my_free(opt_pass,MYF(MY_ALLOW_ZERO_PTR)); free_defaults(default_argv); @@ -818,27 +798,66 @@ void free_used_memory() } +static void cleanup_and_exit(int exit_code) +{ + free_used_memory(); + my_end(MY_CHECK_ERROR); + + if (!silent) + { + switch (exit_code) + { + case 1: + printf("not ok\n"); + break; + case 0: + printf("ok\n"); + break; + case 62: + printf("skipped\n"); + break; + default: + printf("unknown exit code: %d\n", exit_code); + DBUG_ASSERT(0); + } + } + + exit(exit_code); +} + void die(const char *fmt, ...) { + static int dying= 0; va_list args; DBUG_ENTER("die"); DBUG_PRINT("enter", ("start_lineno: %d", start_lineno)); + /* + Protect against dying twice + first time 'die' is called, try to write log files + second time, just exit + */ + if (dying) + cleanup_and_exit(1); + dying= 1; + /* Print the error message */ - va_start(args, fmt); + fprintf(stderr, "mysqltest: "); + if (cur_file && cur_file != file_stack) + fprintf(stderr, "In included file \"%s\": ", + cur_file->file_name); + if (start_lineno > 0) + fprintf(stderr, "At line %u: ", start_lineno); if (fmt) { - fprintf(stderr, "mysqltest: "); - if (cur_file && cur_file != file_stack) - fprintf(stderr, "In included file \"%s\": ", - cur_file->file_name); - if (start_lineno > 0) - fprintf(stderr, "At line %u: ", start_lineno); + va_start(args, fmt); vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - fflush(stderr); + va_end(args); } - va_end(args); + else + fprintf(stderr, "unknown error"); + fprintf(stderr, "\n"); + fflush(stderr); /* Dump the result that has been accumulated so far to .log file */ if (result_file_name && ds_res.length) @@ -848,14 +867,7 @@ void die(const char *fmt, ...) if (result_file_name && ds_warning_messages.length) dump_warning_messages(); - /* Clean up and exit */ - free_used_memory(); - my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR); - - if (!silent) - printf("not ok\n"); - - exit(1); + cleanup_and_exit(1); } @@ -888,14 +900,7 @@ void abort_not_supported_test(const char *fmt, ...) } va_end(args); - /* Clean up and exit */ - free_used_memory(); - my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR); - - if (!silent) - printf("skipped\n"); - - exit(62); + cleanup_and_exit(62); } @@ -1308,23 +1313,31 @@ void var_set(const char *var_name, const char *var_name_end, DBUG_VOID_RETURN; } + +void var_set_string(const char* name, const char* value) +{ + var_set(name, name + strlen(name), value, value + strlen(value)); +} + + +void var_set_int(const char* name, int value) +{ + char buf[21]; + my_snprintf(buf, sizeof(buf), "%d", value); + var_set_string(name, buf); +} + + /* Store an integer (typically the returncode of the last SQL) - statement in the mysqltest builtin variable $mysql_errno, by - simulating of a user statement "let $mysql_errno= " + statement in the mysqltest builtin variable $mysql_errno */ void var_set_errno(int sql_errno) { - /* TODO MASV make easier */ - const char *var_name= "$mysql_errno"; - char var_val[21]; - uint length= my_sprintf(var_val, (var_val, "%d", sql_errno)); - var_set(var_name, var_name + 12, var_val, var_val + length); - return; + var_set_int("$mysql_errno", sql_errno); } - /* Set variable from the result of a query @@ -1355,6 +1368,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end) MYSQL_RES *res; MYSQL_ROW row; MYSQL* mysql = &cur_con->mysql; + DYNAMIC_STRING ds_query; DBUG_ENTER("var_query_set"); LINT_INIT(res); @@ -1364,13 +1378,17 @@ void var_query_set(VAR *var, const char *query, const char** query_end) die("Syntax error in query, missing '`'"); ++query; - if (mysql_real_query(mysql, query, (int)(end - query)) || + /* Eval the query, thus replacing all environment variables */ + init_dynamic_string(&ds_query, 0, (end - query) + 32, 256); + do_eval(&ds_query, query, end, FALSE); + + if (mysql_real_query(mysql, ds_query.str, ds_query.length) || !(res = mysql_store_result(mysql))) { - *end = 0; - die("Error running query '%s': %d %s", query, + die("Error running query '%s': %d %s", ds_query.str, mysql_errno(mysql), mysql_error(mysql)); } + dynstr_free(&ds_query); if ((row = mysql_fetch_row(res)) && row[0]) { @@ -2501,17 +2519,20 @@ wait_for_position: if (!(res= mysql_store_result(mysql))) die("mysql_store_result() returned NULL for '%s'", query_buf); if (!(row= mysql_fetch_row(res))) + { + mysql_free_result(res); die("empty result in %s", query_buf); + } if (!row[0]) { /* It may be that the slave SQL thread has not started yet, though START SLAVE has been issued ? */ + mysql_free_result(res); if (tries++ == 30) die("could not sync with master ('%s' returned NULL)", query_buf); sleep(1); /* So at most we will wait 30 seconds and make 31 tries */ - mysql_free_result(res); goto wait_for_position; } mysql_free_result(res); @@ -2552,6 +2573,7 @@ int do_save_master_pos() MYSQL *mysql = &cur_con->mysql; const char *query; int rpl_parse; + DBUG_ENTER("do_save_master_pos"); rpl_parse = mysql_rpl_parse_enabled(mysql); mysql_disable_rpl_parse(mysql); @@ -2576,7 +2598,7 @@ int do_save_master_pos() if (have_ndbcluster) { - ulonglong start_epoch= 0, applied_epoch= 0, + ulonglong start_epoch= 0, handled_epoch= 0, latest_epoch=0, latest_trans_epoch=0, latest_handled_binlog_epoch= 0, latest_received_binlog_epoch= 0, latest_applied_binlog_epoch= 0; @@ -2679,9 +2701,9 @@ int do_save_master_pos() if (!row) die("result does not contain '%s' in '%s'", binlog, query); - if (latest_applied_binlog_epoch > applied_epoch) + if (latest_handled_binlog_epoch > handled_epoch) count= 0; - applied_epoch= latest_applied_binlog_epoch; + handled_epoch= latest_handled_binlog_epoch; count++; if (latest_handled_binlog_epoch >= start_epoch) do_continue= 0; @@ -2709,7 +2731,7 @@ int do_save_master_pos() if (rpl_parse) mysql_enable_rpl_parse(mysql); - return 0; + DBUG_RETURN(0); } @@ -3164,7 +3186,7 @@ struct st_connection * find_connection_by_name(const char *name) int select_connection_name(const char *name) { - DBUG_ENTER("select_connection2"); + DBUG_ENTER("select_connection_name"); DBUG_PRINT("enter",("name: '%s'", name)); if (!(cur_con= find_connection_by_name(name))) @@ -3187,7 +3209,7 @@ int select_connection(struct st_command *command) if (*p) *p++= 0; command->last_argument= p; - return select_connection_name(name); + DBUG_RETURN(select_connection_name(name)); } @@ -3543,7 +3565,7 @@ void do_connect(struct st_command *command) opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 /* Turn on ssl_verify_server_cert only if host is "localhost" */ - opt_ssl_verify_server_cert= !strcmp(ds_connection_name.str, "localhost"); + opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost"); mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif @@ -4235,8 +4257,6 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (gptr*) &info_flag, - (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", (gptr*) &opt_host, (gptr*) &opt_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"include", 'i', "Include SQL before each test case.", (gptr*) &opt_include, @@ -4244,7 +4264,7 @@ static struct my_option my_long_options[] = {"logdir", OPT_LOG_DIR, "Directory for log files", (gptr*) &opt_logdir, (gptr*) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"mark-progress", OPT_MARK_PROGRESS, - "Write linenumber and elapsed time to .progress", + "Write linenumber and elapsed time to .progress ", (gptr*) &opt_mark_progress, (gptr*) &opt_mark_progress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"max-connect-retries", OPT_MAX_CONNECT_RETRIES, @@ -4546,17 +4566,18 @@ void dump_result_to_log_file(char *buf, int size) { char log_file[FN_REFLEN]; str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".log", - *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT: + *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT : MY_REPLACE_EXT), buf, size); } void dump_progress(void) { - char log_file[FN_REFLEN]; - str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".progress", - *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT: - MY_REPLACE_EXT), + char progress_file[FN_REFLEN]; + str_to_file(fn_format(progress_file, result_file_name, + opt_logdir, ".progress", + *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT : + MY_REPLACE_EXT), ds_progress.str, ds_progress.length); } @@ -4564,7 +4585,8 @@ void dump_warning_messages(void) { char warn_file[FN_REFLEN]; - str_to_file(fn_format(warn_file, result_file_name, "", ".warnings", + str_to_file(fn_format(warn_file, result_file_name, opt_logdir, ".warnings", + *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT : MY_REPLACE_EXT), ds_warning_messages.str, ds_warning_messages.length); } @@ -5517,7 +5539,11 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) { MYSQL *mysql= &cn->mysql; DYNAMIC_STRING *ds; + DYNAMIC_STRING *save_ds= NULL; DYNAMIC_STRING ds_result; + DYNAMIC_STRING ds_sorted; + DYNAMIC_STRING ds_warnings; + DYNAMIC_STRING eval_query; char *query; int query_len; my_bool view_created= 0, sp_created= 0; @@ -5525,7 +5551,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) (flags & QUERY_REAP_FLAG)); DBUG_ENTER("run_query"); - init_dynamic_string(&global_ds_warnings, NULL, 0, 256); + init_dynamic_string(&ds_warnings, NULL, 0, 256); /* Scan for warning before sendign to server */ scan_command_for_warnings(command); @@ -5535,10 +5561,10 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) */ if (command->type == Q_EVAL) { - init_dynamic_string(&global_eval_query, "", command->query_len+256, 1024); - do_eval(&global_eval_query, command->query, command->end, FALSE); - query = global_eval_query.str; - query_len = global_eval_query.length; + init_dynamic_string(&eval_query, "", command->query_len+256, 1024); + do_eval(&eval_query, command->query, command->end, FALSE); + query = eval_query.str; + query_len = eval_query.length; } else { @@ -5610,7 +5636,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) Collect warnings from create of the view that should otherwise have been produced when the SELECT was executed */ - append_warnings(&global_ds_warnings, cur_con->util_mysql); + append_warnings(&ds_warnings, cur_con->util_mysql); } dynstr_free(&query_str); @@ -5657,6 +5683,18 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) dynstr_free(&query_str); } + if (display_result_sorted) + { + /* + Collect the query output in a separate string + that can be sorted before it's added to the + global result string + */ + init_dynamic_string(&ds_sorted, "", 1024, 1024); + save_ds= ds; /* Remember original ds */ + ds= &ds_sorted; + } + /* Find out how to run this query @@ -5669,10 +5707,18 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) if (ps_protocol_enabled && complete_query && match_re(&ps_re, query)) - run_query_stmt(mysql, command, query, query_len, ds, &global_ds_warnings); + run_query_stmt(mysql, command, query, query_len, ds, &ds_warnings); else run_query_normal(cn, command, flags, query, query_len, - ds, &global_ds_warnings); + ds, &ds_warnings); + + if (display_result_sorted) + { + /* Sort the result set and append it to result */ + dynstr_append_sorted(save_ds, &ds_sorted); + ds= save_ds; + dynstr_free(&ds_sorted); + } if (sp_created) { @@ -5696,11 +5742,11 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) check_require(ds, command->require_file); } - dynstr_free(&global_ds_warnings); + dynstr_free(&ds_warnings); if (ds == &ds_result) dynstr_free(&ds_result); if (command->type == Q_EVAL) - dynstr_free(&global_eval_query); + dynstr_free(&eval_query); DBUG_VOID_RETURN; } @@ -5961,6 +6007,8 @@ int main(int argc, char **argv) 1024, 0, 0, get_var_key, var_free, MYF(0))) die("Variable hash initialization failed"); + var_set_string("$MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION); + memset(&master_pos, 0, sizeof(master_pos)); parser.current_line= parser.read_lines= 0; @@ -6015,15 +6063,13 @@ int main(int argc, char **argv) #ifdef HAVE_OPENSSL -#if MYSQL_VERSION_ID >= 50000 - opt_ssl_verify_server_cert= TRUE; /* Always on in mysqltest */ -#endif - if (opt_use_ssl) { mysql_ssl_set(&cur_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 + /* Turn on ssl_verify_server_cert only if host is "localhost" */ + opt_ssl_verify_server_cert= opt_host && !strcmp(opt_host, "localhost"); mysql_options(&cur_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif @@ -6088,8 +6134,6 @@ int main(int argc, char **argv) case Q_DISABLE_RESULT_LOG: disable_result_log=1; break; case Q_ENABLE_WARNINGS: disable_warnings=0; break; case Q_DISABLE_WARNINGS: disable_warnings=1; break; - case Q_ENABLE_PS_WARNINGS: disable_ps_warnings=0; break; - case Q_DISABLE_PS_WARNINGS: disable_ps_warnings=1; break; case Q_ENABLE_INFO: disable_info=0; break; case Q_DISABLE_INFO: disable_info=1; break; case Q_ENABLE_METADATA: display_metadata=1; break; @@ -6124,37 +6168,24 @@ int main(int argc, char **argv) case Q_EVAL_RESULT: eval_result = 1; break; case Q_EVAL: + case Q_QUERY_VERTICAL: + case Q_QUERY_HORIZONTAL: + case Q_QUERY_SORTED: if (command->query == command->query_buf) { + /* Skip the first part of command, i.e query_xxx */ command->query= command->first_argument; command->first_word_len= 0; } /* fall through */ - case Q_QUERY_VERTICAL: - case Q_QUERY_HORIZONTAL: - { - my_bool old_display_result_vertically= display_result_vertically; - - /* Remove "query_*" if this is first iteration */ - if (command->query == command->query_buf) - command->query= command->first_argument; - - display_result_vertically= (command->type == Q_QUERY_VERTICAL); - if (save_file[0]) - { - strmake(command->require_file, save_file, sizeof(save_file)); - save_file[0]= 0; - } - run_query(cur_con, command, QUERY_REAP_FLAG|QUERY_SEND_FLAG); - display_result_vertically= old_display_result_vertically; - command->last_argument= command->end; - command_executed++; - break; - } case Q_QUERY: case Q_REAP: { - int flags; + my_bool old_display_result_vertically= display_result_vertically; + my_bool old_display_result_sorted= display_result_sorted; + /* Default is full query, both reap and send */ + int flags= QUERY_REAP_FLAG | QUERY_SEND_FLAG; + if (q_send_flag) { /* Last command was an empty 'send' */ @@ -6165,11 +6196,10 @@ int main(int argc, char **argv) { flags= QUERY_REAP_FLAG; } - else - { - /* full query, both reap and send */ - flags= QUERY_REAP_FLAG | QUERY_SEND_FLAG; - } + + /* Check for special property for this query */ + display_result_vertically|= (command->type == Q_QUERY_VERTICAL); + display_result_sorted= (command->type == Q_QUERY_SORTED); if (save_file[0]) { @@ -6179,6 +6209,11 @@ int main(int argc, char **argv) run_query(cur_con, command, flags); command_executed++; command->last_argument= command->end; + + /* Restore settings */ + display_result_vertically= old_display_result_vertically; + display_result_sorted= old_display_result_sorted; + break; } case Q_SEND: @@ -6294,6 +6329,9 @@ int main(int argc, char **argv) /* Stop processing any more commands */ abort_flag= 1; break; + case Q_SKIP: + abort_not_supported_test("%s", command->first_argument); + break; case Q_RESULT: die("result, deprecated command"); @@ -6405,14 +6443,9 @@ int main(int argc, char **argv) dump_warning_messages(); timer_output(); - free_used_memory(); - my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR); - /* Yes, if we got this far the test has suceeded! Sakila smiles */ - if (!silent) - printf("ok\n"); - exit(0); - return 0; /* Keep compiler happy */ + cleanup_and_exit(0); + return 0; /* Keep compiler happy too */ } @@ -7066,7 +7099,7 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern, if (back_ref_num >= 0 && back_ref_num <= (int)r.re_nsub) { regoff_t start_off, end_off; - if ((start_off= subs[back_ref_num].rm_so) > -1 && + if ((start_off=subs[back_ref_num].rm_so) > -1 && (end_off=subs[back_ref_num].rm_eo) > -1) { int block_len= (int) (end_off - start_off); @@ -7791,3 +7824,73 @@ void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val) char *end= longlong10_to_str(val, buff, 10); replace_dynstr_append_mem(ds, buff, end - buff); } + + + +/* + Build a list of pointer to each line in ds_input, sort + the list and use the sorted list to append the strings + sorted to the output ds + + SYNOPSIS + dynstr_append_sorted + ds - string where the sorted output will be appended + ds_input - string to be sorted + +*/ + +static int comp_lines(const char **a, const char **b) +{ + return (strcmp(*a,*b)); +} + +void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input) +{ + unsigned i; + char *start= ds_input->str; + DYNAMIC_ARRAY lines; + DBUG_ENTER("dynstr_append_sorted"); + + if (!*start) + DBUG_VOID_RETURN; /* No input */ + + my_init_dynamic_array(&lines, sizeof(const char*), 32, 32); + + /* First line is result header, skip past it */ + while (*start && *start != '\n') + start++; + start++; /* Skip past \n */ + dynstr_append_mem(ds, ds_input->str, start - ds_input->str); + + /* Insert line(s) in array */ + while (*start) + { + char* line_end= (char*)start; + + /* Find end of line */ + while (*line_end && *line_end != '\n') + line_end++; + *line_end= 0; + + /* Insert pointer to the line in array */ + if (insert_dynamic(&lines, (gptr) &start)) + die("Out of memory inserting lines to sort"); + + start= line_end+1; + } + + /* Sort array */ + qsort(lines.buffer, lines.elements, + sizeof(char**), (qsort_cmp)comp_lines); + + /* Create new result */ + for (i= 0; i < lines.elements ; i++) + { + const char **line= dynamic_element(&lines, i, const char**); + dynstr_append(ds, *line); + dynstr_append(ds, "\n"); + } + + delete_dynamic(&lines); + DBUG_VOID_RETURN; +} diff --git a/config/ac-macros/character_sets.m4 b/config/ac-macros/character_sets.m4 index 1ab6e7dd780..8c3e8ca73b7 100644 --- a/config/ac-macros/character_sets.m4 +++ b/config/ac-macros/character_sets.m4 @@ -429,3 +429,16 @@ then else AC_MSG_RESULT(no) fi + + +# Shall we build experimental collations +AC_ARG_WITH(experimental-collations, + [], + [with_exp_coll=$withval], + [with_exp_coll=no] +) + +if test "$with_exp_coll" = "yes" +then + AC_DEFINE([HAVE_UTF8_GENERAL_CS], [1], [certain Japanese customer]) +fi diff --git a/config/ac-macros/misc.m4 b/config/ac-macros/misc.m4 index fdce85aa136..6e9dfe8231c 100644 --- a/config/ac-macros/misc.m4 +++ b/config/ac-macros/misc.m4 @@ -663,3 +663,27 @@ esac AC_SUBST(AR) AC_SUBST(ARFLAGS) ]) + +dnl +dnl Macro to check time_t range: according to C standard +dnl array index must be greater than 0 => if time_t is signed, +dnl the code in the macros below won't compile. +dnl + +AC_DEFUN([MYSQL_CHECK_TIME_T],[ + AC_MSG_CHECKING(if time_t is unsigned) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ +#include + ]], + [[ + int array[(((time_t)-1) > 0) ? 1 : -1]; + ]] ) + ], [ + AC_DEFINE([TIME_T_UNSIGNED], 1, [Define to 1 if time_t is unsigned]) + AC_MSG_RESULT(yes) + ], + [AC_MSG_RESULT(no)] + ) +]) + diff --git a/config/ac-macros/zlib.m4 b/config/ac-macros/zlib.m4 index 17b951d4723..5586b1ba816 100644 --- a/config/ac-macros/zlib.m4 +++ b/config/ac-macros/zlib.m4 @@ -2,7 +2,7 @@ dnl Define zlib paths to point at bundled zlib AC_DEFUN([MYSQL_USE_BUNDLED_ZLIB], [ ZLIB_INCLUDES="-I\$(top_srcdir)/zlib" -ZLIB_LIBS="\$(top_builddir)/zlib/libz.la" +ZLIB_LIBS="\$(top_builddir)/zlib/libzlt.la" dnl Omit -L$pkglibdir as it's always in the list of mysql_config deps. ZLIB_DEPS="-lz" zlib_dir="zlib" @@ -10,16 +10,25 @@ AC_SUBST([zlib_dir]) mysql_cv_compress="yes" ]) -dnl Auxiliary macro to check for zlib at given path +dnl Auxiliary macro to check for zlib at given path. +dnl We are strict with the server, as "archive" engine +dnl needs zlibCompileFlags(), but for client only we +dnl are less strict, and take the zlib we find. AC_DEFUN([MYSQL_CHECK_ZLIB_DIR], [ save_CPPFLAGS="$CPPFLAGS" save_LIBS="$LIBS" CPPFLAGS="$ZLIB_INCLUDES $CPPFLAGS" LIBS="$LIBS $ZLIB_LIBS" +if test X"$with_server" = Xno +then + zlibsym=zlibVersion +else + zlibsym=zlibCompileFlags +fi AC_CACHE_VAL([mysql_cv_compress], [AC_TRY_LINK([#include ], - [return zlibCompileFlags();], + [return $zlibsym();], [mysql_cv_compress="yes" AC_MSG_RESULT([ok])], [mysql_cv_compress="no"]) diff --git a/configure.in b/configure.in index 9581b5ac46a..aecbe87ff8f 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,10 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.1.17-beta) +# +# When changing major version number please also check switch statement +# in mysqlbinlog::check_master_version(). +AM_INIT_AUTOMAKE(mysql, 5.1.18-beta) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -21,7 +24,10 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # Remember that regexps needs to quote [ and ] since this is run through m4 MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[[a-z]]*-.*$||"` MYSQL_BASE_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|\.[[^.]]*$||"` -MYSQL_VERSION_ID=`echo $MYSQL_NO_DASH_VERSION. | sed -e 's/[[^0-9.]]//g; s/\./ /g; s/ \([[0-9]]\) / 0\\1 /g; s/ //g'` +MYSQL_VERSION_ID=`echo $MYSQL_NO_DASH_VERSION | sed -e 's|[[^0-9.]].*$||;s|$|.|' | sed -e 's/[[^0-9.]]//g; s/\./ /g; s/ \([[0-9]]\) / 0\\1 /g; s/ //g'` + +# Add previous major version for debian package upgrade path +MYSQL_PREVIOUS_BASE_VERSION=5.0 # The port should be constant for a LONG time MYSQL_TCP_PORT_DEFAULT=3306 @@ -52,6 +58,7 @@ romanian russian serbian slovak spanish swedish ukrainian" AC_SUBST(MYSQL_NO_DASH_VERSION) AC_SUBST(MYSQL_BASE_VERSION) AC_SUBST(MYSQL_VERSION_ID) +AC_SUBST(MYSQL_PREVIOUS_BASE_VERSION) AC_SUBST(PROTOCOL_VERSION) AC_DEFINE_UNQUOTED([PROTOCOL_VERSION], [$PROTOCOL_VERSION], [mysql client protocol version]) @@ -739,8 +746,9 @@ AC_CHECK_FUNC(bind, , AC_CHECK_LIB(bind, bind)) # Check if crypt() exists in libc or libcrypt, sets LIBS if needed AC_SEARCH_LIBS(crypt, crypt, AC_DEFINE(HAVE_CRYPT, 1, [crypt])) -# For sem_xxx functions on Solaris 2.6 -AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4, sem_init)) +# For the sched_yield() function on Solaris +AC_CHECK_FUNC(sched_yield, , AC_CHECK_LIB(posix4, sched_yield)) + MYSQL_CHECK_ZLIB_WITH_COMPRESS # For large pages support @@ -2257,11 +2265,10 @@ AC_SUBST(tools_dirs) #MYSQL_CHECK_CPU libmysqld_dirs= -linked_libmysqld_targets= if test "$with_embedded_server" = "yes" then libmysqld_dirs=libmysqld - linked_libmysqld_targets="linked_libmysqld_sources linked_libmysqldex_sources" + AC_CONFIG_FILES(libmysqld/Makefile libmysqld/examples/Makefile) # We can't build embedded library without building the server, because # we depend on libmysys, libmystrings, libmyisam, etc. @@ -2271,7 +2278,6 @@ fi # mysql_config --libmysqld-libs will print out something like # -L/path/to/lib/mysql -lmysqld -lmyisam -lmysys -lmystrings -ldbug ... AC_SUBST([libmysqld_dirs]) -AC_SUBST([linked_libmysqld_targets]) # Shall we build the docs? AC_ARG_WITH(docs, @@ -2295,12 +2301,18 @@ AC_ARG_WITH(man, [with_man=yes] ) -if test "$with_man" = "yes" +if test X"$with_man" = Xyes then man_dirs="man" - man1_files=`ls -1 $srcdir/man/*.1 | sed -e 's;^.*man/;;'` + if test X"$have_ndbcluster" = Xyes + then + man1_files=`ls $srcdir/man/*.1 | sed -e 's;^.*man/;;'` + man8_files=`ls $srcdir/man/*.8 | sed -e 's;^.*man/;;'` + else + man1_files=`ls $srcdir/man/*.1 | grep -v '/ndb' | sed -e 's;^.*man/;;'` + man8_files=`ls $srcdir/man/*.8 | grep -v '/ndb' | sed -e 's;^.*man/;;'` + fi man1_files=`echo $man1_files` - man8_files=`ls -1 $srcdir/man/*.8 | sed -e 's;^.*man/;;'` man8_files=`echo $man8_files` else man_dirs="" @@ -2446,7 +2458,6 @@ thread_dirs= dnl This probably should be cleaned up more - for now the threaded dnl client is just using plain-old libs. sql_client_dirs= -linked_client_targets="linked_libmysql_sources" AM_CONDITIONAL(THREAD_SAFE_CLIENT, test "$THREAD_SAFE_CLIENT" != "no") @@ -2455,7 +2466,6 @@ then sql_client_dirs="strings regex mysys dbug extra libmysql client" else sql_client_dirs="strings regex mysys dbug extra libmysql libmysql_r client" - linked_client_targets="$linked_client_targets linked_libmysql_r_sources" AC_CONFIG_FILES(libmysql_r/Makefile) AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should the client be thread safe]) fi @@ -2467,18 +2477,14 @@ AC_SUBST(CLIENT_THREAD_LIBS) AC_SUBST(NON_THREADED_LIBS) AC_SUBST(STATIC_NSS_FLAGS) AC_SUBST(sql_client_dirs) -AC_SUBST(linked_client_targets) -# If configuring for NetWare, set up to link sources from and build the netware directory +# If configuring for NetWare, build the netware directory netware_dir= -linked_netware_sources= if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null then netware_dir="netware" - linked_netware_sources="linked_netware_sources" fi AC_SUBST(netware_dir) -AC_SUBST(linked_netware_sources) AM_CONDITIONAL(HAVE_NETWARE, test "$netware_dir" = "netware") if test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no" @@ -2549,6 +2555,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl tests/Makefile Docs/Makefile support-files/Makefile dnl support-files/MacOSX/Makefile support-files/RHEL4-SElinux/Makefile dnl mysql-test/Makefile dnl + debian/Makefile debian/defs.mk debian/control dnl mysql-test/ndb/Makefile netware/Makefile sql-bench/Makefile dnl include/mysql_version.h plugin/Makefile win/Makefile) diff --git a/dbug/dbug.c b/dbug/dbug.c index 6a17db588ad..e482fd95073 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -1995,12 +1995,13 @@ static char *DbugMalloc(size_t size) /* - * strtok lookalike - splits on ':', magically handles :\ and :/ + * strtok lookalike - splits on ':', magically handles ::, :\ and :/ */ static const char *DbugStrTok(const char *s) { - while (s[0] && (s[0] != ':' || (s[1] == '\\' || s[1] == '/'))) + while (s[0] && (s[0] != ':' || + (s[1] == '\\' || s[1] == '/' || (s[1] == ':' && s++)))) s++; return s; } diff --git a/dbug/user.r b/dbug/user.r index 3bcc0c91d1d..e41367de321 100644 --- a/dbug/user.r +++ b/dbug/user.r @@ -908,9 +908,10 @@ via the .B DBUG_PUSH or .B DBUG_SET -macros. Control string consists of colon separate flags. A flag -may take an argument or a list of arguments. If a control string -starts from a '+' sign it works +macros. Control string consists of colon separate flags. Colons +that are part of ':\\', ':/', or '::' are not considered flag +separators. A flag may take an argument or a list of arguments. +If a control string starts from a '+' sign it works .I incrementally, that is, it can modify existing state without overriding it. In such a string every flag may be preceded by a '+' or '-' to enable or disable @@ -923,9 +924,7 @@ optional. .LI a[,file] Redirect the debugger output stream and append it to the specified file. The default output stream is stderr. A null argument list -causes output to be redirected to stdout. A colon that is followed by -the '\\' or '/' is cosidered a part of the path and not a flag -separator. +causes output to be redirected to stdout. .SP 1 EX: \fCa,C:\\tmp\\log\fR .LI A[,file] diff --git a/debian/Makefile.am b/debian/Makefile.am new file mode 100644 index 00000000000..14035865371 --- /dev/null +++ b/debian/Makefile.am @@ -0,0 +1,118 @@ +# Copyright (C) 2006 MySQL AB +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to create Makefile.in +EXTRA_DIST = \ + mysql-test-BASE.files.in \ + libndbclientNLIB-dev.files.in \ + mysql-server-BASE.config.in \ + libndbclientNLIB.README.Debian.in \ + mysql-server-BASE.postrm.in \ + mysql-server-BASE.NEWS.in \ + libndbclientNLIB.postinst.in \ + mysql-server-BASE.links.in \ + libndbclientNLIB.files.in \ + source.lintian-overrides.in \ + mysql-server-BASE.docs.in \ + libmysqlclientSLIBoff.files.in \ + mysql-server-BASE.files.in \ + libndbclientNLIB-dev.links.in \ + libmysqlclientSLIBoff.postinst.in \ + mysql-extra-BASE.dirs.in \ + libmysqlclientSLIB-dev.links.in \ + mysql-server-BASE.dirs.in \ + libmysqlclientSLIB-dev.examples.in \ + mysql-client-BASE.lintian-overrides.in \ + copyright.more \ + libndbclientNLIB-dev.dirs.in \ + mysql-server-BASE.README.Debian.in \ + libmysqlclientSLIBoff.docs.in \ + compat \ + mysql-test-BASE.dirs.in \ + libmysqlclientSLIB-dev.files.in \ + libmysqlclientSLIBoff.dirs.in \ + mysql-server-BASE.logcheck.ignore.server.in \ + mysql-storage-BASE.mysql-storage.init.in \ + libmysqlclientSLIBoff.README.Debian.in \ + mysql-client-BASE.README.Debian.in \ + Makefile.am \ + mysql-server-BASE.prerm.in \ + mysql-common.dirs.in \ + defs.mk \ + defs.mk.in \ + mysql-server-BASE.mysql-server.logrotate.in \ + mysql-common.README.Debian.in \ + copyright \ + mysql-storage-BASE.dirs.in \ + mysql-common.preinst.in \ + mysql-client-BASE.files.in \ + mysql-server-BASE.templates.in \ + mysql-tools-BASE.dirs.in \ + mysql-management-BASE.mysql-management.init.in \ + watch \ + mysql-common.postrm.in \ + mysql-server-BASE.preinst.in \ + README.Maintainer \ + mysql-tools-BASE.files.in \ + mysql-client-BASE.NEWS.in \ + mysql-server-BASE.lintian-overrides.in \ + changelog \ + mysql-server-BASE.logcheck.ignore.paranoid.in \ + mysql-common.files.in \ + mysql-server-BASE.logcheck.ignore.workstation.in \ + mysql-extra-BASE.files.in \ + mysql-management-BASE.files.in \ + mysql-client-BASE.docs.in \ + libmysqlclientSLIB-dev.README.Maintainer.in \ + mysql-storage-BASE.files.in \ + additions \ + additions/ndb_mgmd.cnf \ + additions/mysql-server.lintian-overrides \ + additions/my.cnf \ + mysql-server-BASE.postinst.in \ + libndbclientNLIB.dirs.in \ + po \ + po/fr.po \ + po/sv.po \ + po/da.po \ + po/es.po \ + po/ja.po \ + po/tr.po \ + po/nb.po \ + po/POTFILES.in.in \ + po/cs.po \ + po/pt.po \ + po/gl.po \ + po/pt_BR.po \ + po/nl.po \ + po/templates.pot \ + po/de.po \ + po/eu.po \ + po/ro.po \ + po/ru.po \ + po/it.po \ + po/ca.po \ + mysql-client-BASE.dirs.in \ + control.in \ + libmysqlclientSLIB-dev.dirs.in \ + mysql-server-PREV.preinst.in \ + mysql-server.preinst.in \ + mysql-management-BASE.dirs.in \ + rules \ + libmysqlclientSLIB-dev.docs.in + +# Don't update the files from bitkeeper +%::SCCS/s.% + diff --git a/debian/README.Maintainer b/debian/README.Maintainer new file mode 100644 index 00000000000..80b484d7a6c --- /dev/null +++ b/debian/README.Maintainer @@ -0,0 +1,99 @@ +########################################################################### +# Here are some information that are only of interest to the Debiani # +# maintainers of MySQL. # +########################################################################### + +# +# Remarks to dependencies +# +libwrap0-dev (>= 7.6-8.3) + According to bug report 114582 where where build problems on + IA-64/sid with at least two prior versions. +psmisc + /usr/bin/killall in the initscript + +zlib1g in libmysqlclient-dev: + "mysql_config --libs" adds "-lz" + +Build-Dep: + +debhelper (>=4.1.16): + See po-debconf(7). + +autoconf (>= 2.13-20), automake1.7 + Try to get rid of them. + +doxygen, tetex-bin, tetex-extra, gs + for ndb/docs/*tex + +mysql-server-5.0: Pre-Depends: mysql-common + This was necessary as mysql-server-5.0.preinst checks for unmodified + conffiles from mysql-server-4.1 and copies 5.0 ones over them to avoid + unnecessary dpkg questions. As mysql-server-5.0 is not unpacked at its + pre-inst stage, it had to copy those files from a package that is + definetly already unpacked which does not have to be the case with Depends. + +# +# Remarks to the start scripts +# + +## initscripts rely on mysqladmin from a different package +We have the problem that "/etc/init.d/mysql stop" relies on mysqladmin which +is in another package (mysql-client) and a passwordless access that's maybe +only available if the user configured his /root/.my.cnf. Can this be a problem? +* normal mode: not because the user is required to have it. Else: +* purge/remove: not, same as normal mode +* upgrade: not, same as normal mode +* first install: not, it depends on mysql-client which at least is unpacked + so mysqladmin is there (to ping). It is not yet configured + passwordles but if there's a server running then there's a + /root/.my.cnf. Anyways, we simply kill anything that's mysqld. + +## Passwordless access for the maintainer scripts +Another issue is that the scripts needs passwordless access. To ensure this +a debian-sys-maint user is configured which has process and shutdown privs. +The file with the randomly (that's important!) generated password must be +present as long as the databases remain installed because else a new install +would have no access. This file should be used like: + mysqladmin --defaults-file=/etc/mysql/debian.cnf restart +to avoid providing the password in plaintext on a commandline where it would +be visible to any user via the "ps" command. + +## When to start the daemon? +We aim to give the admin full control on when MySQL is running. +Issues to be faced here: +OLD: + 1. Debconf asks whether MySQL should be started on boot so update-rc.d is + only run if the answer has been yes. The admin is likely to forget + this decision but update-rc.d checks for an existing line in + /etc/runlevel.conf and leaves it intact. + 2. On initial install, if the answer is yes, the daemon has to be started. + 3. On upgrades it should only be started if it was already running, everything + else is confusing. Especiall relying on an debconf decision made month ago + is considered suboptimal. See bug #274264 + Implementation so far: + prerm (called on upgrade before stopping the server): + check for a running server and set flag if necessary + preinst (called on initial install and before unpacking when upgrading): + check for the debconf variable and set flag if necessary + postinst (called on initial install and after each upgrade after unpacking): + call update-rc.d if debconf says yes + call invoce-rc.d if the flag has been set + Problems remaining: + dpkg-reconfigure and setting mysql start on boot to yes did not start mysql + (ok "start on boot" literally does not mean "start now" so that might have been ok) +NEW: + 1. --- no debconf anymore for the sake of simplicity. We have runlevel.conf, + the admin should use it + 2. On initial install the server is started. + 3. On upgrades the server is started exactly if it was running before so the + runlevel configuration is irrelevant. It will be preserved by the mean of + update-rc.d's builtin check. + Implementation: + prerm (called on upgrade before stopping the server): + check for a running server and set flag if necessary + preinst (called on initial install and before unpacking when upgrading): + check for $1 beeing (initial) "install" and set flag + postinst (called on initial install and after each upgrade after unpacking): + call update-rc.d + call invoce-rc.d if the flag has been set diff --git a/debian/additions/my.cnf b/debian/additions/my.cnf new file mode 100644 index 00000000000..a569c041401 --- /dev/null +++ b/debian/additions/my.cnf @@ -0,0 +1,134 @@ +# +# The MySQL database server configuration file. +# +# You can copy this to one of: +# - "/etc/mysql/my.cnf" to set global options, +# - "~/.my.cnf" to set user-specific options. +# +# One can use all long options that the program supports. +# Run program with --help to get a list of available options and with +# --print-defaults to see which it would actually understand and use. +# +# For explanations see +# http://dev.mysql.com/doc/mysql/en/server-system-variables.html + +# This will be passed to all mysql clients +# It has been reported that passwords should be enclosed with ticks/quotes +# escpecially if they contain "#" chars... +# Remember to edit /etc/mysql/debian.cnf when changing the socket location. +[client] +port = 3306 +socket = /var/run/mysqld/mysqld.sock + +# Here is entries for some specific programs +# The following values assume you have at least 32M ram + +# This was formally known as [safe_mysqld]. Both versions are currently parsed. +[mysqld_safe] +socket = /var/run/mysqld/mysqld.sock +nice = 0 + +[mysqld] +# +# * Basic Settings +# +user = mysql +pid-file = /var/run/mysqld/mysqld.pid +socket = /var/run/mysqld/mysqld.sock +port = 3306 +basedir = /usr +datadir = /var/lib/mysql +tmpdir = /tmp +language = /usr/share/mysql/english +skip-external-locking +# +# Instead of skip-networking the default is now to listen only on +# localhost which is more compatible and is not less secure. +bind-address = 127.0.0.1 +# +# * Fine Tuning +# +key_buffer = 16M +max_allowed_packet = 16M +thread_stack = 128K +thread_cache_size = 8 +# +# * Query Cache Configuration +# +query_cache_limit = 1048576 +query_cache_size = 16777216 +query_cache_type = 1 +# +# * Logging and Replication +# +# Both location gets rotated by the cronjob. +# Be aware that this log type is a performance killer. +#log = /var/log/mysql/mysql.log +# +# Error logging goes to syslog. This is a Debian improvement :) +# +# Here you can see queries with especially long duration +#log_slow_queries = /var/log/mysql/mysql-slow.log +# +# The following can be used as easy to replay backup logs or for replication. +#server-id = 1 +log_bin = /var/log/mysql/mysql-bin.log +# WARNING: Using expire_logs_days without bin_log crashes the server! See README.Debian! +expire_logs_days = 10 +max_binlog_size = 100M +#binlog_do_db = include_database_name +#binlog_ignore_db = include_database_name +# +# * BerkeleyDB +# +# Using BerkeleyDB is now discouraged as its support will cease in 5.1.12. +skip-bdb +# +# * InnoDB +# +# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/. +# Read the manual for more InnoDB related options. There are many! +# You might want to disable InnoDB to shrink the mysqld process by circa 100MB. +#skip-innodb +# +# * Security Features +# +# Read the manual, too, if you want chroot! +# chroot = /var/lib/mysql/ +# +# For generating SSL certificates I recommend the OpenSSL GUI "tinyca". +# +# ssl-ca=/etc/mysql/cacert.pem +# ssl-cert=/etc/mysql/server-cert.pem +# ssl-key=/etc/mysql/server-key.pem + + + +[mysqldump] +quick +quote-names +max_allowed_packet = 16M + +[mysql] +#no-auto-rehash # faster start of mysql but no tab completition + +[isamchk] +key_buffer = 16M + +# +# * NDB Cluster +# +# See /usr/share/doc/mysql-server-*/README.Debian for more information. +# +# The following configuration is read by the NDB Data Nodes (ndbd processes) +# not from the NDB Management Nodes (ndb_mgmd processes). +# +# [MYSQL_CLUSTER] +# ndb-connectstring=127.0.0.1 + + +# +# * IMPORTANT: Additional settings that can override those from this file! +# +!includedir /etc/mysql/conf.d/ + diff --git a/debian/additions/mysql-server.lintian-overrides b/debian/additions/mysql-server.lintian-overrides new file mode 100644 index 00000000000..9d741cf16e9 --- /dev/null +++ b/debian/additions/mysql-server.lintian-overrides @@ -0,0 +1,2 @@ +W: mysql-dfsg source: maintainer-script-lacks-debhelper-token debian/mysql-server.postinst +W: mysql-server: possible-bashism-in-maintainer-script postinst:68 'p{("a".."z","A".."Z",0..9)[int(rand(62))]}' diff --git a/debian/additions/ndb_mgmd.cnf b/debian/additions/ndb_mgmd.cnf new file mode 100644 index 00000000000..d94a28ff705 --- /dev/null +++ b/debian/additions/ndb_mgmd.cnf @@ -0,0 +1,35 @@ +[NDBD DEFAULT] +NoOfReplicas=2 +DataMemory=10MB +IndexMemory=25MB +MaxNoOfTables=256 +MaxNoOfOrderedIndexes=256 +MaxNoOfUniqueHashIndexes=128 + +[MYSQLD DEFAULT] + +[NDB_MGMD DEFAULT] + +[TCP DEFAULT] + +[NDB_MGMD] +Id=1 # the NDB Management Node (this one) +HostName=127.0.0.1 + +[NDBD] +Id=2 # the first NDB Data Node +HostName=127.0.0.1 +DataDir= /var/lib/mysql-cluster + +[NDBD] +Id=3 # the second NDB Data Node +HostName=127.0.0.1 +DataDir=/var/lib/mysql-cluster + +[MYSQLD] +Id=4 # the first SQL node +HostName=127.0.0.1 + +# [MYSQLD] +# Id=5 # the second SQL node +# HostName=127.0.0.10 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 00000000000..2c1418746cc --- /dev/null +++ b/debian/changelog @@ -0,0 +1,3281 @@ +mysql-5.1 (5.1.18) UNRELEASED; urgency=low + + * Branched for 5.1. + + -- Monty Taylor Fri, 20 Apr 2007 14:46:51 -0700 + +mysql-5.0 (5.0.42) UNRELEASED; urgency=low + + * Upgraded to 5.0.42 branch. + + -- Monty Taylor Thu, 19 Apr 2007 22:18:02 +0200 + +mysql-5.0 (5.0.38) UNRELEASED; urgency=low + + * Imported packaging work from Debian. + * Removed debian-start, mysqlreport and echo_stderr to align with official + packages. + + -- Monty Taylor Wed, 7 Mar 2007 07:52:55 +0800 + +mysql-dfsg-5.0 (5.0.32-3etch1) testing-proposed-updates; urgency=high + + * Backported upstream patch for a bug that crashed the server when using + certain join/group/limit combinations. + Users of the Joomla CMS seemed to be affected by this. Closes: #403721 + * The debian-start script that runs on every server start now first upgrades + the system tables (if neccessary) and then check them as it sometimes did + not work the other way around (e.g. for MediaWiki). The script now uses + mysql_update instead of mysql_update_script as recommended. Closes: 409780 + * The old_passwords setting that is set according to a Debconf question is + now written to /etc/mysql/conf.d/old_passwords.cnf instead directly to the + conffile /etc/mysql/my.cnf which would be fobidden by policy (thanks to + Robert Bihlmeyer). Closes: #409750 + * Added bison to build dependencies. + * Synced Debconf translations with 5.0.32-7. + + -- Christian Hammers Sun, 18 Feb 2007 22:33:05 +0100 + +mysql-dfsg-5.0 (5.0.32-3) unstable; urgency=high + + * mysql-server-5.0 pre-depends on adduser now and has --disabled-login + explicitly added to be on the safe side (thanks to the puiparts team). + Closes: #408362 + * Corrections the terminology regarding NDB in the comments of all config + files and init scripts (thanks to Geert Vanderkelen of MySQL). + * Updated Swedish Debconf translation (thanks to Andreas Henriksson). + Closes: #407859 + * Updated Czech Debconf translation (thanks to Miroslav Kure). + Closes: #407809 + + -- Christian Hammers Thu, 11 Jan 2007 11:18:47 +0100 + +mysql-dfsg-5.0 (5.0.32-2) unstable; urgency=high + + * The last upload suffered from a regression that made NDB totally + unusable and caused a dependency to libmysqlclient15-dev in the + mysql-server-5.0 package. The relevant 85_* patch was re-added again. + Closes: #406435 + * Added lintian-overrides for an error that does not affect our packages. + There are now only warnings and not errors left. + + -- Christian Hammers Tue, 9 Jan 2007 23:55:10 +0100 + +mysql-dfsg-5.0 (5.0.32-1) unstable; urgency=high + + * New upstream version. + * SECURITY: mysql_fix_privilege_tables.sql altered the + table_privs.table_priv column to contain too few privileges, causing + loss of the CREATE VIEW and SHOW VIEW privileges. (MySQL Bug#20589) + * SECURITY (DoS): ALTER TABLE statements that performed both RENAME TO + and {ENABLE|DISABLE} KEYS operations caused a server crash. (MySQL + Bug#24089) + * SECURITY (DoS): LAST_DAY('0000-00-00') could cause a server crash. + (MySQL Bug#23653) + * SECURITY (DoS): Using EXPLAIN caused a server crash for queries that + selected from INFORMATION_SCHEMA in a subquery in the FROM clause. + (MySQL Bug#22413) + * SECURITY (DoS): Invalidating the query cache (e.g. when using stored procedures) + caused a server crash for INSERT INTO ... SELECT statements that + selected from a view. (MySQL Bug#20045) + * Using mysql_upgrade with a password crashed the server. Closes: #406229 + * yaSSL crashed on pre-Pentium Intel and Cyrix CPUs. (MySQL Bug#21765) + Closes: #383759 + * Lots of small fixes to the NDB cluster storage engine. + * Updated Japanese Debconf template (thanks to Hideki Yamane). + Closes: #405793 + * Fixed comment regarding "mycheck" in debian-start (thanks to + Enrico Zini). Closes: #405787 + + -- Christian Hammers Sat, 6 Jan 2007 14:26:20 +0100 + +mysql-dfsg-5.0 (5.0.30-3) unstable; urgency=low + + * Updated Brazilian Debconf translation (thanks to Andre Luis Lopes). + Closes: #403821 + * Added Romanian Debconf translation (thanks to Stan Ioan-Eugen). + Closes: #403943 + * Updated Spanish Debconf translation (thanks to Javier Fernandez-Sanguino + Pena). Closes: #404084 + * Updated Galician Debconf translation (thanks to Jacobo Tarrio). + Closes: #404318 + * Updated Dutch Debconf translation (thanks to Vincent Zweije). + Closes: #404566 + * Updated Danish Debconf translation (thanks to Claus Hindsgaul). + Closes: #405018 + + -- Christian Hammers Thu, 21 Dec 2006 21:35:09 +0100 + +mysql-dfsg-5.0 (5.0.30-2) unstable; urgency=high + + * Fixed upstream regression in header files that lead to FTBFS for + mysql-admin, mysql-query-browser and probably other pacakges. + (thanks to Andreas Henriksson). Closes: #403081, #403082 + * Fixed some upstream scripts by replacing /etc by /etc/mysql (thanks to + Julien Antony). Closes: #401083 + * Updated French Debconf translation (thanks to Christian Perrier). + Closes: #401434 + * Added Spanish Debconf translation (thanks to Javier Fernandez-Sanguino + Pena). Closes: #401953 + * Marked a Debconf question that is just a dummy and only internally + used as not-needing-translation. Closes: #403163 + * Fixed mysqlslowdump patch to not remove the usage() function (thanks + to Monty Tailor). + + -- Christian Hammers Sun, 3 Dec 2006 19:20:10 +0100 + +mysql-dfsg-5.0 (5.0.30-1) unstable; urgency=low + + * New upstream version (switch to the MySQL Enterprise branch). + * Upstream bugfix for the Innodb performance bug: + "Very poor performance with multiple queries running + concurrently (Bug#15815)". + * Upstream bugfix for a possible server crash: + "Selecting from a MERGE table could result in a server crash if the + underlying tables had fewer indexes than the MERGE table itself + (Bug#22937)" + * Upstream bugfies for *lot* of NDB problems. + * Upstream bugfix for Innodb optimizer bug. Closes: #397597 + * Updated Italian Debconf translation (thanks to Luca Monducci). + Closes: #401305 + * Updated debian/watch file to MySQL Enterprise branch. + + -- Christian Hammers Sat, 2 Dec 2006 16:36:38 +0100 + +mysql-dfsg-5.0 (5.0.27-2) unstable; urgency=medium + + * Disabled YaSSL x86 assembler as it was reported to crash applications + like pam-mysql or proftpd-mysql which are linked against libmysqlclient + on i486 and Cyrix (i586) CPUs. Closes: #385147 + * Adjusted mysql-server-4.1 priority to extra and section to oldlibs + according to the ftp masters overrides. + * Updated German Debconf translation (thanks to Alwin Meschede). + Closes: #400809 + + -- Christian Hammers Wed, 22 Nov 2006 13:36:31 +0100 + +mysql-dfsg-5.0 (5.0.27-1) unstable; urgency=medium + + * New upstream version (but no codechange, the only difference to 5.0.26 + was a patch to the ABI change which Debian already included. + * When dist-upgrading from mysql-server-4.1/sarge dpkg does not longer + ask unnecessary "config file has changed" questions regarding + /etc/init.d/mysql, /etc/logrotate.d/mysql-server and + /etc/mysql/debian-start just because these files previously belonged + to mysql-server-4.1 and not to mysql-server-5.0. + To archive this mysql-server-5.0 now pre-depends on mysql-common which + provides current versions of those files. + * The automatic run mysql_upgrade now works with non-standard datadir + settings, too (thanks to Benjami Villoslada). Closes: #394607 + * Debconf now asks if the old_passwords option is really needed. + * Improved explanations of the old_passwords variable in my.cnf. + * Removed possibly leftover cron script from MySQL-4.1 (thanks to + Mario Oyorzabal Salgado). Closes: #390889 + * Postrm ignores failed "userdel mysql". + * Updated Danish Debconf translation (thanks to Claus Hindsgaul). + Closes: #398784 + * Added Euskarian Debconf translation (thanks to Piarres Beobide). + Closes: #399045 + * Updated Japanese Debconf translation (thanks to Hideki Yamane). + Closes: #399074 + * Updated German Debconf translation (thanks to Alwin Meschede). + Closes: #399087 + * New Portuguese debconf translations from Miguel Figueiredo. + Closes: #398186 + + -- Christian Hammers Tue, 7 Nov 2006 21:26:25 +0100 + +mysql-dfsg-5.0 (5.0.26-3) unstable; urgency=high + + [sean finney] + * Fix for the deadly ISAM trap. Now during upgrades we will do our + very best to convert pre-existing ISAM format tables using the + binaries from the previous package. Success is not guaranteed, but + this is probably as good as it gets. Note that this also necessitates + re-introducing an (empty transitional) mysql-server-4.1 package. + Closes: #354544, #354850 + * Remove a couple spurious and wrongly placed WARNING statements from + 45_warn-CLI-passwords.dpatch. thanks to Dan Jacobsen for pointing these + out. Closes: #394262 + + -- sean finney Fri, 03 Nov 2006 18:34:46 +0100 + +mysql-dfsg-5.0 (5.0.26-2) unstable; urgency=high + + * Fixed FTBFS for Alpha by applying an upstream patch (thanks to Falk + Hueffner). Closes: #395921 + + -- Christian Hammers Sat, 28 Oct 2006 20:13:46 +0200 + +mysql-dfsg-5.0 (5.0.26-1) unstable; urgency=high + + * SECURITY: + This combined release of 5.0.25 and 5.0.26 fixes lot of possible server + crashs so it should get into Etch. Quoting the changelog (bug numbers are + bugs.mysql.com ones): + - character_set_results can be NULL to signify no conversion, but some + code did not check for NULL, resulting in a server crash. (Bug#21913) + - Using cursors with READ COMMITTED isolation level could cause InnoDB to + crash. (Bug#19834) + - Some prepared statements caused a server crash when executed a second + time. (Bug#21166) + - When DROP DATABASE or SHOW OPEN TABLES was issued while concurrently + issuing DROP TABLE (or RENAME TABLE, CREATE TABLE LIKE or any other + statement that required a name lock) in another connection, the server + crashed. (Bug#21216) + - Use of zero-length variable names caused a server crash. (Bug#20908) + - For InnoDB tables, the server could crash when executing NOT IN () + subqueries. (Bug#21077) + - Repeated DROP TABLE statements in a stored procedure could sometimes + cause the server to crash. (Bug#19399) + - Performing an INSERT on a view that was defined using a SELECT that + specified a collation and a column alias caused the server to crash + (Bug#21086). + - A query of the form shown here caused the server to crash. (Bug#21007) + - NDB Cluster: Some queries involving joins on very large NDB tables could + crash the MySQL server. (Bug#21059) + - The character set was not being properly initialized for CAST() with a + type like CHAR(2) BINARY, which resulted in incorrect results or even a + server crash. (Bug#17903) + - For certain queries, the server incorrectly resolved a reference to an + aggregate function and crashed. (Bug#20868) + - The server crashed when using the range access method to execut a + subquery with a ORDER BY DESC clause. (Bug#20869) + - Triggers on tables in the mysql database caused a server crash. Triggers + for tables in this database now are disallowed. (Bug#18361) + - Using SELECT on a corrupt MyISAM table using the dynamic record format + could cause a server crash. (Bug#19835) + - Use of MIN() or MAX() with GROUP BY on a ucs2 column could cause a + server crash. (Bug#20076) + - Selecting from a MERGE table could result in a server crash if the + underlying tables had fewer indexes than the MERGE table itself. + (Bug#21617, Bug#22937) + + * New upstream release. + - This bug would cause trouble for Sarge->Etch upgrades, it was supposed to + have been fixed in 5.0.16 but that apparently did not fix the whole + problem: + Using tables from MySQL 4.x in MySQL 5.x, in particular those with VARCHAR + fields and using INSERT DELAYED to update data in the table would result in + either data corruption or a server crash. (Bug#16611, Bug#16218, Bug#17294) + Closes: #386337 + - Fixes data corruption as an automatic client reconnect used to set + the wrong character set. Closes: #365050 + - Fixes an undefined ulong type in an include file. Closes: #389102 + - Fixes wrong output format when using Unicode characters. Closes: #355302 + - Fixes mysql_upgrade when using a password. Closes: #371841 + + [Christian Hammers] + * Removed --sysconfdir from debian/rules as it puts /etc/mysql/ at the + end of the my.cnf search patch thus overriding $HOME/my.cnf + (thanks to Christoph Biedl). Closes: #394992 + * The provided patch from bug #385947 was wrong, the variable is called + BLOCKSIZE not BLOCK_SIZE according to "strings `which df`" (thanks to + Bruno Muller). Closes: #385947 + + [sean finney] + * new dutch debconf translations from Vincent Zweije (closes: #392809). + * new japanese debconf translations from Hideki Yamane (closes: #391625). + * new italian debconf translations from Luca Monducci (closes: #391741). + * new french debconf translations from Christian Perrier (closes: #393334). + * ran debconf-updatepo to merge the fuzzies into svn. + * massage the following patches so they continue to apply cleanly: + - 44_scripts__mysql_config__libs.dpatch to cleanly apply. + - 45_warn-CLI-passwords.dpatch + - 96_TEMP__libmysqlclient_ssl_symbols.dpatch (note, this patch might + no longer be needed, but is retained "just in case" after massaging it) + * the following patches have been incorporated upstream: + - 70_kfreebsd.dpatch + - 80_hurd_mach.dpatch + - 87_ps_Hurd.dpatch + - 90_TEMP__client__mysql_upgrade__O_EXEC.dpatch + - 91_TEMP__client__mysql_upgrade__password.dpatch + - 92_TEMP__client__mysql_upgrade__defaultgroups.dpatch + - 94_TEMP__CVE-2006-4227.dpatch + - 95_TEMP__CVE-2006-4226.dpatch + * the udf_example.cc has disappeared from the source code, but there's + a udf_example.c which seems to be a good example to use instead :) + * update documentation in the configuration to no longer reference + using my.cnf in the DATADIR, as it's never been the recommended + method for debian systems and hasn't worked since 5.0 was released + anyway (closes: #393868). + + -- Christian Hammers Wed, 25 Oct 2006 19:54:04 +0200 + +mysql-dfsg-5.0 (5.0.24a-9) unstable; urgency=medium + + * Having expire_logs_days enabled but log-bin not crashes the server. Using + both or none of those options is safe. To prevent this happening during the + nightly log rotation via /etc/logrotate.d/mysql the initscript checks for + malicious combination of options. See: #368547 + * The Sarge package "mysql-server" which used to include the mysqld daemon + may still be in unselected-configured state (i.e. after a remove but not + purge) in which case its now obsolete cronscript has to be moved away + (thanks to Charles Lepple). Closes: #385669 + * Updated Danish Debconf translation (thanks to Claus Hindsgaul). + Closes: #390315 + * Updated Frensh Debconf translation (thanks to Christian Perrier). + Closes: #390980 + + -- Christian Hammers Tue, 3 Oct 2006 14:55:31 +0200 + +mysql-dfsg-5.0 (5.0.24a-8) unstable; urgency=low + + * (broken upload) + + -- Christian Hammers Tue, 3 Oct 2006 14:55:31 +0200 + +mysql-dfsg-5.0 (5.0.24a-7) unstable; urgency=low + + * Stopped mysql_config from announcing unnecessary library dependencies + which until now cause "NEEDED" dependencies in the "readelf -d" output + of libraries who only depend on libmysqlclient.so (thanks to Michal + Cihar). Closes: #390692 + + -- Christian Hammers Sun, 1 Oct 2006 23:59:43 +0200 + +mysql-dfsg-5.0 (5.0.24a-6) unstable; urgency=low + + [sean finney] + * finally add support for setting a root password at install. + while this is not a random password as requested in one bug + report, we believe it is the best solution and provides a + means to set a random password via preseeding if it's really + desired (Closes: #316127, #298295). + + -- sean finney Sun, 01 Oct 2006 23:34:30 +0200 + +mysql-dfsg-5.0 (5.0.24a-5) unstable; urgency=low + + * Added ${shlibs:Depends} to debian/control section libmysqlclient-dev as it + contains the experimental /usr/lib/mysql/libndbclient.so.0.0.0. + * Bumped standards version to 3.7.2. + * Added LSB info section to init scripts. + * Rephrased Debconf templates as suggested by lintian. + * Added benchmark suite in /usr/share/mysql/sql-bench/. + * The mysql.timezone* tables are now filled by the postinst script (thanks + to Mark Sheppard). Closes: #388491 + * Moved Debconf install notes to README.Debian. Displaying them with + medium priority was a bug anyway. Closes: #388941 + * Replaced /usr/bin/mysql_upgrade by /usr/bin/mysql_upgrade_shell in + /etc/mysql/debian-start.sh as it works without errors (thanks to Javier + Kohen). Closes: #389443 + + -- Christian Hammers Wed, 20 Sep 2006 15:01:42 +0200 + +mysql-dfsg-5.0 (5.0.24a-4) unstable; urgency=high + + * libmysqlclient.so.15 from 5.0.24 accidentaly exports some symbols that are + historically exported by OpenSSL's libcrypto.so. This bug was supposed to + be fixed in 5.0.24a bug according to the mysql bug tracking system will + only be fixed in 5.0.25 so I backported the patch. People already reported + crashing apps due to this (thanks to Duncan Simpson). See also: #385348 + Closes: #388262 + * Fixed BLOCKSIZE to BLOCK_SIZE in initscript (thanks to Bruno Muller). + Closes: #385947 + * Added hint to "--extended-insert=0" to mysqldump manpage (thanks to Martin + Schulze). + * Documented the meaning of "NDB" in README.Debian (thanks to Dan Jacobson). + Closes: #386274 + * Added patch to build on hurd-i386 (thanks to Cyril Brulebois). Closes: #387369 + * Fixed debian-start script to work together with the recend LSB modifications in + the initscript (thanks to wens). Closes: #387481 + * Reverted tmpdir change in my.cnf back to /tmp to comply with FHS (thanks + to Alessandro Valente). Closes: #382778 + * Added logcheck filter rule (thanks to Paul Wise). Closes: #381043 + * I will definetly not disable InnoDB but added a note to the default my.cnf + that disabling it saves about 100MB virtual memory (thanks to Olivier + Berger). Closes: #384399 + * Added thread_cache_size=8 to default my.cnf as this variable seems to have + a negligible memory footprint but can improve performance when lots of + threads connect simultaneously as often seen on web servers. + + -- Christian Hammers Mon, 4 Sep 2006 00:21:50 +0200 + +mysql-dfsg-5.0 (5.0.24a-3) unstable; urgency=low + + * Fixed potential tempfile problem in the newly added mysqlreport script. + + -- Christian Hammers Sun, 3 Sep 2006 23:17:24 +0200 + +mysql-dfsg-5.0 (5.0.24a-2) unstable; urgency=low + + * Added "mysqlreport" (GPL'ed) from hackmysql.com. + * Temporarily disabled expire_days option as it causes the server + to crash. See #368547 + * Made output of init scripts LSB compliant (thanks to David Haerdeman). + Closes: #385874 + + -- Christian Hammers Sun, 3 Sep 2006 19:06:53 +0200 + +mysql-dfsg-5.0 (5.0.24a-1) unstable; urgency=high + + * New upstream version. + * The shared library in the 5.0.24 upstream release accidently exported + some symbols that are also exported by the OpenSSL libraries (notably + BN_bin2bn) causing unexpected behaviour in applications using these + functions (thanks to Peter Cernak). Closes: #385348 + * Added note about possible crash on certain i486 clone CPUs. + * Made recipient address of startup mysqlcheck output configurable + (thanks to Mattias Guns). Closes: #385119 + + -- Christian Hammers Mon, 28 Aug 2006 01:22:12 +0200 + +mysql-dfsg-5.0 (5.0.24-3) unstable; urgency=high + + * SECURITY: + CVE-2006-4226: + When run on case-sensitive filesystems, MySQL allows remote + authenticated users to create or access a database when the database + name differs only in case from a database for which they have + permissions. + CVE-2006-4227: + MySQL evaluates arguments of suid routines in the security context of + the routine's definer instead of the routine's caller, which allows + remote authenticated users to gain privileges through a routine that + has been made available using GRANT EXECUTE. + Thanks to Stefan Fritsch for reporting. Closes: #384798 + + -- Christian Hammers Sat, 26 Aug 2006 04:55:17 +0200 + +mysql-dfsg-5.0 (5.0.24-2) unstable; urgency=high + + * 5.0.24-1 introduced an ABI incompatibility, which this patch reverts. + Programs compiled against 5.0.24-1 are not compatible with any other + version and needs a rebuild. + This bug already caused a lot of segfaults and crashes in various + programs. Thanks to Chad MILLER from MySQL for quickly providing a patch. + The shlibdeps version has been increased to 5.0.24-2. + Closes: #384047, #384221, #383700 + + -- Christian Hammers Fri, 25 Aug 2006 21:47:35 +0200 + +mysql-dfsg-5.0 (5.0.24-1) unstable; urgency=high + + * SECURITY: Upstream fixes a security bug which allows a user to continue + accessing a table using a MERGE TABLE after the right to direct access to + the database has been revoked (CVE-2006-4031, MySQL bug #15195). + (Well they did not exactly fixed it, they documented the behaviour and + allow the admin to disable merge table alltogether...). Closes: #380271 + * SECURITY: Applied patch that fixes a possibly insecure filehandling + in the recently added mysql_upgrade binary file (MySQL bug #10320). + * New upstream version. + - Fixes nasty MySQL bug #19618 that leads to crashes when using + "SELECT ... WHERE ... not in (1, -1)" (e.g. vbulletin was affected). + - Fixes upstream bug #16803 so that linking ~/.mysql_history to /dev/null + now has the desired effect of having no history. + * Really fixed the runlevels. Closes: #377651 + * Added patch for broken upstream handling of "host=" to mysql_upgrade.c. + * Adjusted /etc/mysql/debian-start to new mysql_upgrade.c + + -- Christian Hammers Tue, 8 Aug 2006 00:44:13 +0200 + +mysql-dfsg-5.0 (5.0.22-5) unstable; urgency=low + + * Added further line to the logcheck ignore files (thanks to Paul Wise). + Closes: #381038 + + -- Christian Hammers Wed, 2 Aug 2006 00:28:50 +0200 + +mysql-dfsg-5.0 (5.0.22-4) unstable; urgency=low + + * Upstream fixes a bug in the (never released) version 5.0.23 which could + maybe used to crash the server if the mysqlmanager daemon is in use + which is not yet the default in Debian. (CVE-2006-3486 *DISPUTED*) + * Changed runlevel priority of mysqld from 20 to 19 so that it gets started + before apache and proftpd etc. which might depend on an already running + database server (thanks to Martin Gruner). Closes: #377651 + * Added patch which sets PATH_MAX in ndb (thanks to Cyril Brulebois). + Closes: #378949 + * Activated YaSSL as licence issues are settled according to: + http://bugs.mysql.com/?id=16755. This also closes the FTBFS bug + regarding OpenSSL as it is discouraged to use now. Closes: #368639 + * Removed SSL-MINI-HOWTO as the official documentation is good enough now. + * mysql_upgrade no longer gives --password on the commandline which would + be insecure (thanks to Dean Gaudet). Closes: #379199 + * Adjusted debian/patches/45* to make consecutive builds in the same source + tree possible (thanks to Bob Tanner). Closes: #368661 + * mysql-server-5.0 is now suggesting tinyca as yaSSL is enabled and tinyca + was found to be really cool :) + * Moved tempdir from /tmp to /var/tmp as it will more likely have enough + free space as /tmp is often on the root partition and /var or at least + /var/tmp is on a bigger one. + + -- Christian Hammers Mon, 10 Jul 2006 23:30:26 +0200 + +mysql-dfsg-5.0 (5.0.22-3) unstable; urgency=low + + * Added patch for MySQL bug #19618: "select x from x + where x not in(1,-1)" may crash the server" (thanks to + Ruben Puettmann). + + -- Christian Hammers Fri, 9 Jun 2006 01:41:44 +0200 + +mysql-dfsg-5.0 (5.0.22-2) unstable; urgency=high + + * Fixed debian-sys-maint related bug in postinst (thanks to + Jean-Christophe Dubacq). Closes: #369970 + * The last upload was a security patch (which I did not know as I + uploaded before the announcement came). I now added the CVE id for + reference and set urgency to high as the last entry did not. + + -- Christian Hammers Wed, 31 May 2006 01:04:11 +0200 + +mysql-dfsg-5.0 (5.0.22-1) unstable; urgency=low + + * SECURITY: This upstream release fixes an SQL-injection with multibyte + encoding problem. (CVE-2006-2753) + * New upstream release. + * Upstream fixes REPAIR TABLE problem. Closes: #354300 + * Upstream fixes problem that empty strings in varchar and text columns + are displayed as NULL. Closes: #368663 + + -- Christian Hammers Tue, 30 May 2006 23:43:24 +0200 + +mysql-dfsg-5.0 (5.0.21-4) unstable; urgency=low + + * Added "BLOCKSIZE=" to the diskfree check (thanks to Farzad FARID). + Closes: #367027, #367083 + * Further fixed mysql_upgrade upstream script (thanks to Andreas Pakulat) + Closes: #366155 + * Adjusted the /proc test in debian/rules from /proc/1 to /proc/self + to make building on grsec systems possible (thanks to K. Rosenegger). + Closes: #366824 + * Updated Russion Debconf translation (thanks to Yuriy Talakan). + Closes: #367141 + * Updated Czech Debconf translation (thanks to Kiroslav Kure). + Closes: #367160 + * Updated Galician Debconf translation (thanks to Jacobo Tarrio). + Closes: #367384 + * Updated Swedish Debconf translation (thanks to Daniel Nylander). + Closes: #368186 + + -- Christian Hammers Wed, 10 May 2006 08:45:42 +0200 + +mysql-dfsg-5.0 (5.0.21-3) unstable; urgency=low + + * Fixed FTBFS problem which was caused by a patch that modifies Makefile.am + as well as Makefile.in and was not deteced because my desktop was fast + enough to patch both files within the same second and so fooled automake. + (thanks to Blars Blarson for notifying me). Closes: #366534 + + -- Christian Hammers Sat, 6 May 2006 19:03:58 +0200 + +mysql-dfsg-5.0 (5.0.21-2) unstable; urgency=low + + * Fixed bug in postinst that did not correctly rewrite + /etc/mysql/debian.cnf (thanks to Daniel Leidert). + Closes: #365433, #366155 + + -- Christian Hammers Thu, 4 May 2006 02:37:03 +0200 + +mysql-dfsg-5.0 (5.0.21-1) unstable; urgency=high + + * SECURITY: New upstream release with some security relevant bugfixes: + * "Buffer over-read in check_connection with usernames lacking a + trailing null byte" (CVE-2006-1516) + * "Anonymous Login Handshake - Information Leakage" (CVE-2006-1517) + * "COM_TABLE_DUMP Information Leakage and Arbitrary command execution" + (CVE-2006-1518) + Closes: #365938, #365939 + * Added diskfree check to the init script (thanks to Tim Baverstock). + Closes: #365460 + * First amd64 upload! + + -- Christian Hammers Sat, 29 Apr 2006 04:31:27 +0200 + +mysql-dfsg-5.0 (5.0.20a-2) unstable; urgency=low + + * The new mysql-upgrade which is started from /etc/mysql/debian-start + does now use the debian-sys-maint user for authentication (thanks to + Philipp). Closes: #364991 + * Wrote patch debian/patches/43* which adds a password option to + mysql_update. See MySQL bug #19400. + * Added "Provides: libmysqlclient-dev" to libmysqlclient15-dev as I saw no + obvious reasons against it (problems should be documented in + debian/README.Maintainer!) (thanks to Olaf van der Spek). Closes: #364899 + * Updated Netherlands debconf translation (thanks to Vincent Zweije) + Closes: #364464 + * Updated French debconf translation (thanks to Christian Perrier) + Closes: #364401 + * Updated Danish debconf translation (thanks to Claus Hindsgaul) + Closes: #365135 + + -- Christian Hammers Wed, 26 Apr 2006 01:14:53 +0200 + +mysql-dfsg-5.0 (5.0.20a-1) unstable; urgency=low + + * New upstream release. + * Added the new mysql_upgrade script and added it to + /etc/mysql/debian-start (thanks to Alessandro Polverini). + The script is currently very noise that is a known bug and will be + fixed in the next release! + Closes: #363458 + * No longer creates the "test" database. This actuallay had been tried + to archive before (at least patches) exists but apparently was not the + case in the last versions (thanks to Olaf van der Spek). Closes: #362126 + * Reformatted libmysqlclient15off.NEWS.Debian to changelog format + (thanks to Peter Palfrader). Closes: #363062 + + -- Christian Hammers Sat, 15 Apr 2006 13:05:22 +0200 + +mysql-dfsg-5.0 (5.0.20-1) unstable; urgency=high + + * Upstream contains a fix for a nasty bug (MySQL#18153) that users + already experienced and that caused corrupted triggers after + REPAIR/OPTIMIZE/ALTER TABLE statements. + (thanks to Jerome Despatis for pointing out) + * Added patch for the "updates on multiple tables is buggy after + upgrading from 4.1 to 5.0" problem which MySQL has been committed + for the upcoming 5.0.21 release. Closes #352704 + * Added Netherlands debconf translation (thanks to Vincent Zweije). + Closes: #360443 + * Added Galician debconf translation (thanks to Jacobo Tarrio). + Closes: #361257 + + -- Christian Hammers Fri, 7 Apr 2006 00:00:43 +0200 + +mysql-dfsg-5.0 (5.0.19-3) unstable; urgency=high + + [ Christian Hammers ] + * Fixed libmysqlclient15.README.Debian regarding package name changes + (thanks to Leppo). + * Moved libheap.a etc. back to /usr/lib/mysql/ as their names are just + too generic. Closes: #353924 + [ Sean Finney ] + * updated danish debconf translation, thanks to Claus Hindsgaul + (closes: #357424). + [ Adam Conrad ] + * Send stderr from 'find' in preinst to /dev/null to tidy up chatter. + * Backport patch for CVE-2006-0903 from the upcoming release to resolve + a log bypass vulnerability when using non-binary logs (closes: #359701) + + -- Adam Conrad Tue, 4 Apr 2006 15:23:18 +1000 + +mysql-dfsg-5.0 (5.0.19-2) unstable; urgency=medium + + * New upstream release. + * Renamed package libmysqlclient15 to libmysqlclient15off due to + binary incompatible changes. + See /usr/share/doc/libmysqlclient15off/README.Debian + * Updated Czech debconf translation (thanks to Miroslav Kure). + Closes: #356503 + * Updated French debconf translation (thanks to Christian Perrier). + Closes: #356332 + * Improved README.Debian (thanks to Olaf van der Spek). Closes: #355702 + * Fixed 5.0.18-8 changelog by saying in which package the NEWS.Debian + file is (thanks to Ross Boylan). Closes: #355978 + + -- Christian Hammers Fri, 17 Mar 2006 02:32:19 +0100 + +mysql-dfsg-5.0 (5.0.19-1) experimental; urgency=medium + + * New upstream release. + * SECURITY: CVE-2006-3081: A bug where str_to_date(1,NULL) lead to a + server crash has been fixed. + (this note has been added subsequently for reference) + * Renamed package libmysqlclient15 to libmysqlclient15off. + See /usr/share/doc/libmysqlclient15off/NEWS.Debian + * Updated Czech debconf translation (thanks to Miroslav Kure). + Closes: #356503 + * Updated French debconf translation (thanks to Christian Perrier). + Closes: #356332 + * Improved README.Debian (thanks to Olaf van der Spek). Closes: #355702 + * Fixed 5.0.18-8 changelog by saying in which package the NEWS.Debian + file is (thanks to Ross Boylan). Closes: #355978 + + -- Christian Hammers Tue, 14 Mar 2006 22:56:13 +0100 + +mysql-dfsg-5.0 (5.0.18-9) unstable; urgency=medium + + [ Christian Hammers ] + * When using apt-get the check for left-over ISAM tables can abort the + installation of mysql-server-5.0 but not prevent the mysql-server-4.1 + package from getting removed. The only thing I can do is reflect this + in the Debconf notice that is shown and suggest to reinstall + mysql-server-4.1 for converting. See: #354850 + * Suggests removing of /etc/cron.daily/mysql-server in last NEWS message + (thanks to Mourad De Clerck). Closes: #354111 + * Added versioned symbols for kfreebsd and Hurd, too (thanks to Aurelien + Jarno and Michael Bank). Closes: #353971 + * Added versioned symbols for kfreebsd, too (thanks to Aurelien Jarno). + Closes: #353971 + [ Adam Conrad ] + * Add 39_scripts__mysqld_safe.sh__port_dir.dpatch to ensure that the + permissions on /var/run/mysqld are always correct, even on a tmpfs. + + -- Christian Hammers Mon, 6 Mar 2006 21:42:13 +0100 + +mysql-dfsg-5.0 (5.0.18-8) unstable; urgency=low + + * The rotation of the binary logs is now configured via + expire-logs-days in /etc/mysql/my.cnf and handled completely + by the server and no longer in configured in debian-log-rotate.conf + and handled by a cron job. Thanks to David Johnson. + See /usr/share/doc/mysql-server-5.0/NEWS.Debian + * Ran aspell over some files in debian/ and learned a lot :) + * debian/rules: Added check if versioned symbols are really there. + * Updated SSL-MINI-HOWTO. + * Updated copyright (removed the parts regarding the now removed + BerkeleyDB table handler and mysql-doc package). + * Relocated a variable in preinst (thanks to Michael Heldebrant). + Closes: #349258, #352587, #351216 + * Updated Danish debconf translation (thanks to Claus Hindsgaul). + Closes: #349013 + * Updated Swedish debconf translation (thanks to Daniel Nylander). + Closes: #349522 + * Updated French debconf translation (thanks to Christian Perrier). + Closes: #349592 + * Fixed typo in README.Debian (thanks to Vincent Ricard). + * Prolonged waiting time for mysqld in the init script. Closes: #352070 + + -- Christian Hammers Mon, 23 Jan 2006 23:13:46 +0100 + +mysql-dfsg-5.0 (5.0.18-7) unstable; urgency=low + + * Made mailx in debian-start.inc.sh optional and changed the dependency on it + on it to a mere recommendation. Closes: #316297 + * the previous FTBFS patches for GNU/Hurd inadvertently led to configure + being regenerating, losing a couple trivial things like our versioned + symbols patch, causing many nasty problems (closes: #348854). + + -- sean finney Fri, 20 Jan 2006 20:59:27 +0100 + +mysql-dfsg-5.0 (5.0.18-6) unstable; urgency=low + + * Added version comment (thanks to Daniel van Eeden). + * Added two patches to build on GNU/Hurd (thanks to Michael Bank). + Closes: #348182 + * Abort upgrade if old and now unsupported ISAM tables are present + (thanks to David Coe). Closes: #345895 + + -- Christian Hammers Tue, 17 Jan 2006 19:25:59 +0100 + +mysql-dfsg-5.0 (5.0.18-5) unstable; urgency=low + + * Bump shlibdeps for libmysqlclient15 to (>= 5.0.15-1), which was + the first non-beta release from upstream, as well as being shortly + after we broke the ABI in Debian by introducing versioned symbols. + + -- Adam Conrad Fri, 13 Jan 2006 13:18:03 +1100 + +mysql-dfsg-5.0 (5.0.18-4) unstable; urgency=low + + * Munge our dependencies further to smooth upgrades even more, noting + that we really need 5.0 to conflict with 4.1, and stealing a page from + the book of mysql-common, it doesn't hurt to hint package managers in + the direction of "hey, this stuff is a complete replacement for 4.1" + * Change the description of mysql-server and mysql-client to remove the + references to it being "transition", and instead point out that it's + the way to get the "current best version" of each package installed. + + -- Adam Conrad Wed, 11 Jan 2006 11:39:45 +1100 + +mysql-dfsg-5.0 (5.0.18-3) unstable; urgency=low + + * Make the mysql-{client,server}-5.0 conflict against mysql-{client,server} + versioned, so they can be installed side-by-side and upgrade properly. + * Add myself to Uploaders; since I have access to the alioth repository. + + -- Adam Conrad Tue, 10 Jan 2006 19:15:48 +1100 + +mysql-dfsg-5.0 (5.0.18-2) unstable; urgency=low + + * Removed the transitional package that forced an upgrade from + mysql-server-4.1 to mysql-server-5.0 as I was convinced that + having a general "mysql-server" package with adjusted dependencies + is enough (thanks to Adam Conrad). + * Updated logcheck.ignore files (thanks to Jamie McCarthy). Closes: #340193 + + -- Christian Hammers Mon, 9 Jan 2006 21:54:53 +0100 + +mysql-dfsg-5.0 (5.0.18-1) unstable; urgency=low + + * New upstream version. + * Added empty transitional packages that force an upgrade from the + server and client packages that have been present in Sarge. + * Fixed SSL-MINI-HOWTO (thanks to Jonas Smedegaard). Closes: #340589 + + -- Christian Hammers Mon, 2 Jan 2006 21:17:51 +0100 + +mysql-dfsg-5.0 (5.0.17-1) unstable; urgency=low + + * Never released as Debian package. + + -- Christian Hammers Thu, 22 Dec 2005 07:49:52 +0100 + +mysql-dfsg-5.0 (5.0.16-1) unstable; urgency=low + + * New upstream version. + * Removed the error logs from the logrotate script as Debian does + not use them anymore. Closes: #339628 + + -- Christian Hammers Tue, 22 Nov 2005 01:19:11 +0100 + +mysql-dfsg-5.0 (5.0.15-2) unstable; urgency=medium + + * Added 14_configure__gcc-atomic.h.diff to fix FTBFS on m68k + (thanks to Stephen R Marenka). Closes: #337082 + * Removed dynamic linking against libstdc++ as it was not really + needed (thanks to Adam Conrad). Closes: #328613 + * Fixed the "/var/lib/mysql is a symlink" workaround that accidently + left a stalled symlink (thanks to Thomas Lamy). Closes: #336759 + * As the init script cannot distinguish between a broken startup and + one that just takes very long the "failed" message now says + "or took more than 6s" (thanks to Olaf van der Spek). Closes: #335547 + + -- Christian Hammers Thu, 3 Nov 2005 22:00:15 +0100 + +mysql-dfsg-5.0 (5.0.15-1) unstable; urgency=low + + * New upstream version. 5.0 has finally been declared STABLE! + * Added small patch to debian/rules that fixed sporadic build errors + where stdout and stderr were piped together, got mixed up and broke + * Added --with-big-tables to ./configure (thanks to tj.trevelyan). + Closes: #333090 + * Added capability to parse "-rc" to debian/watch. + * Fixed cronscript (thanks to Andrew Deason). Closes: #335244 + * Added Swedish debconf translation (thanks to Daniel Nylander). + Closes: #333670 + * Added comment to README.Debian regarding applications that manually + set new-style passwords... Closes: #334444 + * Sean Finney: + - Fix duplicate reference to [-e|--extended-insert]. Closes: #334957 + - Fix default behavior for mysqldumpslow. Closes: #334517 + - Reference documentation issue in mysql manpage. Closes: #335219 + + -- Christian Hammers Fri, 30 Sep 2005 00:10:39 +0200 + +mysql-dfsg-5.0 (5.0.13rc-1) unstable; urgency=low + + * New upstream release. Now "release-candidate"! + * Removed any dynamic link dependencies to libndbclient.so.0 which + is due to its version only distributed as a static library. + * Sean Finney: + - FTBFS fix related to stripping rpath in debian/rules + + -- Christian Hammers Mon, 26 Sep 2005 22:09:26 +0200 + +mysql-dfsg-5.0 (5.0.12beta-5) unstable; urgency=low + + * The recent FTBFS were probably result of a timing bug in the + debian/patches/75_*.dpatch file where Makefile.in got patched just + before the Makefile.shared which it depended on. For that reason + only some of the autobuilders failed. Closes: #330149 + * Fixed chrpath removal (option -k had to be added). + * Corrected debconf dependency as requested by Joey Hess. + + -- Christian Hammers Mon, 26 Sep 2005 18:37:07 +0200 + +mysql-dfsg-5.0 (5.0.12beta-4) unstable; urgency=low + + * Removed experimental shared library libndbclient.so.0.0.0 as it + is doomed to cause trouble as long as it is present in both MySQL 4.1 + and 5.0 without real soname and its own package. We still have + libndbclient.a for developers. (thanks to Adam Conrad and + mediaforest.net). Closes: #329772 + + -- Christian Hammers Fri, 23 Sep 2005 12:36:48 +0200 + +mysql-dfsg-5.0 (5.0.12beta-3) unstable; urgency=medium + + * Symbol versioning support! wooooohoooooo! + (thanks to Steve Langasek) Closes: #236288 + * Moved libndbcclient.so.0 to the -dev package as it is provided by + libmysqlclient14 and -15 which must be installable simultaneously. + * Removed mysql-*-doc suggestions. + + -- Christian Hammers Tue, 20 Sep 2005 00:07:03 +0200 + +mysql-dfsg-5.0 (5.0.12beta-2) unstable; urgency=low + + * Added patch to build on GNU/kFreeBSD (thanks to Aurelien Jarno). + Closes: #327702 + * Added patch that was already been present on the 4.1 branch which + makes the "status" command of the init script more sensible + (thanks to Stephen Gildea). Closes: #311836 + * Added Vietnamese Debconf translation (thanks to Clytie Siddal). + Closes: #313006 + * Updated German Debconf translation (thanks to Jens Seidel). + Closes: #313957 + * Corrected commends in example debian-log-rotate.conf. The default is + unlike the mysql-sever-4.1 package which needed to stay backwards + compatible now 2 to avoid filling up the disk endlessly. + * Fixed watch file to be "-beta" aware. + + -- Christian Hammers Thu, 15 Sep 2005 20:50:19 +0200 + +mysql-dfsg-5.0 (5.0.12beta-1) unstable; urgency=medium + + * Christian Hammers: + - New upstream release. + - Changed build-dep to libreadline5-dev as requested by Matthias Klose. + Closes: #326316 + - Applied fix for changed output format of SHOW MASTER LOGS for + binary log rotation (thanks to Martin Krueger). Closes: #326427, #326427 + - Removed explicit setting of $PATH as I saw no sense in it and + it introduced a bug (thanks to Quim Calpe). Closes: #326769 + - Removed PID file creation from /etc/init.d/mysql-ndb as it does + not work with this daemon (thanks to Quim Calpe). + - Updated French Debconf translation (thanks to Christian Perrier). + Closes: #324805 + - Moved conflicts line in debian/control from libmysqlclient15 to + libmysqlclient15-dev and removed some pre-sarge conflicts as + suggested by Adam Majer. Closes: #324623 + * Sean Finney: + - For posterity, CAN-2005-2558 has been fixed since 5.0.7beta. + + -- Christian Hammers Thu, 15 Sep 2005 19:58:22 +0200 + +mysql-dfsg-5.0 (5.0.11beta-3) unstable; urgency=low + + * Temporarily build only with -O2 to circumvent gcc internal errors + (thanks to Matthias Klose). Related to: #321165 + + -- Christian Hammers Thu, 18 Aug 2005 15:44:04 +0200 + +mysql-dfsg-5.0 (5.0.11beta-2) unstable; urgency=low + + * Fixed README.Debian regarding the status of mysql-doc. + * Added "set +e" around chgrp in mysql-server-5.0.preinst to + not fail on .journal files (thanks to Christophe Nowicki). + Closes: #318435 + + -- Christian Hammers Sun, 14 Aug 2005 18:02:08 +0200 + +mysql-dfsg-5.0 (5.0.11beta-1) unstable; urgency=low + + * New upstream version. + * Added Danish Debconf translations (thanks to Claus Hindsgaul). + Closes: #322384 + * Updated Czech Debconf translations (thanks to Miroslav Kure). + Closes: #321765 + + -- Christian Hammers Sat, 13 Aug 2005 11:56:15 +0000 + +mysql-dfsg-5.0 (5.0.10beta-1) unstable; urgency=low + + * New upstream release. + * Christian Hammers: + - Added check for mounted /proc to debian/rules. + * Sean Finney: + - fix for fix_mysql_privilege_tables/mysql_fix_privilege_tables typo + in mysql-server-5.0's README.Debian (see #319838). + + -- Christian Hammers Sun, 31 Jul 2005 00:30:45 +0200 + +mysql-dfsg-5.0 (5.0.7beta-1) unstable; urgency=low + + * Second try for new upstream release. + * Renamed mysql-common-5.0 to mysql-common as future libmysqlclient16 + from e.g. MySQL-5.1 would else introduce mysql-common-5.1 which makes + a simultanous installation of libmysqlclient14 impossible as that + depends on either mysql-common or mysql-common-5.0 but not on future + versions. Thus we decided to always let the newest MySQL version + provide mysql-common. + * Added ${misc:Depends} as suggested by debhelper manpage. + * Raised standard in control file to 3.6.2. + * Removed DH_COMPAT from rules in faviour of debian/compat. + * Checkes for presence of init script before executing it in preinst. + Referres: 315959 + * Added 60_includes_mysys.h__gcc40.dpatch for GCC-4.0 compatibility. + + -- Christian Hammers Wed, 29 Jun 2005 00:39:05 +0200 + +mysql-dfsg-5.0 (5.0.5beta-1) unstable; urgency=low + + * New major release! Still beta so be carefull... + * Added federated storage engine. + + -- Christian Hammers Wed, 8 Jun 2005 19:29:45 +0200 + +mysql-dfsg-4.1 (4.1.12-1) unstable; urgency=low + + * Christian Hammers: + - New upstream release. + - Disabled BerkeleyDB finally. It has been obsoleted by InnoDB. + * Sean Finney: + - Updated French translation from Christian Perrier (Closes: #310526). + - Updated Japanese translation from Hideki Yamane (Closes: #310263). + - Updated Russian translation from Yuriy Talakan (Closes: #310197). + + -- Christian Hammers Sat, 4 Jun 2005 05:49:11 +0200 + +mysql-dfsg-4.1 (4.1.11a-4) unstable; urgency=high + + * Fixed FTBFS problem which was caused due to the fact that last uploads + BerkeleyDB patch was tried to applied on all architectures and not only + on those where BerkeleyDB is actually beeing built. Closes: #310296 + + -- Christian Hammers Mon, 23 May 2005 00:54:51 +0200 + +mysql-dfsg-4.1 (4.1.11a-3) unstable; urgency=high + + * Added patch from Piotr Roszatycki to compile the bundled db3 library + that is needed for the BerkeleyDB support with versioned symbols so + that mysqld no longer crashes when it gets linked together with the + Debian db3 version which happens when e.g. using libnss-db. + Closes: #308966 + + -- Christian Hammers Thu, 19 May 2005 01:41:14 +0200 + +mysql-dfsg-4.1 (4.1.11a-2) unstable; urgency=high + + * Okay, the hackery with /var/lib/dpkg/info/mysql-server.list will not + stand and is removed from the preinst of mysql-server. + * New workaround for the symlink problem that does not involve mucking + with dpkg's file lists is storing the symlinks in a temporary location + across upgrades. + As this sometimes fails since apt-get does not always call new.preinst + before old.postrm, some remarks were added to README.Debian and the + Debconf installation notes to minimize the inconvinience this causes. + + -- sean finney Sun, 15 May 2005 10:25:31 -0400 + +mysql-dfsg-4.1 (4.1.11a-1) unstable; urgency=high + + * Added the "a" to the version number to be able to upload a new + .orig.tar.gz file which now has the non-free Docs/ directory removed + as this has been forgotten in the 4.1.11 release (thanks to Goeran + Weinholt). Closes: #308691 + * The Woody package listed /var/lib/mysql and /var/log/mysql in its + /var/lib/dpkg/info/mysql-server.list. These directories are often + replaced by symlinks to data partitions which triggers a dpkg bug + that causes these symlinks to be removed on upgrades. The new preinst + prevents this by removing the two lines from the .list file + (thanks to Andreas Barth and Jamin W. Collins). See dpkg bug #287978. + * Updated French Debconf translation (thanks to Christian Perrier). + Closes: #308353 + + -- Christian Hammers Thu, 12 May 2005 21:52:46 +0200 + +mysql-dfsg-4.1 (4.1.11-3) unstable; urgency=high + + * The "do you want to remove /var/lib/mysql when purging the package" flag + from old versions is removed once this package is beeing installed so + that purging an old Woody mysql-server package while having a + mysql-server-4.1 package installed can no longer lead to the removal of + all databases. Additionaly clarified the wording of this versions Debconf + template and added a check that skips this purge in the postrm script + if another mysql-server* package has /usr/sbin/mysqld installed. + (thanks to Adrian Bunk for spotting that problem) Closes: #307473 + * Cronfile was not beeing installed as the filename was not in the + correct format for "dh_installcron --name" (thanks to Tomislav + Gountchev). Closes: #302712 + + -- Christian Hammers Sat, 23 Apr 2005 22:55:15 +0200 + +mysql-dfsg-4.1 (4.1.11-2) unstable; urgency=low + + * Sean Finney: + - don't freak out if we can't remove /etc/mysql during purge. + - debian/rules clean works again. + * Christian Hammers: + - Fixed typo in README.Debian (thanks to Joerg Rieger). Closes: #304897 + - Completely removed the passwordless test user as it was not only + insecure but also lead to irritations as MySQL checks first the + permissions of this user and then those of a password having one. + See bug report from Hilko Bengen for details. Closes: #301741 + + -- Christian Hammers Sat, 16 Apr 2005 15:55:00 +0200 + +mysql-dfsg-4.1 (4.1.11-1) unstable; urgency=low + + * New upstream version. + * Upstream fix for charset/collation problem. Closes: #282256 + * Upstream fix for subselect crash. Closes: #297687 + * Corrected minor issue in Debconf template regarding skip-networking + (thanks to Isaac Clerencia). Closes: #303417 + * Made dependency to gawk unnecessary (thanks to Zoran Dzelajlija). + Closes: #302284 + * Removed obsolete 50_innodb_mixlen.dpatch. + * Removed obsolete 51_CAN-2004-0957_db_grant_underscore.dpatch. + + -- Christian Hammers Fri, 8 Apr 2005 00:23:53 +0200 + +mysql-dfsg-4.1 (4.1.10a-7) unstable; urgency=low + + * Sean Finney: + - fix for the mysteriously disappeared cronjob. thanks to + Peter Palfrader for pointing out this omission. + (closes: #302712). + + -- sean finney Sat, 02 Apr 2005 16:54:13 -0500 + +mysql-dfsg-4.1 (4.1.10a-6) unstable; urgency=high + + * Sean Finney: + - the previous upload did not completely address the issue. this one + should do so. d'oh. + + -- sean finney Thu, 31 Mar 2005 03:35:50 +0000 + +mysql-dfsg-4.1 (4.1.10a-5) unstable; urgency=high + + * Sean Finney: + - the following security issue is addressed in this upload: + CAN-2004-0957 (grant privilege escalation on tables with underscores) + thanks to sergei at mysql for all his help with this. + + -- sean finney Wed, 30 Mar 2005 21:19:26 -0500 + +mysql-dfsg-4.1 (4.1.10a-4) unstable; urgency=low + + * Sean Finney: + - FTBFS fix for amd64/gcc-4.0. Thanks to Andreas Jochens + for reporting this (closes: #301807). + - ANSI-compatible quoting fix in daily cron job. thanks to + Karl Hammar for pointing out the problem in + the 4.0 branch. + - Added myself as a co-maintainer in the control file (closes: #295312). + + -- sean finney Tue, 29 Mar 2005 18:54:42 -0500 + +mysql-dfsg-4.1 (4.1.10a-3) unstable; urgency=low + + * BerkeleyDB is now disabled by default as its use is discouraged by MySQL. + * Added embedded server libraries as they finally do compile. + They are currently in libmysqlclient-dev as they are still + experimental and only available as .a library (thanks to Keith Packard). + Closes: #297062 + * Fixed obsolete "tail" syntax (thanks to Sven Mueller). Closes: #301413 + * Added CAN numbers for the latest security bugfix upload. + * Updated manpage of mysqlmanager (thanks to Justin Pryzby). Closes: #299844 + * Added comments to default configuration. + + -- Christian Hammers Sun, 20 Mar 2005 17:40:18 +0100 + +mysql-dfsg-4.1 (4.1.10a-2) unstable; urgency=low + + * Disabled "--with-mysqld-ldflags=-all-static" as it causes sig11 crashes + if LDAP is used for groups in /etc/nsswitch.conf. Confirmed by Sean Finney + and Daniel Dehennin. Closes: #299382 + + -- Christian Hammers Mon, 14 Mar 2005 03:01:03 +0100 + +mysql-dfsg-4.1 (4.1.10a-1) unstable; urgency=high + + * SECURITY: + - The following security related updates are addressed: + CAN-2005-0711 (temporary file creation with "CREATE TEMPORARY TABLE") + CAN-2005-0709 (arbitrary library injection in udf_init()) + CAN-2005-0710 (arbitrary code execution via "CREATE FUNCTION") + Closes: #299029, #299031, #299065 + * New Upstream Release. + - Fixes some server crash conditions. + - Upstream includes fix for TMPDIR overriding my.cnf tmpdir setting + Closes: #294347 + - Fixes InnoDB error message. Closes: #298875 + - Fixes resouce limiting. Closes: #285044 + * Improved checking whether or not the server is alive in the init script + which should make it possible to run several mysqld instances in + different chroot environments. Closes: #297772 + * Fixed cron script name as dots are not allowed (thanks to Michel + v/d Ven). Closes: #298447 + * Added -O3 and --with-mysqld-ldflags=-all-static as MySQL recommends to + build the server binary statically in order to gain about 13% more + performance (thanks to Marcin Kowalski). + * Added patch to let mysqld_safe react to signals (thanks to Erich + Schubert). Closes: #208364 + * (Thanks to Sean Finney for doing a great share of work for this release!) + + -- Christian Hammers Thu, 3 Mar 2005 02:36:39 +0100 + +mysql-dfsg-4.1 (4.1.10-4) unstable; urgency=medium + + * Fixed bug that prevented MySQL from starting after upgrades. + Closes: #297198, #296403 + * Added comment about logging to syslog to the default my.cnf + and the logrotate script (thanks to Ryszard Lach). Closes: #295507 + + -- Christian Hammers Thu, 3 Mar 2005 00:28:02 +0100 + +mysql-dfsg-4.1 (4.1.10-3) unstable; urgency=low + + * Sean Finney: Cronjobs now exit silently when the server package + has been removed but not purged (thanks to Vineet Kumar). + Closes: #297404 + * Fixed comments of /etc/mysql/debian-log-rotate.conf (thanks to + Philip Ross). Closes: #297467 + * Made mysqld_safe reacting sane on signals (thanks to Erich Schubert). + Closes: #208364 + + -- Christian Hammers Tue, 1 Mar 2005 19:44:34 +0100 + +mysql-dfsg-4.1 (4.1.10-2) unstable; urgency=low + + * Converted to dpatch. + * debian/ is now maintained via Subversion on svn.debian.org. + + -- Christian Hammers Tue, 1 Mar 2005 02:16:36 +0100 + +mysql-dfsg-4.1 (4.1.10-1) unstable; urgency=low + + * New upstream version. + * Upstream fixed memleak bug. Closes: #205587 + * Added debian/copyright.more for personal reference. + * Lowered default query cache size as suggested by Arjen from MySQL. + * Switched from log to log-bin as suggested by Arjen from MySQL. + * Fixed typo in my.cnf (thanks to Sebastian Feltel). Closes: #295247 + * Replaced --defaults-extra-file by --defaults-file in Debian scripts + as former lets password/host etc be overwriteable by /root/.my.cnf. + Added socket to /etc/mysql/debian.cnf to let it work. (thanks to + SATOH Fumiyasu). Closes: #295170 + + -- Christian Hammers Tue, 15 Feb 2005 23:47:02 +0100 + +mysql-dfsg-4.1 (4.1.9-4) unstable; urgency=low + + * Improved the way mysqld is started and registered with update-rc.d + in cases where the admin modifies the runlevel configuration. + Most notably removed the debconf question whether or not mysql should + start on when booting. Closes: #274264 + * Renamed configuration option old-passwords to the more preferred + naming convention old_passwords. Same for some others (thanks to + Patrice Pawlak). Closes: #293983 + + -- Christian Hammers Tue, 8 Feb 2005 02:21:18 +0100 + +mysql-dfsg-4.1 (4.1.9-3) unstable; urgency=low + + * Renamed ca_ES.po to ca.po to reach a broader audience (thanks to + Christian Perrier). Closes: #293786 + * Expicitly disabled mysqlfs support as it has never been enabled by + configure during the autodetection but fails due to broken upstream + code when users try to build the package theirselves while having + liborbit-dev installed which triggers the mysqlfs autodetection + (thanks to Max Kellermann). Closes: #293431 + * Added dependencies to gawk as one script does not work with original-awk + (thanks to Petr Ferschmann). Closes: #291634 + + -- Christian Hammers Sun, 6 Feb 2005 23:33:11 +0100 + +mysql-dfsg-4.1 (4.1.9-2) unstable; urgency=high + + * SECURITY: + For historical reasons /usr/share/mysql/ was owned and writable by + the user "mysql". This is a security problem as some scripts that + are run by root are in this directory and could be modified and used + by a malicious user who already has mysql privileges to gain full root + rights (thanks to Matt Brubeck). Closes: #293345 + * Changed "skip-networking" to "bind-address 127.0.0.1" which is more + compatible and not less secure but maybe even more, as less people enable + networking for all interfaces (thanks to Arjen Lentz). + * Enabled InnoDB by default as recommended by Arjen Lentz from MySQL. + * Added remarks about hosts.allow to README.Debian (thanks to David + Chappell). Closes: #291300 + * mysql-server-4.1 now provides mysql-server (thanks to Paul van den Berg). + Closes: #287735 + + -- Christian Hammers Wed, 2 Feb 2005 23:31:55 +0100 + +mysql-dfsg-4.1 (4.1.9-1) unstable; urgency=low + + * New upstream version. + * mysql-client-4.1 now provides "mysql-client" so that packages depending + on mysql-client (ca. 40) can now be used with MySQL-4.1, too. + + -- Christian Hammers Sun, 23 Jan 2005 22:52:48 +0100 + +mysql-dfsg-4.1 (4.1.8a-6) unstable; urgency=high + + * SECURITY: + Javier Fernandez-Sanguino Pena from the Debian Security Audit Project + discovered a temporary file vulnerability in the mysqlaccess script of + MySQL that could allow an unprivileged user to let root overwrite + arbitrary files via a symlink attack and could also could unveil the + contents of a temporary file which might contain sensitive information. + (CAN-2005-0004, http://lists.mysql.com/internals/20600) Closes: #291122 + + -- Christian Hammers Tue, 18 Jan 2005 23:11:48 +0100 + +mysql-dfsg-4.1 (4.1.8a-5) unstable; urgency=medium + + * Fixed important upstream bug that causes from_unixtime(0) to return + NULL instead of "1970-01-01 00:00:00" which fails on NOT NULL columns. + Closes: #287792 + * Fixes upstream bug in mysql_list_fields() . Closes: #282486 + * Fixes bug that lead to double rotated logfiles when mysql-server 4.0 + was previously installed (thanks to Olaf van der Spek). Closes: #289851 + * Fixed typo in README.Debian (thanks to Mark Nipper). Closes: #289131 + * Changed max_allowed_packet in my.cnf to 16M as in 4.0.x (thanks to + Olaf van der Spek). Closes: #289840 + * Updated French debconf translation (thanks to Christian Perrier). + Closes: #287955 + + -- Christian Hammers Thu, 13 Jan 2005 01:29:05 +0100 + +mysql-dfsg-4.1 (4.1.8a-4) unstable; urgency=low + + * Broken patch again :-( + + -- Christian Hammers Sun, 9 Jan 2005 23:47:55 +0100 + +mysql-dfsg-4.1 (4.1.8a-3) unstable; urgency=low + + * The mutex patch was a bit too x86 centric. This broke the alpha build. + + -- Christian Hammers Sun, 9 Jan 2005 14:18:49 +0100 + +mysql-dfsg-4.1 (4.1.8a-2) unstable; urgency=medium + + * Some Makefiles that were patched by me got overwritten by the GNU + autotools, probably because I also patched ./configure. Fixed now, + the critical mutex patch is now back in again. Closes: #286961 + * Added patch to make MySQL compile on ARM (thanks to Adam Majer). + Closes: #285071 + + -- Christian Hammers Thu, 6 Jan 2005 09:30:13 +0100 + +mysql-dfsg-4.1 (4.1.8a-1) unstable; urgency=medium + + * Upstream 4.1.8 had some problems in their GNU Autotools files so they + released 4.1.8a. Debian's 4.1.8 was fixed by running autoreconf but this + again overwrote MySQL changes to ltmain.sh which are supposed to fix some + problems on uncommon architectures (maybe the FTBFS on alpha, arm, m68k + and sparc?). + * libmysqlclient_r.so.14 from 4.1.8-3 also missed a link dependency to + libz which lead to unresolved symbols visible with "ldd -r" (thanks + to Laurent Bonnaud). Closes: #287573 + + -- Christian Hammers Wed, 29 Dec 2004 14:26:33 +0100 + +mysql-dfsg-4.1 (4.1.8-3) unstable; urgency=low + + * Fixed checking for error messages by forcing english language + output by adding LC_ALL=C to debian-start (thanks to Rene + Konasz) Closes: #285709 + * Fixed bashisms in Debian scripts. Closes: #286863 + * Updated Japanese Debconf translation (thanks to Hideki Yamane). + Closes: #287003 + * Improved 4.0 to 4.1 upgrade if /var/lib/mysql is a symlink + (thanks to Thomas Lamy). Closes: #286560 + * Added patch for FTBFS problem where no LinuxThreads can be found. + I don't know if this still applies but it should not hurt. + The patch is debian/patches/configure__AMD64-LinuxThreads-vs-NPTL.diff + + -- Christian Hammers Sun, 26 Dec 2004 14:04:20 +0100 + +mysql-dfsg-4.1 (4.1.8-2) unstable; urgency=low + + * If /var/lib/mysql is a symlink then it is kept as such. + * Added the old-passwords option to the default my.cnf to stay + compatible to clients that are still compiled to libmysqlclient10 + and libmysqlclient12 for licence reasons. + * Adjusted tetex build-deps to ease backporting (thanks to Norbert + Tretkowski from backports.org). + + -- Christian Hammers Tue, 21 Dec 2004 01:00:27 +0100 + +mysql-dfsg-4.1 (4.1.8-1) unstable; urgency=medium + + * New upstream version. Closes: #286175 + * Added conflict to libmysqlclient-dev (thanks to Adam Majer). + Closes: #286538 + * Added debconf-updatepo to debian/rules:clean. + * Updated Japanese Debconf translation (thanks to Hideki Yamane). + Closes: #285107 + * Updated French Debconf translation (thanks to Christian Perrier). + Closes: #285977 + * Renamed cz.po to cs.po (thanks to Miroslav Kure). Closes: #285438 + * Aplied patch for changed server notice to debian-start (thanks to + Adam Majer). Closes: #286035 + * Changed nice value in default my.cnf as nohup changed its behaviour + (thanks to Dariush Pietrzak). Closes: #285446 + * Increased verbosity of preinst script in cases where it cannot stop + a running server (thanks to Jan Minar). Closes: #285982 + * Splitted the code parts of /etc/mysql/debian-start to + /usr/share/mysql/debian-start.inc.sh (thanks to Jan Minar). + Closes: #285988 + + -- Christian Hammers Mon, 20 Dec 2004 00:33:21 +0100 + +mysql-dfsg-4.1 (4.1.7-4) unstable; urgency=medium + + * Removed OpenSSL support. + After a short discussion with MySQL, I decided to drop OpenSSL support as + 1. MySQL started shipping their binaries without it, too and do not + seem to support it in favour of using a different library somewhen. + 2. MySQL did not adjust their licence to grant permission to link + against OpenSSL. + 3. Even if they did, third parties who use libmysqlclient.so often + do not realise licencing problems or even do not want OpenSSL. + (thanks to Jordi Mallach and the responders to MySQL bug #6924) + Closes: #283786 + * debian/control: Improved depends and conflicts to mysql-4.0. + + -- Christian Hammers Thu, 2 Dec 2004 22:02:28 +0100 + +mysql-dfsg-4.1 (4.1.7-3) unstable; urgency=low + + * Raised version to make it higher as the one in experimental. + + -- Christian Hammers Wed, 1 Dec 2004 21:09:20 +0100 + +mysql-dfsg-4.1 (4.1.7-2) unstable; urgency=low + + * Patched scripts/mysql_install_db so that it no longer creates a + passwordless test database during installation (thanks to Patrick + Schnorbus). Closes: #281158 + * Added Czech debconf translation (thanks to Miroslav Kure). + Closes: #283222 + + -- Christian Hammers Wed, 1 Dec 2004 01:29:31 +0100 + +mysql-dfsg-4.1 (4.1.7-1) unstable; urgency=low + + * New upstream branch! + * Adjusted debian/control to make this package suitable to get parallel + to version 4.0.x into unstable and sarge. The package names are + different so that "mysql-server" still defaults to the rock-stable + 4.0 instead to this announced-to-be-stable 4.1. + * Added --with-mutex=i86/gcc-assemler to the Berkeley-DB configure + to prevent the use of NPLT threads when compiling under kernel 2.6 + because the binaries are else not runable on kernel 2.4 hosts. + Closes: #278638, #274598 + + -- Christian Hammers Sun, 31 Oct 2004 20:15:03 +0100 + +mysql-dfsg (4.1.6-1) experimental; urgency=low + + * New upstream version. + * Fixed symlinks in libmysqlclient-dev package. Closes: #277028 + * This time I did not update the libtool files as they were pretty + up to date and I want to have a shorter diff file. + + -- Christian Hammers Wed, 20 Oct 2004 00:07:58 +0200 + +mysql-dfsg (4.1.5-3) experimental; urgency=low + + * debian/postinst: mysql_install_db changed parameter from --IN-RPM + to --rpm which caused problems during installs. Closes: #276320 + + -- Christian Hammers Sat, 16 Oct 2004 20:36:46 +0200 + +mysql-dfsg (4.1.5-2) experimental; urgency=low + + * Activated support for ndb clustering (thanks to Kevin M. Rosenberg). + Closes: #275109 + + -- Christian Hammers Wed, 6 Oct 2004 01:58:00 +0200 + +mysql-dfsg (4.1.5-1) experimental; urgency=low + + * WARNING: + The upstream branch 4.1 is still considered BETA. + The Debian packages for 4.1 were done without big testing. If you miss + a new functionality or binary, contact me and I check add the relevant + configure option or include the program. + * New MAJOR upstream version. + Thanks to the great demand here's now the first MySQL 4.1 experimental + release. FEEDBACK IS WELCOME. + * 4.0->4.1 notes: + - debian/patches/alpha.diff could not be applied, I fix that later + - debian/patches/scripts__mysql_install_db.sh.diff was obsolete + - debian/patches/scripts__Makefile.in was neccessary due to a dependency + to the removed non-free Docs/ directory. Upstream has been contacted. + - Build-Deps: += automake1.7 + - debian/rules: embedded servers examples did not compile, removed + + -- Christian Hammers Sun, 26 Sep 2004 19:46:47 +0200 + +mysql-dfsg (4.0.21-3) unstable; urgency=low + + * Upstream tried to fix a security bug in mysqlhotcopy and broke it :-) + Applied a patch (see debian/patches) from Martin Pitt. Closes: #271632 + * Between 4.0.20 and 4.0.21 the Debian specific changes in + /usr/bin/mysqld_safe that piped the error log to syslog got lost + and are now back again. + * Fixed capitalization in debconf headings. + * Changed wording of the initscript status message to make heartbeat + happier. Closes: #271591 + + -- Christian Hammers Fri, 17 Sep 2004 18:42:25 +0200 + +mysql-dfsg (4.0.21-2) unstable; urgency=medium + + * The dependencies between mysql-client and libmysqlclient12 were + too loose, when upgrading only the client this can lead to non working + binaries due to relocation errors (thanks to Dominic Cleal). + Closes: #271803 + * Fixed typo in mysqldump.1 manpage (thanks to Nicolas Francois). + Closes: #271334 + + -- Christian Hammers Wed, 15 Sep 2004 15:38:11 +0200 + +mysql-dfsg (4.0.21-1) unstable; urgency=high + + * SECURITY: + This upstream version fixes some security problems that might at least + allow a DoS attack on the server. + * Fixed an old bug in concurrent accesses to `MERGE' tables (even + one `MERGE' table and `MyISAM' tables), that could've resulted in + a crash or hang of the server. (Bug #2408) + * Fixed bug in privilege checking where, under some conditions, one + was able to grant privileges on the database, he has no privileges + on. (Bug #3933) + * Fixed crash in `MATCH ... AGAINST()' on a phrase search operator + with a missing closing double quote. (Bug #3870) + * Fixed potential memory overrun in `mysql_real_connect()' (which + required a compromised DNS server and certain operating systems). + (Bug #4017) + * New upstream version. + * Fixes bug that made x="foo" in WHERE sometimes the same as x="foo ". + Closes: #211618 + * Updated Japanese Debconf translation (thanks to Hideki Yamane). + Closes: #271097 + + -- Christian Hammers Sat, 11 Sep 2004 23:15:44 +0200 + +mysql-dfsg (4.0.20-14) unstable; urgency=low + + * Dave Rolsky spottet that -DBIG_JOINS was not properly enabled. + It allowes joining 64 instead of an 32 tables to join. + + -- Christian Hammers Thu, 9 Sep 2004 20:24:02 +0200 + +mysql-dfsg (4.0.20-13) unstable; urgency=medium + + * Fixed a bug in the initscript which caused the check for not properly + closed i.e. corrupt tables that is executed when the server starts + not to run in background as supposed. + Although the check does not repair anything on servers with several + thousand tables the script was reported to take some minutes which + is quite annoying. (Thanks to Jakob Goldbach). Closes: #270800 + + -- Christian Hammers Thu, 9 Sep 2004 17:11:05 +0200 + +mysql-dfsg (4.0.20-12) unstable; urgency=medium + + * Filter messages regarding table handles that do not support CHECK TABLE + in the script that checks for corrupted tables on every start which lead + to unnecessary mails (thanks to David Everly). Closes: #269811 + * Added a note to the corrupt-table-check mail which notes that a + false-positive is reported in the case that immediately after starting + the server a client starts using a table (thanks to Uwe Kappe). + Closes: #269985 + * Added "quote-names" as default to the [mysqldump] section in + /etc/mysql/my.cnf as too many users stumble over dump files that + could not be read in again due to the valid use of reserved words + as table names. This has also be done by upstream in 4.1.1 and has + no known drawbacks. Closes: #269865 + * Binary logs can now be rotated as well. Defaults to off, though, for + compatibilty reasons (thanks to Mark Ferlatte). Closes: #94230, #269110 + * The mysql user "debian-sys-maint" now gets all possible rights which + makes binary logging possible and helps other package maintainer who + wants to use it to create package specific databases and users. + * Added example how to change daemon nice level via /etc/mysql/my.cnf + * Updated French debconf translations (thanks to Christian Perrier). + Closes: #265811 + * Renamed options in the default config file that still had old names + (thanks to Yves Kreis). Closes: #266445 + * Fixed spelling in debconf note. + * Added -l and -L to dh_shlibdeps. + + -- Christian Hammers Fri, 3 Sep 2004 20:10:46 +0200 + +mysql-dfsg (4.0.20-11) unstable; urgency=high + + * SECURITY + This version fixes a security flaw in mysqlhotcopy which created + temporary files in /tmp which had predictable filenames and such + could be used for a tempfile run attack. + The issue has been recorded as CAN-2004-0457. + + -- Christian Hammers Sat, 14 Aug 2004 18:27:19 +0200 + +mysql-dfsg (4.0.20-10) unstable; urgency=low + + * MySQL finally updated their copyright page and installed v1.5 of + the "Free/Libre and Open Source Software License (FLOSS) - Exception" + which will hopefully end the license hell they created by putting the + client libraries under GPL instead of LGPL which conflicts with PHP and + other software that used to link against MySQL. + The license text is not yet in any release MySQL version but visible + on their web site and copied into the debian/copyright file. + Special thanks to Zak Greant and the debian-legal list + for helping to solve this release critical problem. + Closes: #242449 + * Updated Brazil debconf translation (thanks to Andre Luis Lopes). + Closes: #264233 + * Updated Japanese debconf translation (thanks to Hideki Yamane). + Closes: #264620 + * Fixed minor typo in debconf description (thanks to TROJETTE Mohammed + Adnene). Closes: #264840 + * Improved init and preinst script which now detects stalled servers which + do no longer communicate but are present in the process list (thanks to + Henrik Johansson). Closes: #263215 + + -- Christian Hammers Mon, 9 Aug 2004 19:44:28 +0200 + +mysql-dfsg (4.0.20-9) unstable; urgency=medium + + * Partly reverted the last patch which gave the mysql-user + "debian-sys-maint" more rights as there are old versions of MySQL which + have fewer privlige columns. Now only those are set (thanks to Alan Tam). + Closes: #263111 + + -- Christian Hammers Tue, 3 Aug 2004 13:03:02 +0200 + +mysql-dfsg (4.0.20-8) unstable; urgency=low + + * The mysqlcheck that is started from the initscript will now be + backgrounded because it might else prevent the boot process to continue. + It also now notifies root by mail and syslog if a table is corrupt. + * The "debian-sys-maint" MySQL user now has almost full rights so that other + packages might use this account to create databases and user (thanks to + Andreas Barth). Closes: #262541 + * Added paranoid rules for logcheck. + + -- Christian Hammers Sun, 1 Aug 2004 21:00:55 +0200 + +mysql-dfsg (4.0.20-8) unstable; urgency=low + + * Upload stalled. Not released. + + -- Christian Hammers Sun, 1 Aug 2004 20:27:55 +0200 + +mysql-dfsg (4.0.20-7) unstable; urgency=medium + + * Solved the upstream bug that error messages of the server are written + in a file that is then rotated away leaving mysqld logging effectively + to /dev/null. It now logs to a /usr/bin/logger process which puts the + messages into the syslog. + Modified files: /etc/init.d/mysql, /usr/bin/mysqld_safe and the + logchecker files. Closes: #254070 + * The initscript does no longer call mysqlcheck directly but via + /etc/mysql/debian-start which is a user customizable config script. + * Splitted the debconf "install and update notes" and only show them + when it is appropriate (thanks to Steve Langasek). Closes: #240515 + * Added NEWS.Debian. + * Added hint to -DBIG_ROWS, which is currently not used, to README.Debian. + * Corrected typo in myisampack manpage (thanks to Marc Lehmann). + Closes: #207090 + * Added Catalan debconf translation (thanks to Aleix Badia i Bosch). + Closes: #236651 + + -- Christian Hammers Wed, 28 Jul 2004 01:41:51 +0200 + +mysql-dfsg (4.0.20-6) unstable; urgency=low + + * The build arch detected by configure was "pc-linux-gnu (i686)" + instead of "pc-linux-gnu (i386)". Was no problem AFAIK but + Adam Majer asked me to explicitly change it to i386. Closes: #261382 + * Removed some unused shell scripts from /usr/share/mysql. + * Added lintian overrides. + * Removed rpath by using chrpath. + + -- Christian Hammers Mon, 26 Jul 2004 00:17:12 +0200 + +mysql-dfsg (4.0.20-5) unstable; urgency=medium + + * The mysqlcheck in the init script is only called when the server + is really alive. Also, the mysql-user 'debian-sys-maint' now has + global select rights (thanks to Nathan Poznick). Closes: #261130 + * Moved the debconf question whether to remove the databases or not + from mysql-server.config to mysql-server.postrm so that it shows + up on purge time and not months earlier (thanks to Wouter Verhelst). + Closes: #251838 + + -- Christian Hammers Fri, 23 Jul 2004 22:41:13 +0200 + +mysql-dfsg (4.0.20-4) unstable; urgency=low + + * Added a "mysqlcheck -A --fast" to the 'start' section of the + init script to help admins detect corrupt tables after a server crash. + Currently it exists with an error message but leaves the server + running. Feedback appreciated! + * Made postinst script more robust by calling db_stop earlier and + so prevent pipe-deadlocks. + * Fixed minor typos in initscript (thanks to "C.Y.M."). Closes: 259518 + * Added the undocumented "-DBIG_JOINS" that MySQL apparently uses in + their MAX binaries. It enables 62 instead of 30 tables in a "join". + (thanks to Dave Rolsky). Closes: #260843 + * Added a "df --portability /var/lib/mysql/." check to the preinst + script as users experienced hard to kill hanging mysqlds in such + a situation (thanks to Vaidas Pilkauskas). Closes: #260306 + + -- Christian Hammers Fri, 23 Jul 2004 00:51:32 +0200 + +mysql-dfsg (4.0.20-3) unstable; urgency=low + + * Improved tolerance if the init script has been deleted (thanks to + Leonid Shulov for spotting the problem). + * Minor wording changes to README.Debian generalizing /root/ by $HOME + (thanks to Santiago Vila). Closes: #257725 + * Added Japanese debconf translation (thanks to Hideki Yamane). + Closes: #256485 + * Fixed commend in my.cnf regarding logfile directory (thanks to Jayen + Ashar). Closes: #253434 + * Correted "ease to" by "ease of" in package description (thanks to + Johannes Berg). Closes: #253510 + + -- Christian Hammers Fri, 9 Jul 2004 00:57:42 +0200 + +mysql-dfsg (4.0.20-2) unstable; urgency=low + + * Removed RPM .spec file from the included documentation as it is pretty + useless (thanks to Loic Minier). + * Added turkish debconf translation (thanks to Recai Oktas). Closes: #252802 + + -- Christian Hammers Sun, 6 Jun 2004 14:48:26 +0200 + +mysql-dfsg (4.0.20-1) unstable; urgency=low + + * New upstream version. + + -- Christian Hammers Mon, 31 May 2004 23:36:39 +0200 + +mysql-dfsg (4.0.18-8) unstable; urgency=low + + * Updated french translation (thanks to Christian Perrier). Closes: #246789 + + -- Christian Hammers Tue, 4 May 2004 23:26:54 +0200 + +mysql-dfsg (4.0.18-7) unstable; urgency=low + + * Added CVE ids for the recent security fixes. + 4.0.18-4 is CAN-2004-0381 (mysqlbug) and + 4.0.18-6 is CAN-2004-0388 (mysql_multi) + + -- Christian Hammers Mon, 19 Apr 2004 18:32:03 +0200 + +mysql-dfsg (4.0.18-6) unstable; urgency=medium + + * SECURITY: + Fixed minor tempfile-run security problem in mysqld_multi. + Unprivileged users could create symlinks to files which were then + unknowingly overwritten by run when this script gets executed. + Upstream informed. Thanks to Martin Schulze for finding this. + + -- Christian Hammers Wed, 7 Apr 2004 01:28:22 +0200 + +mysql-dfsg (4.0.18-5) unstable; urgency=low + + * Little improvements in debian scripts for last upload. + * Added check to logrotate script for the case that a mysql + server is running but not be accessible with the username and + password from /etc/mysql/debian.conf (thanks to Jeffrey W. Baker). + Closes: 239421 + + -- Christian Hammers Sun, 4 Apr 2004 15:27:40 +0200 + +mysql-dfsg (4.0.18-4) unstable; urgency=medium + + * SECURITY: + Aplied fix for unprobable tempfile-symlink security problem in + mysqlbug reported by Shaun Colley on bugtraq on 2004-03-24. + * Updated french debconf translation (thanks to Christian Perrier). + Closes: #236878 + * Updated portugesian debconf translation (thanks to Nuno Senica). + Closes: #239168 + * Updated german debconf translation (thanks to Alwin Meschede). + Closes: #241749 + * Improved debconf template regarding fix_privileges_tables (thanks + to Matt Zimmermann for suggestions). Closes: #219400 + * Improved README.Debian regarding to password settings (thanks to + Yann Dirson). Closes: #241328 + + -- Christian Hammers Sat, 3 Apr 2004 19:52:15 +0200 + +mysql-dfsg (4.0.18-3) unstable; urgency=medium + + * Added Build-Depend to po-debconf to let it build everywhere. + + -- Christian Hammers Wed, 31 Mar 2004 23:43:33 +0200 + +mysql-dfsg (4.0.18-2) unstable; urgency=low + + * Added a "2>/dev/null" to a "which" command as there are two + "which" versions in Debian of which one needs it. Closes: #235363 + + -- Christian Hammers Tue, 2 Mar 2004 23:31:28 +0100 + +mysql-dfsg (4.0.18-1) unstable; urgency=low + + * New upstream version. + * Should now compile and run on ia64 (thanks to Thorsten Werner and + David Mosberger-Tang). Closes: #226863 #228834 + * Converted init scripts to invoce-rc.d (thanks to Erich Schubert). + Closes: 232118 + * Secondlast upload changed logfile location. Closes: #182655 + * Updated Brasilian translation (thanks to Andre Luis Lopes). Closes: + #219847 + + -- Christian Hammers Tue, 17 Feb 2004 23:44:58 +0100 + +mysql-dfsg (4.0.17-2) unstable; urgency=low + + * Improved manpage for mysqldumpslow.1 (thanks to Anthony DeRobertis). + Closes: #231039 + * Improved stopping of crashed daemons in init script (thanks to + Matthias Urlichs). Closes: #230327 + + -- Christian Hammers Mon, 9 Feb 2004 21:54:29 +0100 + +mysql-dfsg (4.0.17-1) unstable; urgency=low + + * Made logging into /var/log/mysql/ the default. Closes: #225206 + + * New upstream version. Closes: #225028 + * Turned on a 25MB query cache by default (thanks to Cyril Bouthors). + Closes: #226789 + * Updated russian translation (thanks to Ilgiz Kalmetev). Closes: #219263 + * Upstream fixes the problem that AND was not commutative (thanks for + Iain D Broadfoot for mentioning). Closes: #227927 + * Fixed minor typo in my.cnf comments (thanks to James Renken). + Closes: #221496 + * Better documents regex. Closes: #214952 + * Fixed minor germanism in debconf template (thanks to Marc Haber). + Closes: #224148 + * Added explaining comment to my.cnf regarding quoted passwords + (Thanks to Patrick von der Hagen). Closes: #224906 + * Changed "find -exec" to "find -print0 | xargs -0" in preinst to + speed it up. Thanks to Cyril Bouthors. Closes: #220229 + + -- Christian Hammers Sun, 18 Jan 2004 16:16:25 +0100 + +mysql-dfsg (4.0.16-2) unstable; urgency=low + + * Tried to repair undefined weak symbols by adding a little Makefile + patch. Closes: #215973 + + -- Christian Hammers Mon, 27 Oct 2003 22:52:10 +0100 + +mysql-dfsg (4.0.16-1) unstable; urgency=low + + * New upstream release. + (Mostly little memory problems and other bugfixes it seems) + * Replaced "." by ":" in chown calls to comply with the env setting + "_POSIX2_VERSION=2000112" (thanks to Robert Luberda). Closes: #217399 + * Adjusted syntax in my.cnf to 4.x standard (thanks to Guillaume Plessis). + Closes: #217273 + * Improved README.Debian password instructions (thanks to Levi Waldron). + Closes: #215046 + * Improved NIS warning debconf-template (thanks to Jeff Breidenbach). + Closes: #215791 + * Explicitly added libssl-dev to the libmysqlclient-dev package as it + is needed for mysql_config and the libmysqlclient package only depends + on libssl which has no unnumbered .so version (thanks to Simon Peter + and Davor Ocelic). Closes: #214436, #216162 + * Added "-lwrap" to "mysql_config --libmysqld-libs" and filed it as + upstream bug #1650 (thanks to Noah Levitt). Closes: #214636 + + -- Christian Hammers Sat, 25 Oct 2003 01:09:27 +0200 + +mysql-dfsg (4.0.15a-1) unstable; urgency=low + + * Same package as 4.0.15-2 but I could not convince the Debian + installer to move the packages out of incoming. + + -- Christian Hammers Tue, 7 Oct 2003 15:10:26 +0200 + +mysql-dfsg (4.0.15-2) unstable; urgency=low + + * Updated package description (thanks to Adrian Bunk). Closes: #210988 + * Fixed small typos in manpages (thanks to Nicolas Francois). + Closes: #211983 + * More updates to package description (thanks to Matthias Lutz/ddtp). + Closes: #213456 + * Updated standards to 3.6.1. + * Closes "new 4.0.15 available" bug. Closes: #213349 + * Updated README.Debian with notes regarding the MySQL manual section + "2.4 Post-installation Setup and Testing" (thanks to Daniel B.). + Closes: #210841 + + -- Christian Hammers Fri, 3 Oct 2003 15:59:39 +0200 + +mysql-dfsg (4.0.15-1) unstable; urgency=high + + * SECURITY: + Users who are able to use the "ALTER TABLE" command on the "mysql" + database may be able to exploit this vulnerability to gain a shell with + the privileges of the mysql server (usually running as the 'mysql' user). + Closes: #210403 + * Fixes small description typos (thanks to Oscar Jarkvik). + * Updated Brazilian Portuguese debconf translation. (thanks to Andre Luis + Lopes). Closes: 208030 + * Replaced depricated '.' by ':' in chown (thanks to Matt Zimmerman). + * Fixed manpage typo (thanks to Marc Lehmann). Closes: #207090 + + -- Christian Hammers Fri, 3 Oct 2003 15:59:35 +0200 + +mysql-dfsg (4.0.14-1) unstable; urgency=low + + * New upstream version. + + -- Christian Hammers Sun, 24 Aug 2003 16:40:36 +0200 + +mysql-dfsg (4.0.13-3) unstable; urgency=low + + * Now start mysqld as default unless you choose not when configurig + with debconf priority low. So packages depending on the server when + installing can access it. Thanks Matt Zimmermann (Closes: #200277) + * Made mysql-server de-installable if the config and database files were + removed by hand before. Thanks to Ard van Breemen (Closes: #200304) + + -- Christian Hammers Tue, 8 Jul 2003 22:30:40 +0200 + +mysql-dfsg (4.0.13-2) unstable; urgency=low + + * Added "nice" option for mysqld_safe to give mysqld a different priority. + Submitted to upstream as MySQL Bug #627. Closes: #192087 + * Fixed possible unbound variable in init script. Closes: #194621 + * Fixed french debconf translation (thx Christian Perrier) Closes: #194739 + * Get rid of automake1.5 (for Eric Dorland). + + -- Christian Hammers Wed, 11 Jun 2003 18:58:32 +0200 + +mysql-dfsg (4.0.13-1) unstable; urgency=medium + + * New upstream version. + !!! Fixes a very bad natural join bug which justifies the urgency=medium. + !!! http://bugs.mysql.com/bug.php?id=291 + * Fixed mysql_fix_privileges manpage (Frederic Briere) Closes: #191776 + * preinst: "which" is more chatty normal executable than as builtin. + (Thanks to David B Harris). Closes: #188659 + + -- Christian Hammers Tue, 6 May 2003 22:03:45 +0200 + +mysql-dfsg (4.0.12-3) unstable; urgency=medium + + * Reincluded new way of creating my debian-sys-maint user from + an old release from experimental. Now works again with old + and new privilege table format. (Thanks to Vincent Danjean + for spotting the problem) Closes: #188201 + * Reincluded hurd build dependency fix from 3.23 branch. + (Thanks to Robert Millan). Closes: #185929 + * Fixed soname in libmysqlclient-dev. Closes: #188160 + * Remove /var/log/mysql/ when purging the package. Closes: #188064 + * Removed /usr/share/doc/mysql/ from mysql-server. Closes: #188066 + * Let group "adm" be able to read logfiles. Closes: #188067 + * Do not call usermod on every upgrade. Closes: #188248 + (Thanks to Philippe Troin for the last three) + * Fixed mysql-server.preinst so that it works on shells where + which is a builtin, too. (Thanks to Erich Schubert) Closes: #181525 + + -- Christian Hammers Fri, 11 Apr 2003 11:32:45 +0200 + +mysql-dfsg (4.0.12-2) unstable; urgency=low + + * + * NEW MAJOR UPSTREAM RELEASE: + * + MySQL 4 has finally been declared as 'stable'. Hurray! Read changelogs. + Thanks to all testers, esp. Jose Luis Tallon, of the versions + that were in the "experimental" section before. + * Modified postinst script to run mysql_fix_privileges on every update. + IMPORTANT: Please report if this breaks anything, it is not supposed to. + * Wrote a SSL-MINI-HOWTO.txt! + * Added zlib1g-dev to libmysqlclient12-dev. Closes: 186656 + * Changed section of libmysqlclient12-dev to libdevel. + * Added even more selfwritten manpages. + * Fixed typos. + + -- Christian Hammers Sun, 6 Apr 2003 13:47:32 +0200 + +mysql-dfsg (4.0.10.gamma-1) experimental; urgency=low + + * New upstream version. + * They merged some of my patches from debian/patches. Whoa! + * This release should fix the error-logfile problem where mysqld + keeps the error.log open while logrotate removes it. + + -- Christian Hammers Wed, 12 Feb 2003 22:39:48 +0100 + +mysql-dfsg (4.0.9.gamma-1) experimental; urgency=low + + * New upstream version. + * Updated the GNU autoconf files to make building on MIPS work. + See bug #176829. + + -- Christian Hammers Wed, 29 Jan 2003 22:07:44 +0100 + +mysql-dfsg (4.0.8.gamma-1) experimental; urgency=low + + * New upstream release. + * Improved logging of init script. Closes: #174790 + * We have now libmysqlclient.so.12 instead of .11. + + -- Christian Hammers Thu, 9 Jan 2003 20:14:11 +0100 + +mysql-dfsg (4.0.7.gamma-1) experimental; urgency=high + + * SECURITY: This version fixes an upstream security release that is only + present in the 4.x branch which is currently only in the + experimental distribution and therefore will not get a DSA. + * New upstream release. + + -- Christian Hammers Sat, 28 Dec 2002 15:51:39 +0100 + +mysql-dfsg (4.0.6.gamma-2) experimental; urgency=low + + * Added --system to addgroup. Closes: #173866 + + -- Christian Hammers Sat, 21 Dec 2002 15:28:26 +0100 + +mysql-dfsg (4.0.6.gamma-1) experimental; urgency=low + + * New upstream version. Now Gamma! + * There are no longer changes to the .orig.tar.gz neccessary to make diff + happy. docs/ has still to be deleted, although, as it is non-free. + * Incorporated patches from unstable. + * Added mysqlmanager and a couple of other new scripts. + * Enabled libmysqld embedded server library. + * Enabled SSL and Virtual-IO support. + (CORBA based MySQL-FS seems to be not existing..) + + -- Christian Hammers Fri, 20 Dec 2002 22:30:51 +0100 + +mysql-dfsg (4.0.5a.beta-3) experimental; urgency=low + + * Modified postinst to work with old and new mysql.user table format + and fixed spelling typo in postinst. Thanks to Roger Aich. + * Updated config.{guess,sub} to make the mipsel porters happy. + Thanks to Ryan Murray. Closes: #173553 + + -- Christian Hammers Wed, 18 Dec 2002 15:56:34 +0100 + +mysql-dfsg (4.0.5a.beta-2) experimental; urgency=low + + * Upstream removed option "--skip-gemini". So did I. Closes: 173142 + + -- Christian Hammers Tue, 17 Dec 2002 10:35:49 +0100 + +mysql-dfsg (4.0.5a.beta-1) experimental; urgency=low + + * First 4.x experimental package due to continuous user requests :-) + Please test and report! + * upstream: safe_mysqld has been renamed to mysqld_safe + * upstream: new library soname version libmysqlclient.so.11 + * Renamed libmysqlclientXX-dev to libmysqlclient-dev as I don't plan to + support more than one development environment and this makes the + dependencies easier. + * FIXME: Skipped parts of the debian/patches/alpha patch as the global.h + is not existing. + * FIXME: How to get rid this? Old ltconfig patch already applied. + "lintian: binary-or-shlib-defines-rpath ./usr/bin/mysql /usr/lib/mysql" + + -- Christian Hammers Sun, 1 Dec 2002 18:32:32 +0100 + +mysql-dfsg (3.23.53-4) unstable; urgency=medium + + * Fixed errno.h problem. Closes: #168533, #168535 + + -- Christian Hammers Sun, 10 Nov 2002 18:32:08 +0100 + +mysql-dfsg (3.23.53-3) unstable; urgency=medium + + * Changed automake build-dep to unversioned automake1.4. Closes: #166391 + * Fixed description. Closes: #167270 + (Thanks to Soren Boll Overgaard) + + -- Christian Hammers Tue, 5 Nov 2002 01:25:01 +0100 + +mysql-dfsg (3.23.53-2) unstable; urgency=low + + * Reverted user creation in init scripts. Closes: #166432 + (Thanks to Birzan George Cristian) + + -- Christian Hammers Thu, 31 Oct 2002 15:36:25 +0100 + +mysql-dfsg (3.23.53-1) unstable; urgency=low + + * New upstream release. + + -- Christian Hammers Thu, 24 Oct 2002 23:04:16 +0200 + +mysql-dfsg (3.23.52-3) unstable; urgency=low + + * Substituted the first-install 'debian-sys-maint' user creation by + something ANSI SQL compliant. Closes: #163497 + (Thanks to Karl Hammar) + * Tightend dependency to debhelper (>= 4.0.12) to be sure that + debconf-utils gets installed, too, as I use dh_installdebconf. + * Fixed upstream manpage bug in mysqldump.1. Closes: #159779 + (Thanks to Colin Watson) + * Added comment about MIN_WORD_LEN to mysql-server.README.Debian + (Thanks to Philipp Dreimann) + * Added a dependency for zlib1g-dev to libmysqlclient10-dev. + (Thanks to Jordi Mallach) + + -- Christian Hammers Sun, 15 Sep 2002 17:14:44 +0200 + +mysql-dfsg (3.23.52-2) unstable; urgency=low + + * Fixed typo in preinst scripts. + * Removed bashism in init script. + * Fixed ambiguous debconf example. Closes: #158884 + + -- Christian Hammers Fri, 30 Aug 2002 00:51:29 +0200 + +mysql-dfsg (3.23.52-1) unstable; urgency=low + + * New upstream version. Closes: #157731 + * Clearified the meaning of the debian-sys-maint special user in the + README.Debian file. Closes: #153702 + * Wrote some words regarding the skip-networking in README.Debian. + Closes: #157038 + * Added dependency to passwd. + * Fixes typo and unnecessarily complication in is_mysql_alive(). + * Added check for /etc/mysql/my.cnf in init script. + + -- Christian Hammers Tue, 27 Aug 2002 01:53:32 +0200 + +mysql-dfsg (3.23.51-4) unstable; urgency=low + + * Added a compressed "nm mysqld" output to allow people to trace + core dumps with /usr/bin/resolve_stack_dump as suggested in the + INSTALL-SOURCE file. Thanks to atudor@labs.agilent.com for the hint. + + -- Christian Hammers Wed, 24 Jul 2002 20:44:55 +0200 + +mysql-dfsg (3.23.51-3) unstable; urgency=low + + * Corrected copyright file: the MySQL client library is licenced under + the LGPL-2 not the GPL. From version 4.x it actually will be GPL this + is why parts of http://www.mysql.com/ already say so. Closes: #153591 + * Corrected german translation. + Thanks to Roland Rosenfeld . Closes: #151903 + + -- Christian Hammers Thu, 11 Jul 2002 20:32:28 +0200 + +mysql-dfsg (3.23.51-2) unstable; urgency=low + + * Improved NIS tolerance in preinst script. + + -- Christian Hammers Sun, 7 Jul 2002 04:43:28 +0200 + +mysql-dfsg (3.23.51-1) unstable; urgency=medium + + * New upstream version. + * I applied a patch that fixes a binary imcompatibility in + the shared libary libmysqlclient.so.10 between 3.23.50 and + some versions earlier. Upstream has been contacted and asked + for clarification. Closes: #149952 + * Added support for NIS i.e. it shows a warning and fails if the + needed 'mysql' user does not exists but works if it does. + Closes: #143282, #147869 + * Substituted $0 in init scripts by something really weird so that + "./S20mysql restart" works now, too. (BTW: S20? install file-rc!!!) + Closes: #148658 + * Now postinst works even if /etc/init.d/mysql is removed. Closes: #151021 + * Decided to leave "set +x" in postinst but wrote comment. Closes: #151022 + + -- Christian Hammers Sun, 7 Jul 2002 04:43:25 +0200 + +mysql-dfsg (3.23.50-1) unstable; urgency=medium + + * New upstream version. + Fixes a very annoying and important bug that lets all mysql programs + including perl scripts etc. segfault when using the read_default_group() + function. 3.23.50 is currently a pre-release and expected to be released + next week. I plan to propose it for woody as soon as its stability has + been proven. The following bug reports are all regarding this issue. + Closes: #144960, #145322, #136798, #138143, + + -- Christian Hammers Sat, 18 May 2002 21:14:01 +0200 + +mysql-dfsg (3.23.49x-1) unstable; urgency=low + + * I had to split the package to seperate the manual as it is not GPL + like the rest of the software and docs but under a license that + e.g. forbids selling printed versions. + . + The upstream authors were contacted a while ago but did not like to + change the situation. + . + The names of the resulting packages have not changed as the manual + already was in a seperate mysql-doc package due to it's size. + The source packages are now splitted from one "mysql" to + "mysql-dfsg" in main and "mysql-nonfree" in non-free. + * No code change! + The "x" at the end of the version number ist just to be able to + upload a new source package. ("a" was already taken by upstream + for their binary upload correction) + + -- Christian Hammers Wed, 8 May 2002 02:01:41 +0200 + +mysql (3.23.49-8) unstable; urgency=low + + * Substituted $0 in init script to let e.g. "/etc# ./init.d/mysql restart" + works, too. Closes: #141555 + + -- Christian Hammers Sun, 7 Apr 2002 15:00:44 +0200 + +mysql (3.23.49-7) unstable; urgency=low + + * The Makefiles are totally broken for the --enable-local-infile + option. I now patched libmysql/libmysql.c#mysql_init() manually. + Closes: #138347 + + -- Christian Hammers Fri, 29 Mar 2002 23:55:15 +0100 + +mysql (3.23.49-6) unstable; urgency=low + + * Moved mysqlcheck from server to client package. Closes: #139799 + * Added manpage for mysqlhotcopy. Regarding: #87097 + * Added 'sharedscripts' directive to the logrotate script. + * Replaced grep by /usr/bin/getent to let the group/user checking work + on NIS/LDAP systems, too. Closes: #115677, #101529 + + -- Christian Hammers Fri, 22 Mar 2002 22:40:51 +0100 + +mysql (3.23.49-5) unstable; urgency=low + + * Added skip-innodb to default my.cnf. + * Enabled --enable-local-infile, it seems to be a new option that + defaults to disable a formerly enabled feaure. Closes: #137115 + + -- Christian Hammers Sat, 16 Mar 2002 00:29:10 +0100 + +mysql (3.23.49-4) unstable; urgency=medium + + * Recompiled against fixed libz. + + * Enabled --enable-local-infile, it seems to be a new option that + defaults to disable a formerly enabled feaure. Closes: #137115 + * Fixed README.compile_on_potato. Closes: #136529 + * Now a ext3 .jounal file in /var/lib/mysql does not prevent the + installation (happens when creating a jounal on an already mounted + partition). Closes: #137146 + + -- Christian Hammers Wed, 13 Mar 2002 13:34:24 +0100 + +mysql (3.23.49-3) unstable; urgency=low + + * Added Russian translation. Closes: #135846 + * Fixed installation of .info documents. Closes: #135030 + + -- Christian Hammers Wed, 27 Feb 2002 23:36:35 +0100 + +mysql (3.23.49-2) unstable; urgency=low + + * Updated french translation and split template files. Closes: #134754 + * Fixed a small debian.cnf related bug in mysql-server.postinst. + + -- Christian Hammers Tue, 19 Feb 2002 23:13:58 +0100 + +mysql (3.23.49-1) unstable; urgency=low + + * New upstream release. + (Mainly InnoDB related fixes) + * Exported a $HOME variable in the scripts so that /root/.my.cnf + is not read anymore. This will avoid problems when admins put + only passwords but no usernames in this file. Closes: #132048 + * New debian-sys-maint password algorithm (now ~96bit :-)) Closes: #133863 + * Recreating debian-sys-main pwd on every install to help people who + accidently delete user or password files... + * Added /var/log/mysql so that user can put the binary logs in there as + mysql cannot write the .001 etc files itself in /var/log which is + owned by root. + + -- Christian Hammers Thu, 14 Feb 2002 22:17:45 +0100 + +mysql (3.23.47-6) unstable; urgency=low + + * Dropped a sentence about the new debian-sys-maint user in the + debconf note and updated the README.Debian. Related: #132048 + * Added more french translation. Closes: #132390 + + -- Christian Hammers Wed, 6 Feb 2002 09:41:29 +0100 + +mysql (3.23.47-5) unstable; urgency=low + + * Fixed grammar error in template. Closes: #132238 + * Really fixed typo in logrotate script. Closes: #131711 + + -- Christian Hammers Tue, 5 Feb 2002 14:20:08 +0100 + +mysql (3.23.47-4) unstable; urgency=medium + + * Fixes typo in postinst that let init script fail. Closes: #131743 + * Fixed bashism bug that failed on ash. Closes: #131697 + * Fixed typo in logrotate script. Closes: #131711 + + -- Christian Hammers Thu, 31 Jan 2002 23:58:46 +0100 + +mysql (3.23.47-3) unstable; urgency=low + + * Added new Debian specific mysql user called 'debian-sys-maint' which + is used for pinging the server status, flushing the logs or shutting + down the server in maintenance scripts. The credentials of this user + are stored in the UID0-only readable file /etc/mysql/debian.cnf. + Closes: #129887, #130326, #99274 + * Fixed unintended server startup at boottime. Closes: #122676, #130105 + * New upstream fixes command line parsing bug: Closes: #128473 + * Fixed manpage headers to let apropos work: Closes: #119122 + * Added "status" options for /etc/init.d/mysql. Closes: #129020 + + -- Christian Hammers Sun, 27 Jan 2002 19:46:11 +0100 + +mysql (3.23.47-2) unstable; urgency=low + + * Enhanced init scripts by using mysqladmin instead of kill $pid. + Thanks to Aaron Brick. + + -- Christian Hammers Fri, 18 Jan 2002 01:42:23 +0100 + +mysql (3.23.47-1) unstable; urgency=low + + * New upstream release. + * Updated brazilian translation of debconf descriptions. Closes: #123332 + + -- Christian Hammers Sun, 6 Jan 2002 21:11:17 +0100 + +mysql (3.23.46-3) unstable; urgency=low + + * Fixed bug in postinst where a script was accidently called with + "bash -c