From bed8ef69241cbf20bbbd4a4f0de20f1e1cbfba37 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 3 Sep 2001 13:09:08 -0600 Subject: [PATCH 01/18] added symbols files to RPM to resolve stack trace fixed Do-rpm to accept command-line options for easier testing/local RPM build BUILD/compile-pentium-max: add enable-thread-safe-client Build-tools/Do-rpm: make configurable from command line support-files/mysql.spec.sh: add mysqld.sym and mysqld-max.sym to the RPM --- BUILD/compile-pentium-max | 3 +- Build-tools/Do-rpm | 178 ++++++++++++++++++++++++++++-------- support-files/mysql.spec.sh | 12 ++- 3 files changed, 150 insertions(+), 43 deletions(-) diff --git a/BUILD/compile-pentium-max b/BUILD/compile-pentium-max index 5fb4c1f89d2..55f88ef4748 100755 --- a/BUILD/compile-pentium-max +++ b/BUILD/compile-pentium-max @@ -7,6 +7,7 @@ extra_flags="$pentium_cflags $fast_cflags" extra_configs="$pentium_configs" strip=yes -extra_configs="$extra_configs --with-innodb --with-berkeley-db" +extra_configs="$extra_configs --with-innodb --with-berkeley-db \ + --enable-thread-safe-client" . "$path/FINISH.sh" diff --git a/Build-tools/Do-rpm b/Build-tools/Do-rpm index 31f0d14802c..138953ab188 100755 --- a/Build-tools/Do-rpm +++ b/Build-tools/Do-rpm @@ -1,5 +1,36 @@ #!/bin/bash +#helper functions + +function copy_to_bmachine +{ + if [ x$local_build = x1 ]; then + cp $1 $2 + else + scp $1 $owner@$bmachine:$2 + fi +} + +function copy_from_bmachine +{ + if [ x$local_build = x1 ]; then + cp $1 $2 + else + scp $owner@$bmachine:$1 $2 + fi +} + +function run_command +{ + if [ x$local_build = x1 ]; then + bash $1 + else + cat $1 | ssh $owner@$bmachine bash + fi +} + +#Supply defaults + # We built on one of two machines bmachine=work smachine=work @@ -8,6 +39,7 @@ owner=my # Hard path!! bpath=`/bin/pwd` rpmdir="/usr/src/redhat" +logdir="$bpath/Logs" ###### Perl STUFF ##### @@ -24,6 +56,38 @@ AM_MAKEFLAGS="-j 2" VER=`grep "AM_INIT_AUTOMAKE(mysql, " $bpath/configure.in | \ sed -e 's;AM_INIT_AUTOMAKE(mysql, ;;' -e 's;);;'` VER_NO_DASH=`echo $VER | sed -e "s|-.*$||"` +tarball=$bpath/mysql-$VER.tar.gz + +while test $# -gt 0; do + case "$1" in + --rpmdir=*) + rpmdir=`echo $1 | sed -e "s;--rpmdir=;;"` + ;; + --smachine=*) + smachine=`echo $1 | sed -e "s;--smachine=;;"` + ;; + --bmachine=*) + bmachine=`echo $1 | sed -e "s;--bmachine=;;"` + ;; + --owner=*) + owner=`echo $1 | sed -e "s;--owner=;;"` + ;; + --tarball=*) + tarball=`echo $1 | sed -e "s;--tarball=;;"` + ;; + --logdir=*) + logdir=`echo $1 | sed -e "s;--logdir=;;"` + ;; + --local ) + local_build=1 + ;; + --skip-perl ) + skip_perl=1 + ;; + * ) break ;; + esac + shift +done echo "Removing old MySQL packages" rm -rf $rpmdir/BUILD/mysql-* @@ -31,16 +95,34 @@ rm -f $rpmdir/SOURCES/mysql-* rm -f $rpmdir/SRPMS/MySQL-* rm -f $rpmdir/SPEC/mysql-* +if [ ! -d "$logdir" ]; then + echo "$logdir does not exist, creating" + mkdir -p $logdir +fi + +if [ ! -f "$tarball" ]; then + echo "Tarball file $tarball does not exist, please make one first" + exit 1 +fi + echo "Building RPM for MySQL version $VER on $bmachine" -log=$bpath/Logs/Log-RPM-`date +%y%m%d-%H%M` +log=$logdir/Log-RPM-`date +%y%m%d-%H%M` ( set -x # Copy MySQL source and spec files -scp $bpath/mysql-$VER.tar.gz $owner@$bmachine:$rpmdir/SOURCES -scp $bpath/Docs/Images/mysql-logo.gif $owner@$bmachine:$rpmdir/SOURCES/mysql.gif -scp $bpath/support-files/mysql-$VER.spec $owner@$bmachine:$rpmdir/SPECS + +#Sasha: I left the scp stuff commented out instead of deleted to make it +#easy to revert in a hurry, if there is a need. Once everything is tested +#and works perfectly, the scp stuff should be deleted to avoid confusion + +#scp $bpath/mysql-$VER.tar.gz $owner@$bmachine:$rpmdir/SOURCES +copy_to_bmachine $tarball $rpmdir/SOURCES +#scp $bpath/Docs/Images/mysql-logo.gif $owner@$bmachine:$rpmdir/SOURCES/mysql.gif +copy_to_bmachine $bpath/Docs/Images/mysql-logo.gif $rpmdir/SOURCES/mysql.gif +#scp $bpath/support-files/mysql-$VER.spec $owner@$bmachine:$rpmdir/SPECS +copy_to_bmachine $bpath/support-files/mysql-$VER.spec $rpmdir/SPECS # Copy perl things. Has to be uncompressed since Compress.pm is not # installed yet. Set CEXT to .gz when we support compression. @@ -52,7 +134,7 @@ CEXT= # cd /usr/lib/perl5/site_perl/5.005; ln -s ../* .; rm -f 5.005 TMP_SCRIPT_MYSQL=00-temp-for-do-rpm.$$ -cat > $bpath/Logs/$TMP_SCRIPT_MYSQL < $logdir/$TMP_SCRIPT_MYSQL < $bpath/Logs/$TMP_SCRIPT_PERL < $logdir/$TMP_SCRIPT_PERL < $log 2>&1 + + diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 6912953495e..3245908c9b0 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -151,9 +151,9 @@ BuildMySQL() { # The --enable-assembler simply does nothing on systems that does not # support assembler speedups. sh -c "PATH=\"${MYSQL_BUILD_PATH:-/bin:/usr/bin}\" \ - CC=\"${MYSQL_BUILD_CC:-egcs}\" \ + CC=\"${MYSQL_BUILD_CC:-gcc}\" \ CFLAGS=\"${MYSQL_BUILD_CFLAGS:- -O3}\" \ - CXX=\"${MYSQL_BUILD_CXX:-egcs}\" \ + CXX=\"${MYSQL_BUILD_CXX:-gcc}\" \ CXXFLAGS=\"${MYSQL_BUILD_CXXFLAGS:- -O3 \ -felide-constructors -fno-exceptions -fno-rtti \ }\" \ @@ -204,6 +204,7 @@ BuildMySQL "--enable-shared --enable-thread-safe-client --with-berkeley-db --wit # Save shared libraries and mysqld-max mv sql/mysqld sql/mysqld-max +nm --numeric-sort sql/mysqld-max > sql/mysqld-max.sym (cd libmysql/.libs; tar cf $RBR/shared-libs.tar *.so*) (cd libmysql_r/.libs; tar rf $RBR/shared-libs.tar *.so*) @@ -219,6 +220,7 @@ BuildMySQL "--disable-shared" \ "--with-mysqld-ldflags='-all-static'" \ "--with-client-ldflags='-all-static'" \ "--without-berkeley-db --without-innodb" +nm --numeric-sort sql/mysqld > sql/mysqld.sym %install -n mysql-%{mysql_version} RBR=$RPM_BUILD_ROOT @@ -240,6 +242,10 @@ make install DESTDIR=$RBR benchdir_root=/usr/share/ # install saved mysqld-max install -m755 $MBD/sql/mysqld-max $RBR/usr/sbin/mysqld-max +# install symbol files ( for stack trace resolution) +install -m644 $MBD/sql/mysqld-max.sym $RBR/usr/lib/mysql/mysqld-max.sym +install -m644 $MBD/sql/mysqld.sym $RBR/usr/lib/mysql/mysqld.sym + # Install logrotate and autostart install -m644 $MBD/support-files/mysql-log-rotate $RBR/etc/logrotate.d/mysql install -m755 $MBD/support-files/mysql.server $RBR/etc/rc.d/init.d/mysql @@ -349,6 +355,7 @@ fi %attr(644, root, root) /usr/info/mysql.info* %attr(755, root, root) /usr/sbin/mysqld +%attr(644, root, root) /usr/lib/mysql/mysqld.sym %attr(644, root, root) /etc/logrotate.d/mysql %attr(755, root, root) /etc/rc.d/init.d/mysql @@ -403,6 +410,7 @@ fi %files Max %attr(755, root, root) /usr/sbin/mysqld-max +%attr(644, root, root) /usr/lib/mysql/mysqld-max.sym %changelog From f736e3e1d25c492cc4eaa1aeb52bf369b7a84d33 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 4 Sep 2001 16:17:31 +0300 Subject: [PATCH 02/18] Portability fix --- include/my_pthread.h | 1 + sql/mysqld.cc | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index 79baa7a53e3..c2c671ae28a 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -146,6 +146,7 @@ int pthread_mutex_destroy (pthread_mutex_t *); #define pthread_mutex_destroy(A) DeleteCriticalSection(A) #define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B)) #define pthread_kill(A,B) pthread_dummy(0) +#define pthread_exit(A) pthread_dummy() #endif /* OS2 */ /* Dummy defines for easier code */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b484eee3480..cd532ac0f24 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -634,9 +634,7 @@ static void __cdecl kill_server(int sig_ptr) unireg_abort(1); /* purecov: inspected */ else unireg_end(0); -#ifndef OS2 pthread_exit(0); /* purecov: deadcode */ -#endif RETURN_FROM_KILL_SERVER; } @@ -668,9 +666,7 @@ static sig_handler print_signal_warning(int sig) void unireg_end(int signal_number __attribute__((unused))) { clean_up(); -#ifndef OS2 pthread_exit(0); // Exit is in main thread -#endif } From aa161036d69995a71fcdb76d6732a8e658188f06 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 4 Sep 2001 15:21:54 +0200 Subject: [PATCH 03/18] manual.texi: Fix a couple of mirror e-mail addresses Docs/manual.texi: Fix a couple of mirror e-mail addresses --- Docs/manual.texi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index ae2fc7facc9..4f2b551f464 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -6434,13 +6434,13 @@ Please report bad or out-of-date mirrors to @email{webmaster@@mysql.com}. @item @c Added: 990920 -@c EMAIL: (Radek Libovicky) +@c EMAIL: radek@sopik.cz (Radek Libovicky) @image{Flags/czech-republic} Czech Republic [www.sopik.cz] @ @uref{http://www.mysql.cz/, WWW} @item @c Added: 000418 -@c EMAIL: (Ondrej Feela Filip) +@c EMAIL: feela@ipex.cz (Ondrej Feela Filip) @image{Flags/czech-republic} Czech Republic [www.gin.cz] @ @uref{http://mysql.gin.cz/, WWW} @uref{ftp://ftp.gin.cz/pub/MIRRORS/www.mysql.com/, FTP} @@ -6648,7 +6648,7 @@ Please report bad or out-of-date mirrors to @email{webmaster@@mysql.com}. @c @item @c Not ok 20000919; Non-existent (Matt) -@c EMAIL: Equipa de suporte do Leirianet +@c EMAIL: support@leirianet.pt (Equipa de suporte do Leirianet) @c @image{Flags/portugal} Portugal [lerianet] @ @c @uref{http://mysql.leirianet.pt, WWW} @c @uref{ftp://ftp.leirianet.pt/pub/mysql/,FTP} From 993603fe7155e8317294434b7e0c85d86b010a9e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 5 Sep 2001 18:21:21 +0300 Subject: [PATCH 04/18] lock0lock.c Fix slowness of deadlock detection algorithm trx0trx.h Fix slowness of deadlock detection algorithm innobase/include/trx0trx.h: Fix slowness of deadlock detection algorithm innobase/lock/lock0lock.c: Fix slowness of deadlock detection algorithm --- innobase/include/trx0trx.h | 2 ++ innobase/lock/lock0lock.c | 56 ++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index fdef041e929..f179e20ad62 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -397,6 +397,8 @@ struct trx_struct{ wait_thrs; /* query threads belonging to this trx that are in the QUE_THR_LOCK_WAIT state */ + ulint deadlock_mark; /* a mark field used in deadlock + checking algorithm */ /*------------------------------*/ mem_heap_t* lock_heap; /* memory heap for the locks of the transaction; protected by diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 819c559ceb4..df35e22005f 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -15,6 +15,10 @@ Created 5/7/1996 Heikki Tuuri #include "usr0sess.h" #include "trx0purge.h" +/* Restricts the length of search we will do in the waits-for +graph of transactions */ +#define LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK 1000000 + /* When releasing transaction locks, this specifies how often we release the kernel mutex for a moment to give also others access to it */ @@ -312,11 +316,14 @@ static ibool lock_deadlock_recursive( /*====================*/ - /* out: TRUE if a deadlock was detected */ + /* out: TRUE if a deadlock was detected + or the calculation took too long */ trx_t* start, /* in: recursion starting point */ trx_t* trx, /* in: a transaction waiting for a lock */ - lock_t* wait_lock); /* in: the lock trx is waiting to be granted */ - + lock_t* wait_lock, /* in: the lock trx is waiting to be granted */ + ulint* cost); /* in/out: number of calculation steps thus + far: if this exceeds LOCK_MAX_N_STEPS_... + we return TRUE */ /************************************************************************* Reserves the kernel mutex. This function is used in this module to allow monitoring the contention degree on the kernel mutex caused by the lock @@ -2655,12 +2662,25 @@ lock_deadlock_occurs( { dict_table_t* table; dict_index_t* index; + trx_t* mark_trx; ibool ret; + ulint cost = 0; ut_ad(trx && lock); ut_ad(mutex_own(&kernel_mutex)); - - ret = lock_deadlock_recursive(trx, trx, lock); + + /* We check that adding this trx to the waits-for graph + does not produce a cycle. First mark all active transactions + with 0: */ + + mark_trx = UT_LIST_GET_FIRST(trx_sys->trx_list); + + while (mark_trx) { + mark_trx->deadlock_mark = 0; + mark_trx = UT_LIST_GET_NEXT(trx_list, mark_trx); + } + + ret = lock_deadlock_recursive(trx, trx, lock, &cost); if (ret) { if (lock_get_type(lock) == LOCK_TABLE) { @@ -2685,10 +2705,14 @@ static ibool lock_deadlock_recursive( /*====================*/ - /* out: TRUE if a deadlock was detected */ + /* out: TRUE if a deadlock was detected + or the calculation took too long */ trx_t* start, /* in: recursion starting point */ trx_t* trx, /* in: a transaction waiting for a lock */ - lock_t* wait_lock) /* in: the lock trx is waiting to be granted */ + lock_t* wait_lock, /* in: the lock trx is waiting to be granted */ + ulint* cost) /* in/out: number of calculation steps thus + far: if this exceeds LOCK_MAX_N_STEPS_... + we return TRUE */ { lock_t* lock; ulint bit_no; @@ -2697,6 +2721,20 @@ lock_deadlock_recursive( ut_a(trx && start && wait_lock); ut_ad(mutex_own(&kernel_mutex)); + if (trx->deadlock_mark == 1) { + /* We have already exhaustively searched the subtree starting + from this trx */ + + return(FALSE); + } + + *cost = *cost + 1; + + if (*cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK) { + + return(TRUE); + } + lock = wait_lock; if (lock_get_type(wait_lock) == LOCK_REC) { @@ -2719,6 +2757,8 @@ lock_deadlock_recursive( } if (lock == NULL) { + /* We can mark this subtree as searched */ + trx->deadlock_mark = 1; return(FALSE); } @@ -2742,7 +2782,7 @@ lock_deadlock_recursive( a lock */ if (lock_deadlock_recursive(start, lock_trx, - lock_trx->wait_lock)) { + lock_trx->wait_lock, cost)) { return(TRUE); } From fec70ce417c4574c3d269337820fe67ae3ff510b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 5 Sep 2001 20:29:34 +0300 Subject: [PATCH 05/18] data0data.c Fix an assertion failure in rem0rec.c line 195 when a > 8000 byte row is updated and an internally stored field shortened innobase/data/data0data.c: Fix an assertion failure in rem0rec.c line 195 when a > 8000 byte row is updated and an internally stored field shortened --- innobase/data/data0data.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/innobase/data/data0data.c b/innobase/data/data0data.c index 97db9d72f98..aecc56ec022 100644 --- a/innobase/data/data0data.c +++ b/innobase/data/data0data.c @@ -470,7 +470,8 @@ dtuple_convert_big_rec( } } - if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10) { + if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10 + + REC_1BYTE_OFFS_LIMIT) { /* Cannot shorten more */ @@ -479,26 +480,18 @@ dtuple_convert_big_rec( return(NULL); } - /* Move data from field longest_i to big rec vector, - but do not let data size of the remaining entry + /* Move data from field longest_i to big rec vector; + we do not let data size of the remaining entry drop below 128 which is the limit for the 2-byte - offset storage format in a physical record */ + offset storage format in a physical record. This + we accomplish by storing 128 bytes of data in entry + itself, and only the remaining part to big rec vec. */ dfield = dtuple_get_nth_field(entry, longest_i); vector->fields[n_fields].field_no = longest_i; - if (dtuple_get_data_size(entry) - dfield->len - <= REC_1BYTE_OFFS_LIMIT) { - vector->fields[n_fields].len = - dtuple_get_data_size(entry) + vector->fields[n_fields].len = dfield->len - REC_1BYTE_OFFS_LIMIT; - /* Since dfield will contain at least - a 20-byte reference to the extern storage, - we know that the data size of entry will be - > REC_1BYTE_OFFS_LIMIT */ - } else { - vector->fields[n_fields].len = dfield->len; - } vector->fields[n_fields].data = mem_heap_alloc(heap, vector->fields[n_fields].len); From 07a887b3836904c19a7dcc74ac1b73e82dbed7ec Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 6 Sep 2001 01:23:01 +0200 Subject: [PATCH 06/18] Portability fixes libmysql/libmysql.c: Remove duplicated define sql/log_event.cc: Portability fix --- libmysql/libmysql.c | 1 - sql/log_event.cc | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 469331641c8..0cb6170b25c 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -15,7 +15,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#define DONT_USE_RAID #include #if defined(__WIN__) || defined(_WIN32) || defined(_WIN64) #include diff --git a/sql/log_event.cc b/sql/log_event.cc index 869167bba2f..521e0f7765f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -278,7 +278,7 @@ void Log_event::print_timestamp(FILE* file, time_t* ts) ts = &when; } #ifdef MYSQL_SERVER - res=localtime_r(ts,&tm_tmp); + localtime_r(ts,(res= &tm_tmp)); #else res=localtime(ts); #endif From d77f9f3642cb864879d77cba729db4d1b1f997da Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 6 Sep 2001 16:48:32 +0300 Subject: [PATCH 07/18] handler.cc Change the parameter name of default-table-type from INNOBASE to INNODB sql/handler.cc: Change the parameter name of default-table-type from INNOBASE to INNODB --- sql/handler.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/handler.cc b/sql/handler.cc index bb17d8f2331..2f6e3b11bdf 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -52,7 +52,7 @@ ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count, const char *ha_table_type[] = { "", "DIAB_ISAM","HASH","MISAM","PISAM","RMS_ISAM","HEAP", "ISAM", - "MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNOBASE", "GEMINI", "?", "?",NullS + "MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNODB", "GEMINI", "?", "?",NullS }; TYPELIB ha_table_typelib= {array_elements(ha_table_type)-4,"", From 44e61cdad7da3d5c98002b56dcfa3d026b205bcf Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 6 Sep 2001 23:57:32 +0300 Subject: [PATCH 08/18] Fixed a problem using LOCK TABLES and BDB tables Docs/manual.texi: Added description of C thread functions sql-bench/test-create.sh: Faster --fast option --- Docs/manual.texi | 168 +++++++++++++++++++++++++++------------ sql-bench/test-create.sh | 12 ++- sql/sql_base.cc | 3 + 3 files changed, 130 insertions(+), 53 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 4f2b551f464..389e8befec5 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -6149,9 +6149,9 @@ Nothing; In the long run we plan to be fully ANSI 92 / ANSI 99 compliant. @menu * Quick Standard Installation:: Quick Standard Installation of MySQL * General Installation Issues:: General Installation Issues -* Installing source:: Installing a MySQL source distribution -* Post-installation:: Post-installation setup and testing -* Upgrade:: Upgrading/Downgrading MySQL +* Installing source:: Installing a MySQL source distribution +* Post-installation:: Post-installation setup and testing +* Upgrade:: Upgrading/Downgrading MySQL * Operating System Specific Notes:: Operating System Specific Notes @end menu @@ -8202,7 +8202,7 @@ If your client programs are using threads, you need to also compile a thread-safe version of the MySQL client library with the @code{--with-thread-safe-client} configure options. This will create a @code{libmysqlclient_r} library with which you should link your threaded -applications. @xref{Thread-safe clients}. +applications. @xref{Threaded clients}. @item Options that pertain to particular systems can be found in the @@ -38964,9 +38964,10 @@ likely it is that we can fix the problem! * C API datatypes:: C API Datatypes * C API function overview:: C API Function Overview * C API functions:: C API Function Descriptions +* C Thread functions:: * C API problems:: Common questions and problems when using the C API * Building clients:: Building Client Programs -* Thread-safe clients:: How to Make a Thread-safe Client +* Threaded clients:: How to Make a Threaded Client @end menu The C API code is distributed with MySQL. It is included in the @@ -39007,7 +39008,7 @@ the buffer associated with a connection is not decreased until the connection is closed, at which time client memory is reclaimed. For programming with threads, consult the 'how to make a thread-safe -client' chapter. @xref{Thread-safe clients}. +client' chapter. @xref{Threaded clients}. @node C API datatypes, C API function overview, C, C @@ -39455,7 +39456,7 @@ recently invoked function that can succeed or fail, allowing you to determine when an error occurred and what it was. -@node C API functions, C API problems, C API function overview, C +@node C API functions, C Thread functions, C API function overview, C @subsection C API Function Descriptions @menu @@ -40373,7 +40374,7 @@ of @code{mysql_field_count()} whether or not the statement was a @code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)} -* Thread-safe clients:: How to Make a Thread-safe Client +* Threaded clients:: How to Make a Threaded Client @subsubheading Description Sets the field cursor to the given offset. The next call to @@ -41650,8 +41651,71 @@ The connection to the server was lost during the query. An unknown error occurred. @end table +@node C Thread functions, C API problems, C API functions, C +@subsection C Threaded Function Descriptions -@node C API problems, Building clients, C API functions, C +You need to use the following functions when you want to create a +threaded client. @xref{Threaded clients}. + +@menu +* my_init:: +* my_thread_init():: +* my_thread_end():: +@end menu + +@node my_init, my_thread_init(), C Thread functions, C Thread functions +@subsubsection @code{my_init()} + +@findex @code{my_init()} + +@subsubheading Description + +This function needs to be called once in the program before calling any +MySQL function. This initializes some global variables that MySQL +needs. If you are using a thread safe client library, this will also +call @code{my_thread_init()} for this thread. + +This is automaticly called by @code{mysql_init()} +and @code{mysql_connect()}. + +@subsubheading Return Values + +none. + +@node my_thread_init(), my_thread_end(), my_init, C Thread functions +@subsubsection @code{my_thread_init()} + +@findex @code{my_thread_init()} + +@subsubheading Description + +This function needs to be called for each created thread to initialize +thread specific variables. + +This is automaticly called by @code{my_init()} and @code{mysql_connect()}. + +@subsubheading Return Values + +none. + +@node my_thread_end(), , my_thread_init(), C Thread functions +@subsubsection @code{my_thread_end()} + +@findex @code{my_thread_end()} + +@subsubheading Description + +This function needs to be called before calling @code{pthread_exit()} to +freed memory allocated by @code{my_thread_init()}. + +Note that this function is NOT invoked automaticly be the client +library! + +@subsubheading Return Values + +none. + +@node C API problems, Building clients, C Thread functions, C @subsection Common questions and problems when using the C API @tindex @code{mysql_query()} @@ -41806,7 +41870,7 @@ If this happens on your system, you must include the math library by adding @code{-lm} to the end of the compile/link line. -@node Building clients, Thread-safe clients, C API problems, C +@node Building clients, Threaded clients, C API problems, C @subsection Building Client Programs @cindex client programs, building @@ -41827,11 +41891,11 @@ For clients that use MySQL header files, you may need to specify a files. -@node Thread-safe clients, , Building clients, C -@subsection How to Make a Thread-safe Client +@node Threaded clients, , Building clients, C +@subsection How to Make a Threaded Client -@cindex clients, thread-safe -@cindex thread-safe clients +@cindex clients, threaded +@cindex threaded clients The client library is almost thread safe. The biggest problem is that the subroutines in @file{net.c} that read from sockets are not @@ -41846,20 +41910,21 @@ Windows binaries are by default compiled to be thread safe). Newer binary distributions should have both a normal and a thread-safe client library. -To get a really thread-safe client where you can interrupt the client -from other threads and set timeouts when talking with the MySQL -server, you should use the @code{-lmysys}, @code{-lstring}, and @code{-ldbug} -libraries and the @code{net_serv.o} code that the server uses. +To get a threaded client where you can interrupt the client from other +threads and set timeouts when talking with the MySQL server, you should +use the @code{-lmysys}, @code{-lstring}, and @code{-ldbug} libraries and +the @code{net_serv.o} code that the server uses. If you don't need interrupts or timeouts, you can just compile a thread safe client library @code{(mysqlclient_r)} and use this. @xref{C,, MySQL C API}. In this case you don't have to worry about the @code{net_serv.o} object file or the other MySQL libraries. -When using a threaded client and you want to use timeouts and interrupts, -you can make great use of the routines in the @file{thr_alarm.c} file. -If you are using routines from the @code{mysys} library, the only thing -you must remember is to call @code{my_init()} first! +When using a threaded client and you want to use timeouts and +interrupts, you can make great use of the routines in the +@file{thr_alarm.c} file. If you are using routines from the +@code{mysys} library, the only thing you must remember is to call +@code{my_init()} first! @xref{C Thread functions}. All functions except @code{mysql_real_connect()} are by default thread safe. The following notes describe how to compile a thread safe @@ -41906,11 +41971,38 @@ If you program with POSIX threads, you can use establish and release a mutex lock. @end itemize +You need to know the following if you have a thread that is calling +MySQL functions, but that thread has not created the connection to the +MySQL database: + +When you call @code{mysql_init()} or @code{mysql_connect()}, MySQL will +create a thread specific variable for the thread that is used by the +debug library (among other things). + +If you have in a thread call a MySQL function, before a thread has +called @code{mysql_init()} or @code{mysql_connect()}, the thread will +not have the necessary thread specific variables in place and you are +likely to end up with a core dump sooner or later. + +The get things to work smoothly you have to do the following: + +@enumerate +@item +Call @code{my_init()} at the start of your program if it calls +any other MySQL function before calling @code{mysql_real_connect()}. +@item +Call @code{my_thread_init()} in the thread handler before calling +any MySQL function. +@item +In the thread, call @code{my_thread_end()} before calling +@code{pthread_exit()}. This will free the memory used by MySQL thread +specific variables. +@end enumerate + You may get some errors because of undefined symbols when linking your client with @code{mysqlclient_r}. In most cases this is because you haven't included the thread libraries on the link/compile line. - @node Cplusplus, Java, C, Clients @section MySQL C++ APIs @@ -44221,34 +44313,6 @@ thread that is waiting on the disk-full condition will allow the other threads to continue. @end itemize -You need to know the following if you have a thread that is calling -MySQL functions, but that thread has not created the connection to the -MySQL database: - -When you call @code{mysql_init()} or @code{mysql_connect()}, MySQL will -create a thread specific variable for the thread that is used by the -debug library (among other things). - -If you have in a thread call a MySQL function, before a thread has -called @code{mysql_init()} or @code{mysql_connect()}, the thread will -not have the necessary thread specific variables in place and you are -likely to end up with a core dump sooner or later. - -The get things to work smoothly you have to do the following: - -@enumerate -@item -Call @code{my_init()} at the start of your program if it calls -any other MySQL function before calling @code{mysql_real_connect()}. -@item -Call @code{my_thread_init()} in the thread handler before calling -any MySQL function. -@item -In the thread, call @code{my_thread_end()} before calling -@code{pthread_exit()}. This will free the memory used by MySQL thread -specific variables. -@end enumerate - Exceptions to the above behaveour is when you use @code{REPAIR} or @code{OPTIMIZE} or when the indexes are created in a batch after an @code{LOAD DATA INFILE} or after an @code{ALTER TABLE} statement. @@ -46707,6 +46771,8 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.42 @itemize @bullet @item +Fixed a problem when using @code{LOCK TABLES} and @code{BDB} tables. +@item Fixed problem with @code{REPAIR TABLE} on MyISAM tables with row lengths between 65517 - 65520 bytes @item diff --git a/sql-bench/test-create.sh b/sql-bench/test-create.sh index 09d79c67b04..2853984e393 100644 --- a/sql-bench/test-create.sh +++ b/sql-bench/test-create.sh @@ -39,13 +39,21 @@ $opt_loop_count=10000; # Change this to make test harder/easier chomp($pwd = `pwd`); $pwd = "." if ($pwd eq ''); require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n"; +$create_loop_count=$opt_loop_count; if ($opt_small_test) { $opt_loop_count/=100; + $create_loop_count/=1000; } $max_tables=min($limits->{'max_tables'},$opt_loop_count); +if ($opt_small_test) +{ + $max_tables=10; +} + + print "Testing the speed of creating and droping tables\n"; print "Testing with $max_tables tables and $opt_loop_count loop count\n\n"; @@ -177,7 +185,7 @@ print "Testing create+drop\n"; $loop_time=new Benchmark; -for ($i=1 ; $i <= $opt_loop_count ; $i++) +for ($i=1 ; $i <= $create_loop_count ; $i++) { do_many($dbh,$server->create("bench_$i", ["i int NOT NULL", @@ -190,7 +198,7 @@ for ($i=1 ; $i <= $opt_loop_count ; $i++) } $end_time=new Benchmark; -print "Time for create+drop ($opt_loop_count): " . +print "Time for create+drop ($create_loop_count): " . timestr(timediff($end_time, $loop_time),"all") . "\n"; if ($opt_fast && defined($server->{vacuum})) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 16495ab03b0..624377b688e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -413,7 +413,10 @@ void close_thread_tables(THD *thd, bool locked) DBUG_ENTER("close_thread_tables"); if (thd->locked_tables) + { + ha_commit_stmt(thd); // If select statement DBUG_VOID_RETURN; // LOCK TABLES in use + } TABLE *table,*next; bool found_old_table=0; From 36b6c73f831d50cd5e2d95bdd4aef12b8a8feb23 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Sep 2001 09:48:09 +0200 Subject: [PATCH 09/18] manual.texi: Fix danish mirror contact Docs/manual.texi: Fix danish mirror contact --- Docs/manual.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 4f2b551f464..52d19b3be78 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -6448,7 +6448,7 @@ Please report bad or out-of-date mirrors to @email{webmaster@@mysql.com}. @item @c removed 991020 (no DNS entry). New name 991026. Added 991121 @c Statistics at http://mirror.borsen.dk/ -@c EMAIL: mirrorman@borsen.dk (Michael Kyed) +@c EMAIL: guru@borsen.dk (Jesper Angelo) @image{Flags/denmark} Denmark [Borsen] @ @uref{ http://mysql.borsen.dk/, WWW} From 0edad3cb96a2d7545eb9980292ad89d885613be3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 8 Sep 2001 01:02:41 +0300 Subject: [PATCH 10/18] Fix for LOCK TABLES and BDB tables Docs/manual.texi: Added more information to MySQL comparison --- Docs/manual.texi | 45 +++++++++++++++++++++++++++++---------------- sql/ha_berkeley.cc | 13 +++++++++---- sql/mysql_priv.h | 3 ++- sql/sql_parse.cc | 10 +++++++++- 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 389e8befec5..5ddcd1fa67a 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -5467,9 +5467,10 @@ something that is of course not true. We could make things even worse by just taking the test where PostgreSQL performs worst and claim that MySQL is more than 2000 times faster than PostgreSQL. -The case is that MySQL does a lot of optimizations that PostgreSQL doesn't -do and the other way around. An SQL optimizer is a very complex thing, and -a company could spend years on just making the optimizer faster and faster. +The case is that MySQL does a lot of optimizations that PostgreSQL +doesn't do. This is of course also true the other way around. An SQL +optimizer is a very complex thing, and a company could spend years on +just making the optimizer faster and faster. When looking at the benchmark results you should look for things that you do in your application and just use these results to decide which @@ -5604,12 +5605,14 @@ MySQL with 2000 simultaneous connections doing 400 queries per second. It sounded like he was using a Linux kernel that either had some problems with many threads, such as kernels before 2.4, which had a problem -with this but we have documented how to fix this and Tim should be aware of -this problem. The other possible problem could have been an old glibc -library and that Tim didn't use a MySQL binary from our site, which is -linked with a corrected glibc library, but had compiled a version of his -own with. In any of the above cases, the symptom would have been exactly -what Tim had measured. +with many threads on multi-CPU machines. We have documented in this manual +how to fix this and Tim should be aware of this problem. + +The other possible problem could have been an old glibc library and +that Tim didn't use a MySQL binary from our site, which is linked with +a corrected glibc library, but had compiled a version of his own with. +In any of the above cases, the symptom would have been exactly what Tim +had measured. We asked Tim if we could get access to his data so that we could repeat the benchmark and if he could check the MySQL version on the machine to @@ -5618,6 +5621,16 @@ He has not done that yet. Because of this we can't put any trust in this benchmark either :( +Over time things also changes and the above benchmarks are not that +relevant anymore. MySQL now have a couple of different table handlers +with different speed/concurrency tradeoffs. @xref{Table types}. It +would be interesting to see how the above tests would run with the +different transactional table types in MySQL. PostgreSQL has of course +also got new features since the test was made. As the above test are +not publicly available there is no way for us to know how the +database would preform in the same tests today. + + Conclusion: The only benchmarks that exist today that anyone can download and run @@ -5632,15 +5645,15 @@ The thing we find strange is that every test we have seen about PostgreSQL, that is impossible to reproduce, claims that PostgreSQL is better in most cases while our tests, which anyone can reproduce, clearly shows otherwise. With this we don't want to say that PostgreSQL -isn't good at many things (it is!). We would just like to see a fair test -where they are very good so that we could get some friendly competition -going! +isn't good at many things (it is!) or that it isn't faster than MySQL +under certain conditions. We would just like to see a fair test where +they are very good so that we could get some friendly competition going! For more information about our benchmarks suite @xref{MySQL Benchmarks}. -We are working on an even better benchmark suite, including much better -documentation of what the individual tests really do, and how to add more -tests to the suite. +We are working on an even better benchmark suite, including multi user +tests, and a better documentation of what the individual tests really +do and how to add more tests to the suite. @node TODO, , Comparisons, Introduction @@ -46771,7 +46784,7 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.42 @itemize @bullet @item -Fixed a problem when using @code{LOCK TABLES} and @code{BDB} tables. +Fixed problem when using @code{LOCK TABLES} and @code{BDB} tables. @item Fixed problem with @code{REPAIR TABLE} on MyISAM tables with row lengths between 65517 - 65520 bytes diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 25f8148e52f..7ee72803dd9 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -1658,12 +1658,15 @@ int ha_berkeley::external_lock(THD *thd, int lock_type) { if (!thd->transaction.bdb_lock_count++) { + changed_rows=0; /* First table lock, start transaction */ - if ((thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)) && + if ((thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN | + OPTION_TABLE_LOCK)) && !thd->transaction.all.bdb_tid) { + DBUG_ASSERT(thd->transaction.stmt.bdb_tid != 0); /* We have to start a master transaction */ - DBUG_PRINT("trans",("starting transaction")); + DBUG_PRINT("trans",("starting transaction all")); if ((error=txn_begin(db_env, 0, (DB_TXN**) &thd->transaction.all.bdb_tid, 0))) @@ -1671,8 +1674,10 @@ int ha_berkeley::external_lock(THD *thd, int lock_type) thd->transaction.bdb_lock_count--; // We didn't get the lock /* purecov: inspected */ DBUG_RETURN(error); /* purecov: inspected */ } + if (thd->in_lock_tables) + DBUG_RETURN(0); // Don't create stmt trans } - DBUG_PRINT("trans",("starting transaction for statement")); + DBUG_PRINT("trans",("starting transaction stmt")); if ((error=txn_begin(db_env, (DB_TXN*) thd->transaction.all.bdb_tid, (DB_TXN**) &thd->transaction.stmt.bdb_tid, @@ -1684,7 +1689,6 @@ int ha_berkeley::external_lock(THD *thd, int lock_type) } } transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid; - changed_rows=0; } else { @@ -1722,6 +1726,7 @@ int ha_berkeley::start_stmt(THD *thd) DBUG_ENTER("ha_berkeley::start_stmt"); if (!thd->transaction.stmt.bdb_tid) { + DBUG_PRINT("trans",("starting transaction stmt")); error=txn_begin(db_env, (DB_TXN*) thd->transaction.all.bdb_tid, (DB_TXN**) &thd->transaction.stmt.bdb_tid, 0); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 06d0b1528f4..841d76928e1 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -163,7 +163,8 @@ void kill_one_thread(THD *thd, ulong id); #define OPTION_BIN_LOG OPTION_BUFFER_RESULT*2 #define OPTION_NOT_AUTO_COMMIT OPTION_BIN_LOG*2 #define OPTION_BEGIN OPTION_NOT_AUTO_COMMIT*2 -#define OPTION_QUICK OPTION_BEGIN*2 +#define OPTION_TABLE_LOCK OPTION_BEGIN*2 +#define OPTION_QUICK OPTION_TABLE_LOCK*2 #define OPTION_QUOTE_SHOW_CREATE OPTION_QUICK*2 #define OPTION_INTERNAL_SUBTRANSACTIONS OPTION_QUOTE_SHOW_CREATE*2 diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 417484b2ef7..18ab3c45359 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -81,7 +81,8 @@ static void init_signals(void) inline bool end_active_trans(THD *thd) { int error=0; - if (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)) + if (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN | + OPTION_TABLE_LOCK)) { thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); thd->server_status&= ~SERVER_STATUS_IN_TRANS; @@ -1825,7 +1826,11 @@ mysql_execute_command(void) { thd->lock=thd->locked_tables; thd->locked_tables=0; // Will be automaticly closed + } + if (thd->options & OPTION_TABLE_LOCK) + { end_active_trans(thd); + thd->options&= ~(ulong) (OPTION_TABLE_LOCK); } if (thd->global_read_lock) { @@ -1847,12 +1852,15 @@ mysql_execute_command(void) if (check_db_used(thd,tables) || end_active_trans(thd)) goto error; thd->in_lock_tables=1; + thd->options|= OPTION_TABLE_LOCK; if (!(res=open_and_lock_tables(thd,tables))) { thd->locked_tables=thd->lock; thd->lock=0; send_ok(&thd->net); } + else + thd->options&= ~(ulong) (OPTION_TABLE_LOCK); thd->in_lock_tables=0; break; case SQLCOM_CREATE_DB: From 8e9c21de2ba0a41ba81ce14f0c5bbaa2187015b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 8 Sep 2001 11:47:34 +0300 Subject: [PATCH 11/18] More debug info Fix DBUG_ASSERT() Optimization for BDB tables Fix for BDB under Win98 Docs/manual.texi: Removed wrong info bdb/os_win32/os_rename.c: Fix for windows 98 configure.in: Better options for MAC OS X include/dbug.h: Fix DBUG_ASSERT() mysys/thr_lock.c: More DBUG messages sql/ha_berkeley.cc: Use cursor in remove_key sql/lock.cc: Fix possible problem when pre-unlocking tables in SELECT sql/sql_select.cc: More DBUG messages sql/violite.c: Fix DBUG messages --- Docs/manual.texi | 3 --- bdb/os_win32/os_rename.c | 2 +- configure.in | 6 ++---- include/dbug.h | 2 +- mysys/thr_lock.c | 2 +- sql/ha_berkeley.cc | 14 ++++++++++---- sql/lock.cc | 11 +++++++---- sql/sql_select.cc | 2 ++ sql/violite.c | 6 +++--- 9 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 2537255008c..a437a143cab 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -32591,9 +32591,6 @@ tblTemp1.fldOrder_ID > 100; The following conditions hold for an @code{INSERT ... SELECT} statement: @itemize @minus -@item -The query cannot contain an @code{ORDER BY} clause. - @item The target table of the @code{INSERT} statement cannot appear in the @code{FROM} clause of the @code{SELECT} part of the query because it's diff --git a/bdb/os_win32/os_rename.c b/bdb/os_win32/os_rename.c index c824820462c..cd53ec02022 100644 --- a/bdb/os_win32/os_rename.c +++ b/bdb/os_win32/os_rename.c @@ -47,7 +47,7 @@ __os_rename(dbenv, old, new) */ if (MoveFileEx(old, new, MOVEFILE_REPLACE_EXISTING) != TRUE) ret = __os_win32_errno(); - if (ret == ENOENT && MoveFile(old, new) == TRUE) + if ((ret == ENOENT || ret == EIO) && MoveFile(old, new) == TRUE) ret = 0; } if (ret != 0) diff --git a/configure.in b/configure.in index 121d54009f1..ddf2aa396e3 100644 --- a/configure.in +++ b/configure.in @@ -797,10 +797,8 @@ case $SYSTEM_TYPE in *darwin*) if test "$ac_cv_prog_gcc" = "yes" then - CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS" - CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS" - CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE" - CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE" + CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ" + CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ" MAX_C_OPTIMIZE="-O" with_named_curses="" fi diff --git a/include/dbug.h b/include/dbug.h index d86b83f4de8..3c86cbb8ac2 100644 --- a/include/dbug.h +++ b/include/dbug.h @@ -66,7 +66,7 @@ extern void _db_unlock_file(); #define DEBUGGER_ON _no_db_=0 #define DBUG_LOCK_FILE { _db_lock_file(); } #define DBUG_UNLOCK_FILE { _db_unlock_file(); } -#define DBUG_ASSERT(A) A +#define DBUG_ASSERT(A) assert(A) #else /* No debugger */ #define DBUG_ENTER(a1) diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index d2b3960d6b5..10c803378df 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -736,7 +736,7 @@ void thr_unlock(THR_LOCK_DATA *data) data->type == TL_WRITE_ALLOW_WRITE)); else { - DBUG_PRINT("lock",("No locks to free")); + DBUG_PRINT("lock",("No waiting read locks to free")); } } else if (data && diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 7ee72803dd9..ac4088ed6a9 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -1181,9 +1181,11 @@ int ha_berkeley::remove_key(DB_TXN *trans, uint keynr, const byte *record, DBUG_ENTER("remove_key"); DBUG_PRINT("enter",("index: %d",keynr)); - if (keynr == primary_key || - ((table->key_info[keynr].flags & (HA_NOSAME | HA_NULL_PART_KEY)) == - HA_NOSAME)) + if (keynr == active_index && cursor) + error=cursor->c_del(cursor,0); + else if (keynr == primary_key || + ((table->key_info[keynr].flags & (HA_NOSAME | HA_NULL_PART_KEY)) == + HA_NOSAME)) { // Unique key dbug_assert(keynr == primary_key || prim_key->data != key_buff2); error=key_file[keynr]->del(key_file[keynr], trans, @@ -1312,7 +1314,10 @@ int ha_berkeley::index_init(uint keynr) an active cursor at this point */ if (cursor) + { + DBUG_PRINT("note",("Closing active cursor")); cursor->c_close(cursor); + } active_index=keynr; if ((error=key_file[keynr]->cursor(key_file[keynr], transaction, &cursor, table->reginfo.lock_type > @@ -1659,12 +1664,13 @@ int ha_berkeley::external_lock(THD *thd, int lock_type) if (!thd->transaction.bdb_lock_count++) { changed_rows=0; + transaction=0; // Safety /* First table lock, start transaction */ if ((thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN | OPTION_TABLE_LOCK)) && !thd->transaction.all.bdb_tid) { - DBUG_ASSERT(thd->transaction.stmt.bdb_tid != 0); + DBUG_ASSERT(thd->transaction.stmt.bdb_tid == 0); /* We have to start a master transaction */ DBUG_PRINT("trans",("starting transaction all")); if ((error=txn_begin(db_env, 0, diff --git a/sql/lock.cc b/sql/lock.cc index a8b26c3b17d..7bac2d54631 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -169,8 +169,11 @@ static int lock_external(TABLE **tables,uint count) void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock) { DBUG_ENTER("mysql_unlock_tables"); - thr_multi_unlock(sql_lock->locks,sql_lock->lock_count); - VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count)); + if (sql_lock->lock_count) + { + thr_multi_unlock(sql_lock->locks,sql_lock->lock_count); + VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count)); + } my_free((gptr) sql_lock,MYF(0)); DBUG_VOID_RETURN; } @@ -213,7 +216,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock) if (i != found) { thr_multi_unlock(lock,i-found); - sql_lock->lock_count-=found; + sql_lock->lock_count= found; } /* Then to the same for the external locks */ @@ -232,7 +235,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock) if (i != found) { VOID(unlock_external(thd,table,i-found)); - sql_lock->table_count-=found; + sql_lock->table_count=found; } DBUG_VOID_RETURN; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b30cb6bb639..b6c261d1463 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2516,6 +2516,7 @@ static void join_free(JOIN *join) { JOIN_TAB *tab,*end; + DBUG_ENTER("join_free"); if (join->table) { @@ -2556,6 +2557,7 @@ join_free(JOIN *join) join->tmp_table_param.copy_funcs.delete_elements(); delete [] join->tmp_table_param.copy_field; join->tmp_table_param.copy_field=0; + DBUG_VOID_RETURN; } diff --git a/sql/violite.c b/sql/violite.c index 0d96c71969c..d551b9b8632 100644 --- a/sql/violite.c +++ b/sql/violite.c @@ -154,7 +154,7 @@ int vio_read(Vio * vio, gptr buf, int size) { int r; DBUG_ENTER("vio_read"); - DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size)); #if defined( __WIN__) || defined(OS2) if (vio->type == VIO_TYPE_NAMEDPIPE) { @@ -188,7 +188,7 @@ int vio_write(Vio * vio, const gptr buf, int size) { int r; DBUG_ENTER("vio_write"); - DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size)); #if defined( __WIN__) || defined(OS2) if ( vio->type == VIO_TYPE_NAMEDPIPE) { @@ -303,7 +303,7 @@ int vio_keepalive(Vio* vio, my_bool set_keep_alive) int r=0; uint opt = 0; DBUG_ENTER("vio_keepalive"); - DBUG_PRINT("enter", ("sd=%d, set_keep_alive=%d", vio->sd, (int) + DBUG_PRINT("enter", ("sd=%d set_keep_alive=%d", vio->sd, (int) set_keep_alive)); if (vio->type != VIO_TYPE_NAMEDPIPE) { From 851bea0e88c0148b87eda3b32d287ef3211b262f Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 8 Sep 2001 20:45:53 +0300 Subject: [PATCH 12/18] Fix bugs when using LOCK TABLES with BDB tables Optimized remove of key when using internal cursor in BDB tables. mysql-test/r/bdb.result: Test for LOCK bug mysql-test/t/bdb.test: Test for LOCK bug sql/ha_berkeley.cc: Fix bugs when using LOCK TABLES Optimized remove of key when using internal cursor sql/ha_berkeley.h: Initilize of changed_rows sql/lock.cc: Fix for BDB tables --- mysql-test/r/bdb.result | 3 +++ mysql-test/t/bdb.test | 27 +++++++++++++++++++-------- sql/ha_berkeley.cc | 27 ++++++++++++++++----------- sql/ha_berkeley.h | 2 +- sql/lock.cc | 8 ++++---- 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index 39b4962ef58..e66ca657484 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -524,3 +524,6 @@ a b a b a b 1 1 1 2 +id id2 id3 dummy1 +id id2 id3 dummy1 +NULL NULL NULL NULL diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test index 5e28c31e051..465dc9634cc 100644 --- a/mysql-test/t/bdb.test +++ b/mysql-test/t/bdb.test @@ -727,13 +727,24 @@ DROP TABLE t1,t2; # Test problem with joining table to itself on a multi-part unique key # -drop table if exists t; -create table t (a int(11) not null, b int(11) not null, unique (a,b)) type=bdb; +drop table if exists t1; +create table t1 (a int(11) not null, b int(11) not null, unique (a,b)) type=bdb; +insert into t1 values (1,1), (1,2); +select * from t1 where a = 1; +select t1.*, t2.* from t1, t1 t2 where t1.a = t2.a and t2.a = 1; +select * from t1 where a = 1; +drop table t1; -insert into t values (1,1), (1,2); +# +# This caused a deadlock in BDB internal locks +# -select * from t where a = 1; -select t1.*, t2.* from t t1, t t2 where t1.a = t2.a and t2.a = 1; -select * from t where a = 1; - -drop table t; +create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=bdb; +insert into t1 values (0,0,0,'ABCDEFGHIJ'); +create table t2 (id int NOT NULL,primary key (id)) type=bdb; +LOCK TABLES t1 WRITE, t2 WRITE; +insert into t2 values(1); +SELECT t1.* FROM t1 WHERE id IN (1); +SELECT t1.* FROM t2 left outer join t1 on (t1.id=t2.id); +delete from t1 where id3 >= 0 and id3 <= 0; +drop table t1,t2; diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index ac4088ed6a9..9a437607729 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -1306,7 +1306,7 @@ int ha_berkeley::delete_row(const byte * record) int ha_berkeley::index_init(uint keynr) { int error; - DBUG_ENTER("index_init"); + DBUG_ENTER("ha_berkeley::index_init"); DBUG_PRINT("enter",("table: '%s' key: %d", table->real_name, keynr)); /* @@ -1347,7 +1347,7 @@ int ha_berkeley::index_end() int ha_berkeley::read_row(int error, char *buf, uint keynr, DBT *row, DBT *found_key, bool read_next) { - DBUG_ENTER("read_row"); + DBUG_ENTER("ha_berkeley::read_row"); if (error) { if (error == DB_NOTFOUND || error == DB_KEYEMPTY) @@ -1399,6 +1399,7 @@ int ha_berkeley::index_read_idx(byte * buf, uint keynr, const byte * key, statistic_increment(ha_read_key_count,&LOCK_status); DBUG_ENTER("index_read_idx"); current_row.flags=DB_DBT_REALLOC; + active_index= -1; DBUG_RETURN(read_row(key_file[keynr]->get(key_file[keynr], transaction, pack_key(&last_key, keynr, key_buff, key, key_len), @@ -1413,7 +1414,7 @@ int ha_berkeley::index_read(byte * buf, const byte * key, DBT row; int error; KEY *key_info= &table->key_info[active_index]; - DBUG_ENTER("index_read"); + DBUG_ENTER("ha_berkeley::index_read"); statistic_increment(ha_read_key_count,&LOCK_status); bzero((char*) &row,sizeof(row)); @@ -1518,8 +1519,9 @@ int ha_berkeley::index_last(byte * buf) int ha_berkeley::rnd_init(bool scan) { + DBUG_ENTER("rnd_init"); current_row.flags=DB_DBT_REALLOC; - return index_init(primary_key); + DBUG_RETURN(index_init(primary_key)); } int ha_berkeley::rnd_end() @@ -1534,7 +1536,7 @@ int ha_berkeley::rnd_next(byte *buf) statistic_increment(ha_read_rnd_next_count,&LOCK_status); bzero((char*) &row,sizeof(row)); DBUG_RETURN(read_row(cursor->c_get(cursor, &last_key, &row, DB_NEXT), - (char*) buf, active_index, &row, &last_key, 1)); + (char*) buf, primary_key, &row, &last_key, 1)); } @@ -1564,10 +1566,11 @@ int ha_berkeley::rnd_pos(byte * buf, byte *pos) DBT db_pos; statistic_increment(ha_read_rnd_count,&LOCK_status); + active_index= (uint) -1; // Don't delete via cursor return read_row(file->get(file, transaction, get_pos(&db_pos, pos), ¤t_row, 0), - (char*) buf, active_index, ¤t_row, (DBT*) 0, 0); + (char*) buf, primary_key, ¤t_row, (DBT*) 0, 0); } void ha_berkeley::position(const byte *record) @@ -1582,10 +1585,10 @@ void ha_berkeley::position(const byte *record) void ha_berkeley::info(uint flag) { - DBUG_ENTER("info"); + DBUG_ENTER("ha_berkeley::info"); if (flag & HA_STATUS_VARIABLE) { - records = share->rows; // Just to get optimisations right + records = share->rows + changed_rows; // Just to get optimisations right deleted = 0; } if ((flag & HA_STATUS_CONST) || version != share->version) @@ -1663,14 +1666,13 @@ int ha_berkeley::external_lock(THD *thd, int lock_type) { if (!thd->transaction.bdb_lock_count++) { - changed_rows=0; + DBUG_ASSERT(thd->transaction.stmt.bdb_tid == 0); transaction=0; // Safety /* First table lock, start transaction */ if ((thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN | OPTION_TABLE_LOCK)) && !thd->transaction.all.bdb_tid) { - DBUG_ASSERT(thd->transaction.stmt.bdb_tid == 0); /* We have to start a master transaction */ DBUG_PRINT("trans",("starting transaction all")); if ((error=txn_begin(db_env, 0, @@ -1700,6 +1702,7 @@ int ha_berkeley::external_lock(THD *thd, int lock_type) { lock.type=TL_UNLOCK; // Unlocked thread_safe_add(share->rows, changed_rows, &share->mutex); + changed_rows=0; if (!--thd->transaction.bdb_lock_count) { if (thd->transaction.stmt.bdb_tid) @@ -1736,8 +1739,8 @@ int ha_berkeley::start_stmt(THD *thd) error=txn_begin(db_env, (DB_TXN*) thd->transaction.all.bdb_tid, (DB_TXN**) &thd->transaction.stmt.bdb_tid, 0); - transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid; } + transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid; DBUG_RETURN(error); } @@ -1942,6 +1945,8 @@ longlong ha_berkeley::get_auto_increment() longlong nr=1; // Default if error or new key int error; (void) ha_berkeley::extra(HA_EXTRA_KEYREAD); + + /* Set 'active_index' */ ha_berkeley::index_init(table->next_number_index); if (!table->next_number_key_offset) diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index 3eb793937ae..fda7d2f2069 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -93,7 +93,7 @@ class ha_berkeley: public handler HA_BLOB_KEY | HA_NOT_EXACT_COUNT | HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | HA_AUTO_PART_KEY), - last_dup_key((uint) -1),version(0),using_ignore(0) + changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0) { } ~ha_berkeley() {} diff --git a/sql/lock.cc b/sql/lock.cc index 7bac2d54631..aa06822e03f 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -170,10 +170,9 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock) { DBUG_ENTER("mysql_unlock_tables"); if (sql_lock->lock_count) - { thr_multi_unlock(sql_lock->locks,sql_lock->lock_count); + if (sql_lock->table_count) VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count)); - } my_free((gptr) sql_lock,MYF(0)); DBUG_VOID_RETURN; } @@ -317,7 +316,7 @@ static int unlock_external(THD *thd, TABLE **table,uint count) DBUG_ENTER("unlock_external"); error_code=0; - for (; count-- ; table++) + do { if ((*table)->current_lock != F_UNLCK) { @@ -325,7 +324,8 @@ static int unlock_external(THD *thd, TABLE **table,uint count) if ((error=(*table)->file->external_lock(thd, F_UNLCK))) error_code=error; } - } + table++; + } while (--count); if (error_code) print_lock_error(error_code); DBUG_RETURN(error_code); From a278411271b00f0f1c8b49eb659dbeffa4cfce10 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 8 Sep 2001 22:04:17 +0300 Subject: [PATCH 13/18] Some cleanups to replication section --- Docs/manual.texi | 122 ++++++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 48 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index a437a143cab..834782257d1 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -23616,20 +23616,29 @@ Because the user could issue the @code{FLUSH LOGS} command, we need to know which log is currently active and which ones have been rotated out and in what sequence. This information is stored in the binary log index file. The default is `hostname`.index. You can use this option if you want to -be a rebel. (Example: @code{log-bin-index=db.index}) +be a rebel. + +Example: @code{log-bin-index=db.index}. @item @code{sql-bin-update-same} @tab If set, setting @code{SQL_LOG_BIN} to a value will automatically set @code{SQL_LOG_UPDATE} to the same value and vice versa. @item @code{binlog-do-db=database_name} @tab -Tells the master it should log updates for the specified database, and -exclude all others not explicitly mentioned. -(Example: @code{binlog-do-db=some_database}) +Tells the master that it should log updates to the binary log if the +current database is 'database_name'. All others database are ignored. +Note that if you use this you should ensure that you only do updates in +the current database. + +Example: @code{binlog-do-db=some_database}. @item @code{binlog-ignore-db=database_name} @tab -Tells the master that updates to the given database should not be logged -to the binary log (Example: @code{binlog-ignore-db=some_database}) +Tells the master that updates where the current database is +'database_name' should not be stored in the binary log. Note that if +you use this you should ensure that you only do updates in the current +database. + +Example: @code{binlog-ignore-db=some_database} @end multitable The following table has the options you can use for the @strong{SLAVE}: @@ -23640,65 +23649,79 @@ The following table has the options you can use for the @strong{SLAVE}: @item @code{master-host=host} @tab Master hostname or IP address for replication. If not set, the slave thread will not be started. -(Example: @code{master-host=db-master.mycompany.com}) + +Example: @code{master-host=db-master.mycompany.com}. @item @code{master-user=username} @tab The user the slave thread will us for authentication when connecting to the master. The user must have @code{FILE} privilege. If the master user -is not set, user @code{test} is assumed. (Example: -@code{master-user=scott}) +is not set, user @code{test} is assumed. + +Example: @code{master-user=scott}. @item @code{master-password=password} @tab The password the slave thread will authenticate with when connecting to -the master. If not set, an empty password is assumed. (Example: -@code{master-password=tiger}) +the master. If not set, an empty password is assumed. + +Example: @code{master-password=tiger}. @item @code{master-port=portnumber} @tab The port the master is listening on. If not set, the compiled setting of @code{MYSQL_PORT} is assumed. If you have not tinkered with -@code{configure} options, this should be 3306. (Example: -@code{master-port=3306}) +@code{configure} options, this should be 3306. + +Example: @code{master-port=3306}. @item @code{master-connect-retry=seconds} @tab The number of seconds the slave thread will sleep before retrying to connect to the master in case the master goes down or the connection is -lost. Default is 60. (Example: @code{master-connect-retry=60}) +lost. Default is 60. + +Example: @code{master-connect-retry=60}. @item @code{master-info-file=filename} @tab The location of the file that remembers where we left off on the master during the replication process. The default is master.info in the data directory. Sasha: The only reason I see for ever changing the default -is the desire to be rebelious. (Example: -@code{master-info-file=master.info}) +is the desire to be rebelious. + +Example: @code{master-info-file=master.info}. @item @code{replicate-do-table=db_name.table_name} @tab -Tells the slave thread to restrict replication to the specified database. -To specify more than one table, use the directive multiple times, -once for each table. . -(Example: @code{replicate-do-table=some_db.some_table}) +Tells the slave thread to restrict replication to the specified table. +To specify more than one table, use the directive multiple times, once +for each table. This will work for cross-database updates, in +contrast to @code{replicate-do-db}. + +Example: @code{replicate-do-table=some_db.some_table}. @item @code{replicate-ignore-table=db_name.table_name} @tab Tells the slave thread to not replicate to the specified table. To -specify more than one table to ignore, use the directive multiple -times, once for each table.(Example: -@code{replicate-ignore-table=db_name.some_table}) +specify more than one table to ignore, use the directive multiple times, +once for each table. This will work for cross-datbase updates, +in contrast to @code{replicate-ignore-db}. + +Example: @code{replicate-ignore-table=db_name.some_table}. @item @code{replicate-wild-do-table=db_name.table_name} @tab -Tells the slave thread to restrict replication to the tables that match the -specified wildcard pattern. . -To specify more than one table, use the directive multiple times, -once for each table. . -(Example: @code{replicate-do-table=foo%.bar%} will replicate only updates +Tells the slave thread to restrict replication to the tables that match +the specified wildcard pattern. To specify more than one table, use the +directive multiple times, once for each table. This will work for +cross-database updates. + +Example: @code{replicate-wild-do-table=foo%.bar%} will replicate only updates to tables in all databases that start with foo and whose table names -start with bar) +start with bar. @item @code{replicate-wild-ignore-table=db_name.table_name} @tab -Tells the slave thread to not replicate to the tables that match the given -wild card pattern. To -specify more than one table to ignore, use the directive multiple -times, once for each table.(Example: -@code{replicate-ignore-table=foo%.bar%} - will not upates to tables in all databases that start with foo and whose table names -start with bar) +Tells the slave thread to not replicate to the tables that match the +given wild card pattern. To specify more than one table to ignore, use +the directive multiple times, once for each table. This will work for +cross-database updates. + +Example: @code{replicate-wild-ignore-table=foo%.bar%} will not do updates +to tables in databases that start with foo and whose table names start +with bar. @item @code{replicate-ignore-db=database_name} @tab Tells the slave thread to not replicate to the specified database. To @@ -23706,19 +23729,21 @@ specify more than one database to ignore, use the directive multiple times, once for each database. This option will not work if you use cross database updates. If you need cross database updates to work, make sure you have 3.23.28 or later, and use -@code{replicate-wild-ignore-table=db_name.%}(Example: -@code{replicate-ignore-db=some_db}) +@code{replicate-wild-ignore-table=db_name.%} + +Example: @code{replicate-ignore-db=some_db}. @item @code{replicate-do-db=database_name} @tab -Tells the slave thread to restrict replication to the specified database. -To specify more than one database, use the directive multiple times, -once for each database. Note that this will only work if you do not use -cross-database queries such as @code{UPDATE some_db.some_table SET -foo='bar'} while having selected a different or no database. If you need -cross database updates to work, make sure -you have 3.23.28 or later, and use -@code{replicate-wild-do-table=db_name.%} -(Example: @code{replicate-do-db=some_db}) + +Tells the slave thread to restrict replication to the specified +database. To specify more than one database, use the directive multiple +times, once for each database. Note that this will only work if you do +not use cross-database queries such as @code{UPDATE some_db.some_table +SET foo='bar'} while having selected a different or no database. If you +need cross database updates to work, make sure you have 3.23.28 or +later, and use @code{replicate-wild-do-table=db_name.%} + +Example: @code{replicate-do-db=some_db}. @item @code{log-slave-updates} @tab Tells the slave to log the updates from the slave thread to the binary @@ -23726,8 +23751,9 @@ log. Off by default. You will need to turn it on if you plan to daisy-chain the slaves. @item @code{replicate-rewrite-db=from_name->to_name} @tab -Updates to a database with a different name than the original (Example: -@code{replicate-rewrite-db=master_db_name->slave_db_name} +Updates to a database with a different name than the original + +Example: @code{replicate-rewrite-db=master_db_name->slave_db_name}. @item @code{skip-slave-start} @tab Tells the slave server not to start the slave on the startup. The user From 1c404ff9e3ec640a45e4451aaf612aeb699ed357 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 9 Sep 2001 17:41:29 +0300 Subject: [PATCH 14/18] ha_innobase.cc mean_rec_length was set to a too small value for > 4 GB tables because of a wrong typecast sql/ha_innobase.cc: mean_rec_length was set to a too small value for > 4 GB tables because of a wrong typecast --- sql/ha_innobase.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 2eed5ada680..104aaf8886c 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -21,7 +21,7 @@ InnoDB */ - Ask Monty if strings of different languages can exist in the same database. Answer: in near future yes, but not yet. */ - + #ifdef __GNUC__ #pragma implementation // gcc: Class implementation #endif @@ -2844,7 +2844,7 @@ ha_innobase::info( if (records == 0) { mean_rec_length = 0; } else { - mean_rec_length = (ulong) data_file_length / records; + mean_rec_length = (ulong) (data_file_length / records); } } From 341504b3c9770c450b8101784344b403bd0257cc Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 10 Sep 2001 17:36:42 +0300 Subject: [PATCH 15/18] handler.cc If CREATE TABLE fails for an InnoDB table, do not put the OS error number to the error message, because it is not the cause sql/handler.cc: If CREATE TABLE fails for an InnoDB table, do not put the OS error number to the error message, because it is not the cause --- sql/handler.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 2f6e3b11bdf..1c50634de1f 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -837,8 +837,15 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, } error=table.file->create(name,&table,create_info); VOID(closefrm(&table)); - if (error) - my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,my_errno); + if (error) { + if (table.db_type == DB_TYPE_INNOBASE) { + /* Creation of InnoDB table cannot fail because of an OS error: + put error as the number */ + my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error); + } else { + my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,my_errno); + } + } DBUG_RETURN(error != 0); } From 8cfd4949c2725431d78605d30c1138c4d42ab4d2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 10 Sep 2001 17:30:29 -0600 Subject: [PATCH 16/18] fixed IDENTITY crisis --- mysql-test/r/identity.result | 4 ++++ mysql-test/t/identity.test | 2 ++ sql/sql_lex.cc | 16 +++++++++++++--- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 mysql-test/r/identity.result create mode 100644 mysql-test/t/identity.test diff --git a/mysql-test/r/identity.result b/mysql-test/r/identity.result new file mode 100644 index 00000000000..45968248d26 --- /dev/null +++ b/mysql-test/r/identity.result @@ -0,0 +1,4 @@ +last_insert_id(345) +345 +@@IDENTITY last_insert_id() +345 345 diff --git a/mysql-test/t/identity.test b/mysql-test/t/identity.test new file mode 100644 index 00000000000..37183fd3b35 --- /dev/null +++ b/mysql-test/t/identity.test @@ -0,0 +1,2 @@ +select last_insert_id(345); +select @@IDENTITY,last_insert_id(); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 20bda932f2f..e0044a0710f 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -793,9 +793,19 @@ int yylex(void *arg) } break; case STATE_USER_END: // end '@' of user@hostname - if (state_map[yyPeek()] != STATE_STRING && - state_map[yyPeek()] != STATE_USER_VARIABLE_DELIMITER) - lex->next_state=STATE_HOSTNAME; // Mark for next loop + switch (state_map[yyPeek()]) + { + case STATE_STRING: + case STATE_USER_VARIABLE_DELIMITER: + break; + case STATE_USER_END: + lex->next_state=STATE_USER_END; + yySkip(); + break; + default: + lex->next_state=STATE_HOSTNAME; + break; + } yylval->lex_str.str=(char*) lex->ptr; yylval->lex_str.length=1; return((int) '@'); From a53e8ea0ac4f7d53297b7942febf04e02d8c3b54 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Sep 2001 00:11:18 +0300 Subject: [PATCH 17/18] First drop merge table, then other tables Docs/manual.texi: Updated information about mysql_insert_id() --- Docs/manual.texi | 17 ++++++++++++++--- mysql-test/t/merge.test | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 834782257d1..c63fb14011e 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -31863,9 +31863,10 @@ The reason for this is so that you it makes it possible to easily reproduce the same @code{INSERT} statement against some other server. @cindex sequence emulation -If @code{expr} is given as an argument to @code{LAST_INSERT_ID()} in an -@code{UPDATE} clause, then the value of the argument is returned as a -@code{LAST_INSERT_ID()} value. This can be used to simulate sequences. +If @code{expr} is given as an argument to @code{LAST_INSERT_ID()}, then +the value of the argument is returned by the function, is set as the +next value to be returned by @code{LAST_INSERT_ID()} and used as the next +auto_increment value. This can be used to simulate sequences: First create the table: @@ -31888,6 +31889,12 @@ MySQL. For example, @code{LAST_INSERT_ID()} (without an argument) will return the new ID. The C API function @code{mysql_insert_id()} can also be used to get the value. +Note that as @code{mysql_insert_id()} is only updated after +@code{INSERT} and @code{UPDATE} statements, you can't use this function +to retrieve the value used @code{LAST_INSERT_ID(expr)} for other SQL +statements. + + @findex FORMAT() @item FORMAT(X,D) Formats the number @code{X} to a format like @code{'#,###,###.##'}, rounded @@ -40633,6 +40640,10 @@ does not generate an @code{AUTO_INCREMENT} value. If you need to save the value for later, be sure to call @code{mysql_insert_id()} immediately after the query that generates the value. +@code{mysql_insert_id()} is only updated after @code{INSERT} and +@code{UPDATE} statements, not after using @code{LAST_INSERT_ID(expr)}. +@xref{Miscellaneous functions}. + Also note that the value of the SQL @code{LAST_INSERT_ID()} function always contains the most recently generated @code{AUTO_INCREMENT} value, and is not reset between queries because the value of that function is maintained diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 6820242d562..238dd599664 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -113,4 +113,4 @@ insert into t1 values (1,2),(2,1),(0,0),(4,4),(5,5),(6,6); insert into t2 values (1,1),(2,2),(0,0),(4,4),(5,5),(6,6); flush tables; select * from t3 where a=1 order by b limit 2; -drop table t1,t2,t3; +drop table t3,t1,t2; From 76989cf55c016a9d8619f582f753444241a4d934 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Sep 2001 23:53:31 +0300 Subject: [PATCH 18/18] OS2 patch Docs/manual.texi: Updated section of how to change the socket file. Changelog for 3.23.43 include/merge.h: Fixed typo include/my_pthread.h: Fixed bug for WIN32 include/myisam.h: Fixed typo include/nisam.h: Fixed typo sql/handler.h: Fixed typo sql/sql_table.cc: Fixed typo sql/unireg.cc: F --- Docs/manual.texi | 126 ++++++++++++++++++++++++++++-------------- client/Makefile.am | 1 + client/client_priv.h | 31 +++++++++++ client/mysql.cc | 11 +--- client/mysqladmin.c | 9 +-- client/mysqlbinlog.cc | 16 +++--- client/mysqlcheck.c | 12 +--- client/mysqlimport.c | 10 +--- extra/comp_err.c | 15 ++--- heap/hp_test2.c | 55 +++++++++--------- heap/hp_update.c | 12 ++-- heap/hp_write.c | 2 +- include/config-os2.h | 9 ++- include/global.h | 11 +++- include/merge.h | 2 +- include/my_pthread.h | 2 +- include/myisam.h | 2 +- include/nisam.h | 2 +- libmysql/dll.c | 22 ++++++++ libmysql/libmysql.c | 21 ++++--- libmysql/net.c | 4 +- libmysql/violite.c | 14 +---- myisam/myisampack.c | 48 ++++++++-------- myisam/sort.c | 6 +- mysys/my_write.c | 39 ------------- sql/handler.h | 2 +- sql/mini_client.cc | 12 +--- sql/mysqld.cc | 23 +++++--- sql/net_serv.cc | 4 +- sql/sql_table.cc | 2 +- sql/unireg.cc | 4 +- 31 files changed, 273 insertions(+), 256 deletions(-) create mode 100644 client/client_priv.h diff --git a/Docs/manual.texi b/Docs/manual.texi index c63fb14011e..a61faa7647e 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -1,4 +1,4 @@ -\input texinfo @c -*-texinfo-*- +input texinfo @c -*-texinfo-*- @c Copyright 1997-2001 TcX AB, Detron HB and MySQL Finland AB @c @c ********************************************************* @@ -1566,6 +1566,10 @@ Hands on tutorial for MySQL. @subheading Porting MySQL/Using MySQL on Different Systems @table @asis +@item @uref{http://www.entropy.ch/software/macosx/mysql/} +Binary of MySQL for Mac OS X Client. Includes information of how to +build and use MySQL on Mac OS X. + @item @uref{http://xclave.macnn.com/MySQL/} The Mac OS Xclave. Running MySQL on Mac OS X. @@ -5186,9 +5190,6 @@ formerly TCX DataKonsult AB, has provided top quality commercial support for MySQL from the day it was released, whereas until recently PostgreSQL was unsupported. -@item -MySQL works on more platforms than PostgreSQL. @xref{Which OS}. - @item MySQL works better on Windows than PostgreSQL does. MySQL runs as a native Windows application (a service on NT/Win2000/WinXP), while @@ -8074,6 +8075,8 @@ shell> ./configure --with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock @end example Note that the given file must be an absolute pathname! +You can also later change the location @file{mysql.sock} by using the MySQL +option files. @xref{Problems with mysql.sock}. @cindex compiling, statically @cindex statically, compiling @@ -8087,6 +8090,8 @@ shell> ./configure --with-client-ldflags=-all-static \ --with-mysqld-ldflags=-all-static @end example + + @tindex @code{CC} environment variable @tindex environment variable, @code{CC} @tindex @code{CXX} environment variable @@ -8993,6 +8998,8 @@ shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysqld.sock shell> export TMPDIR MYSQL_UNIX_PORT @end example +@xref{Problems with mysql.sock}. + @file{some_tmp_dir} should be the path to some directory for which you have write permission. @xref{Environment variables}. @@ -9233,6 +9240,7 @@ should append the following to it: /bin/sh -c 'cd /usr/local/mysql ; ./bin/safe_mysqld --user=mysql &' @end example +@cindex changing socket location You can also add options for @code{mysql.server} in a global @file{/etc/my.cnf} file. A typical @file{/etc/my.cnf} file might look like this: @@ -9240,7 +9248,7 @@ this: @example [mysqld] datadir=/usr/local/mysql/var -socket=/tmp/mysqld.sock +socket=/var/tmp/mysql.sock port=3306 user=mysql @@ -28268,18 +28276,22 @@ example: @end example In this example, @code{9} (@code{precision}) represents the number of -significant decimal digits that will be stored for values, and -@code{2} (@code{scale}) represents the number of digits that will be -stored following the decimal point. In this case, therefore, the range -of values that can be stored in the @code{salary} column is from -@code{-999999.99} to @code{9999999.99}. In ANSI/ISO SQL92, the syntax -@code{DECIMAL(p)} is equivalent to @code{DECIMAL(p,0)}. Similarly, the -syntax @code{DECIMAL} is equivalent to @code{DECIMAL(p,0)}, where the -implementation is allowed to decide the value of @code{p}. -MySQL does not currently support either of these variant forms -of the @code{DECIMAL}/@code{NUMERIC} data types. This is not generally -a serious problem, as the principal benefits of these types derive from -the ability to control both precision and scale explicitly. +significant decimal digits that will be stored for values, and @code{2} +(@code{scale}) represents the number of digits that will be stored +following the decimal point. In this case, therefore, the range of +values that can be stored in the @code{salary} column is from +@code{-9999999.99} to @code{9999999.99}. +(MySQL can actually store numbers up to @code{9999999.99} in this column +because it doesn't have to store the sign for positive numbers) + +In ANSI/ISO SQL92, the syntax @code{DECIMAL(p)} is equivalent to +@code{DECIMAL(p,0)}. Similarly, the syntax @code{DECIMAL} is equivalent +to @code{DECIMAL(p,0)}, where the implementation is allowed to decide +the value of @code{p}. MySQL does not currently support either of these +variant forms of the @code{DECIMAL}/@code{NUMERIC} data types. This is +not generally a serious problem, as the principal benefits of these +types derive from the ability to control both precision and scale +explicitly. @code{DECIMAL} and @code{NUMERIC} values are stored as strings, rather than as binary floating-point numbers, in order to preserve the decimal @@ -31891,8 +31903,8 @@ can also be used to get the value. Note that as @code{mysql_insert_id()} is only updated after @code{INSERT} and @code{UPDATE} statements, you can't use this function -to retrieve the value used @code{LAST_INSERT_ID(expr)} for other SQL -statements. +to retrieve the value for @code{LAST_INSERT_ID(expr)} after executing +other SQL statements like @code{SELECT} or @code{SET}. @findex FORMAT() @@ -40640,8 +40652,9 @@ does not generate an @code{AUTO_INCREMENT} value. If you need to save the value for later, be sure to call @code{mysql_insert_id()} immediately after the query that generates the value. -@code{mysql_insert_id()} is only updated after @code{INSERT} and -@code{UPDATE} statements, not after using @code{LAST_INSERT_ID(expr)}. +@code{mysql_insert_id()} is updated after @code{INSERT} and +@code{UPDATE} statements that generate an @code{AUTO_INCREMENT} value or +that set a column value to @code{LAST_INSERT_ID(expr)}. @xref{Miscellaneous functions}. Also note that the value of the SQL @code{LAST_INSERT_ID()} function always @@ -43402,27 +43415,14 @@ the MySQL socket (for example, a job that removes old files from the @file{/tmp} directory). You can always run @code{mysqladmin version} and check that the socket @code{mysqladmin} is trying to use really exists. The fix in this case is to change the @code{cron} job to -not remove @file{mysqld.sock} or to place the socket somewhere else. You -can specify a different socket location at MySQL configuration -time with this command: -@example -shell> ./configure --with-unix-socket-path=/path/to/socket -@end example -You can also start @code{safe_mysqld} with the -@code{--socket=/path/to/socket} option and set the environment variable -@code{MYSQL_UNIX_PORT} to the socket pathname before starting your -MySQL clients. +not remove @file{mysqld.sock} or to place the socket somewhere else. +@xref{Problems with mysql.sock}. @item You have started the @code{mysqld} server with the @code{--socket=/path/to/socket} option. If you change the socket pathname for the server, you must also notify the MySQL clients -about the new path. You can do this by setting the environment variable -@code{MYSQL_UNIX_PORT} to the socket pathname or by providing the socket path -as an argument to the clients. You can test the socket with this command: - -@example -shell> mysqladmin --socket=/path/to/socket version -@end example +about the new path. You can do this by providing the socket path +as an argument to the client. @xref{Problems with mysql.sock}. @item You are using Linux and one thread has died (core dumped). In this case you must kill the other @code{mysqld} threads (for example, with the @@ -44409,8 +44409,8 @@ tables. These are not hidden and have names of the form @file{SQL_*}. the original table. -@node Problems with mysql.sock, Timezone problems, Temporary files, Administration Issues -@appendixsubsec How to Protect @file{/tmp/mysql.sock} from Being Deleted +@node Problems with mysql.sock, Timezone problems, Temporary files, Administration Issues +@appendixsubsec How to Protect or change the MySQL socket file @file{/tmp/mysql.sock} @cindex @code{mysql.sock}, protection @cindex deletion, @code{mysql.sock} @@ -44430,6 +44430,40 @@ only by their owners or the superuser (@code{root}). You can check if the @code{sticky} bit is set by executing @code{ls -ld /tmp}. If the last permission bit is @code{t}, the bit is set. +@cindex changing socket location + +You can change the place where MySQL uses / puts the socket file the +following ways: + +@itemize @bullet +@item +Specify the path in a global or local option file. +For example, put in @code{/etc/my.cnf}: + +@example +[client] +socket=path-for-socket-file + +[mysqld] +socket=path-for-socket-file +@end example +@xref{Option files}. +@item +Specifying this on the command line to @code{safe_mysqld} and most +clients with the @code{--socket=path-for-socket-file} option. +@item +Specify the path to the socket in the @code{MYSQL_UNIX_PORT} environment +variable. +@item +Defining the path with the @code{configure} option +@code{--with-unix-socket-path=path-for-socket-file}. @xref{configure options}. +@end itemize + +You can test that the socket works with this command: + +@example +shell> mysqladmin --socket=/path/to/socket version +@end example @node Timezone problems, , Problems with mysql.sock, Administration Issues @appendixsubsec Time Zone Problems @@ -46768,6 +46802,7 @@ users use this code as the rest of the code and because of this we are not yet 100% confident in this code. @menu +* News-3.23.43:: Changes in release 3.23.43 * News-3.23.42:: Changes in release 3.23.42 * News-3.23.41:: Changes in release 3.23.41 * News-3.23.40:: Changes in release 3.23.40 @@ -46814,7 +46849,16 @@ not yet 100% confident in this code. * News-3.23.0:: Changes in release 3.23.0 @end menu -@node News-3.23.42, News-3.23.41, News-3.23.x, News-3.23.x +@node News-3.23.43, News-3.23.42, News-3.23.x, News-3.23.x +@appendixsubsec Changes in release 3.23.43 +@itemize @bullet +@item +Fixed problem with @code{myisampack} when using pre-space filled CHAR columns. +@item +Applied patch from Yuri Dario for OS2. +@end itemize + +@node News-3.23.42, News-3.23.41, News-3.23.43, News-3.23.x @appendixsubsec Changes in release 3.23.42 @itemize @bullet @item diff --git a/client/Makefile.am b/client/Makefile.am index a91c7d05f77..380c9f2acbe 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -19,6 +19,7 @@ INCLUDES = -I$(srcdir)/../include \ -I../include -I$(srcdir)/.. -I$(top_srcdir) \ -I.. +noinst_HEADERS = client_priv.h LIBS = @CLIENT_LIBS@ LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \ diff --git a/client/client_priv.h b/client/client_priv.h new file mode 100644 index 00000000000..7bee03a8ab5 --- /dev/null +++ b/client/client_priv.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Common defines for all clients */ + +#include +#include +#include +#include +#include +#include + +/* We have to define 'enum options' identical in all files to keep OS2 happy */ + +enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, + OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE, + OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS, + OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES}; diff --git a/client/mysql.cc b/client/mysql.cc index e4db7e93256..96536c9d5f0 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -25,17 +25,12 @@ * **/ -#include -#include -#include +#include "client_priv.h" #include -#include "mysql.h" -#include "errmsg.h" #include #ifndef __GNU_LIBRARY__ #define __GNU_LIBRARY__ // Skip warnings in getopt.h #endif -#include #include "my_readline.h" #include @@ -380,10 +375,6 @@ sig_handler mysql_end(int sig) exit(status.exit_status); } -enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, - OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE} ; - - static struct option long_options[] = { {"i-am-a-dummy", optional_argument, 0, 'U'}, diff --git a/client/mysqladmin.c b/client/mysqladmin.c index e95d6492949..ca568a914f2 100644 --- a/client/mysqladmin.c +++ b/client/mysqladmin.c @@ -17,13 +17,8 @@ /* maintaince of mysql databases */ -#include -#include -#include +#include "client_priv.h" #include -#include "mysql.h" -#include "errmsg.h" -#include #ifdef THREAD #include /* because of signal() */ #endif @@ -102,8 +97,6 @@ static const char *command_names[]= { static TYPELIB command_typelib= { array_elements(command_names)-1,"commands", command_names}; -enum options { OPT_CHARSETS_DIR=256 }; - static struct option long_options[] = { {"compress", no_argument, 0, 'C'}, {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR}, diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 289f5aa517f..ac2f3e4efda 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -17,23 +17,20 @@ #define MYSQL_CLIENT #undef MYSQL_SERVER -#include -#include -#include -#include -#include +#include "client_priv.h" #include #include "log_event.h" #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES) +#ifndef OS2 extern "C" { int simple_command(MYSQL *mysql,enum enum_server_command command, - const char *arg, - uint length, my_bool skipp_check); - int net_safe_read(MYSQL* mysql); + const char *arg, uint length, my_bool skipp_check); + uint net_safe_read(MYSQL* mysql); } +#endif char server_version[SERVER_VERSION_LENGTH]; uint32 server_id = 0; @@ -42,7 +39,8 @@ uint32 server_id = 0; ulong bytes_sent = 0L, bytes_received = 0L; ulong mysqld_net_retry_count = 10L; uint test_flags = 0; -FILE *result_file; + +static FILE *result_file; #ifndef DBUG_OFF static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index ebaa8366c72..0f7bfb37ecf 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -18,19 +18,12 @@ #define CHECK_VERSION "1.02" -#include -#include -#include +#include "client_priv.h" #include - -#include "mysql.h" #include "mysql_version.h" #include "mysqld_error.h" -#include #include "sslopt-vars.h" -#include - /* Exit codes */ #define EX_USAGE 1 @@ -50,9 +43,6 @@ DYNAMIC_ARRAY tables4repair; enum operations {DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE}; -enum options {OPT_CHARSETS_DIR=256, OPT_COMPRESS, OPT_DEFAULT_CHARSET, - OPT_TABLES, OPT_AUTO_REPAIR}; - static struct option long_options[] = { {"all-databases", no_argument, 0, 'A'}, diff --git a/client/mysqlimport.c b/client/mysqlimport.c index cbdedf56cbe..d8f763b9653 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -27,13 +27,8 @@ */ #define IMPORT_VERSION "2.7" -#include -#include -#include -#include "mysql.h" +#include "client_priv.h" #include "mysql_version.h" -#include - static void db_error_with_table(MYSQL *mysql, char *table); static void db_error(MYSQL *mysql); @@ -54,9 +49,6 @@ static uint opt_mysql_port=0; static my_string opt_mysql_unix_port=0; #include "sslopt-vars.h" -enum mi_options {OPT_FTB=256, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, - OPT_LOW_PRIORITY, OPT_CHARSETS_DIR, OPT_DEFAULT_CHARSET}; - static struct option long_options[] = { {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR}, diff --git a/extra/comp_err.c b/extra/comp_err.c index 198bdffb0db..f7b68ff0891 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -119,9 +119,7 @@ int main(int argc,char *argv[]) /* Read options */ -static void get_options(argc,argv) -register int *argc; -register char **argv[]; +static void get_options(register int *argc,register char **argv[]) { int help=0; char *pos,*progname; @@ -163,9 +161,7 @@ register char **argv[]; /* Count rows in from-file until row that start with char is found */ -static int count_rows(from,c,c2) -FILE *from; -pchar c,c2; +static int count_rows(FILE *from, pchar c, pchar c2) { int count; long pos; @@ -189,9 +185,7 @@ pchar c,c2; /* Read rows and remember them until row that start with char */ /* Converts row as a C-compiler would convert a textstring */ -static int remember_rows(from,c) -FILE *from; -pchar c; +static int remember_rows(FILE* from, pchar c) { int i,nr,start_count,found_end; char row[MAXLENGTH],*pos; @@ -253,8 +247,7 @@ pchar c; /* Copy rows from memory to file and remember position */ -static int copy_rows(to) -FILE *to; +static int copy_rows(FILE *to) { int row_nr; long start_pos; diff --git a/heap/hp_test2.c b/heap/hp_test2.c index e3ed7a90df5..a76aa19e082 100644 --- a/heap/hp_test2.c +++ b/heap/hp_test2.c @@ -45,13 +45,11 @@ static int calc_check(byte *buf,uint length); /* Huvudprogrammet */ -int main(argc,argv) -int argc; -char *argv[]; +int main(int argc, char *argv[]) { register uint i,j; uint ant,n1,n2,n3; - uint reclength,write_count,update,delete,check2,dupp_keys,found_key; + uint reclength,write_count,update,opt_delete,check2,dupp_keys,found_key; int error; ulong pos; unsigned long key_check; @@ -70,7 +68,7 @@ char *argv[]; get_options(argc,argv); reclength=37; - write_count=update=delete=0; + write_count=update=opt_delete=0; key_check=0; keyinfo[0].seg=keyseg; @@ -169,7 +167,7 @@ char *argv[]; printf("error: %d; can't delete record: \"%s\"\n", my_errno,record); goto err; } - delete++; + opt_delete++; key1[atoi(record+keyinfo[0].seg[0].start)]--; key3[atoi(record+keyinfo[2].seg[0].start)]=0; key_check-=atoi(record); @@ -198,7 +196,7 @@ char *argv[]; { if (heap_scan_init(file)) goto err; - j=rnd(write_count-delete); + j=rnd(write_count-opt_delete); while ((error=heap_scan(file,record) == HA_ERR_RECORD_DELETED) || (!error && j)) { @@ -271,7 +269,7 @@ char *argv[]; key_check-=atoi(record3); key1[atoi(record+keyinfo[0].seg[0].start)]--; key3[atoi(record+keyinfo[2].seg[0].start)]=0; - delete++; + opt_delete++; ant=2; while ((error=heap_rnext(file,record3)) == 0 || error == HA_ERR_RECORD_DELETED) @@ -291,21 +289,21 @@ char *argv[]; } if (!silent) - printf("- Read last key - delete - prev - prev - delete - prev -> first\n"); + printf("- Read last key - delete - prev - prev - opt_delete - prev -> first\n"); if (heap_rlast(file,record3)) goto err; if (heap_delete(file,record3)) goto err; key_check-=atoi(record3); key1[atoi(record+keyinfo[0].seg[0].start)]--; key3[atoi(record+keyinfo[2].seg[0].start)]=0; - delete++; + opt_delete++; if (heap_rprev(file,record3) || heap_rprev(file,record3)) goto err; if (heap_delete(file,record3)) goto err; key_check-=atoi(record3); key1[atoi(record+keyinfo[0].seg[0].start)]--; key3[atoi(record+keyinfo[2].seg[0].start)]=0; - delete++; + opt_delete++; ant=3; while ((error=heap_rprev(file,record3)) == 0 || error == HA_ERR_RECORD_DELETED) @@ -340,7 +338,7 @@ char *argv[]; goto err; if (heap_delete(file,record3)) goto err; key_check-=atoi(record3); - delete++; + opt_delete++; key1[atoi(record+keyinfo[0].seg[0].start)]--; key3[atoi(record+keyinfo[2].seg[0].start)]=0; ant=0; @@ -348,9 +346,9 @@ char *argv[]; error == HA_ERR_RECORD_DELETED) if (! error) ant++; - if (ant != write_count-delete) + if (ant != write_count-opt_delete) { - printf("next: Found: %d records of %d\n",ant,write_count-delete); + printf("next: Found: %d records of %d\n",ant,write_count-opt_delete); goto end; } if (heap_check_heap(file,0)) @@ -361,7 +359,7 @@ char *argv[]; puts("- Test if: Read rrnd - same - rkey - same"); DBUG_PRINT("progpos",("Read rrnd - same")); - pos=rnd(write_count-delete-5)+5; + pos=rnd(write_count-opt_delete-5)+5; heap_scan_init(file); i=5; while ((error=heap_scan(file,record)) == HA_ERR_RECORD_DELETED || @@ -399,14 +397,14 @@ char *argv[]; { HEAPINFO info; heap_info(file,&info,0); - /* We have to test with delete +1 as this may be the case if the last + /* We have to test with opt_delete +1 as this may be the case if the last inserted row was a duplicate key */ - if (info.records != write_count-delete || - (info.deleted != delete && info.deleted != delete+1)) + if (info.records != write_count-opt_delete || + (info.deleted != opt_delete && info.deleted != opt_delete+1)) { puts("Wrong info from heap_info"); printf("Got: records: %ld(%d) deleted: %ld(%d)\n", - info.records,write_count-delete,info.deleted,delete); + info.records,write_count-opt_delete,info.deleted,opt_delete); } } @@ -429,10 +427,10 @@ char *argv[]; check+=calc_check(record,reclength); } } - if (ant != write_count-delete) + if (ant != write_count-opt_delete) { printf("rrnd: I can only find: %d records of %d\n", ant, - write_count-delete); + write_count-opt_delete); goto end; } if (heap_extra(file,HA_EXTRA_NO_CACHE)) @@ -460,10 +458,10 @@ char *argv[]; check2+=calc_check(record,reclength); } } - if (ant != write_count-delete) + if (ant != write_count-opt_delete) { printf("scan: I can only find: %d records of %d\n", ant, - write_count-delete); + write_count-opt_delete); goto end; } #ifdef OLD_HEAP_VERSION @@ -552,7 +550,7 @@ char *argv[]; write_count++; if (heap_delete(file,record)) goto err; - delete++; + opt_delete++; } pos++; } @@ -570,7 +568,7 @@ char *argv[]; end: printf("\nFollowing test have been made:\n"); - printf("Write records: %d\nUpdate records: %d\nDelete records: %d\n", write_count,update,delete); + printf("Write records: %d\nUpdate records: %d\nDelete records: %d\n", write_count,update,opt_delete); heap_clear(file); if (heap_close(file) || (file2 && heap_close(file2))) goto err; @@ -629,8 +627,7 @@ static int get_options(int argc,char *argv[]) /* Generate a random value in intervall 0 <=x <= n */ -static int rnd(max_value) -int max_value; +static int rnd(int max_value) { return (int) ((rand() & 32767)/32767.0*max_value); } /* rnd */ @@ -650,9 +647,7 @@ static sig_handler endprog(int sig_number __attribute__((unused))) } } -static int calc_check(buf,length) -byte *buf; -uint length; +static int calc_check(byte *buf, uint length) { int check=0; while (length--) diff --git a/heap/hp_update.c b/heap/hp_update.c index 5eb4562ca5c..a1d9c51e9dd 100644 --- a/heap/hp_update.c +++ b/heap/hp_update.c @@ -18,7 +18,7 @@ #include "heapdef.h" -int heap_update(HP_INFO *info, const byte *old, const byte *new) +int heap_update(HP_INFO *info, const byte *old, const byte *heap_new) { uint key; byte *pos; @@ -35,16 +35,16 @@ int heap_update(HP_INFO *info, const byte *old, const byte *new) for (key=0 ; key < share->keys ; key++) { - if (_hp_rec_key_cmp(share->keydef+key,old,new)) + if (_hp_rec_key_cmp(share->keydef+key,old,heap_new)) { if (_hp_delete_key(info,share->keydef+key,old,pos,key == (uint) info->lastinx) || - _hp_write_key(share,share->keydef+key,new,pos)) + _hp_write_key(share,share->keydef+key,heap_new,pos)) goto err; } } - memcpy(pos,new,(size_t) share->reclength); + memcpy(pos,heap_new,(size_t) share->reclength); if (++(share->records) == share->blength) share->blength+= share->blength; DBUG_RETURN(0); @@ -54,9 +54,9 @@ int heap_update(HP_INFO *info, const byte *old, const byte *new) info->errkey=key; do { - if (_hp_rec_key_cmp(share->keydef+key,old,new)) + if (_hp_rec_key_cmp(share->keydef+key,old,heap_new)) { - if (_hp_delete_key(info,share->keydef+key,new,pos,0) || + if (_hp_delete_key(info,share->keydef+key,heap_new,pos,0) || _hp_write_key(share,share->keydef+key,old,pos)) break; } diff --git a/heap/hp_write.c b/heap/hp_write.c index e74183276f7..12b5c638f78 100644 --- a/heap/hp_write.c +++ b/heap/hp_write.c @@ -38,7 +38,7 @@ int heap_write(HP_INFO *info, const byte *record) DBUG_ENTER("heap_write"); #ifndef DBUG_OFF - if (info->mode && O_RDONLY) + if (info->mode & O_RDONLY) { DBUG_RETURN(my_errno=EACCES); } diff --git a/include/config-os2.h b/include/config-os2.h index 172a04a9f01..9064cd5a5bb 100644 --- a/include/config-os2.h +++ b/include/config-os2.h @@ -87,6 +87,8 @@ #define S_IFMT 0xF000 /* Mask for file type */ #define F_TO_EOF 0L /* Param to lockf() to lock rest of file */ +#define HUGE_PTR + #ifdef __cplusplus extern "C" #endif @@ -102,8 +104,13 @@ BOOL TlsSetValue( DWORD, PVOID); #define lseek(A,B,C) _lseek64( A, B, C) #define tell(A) _lseek64( A, 0, SEEK_CUR) +void* dlopen( char* path, int flag); +char* dlerror( void); +void* dlsym( void* hmod, char* fn); +void dlclose( void* hmod); + /* Some typedefs */ -typedef ulonglong os_off_t; +typedef unsigned long long os_off_t; /* config.h. Generated automatically by configure. */ /* config.h.in. Generated automatically from configure.in by autoheader. */ diff --git a/include/global.h b/include/global.h index f10411af0aa..c7d6952f1c6 100644 --- a/include/global.h +++ b/include/global.h @@ -647,15 +647,24 @@ typedef off_t os_off_t; #define socket_errno WSAGetLastError() #define SOCKET_EINTR WSAEINTR #define SOCKET_EAGAIN WSAEINPROGRESS +#define SOCKET_ENFILE ENFILE +#define SOCKET_EMFILE EMFILE #elif defined(OS2) #define socket_errno sock_errno() +#define SOCKET_EINTR SOCEINTR +#define SOCKET_EAGAIN SOCEINPROGRESS +#define SOCKET_EWOULDBLOCK SOCEWOULDBLOCK +#define SOCKET_ENFILE SOCENFILE +#define SOCKET_EMFILE SOCEMFILE #define closesocket(A) soclose(A) #else /* Unix */ -#define socket_errno errno +#define socket_errno errno #define closesocket(A) close(A) #define SOCKET_EINTR EINTR #define SOCKET_EAGAIN EAGAIN #define SOCKET_EWOULDBLOCK EWOULDBLOCK +#define SOCKET_ENFILE ENFILE +#define SOCKET_EMFILE EMFILE #endif typedef uint8 int7; /* Most effective integer 0 <= x <= 127 */ diff --git a/include/merge.h b/include/merge.h index b090e49b471..c661e03a0c7 100644 --- a/include/merge.h +++ b/include/merge.h @@ -43,7 +43,7 @@ typedef struct st_mrg_info /* Struct from h_info */ ulonglong data_file_length; uint reclength; /* Recordlength */ int errkey; /* With key was dupplicated on err */ - uint options; /* HA_OPTIONS_... used */ + uint options; /* HA_OPTION_... used */ } MERGE_INFO; typedef struct st_mrg_table_info diff --git a/include/my_pthread.h b/include/my_pthread.h index b54a94f83fc..cd72bcced83 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -139,6 +139,7 @@ int pthread_mutex_unlock (pthread_mutex_t *); int pthread_mutex_destroy (pthread_mutex_t *); #define my_pthread_setprio(A,B) DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE, B, A) #define pthread_kill(A,B) raise(B) +#define pthread_exit(A) pthread_dummy() #else #define pthread_mutex_init(A,B) InitializeCriticalSection(A) #define pthread_mutex_lock(A) (EnterCriticalSection(A),0) @@ -146,7 +147,6 @@ int pthread_mutex_destroy (pthread_mutex_t *); #define pthread_mutex_destroy(A) DeleteCriticalSection(A) #define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B)) #define pthread_kill(A,B) pthread_dummy(0) -#define pthread_exit(A) pthread_dummy() #endif /* OS2 */ /* Dummy defines for easier code */ diff --git a/include/myisam.h b/include/myisam.h index 9b006467ac8..8d25e17e589 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -69,7 +69,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */ ulonglong auto_increment; ulonglong key_map; /* Which keys are used */ uint keys; /* Number of keys in use */ - uint options; /* HA_OPTIONS_... used */ + uint options; /* HA_OPTION_... used */ int errkey, /* With key was dupplicated on err */ sortkey; /* clustered by this key */ File filenr; /* (uniq) filenr for datafile */ diff --git a/include/nisam.h b/include/nisam.h index 77ca12bbc5c..7ce2b44ee79 100644 --- a/include/nisam.h +++ b/include/nisam.h @@ -57,7 +57,7 @@ typedef struct st_n_isaminfo /* Struct from h_info */ uint reclength; /* Recordlength */ uint mean_reclength; /* Mean recordlength (if packed) */ uint keys; /* How many keys used */ - uint options; /* HA_OPTIONS_... used */ + uint options; /* HA_OPTION_... used */ int errkey, /* With key was dupplicated on err */ sortkey; /* clustered by this key */ File filenr; /* (uniq) filenr for datafile */ diff --git a/libmysql/dll.c b/libmysql/dll.c index 4c952c5889e..d1a23794025 100644 --- a/libmysql/dll.c +++ b/libmysql/dll.c @@ -110,3 +110,25 @@ int _export FAR PASCAL libmain(HANDLE hModule,short cbHeapSize, } #endif + +#ifdef OS2 + +// +// This function is called automatically by _DLL_InitTerm +// Every dll runtime enviroment is not tz enabled, so tzset() +// must be called to enable TZ handling +// Also timezone is fixed. +// +extern "C" unsigned long _System DllMain(unsigned long modhandle, + unsigned long flag) +{ + if (flag == 0) { + tzset(); // Set tzname + time_t currentTime = time(NULL); + struct tm *ts = localtime(¤tTime); + if (ts->tm_isdst > 0) + _timezone -= 3600; + } +} + +#endif diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 0cb6170b25c..0e202a4fc08 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -70,11 +70,10 @@ my_string mysql_unix_port=0; #endif #if defined(MSDOS) || defined(__WIN__) -#define ERRNO WSAGetLastError() +// socket_errno is defined in global.h for all platforms #define perror(A) #else #include -#define ERRNO errno #define SOCKET_ERROR -1 #endif /* __WIN__ */ @@ -451,7 +450,7 @@ simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg, if (net_write_command(net,(uchar) command,arg, length ? length : (ulong) strlen(arg))) { - DBUG_PRINT("error",("Can't send command to server. Error: %d",errno)); + DBUG_PRINT("error",("Can't send command to server. Error: %d",socket_errno)); end_server(mysql); if (mysql_reconnect(mysql) || net_write_command(net,(uchar) command,arg, @@ -1213,7 +1212,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR) { net->last_errno=CR_SOCKET_CREATE_ERROR; - sprintf(net->last_error,ER(net->last_errno),ERRNO); + sprintf(net->last_error,ER(net->last_errno),socket_errno); goto error; } net->vio = vio_new(sock, VIO_TYPE_SOCKET, TRUE); @@ -1223,9 +1222,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (connect2(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr), mysql->options.connect_timeout) <0) { - DBUG_PRINT("error",("Got error %d on connect to local server",ERRNO)); + DBUG_PRINT("error",("Got error %d on connect to local server",socket_errno)); net->last_errno=CR_CONNECTION_ERROR; - sprintf(net->last_error,ER(net->last_errno),unix_socket,ERRNO); + sprintf(net->last_error,ER(net->last_errno),unix_socket,socket_errno); goto error; } } @@ -1276,7 +1275,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if ((sock = (my_socket) socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR) { net->last_errno=CR_IPSOCK_ERROR; - sprintf(net->last_error,ER(net->last_errno),ERRNO); + sprintf(net->last_error,ER(net->last_errno),socket_errno); goto error; } net->vio = vio_new(sock,VIO_TYPE_TCPIP,FALSE); @@ -1313,7 +1312,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (!(hp=gethostbyname(host))) { net->last_errno=CR_UNKNOWN_HOST; - sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, errno); + sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, socket_errno); goto error; } memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length); @@ -1323,9 +1322,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (connect2(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr), mysql->options.connect_timeout) <0) { - DBUG_PRINT("error",("Got error %d on connect to '%s'",ERRNO,host)); + DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,host)); net->last_errno= CR_CONN_HOST_ERROR; - sprintf(net->last_error ,ER(CR_CONN_HOST_ERROR), host, ERRNO); + sprintf(net->last_error ,ER(CR_CONN_HOST_ERROR), host, socket_errno); goto error; } } @@ -1810,7 +1809,7 @@ send_file_to_server(MYSQL *mysql, const char *filename) if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net)) { mysql->net.last_errno=CR_SERVER_LOST; - sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno); + sprintf(mysql->net.last_error,ER(mysql->net.last_errno),socket_errno); my_free(tmp_name,MYF(0)); DBUG_RETURN(-1); } diff --git a/libmysql/net.c b/libmysql/net.c index ba0944a2516..24e4da3561a 100644 --- a/libmysql/net.c +++ b/libmysql/net.c @@ -77,7 +77,7 @@ extern ulong mysqld_net_retry_count; typedef my_bool thr_alarm_t; typedef my_bool ALARM; #define thr_alarm_init(A) (*(A))=0 -#define thr_alarm_in_use(A) (*(A)) +#define thr_alarm_in_use(A) (*(A)!= 0) #define thr_end_alarm(A) #define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C)) inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused))) @@ -372,7 +372,7 @@ net_real_write(NET *net,const char *packet,ulong len) #endif /* EXTRA_DEBUG */ } #if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) - if (vio_errno(net->vio) == EINTR) + if (vio_errno(net->vio) == SOCKET_EINTR) { DBUG_PRINT("warning",("Interrupted write. Retrying...")); continue; diff --git a/libmysql/violite.c b/libmysql/violite.c index aff4224e5a3..0d96c71969c 100644 --- a/libmysql/violite.c +++ b/libmysql/violite.c @@ -44,18 +44,10 @@ #endif /* defined(__EMX__) */ #if defined(MSDOS) || defined(__WIN__) -#ifdef __WIN__ -#undef errno -#undef EINTR -#undef EAGAIN -#define errno WSAGetLastError() -#define EINTR WSAEINTR -#define EAGAIN WSAEINPROGRESS -#endif /* __WIN__ */ #define O_NONBLOCK 1 /* For emulation of fcntl() */ #endif #ifndef EWOULDBLOCK -#define EWOULDBLOCK EAGAIN +#define SOCKET_EWOULDBLOCK SOCKET_EAGAIN #endif #ifndef __WIN__ @@ -327,8 +319,8 @@ int vio_keepalive(Vio* vio, my_bool set_keep_alive) my_bool vio_should_retry(Vio * vio __attribute__((unused))) { - int en = errno; - return en == EAGAIN || en == EINTR || en == EWOULDBLOCK; + int en = socket_errno; + return en == SOCKET_EAGAIN || en == SOCKET_EINTR || en == SOCKET_EWOULDBLOCK; } diff --git a/myisam/myisampack.c b/myisam/myisampack.c index c0c23f28d6c..54a8db457e8 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -111,21 +111,21 @@ typedef struct st_isam_mrg { uint ref_length; uint max_blob_length; my_off_t records; -} MRG_INFO; +} PACK_MRG_INFO; extern int main(int argc,char * *argv); static void get_options(int *argc,char ***argv); static MI_INFO *open_isam_file(char *name,int mode); -static bool open_isam_files(MRG_INFO *mrg,char **names,uint count); -static int compress(MRG_INFO *file,char *join_name); +static bool open_isam_files(PACK_MRG_INFO *mrg,char **names,uint count); +static int compress(PACK_MRG_INFO *file,char *join_name); static HUFF_COUNTS *init_huff_count(MI_INFO *info,my_off_t records); static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees, uint trees, HUFF_COUNTS *huff_counts, uint fields); static int compare_tree(const uchar *s,const uchar *t); -static int get_statistic(MRG_INFO *mrg,HUFF_COUNTS *huff_counts); +static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts); static void check_counts(HUFF_COUNTS *huff_counts,uint trees, my_off_t records); static int test_space_compress(HUFF_COUNTS *huff_counts,my_off_t records, @@ -143,7 +143,7 @@ static int make_huff_decode_table(HUFF_TREE *huff_tree,uint trees); static void make_traverse_code_tree(HUFF_TREE *huff_tree, HUFF_ELEMENT *element,uint size, ulong code); -static int write_header(MRG_INFO *isam_file, uint header_length,uint trees, +static int write_header(PACK_MRG_INFO *isam_file, uint header_length,uint trees, my_off_t tot_elements,my_off_t filelength); static void write_field_info(HUFF_COUNTS *counts, uint fields,uint trees); static my_off_t write_huff_tree(HUFF_TREE *huff_tree,uint trees); @@ -151,7 +151,7 @@ static uint *make_offset_code_tree(HUFF_TREE *huff_tree, HUFF_ELEMENT *element, uint *offset); static uint max_bit(uint value); -static int compress_isam_file(MRG_INFO *file,HUFF_COUNTS *huff_counts); +static int compress_isam_file(PACK_MRG_INFO *file,HUFF_COUNTS *huff_counts); static char *make_new_name(char *new_name,char *old_name); static char *make_old_name(char *new_name,char *old_name); static void init_file_buffer(File file,pbool read_buffer); @@ -159,13 +159,13 @@ static int flush_buffer(ulong neaded_length); static void end_file_buffer(void); static void write_bits(ulong value,uint bits); static void flush_bits(void); -static int save_state(MI_INFO *isam_file,MRG_INFO *mrg,my_off_t new_length, +static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length, ha_checksum crc); -static int save_state_mrg(File file,MRG_INFO *isam_file,my_off_t new_length, +static int save_state_mrg(File file,PACK_MRG_INFO *isam_file,my_off_t new_length, ha_checksum crc); -static int mrg_close(MRG_INFO *mrg); -static int mrg_rrnd(MRG_INFO *info,byte *buf); -static void mrg_reset(MRG_INFO *mrg); +static int mrg_close(PACK_MRG_INFO *mrg); +static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf); +static void mrg_reset(PACK_MRG_INFO *mrg); static int backup=0,error_on_write=0,test_only=0,verbose=0,silent=0, @@ -186,7 +186,7 @@ static const char *load_default_groups[]= { "myisampack",0 }; int main(int argc, char **argv) { int error,ok; - MRG_INFO merge; + PACK_MRG_INFO merge; char **default_argv; MY_INIT(argv[0]); @@ -251,7 +251,7 @@ static struct option long_options[] = static void print_version(void) { - printf("%s Ver 1.10 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE); + printf("%s Ver 1.11 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE); } static void usage(void) @@ -403,7 +403,7 @@ static MI_INFO *open_isam_file(char *name,int mode) } -static bool open_isam_files(MRG_INFO *mrg,char **names,uint count) +static bool open_isam_files(PACK_MRG_INFO *mrg,char **names,uint count) { uint i,j; mrg->count=0; @@ -445,7 +445,7 @@ static bool open_isam_files(MRG_INFO *mrg,char **names,uint count) } -static int compress(MRG_INFO *mrg,char *result_table) +static int compress(PACK_MRG_INFO *mrg,char *result_table) { int error; File new_file,join_isam_file; @@ -721,7 +721,7 @@ static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees, uint trees, /* Read through old file and gather some statistics */ -static int get_statistic(MRG_INFO *mrg,HUFF_COUNTS *huff_counts) +static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts) { int error; uint length; @@ -983,7 +983,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, huff_counts->end_space[huff_counts->field_length]+= huff_counts->empty_fields; } - else + if (huff_counts->tot_pre_space) { huff_counts->tot_pre_space+=length; huff_counts->max_pre_space=huff_counts->field_length; @@ -1461,7 +1461,7 @@ static void make_traverse_code_tree(HUFF_TREE *huff_tree, /* Write header to new packed data file */ -static int write_header(MRG_INFO *mrg,uint head_length,uint trees, +static int write_header(PACK_MRG_INFO *mrg,uint head_length,uint trees, my_off_t tot_elements,my_off_t filelength) { byte *buff=file_buffer.pos; @@ -1639,7 +1639,7 @@ static uint max_bit(register uint value) } -static int compress_isam_file(MRG_INFO *mrg, HUFF_COUNTS *huff_counts) +static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) { int error; uint i,max_calc_length,pack_ref_length,min_record_length,max_record_length, @@ -2025,7 +2025,7 @@ static void flush_bits (void) ** functions to handle the joined files ****************************************************************************/ -static int save_state(MI_INFO *isam_file,MRG_INFO *mrg,my_off_t new_length, +static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length, ha_checksum crc) { MYISAM_SHARE *share=isam_file->s; @@ -2060,7 +2060,7 @@ static int save_state(MI_INFO *isam_file,MRG_INFO *mrg,my_off_t new_length, } -static int save_state_mrg(File file,MRG_INFO *mrg,my_off_t new_length, +static int save_state_mrg(File file,PACK_MRG_INFO *mrg,my_off_t new_length, ha_checksum crc) { MI_STATE_INFO state; @@ -2090,7 +2090,7 @@ static int save_state_mrg(File file,MRG_INFO *mrg,my_off_t new_length, /* reset for mrg_rrnd */ -static void mrg_reset(MRG_INFO *mrg) +static void mrg_reset(PACK_MRG_INFO *mrg) { if (mrg->current) { @@ -2099,7 +2099,7 @@ static void mrg_reset(MRG_INFO *mrg) } } -static int mrg_rrnd(MRG_INFO *info,byte *buf) +static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf) { int error; MI_INFO *isam_info; @@ -2138,7 +2138,7 @@ static int mrg_rrnd(MRG_INFO *info,byte *buf) } -static int mrg_close(MRG_INFO *mrg) +static int mrg_close(PACK_MRG_INFO *mrg) { uint i; int error=0; diff --git a/myisam/sort.c b/myisam/sort.c index 39874d05640..161a5f92bf5 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -40,10 +40,10 @@ typedef struct st_buffpek { my_off_t file_pos; /* Where we are in the sort file */ - ha_rows count; /* Number of rows in table */ uchar *base,*key; /* Key pointers */ - uint mem_count; /* numbers of keys in memory */ - uint max_keys; /* Max keys in buffert */ + ha_rows count; /* Number of rows in table */ + ulong mem_count; /* numbers of keys in memory */ + ulong max_keys; /* Max keys in buffert */ } BUFFPEK; extern void print_error _VARARGS((const char *fmt,...)); diff --git a/mysys/my_write.c b/mysys/my_write.c index 640043192ef..5d5a48a3dda 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -19,45 +19,6 @@ #include "mysys_err.h" #include -#ifdef OS2 - -int _write64( int fd, const void *buffer, unsigned int count) -{ - APIRET rc; - ULONG actual; - - rc = DosWrite( fd, (PVOID) buffer, count, &actual); - - switch (rc) { - case 0: /* NO_ERROR */ - errno = 0; - return( actual); - break; - case ERROR_INVALID_FUNCTION: - errno = EPERM; - break; - case ERROR_ACCESS_DENIED: - errno = EACCESS; - break; - case ERROR_INVALID_HANDLE: - errno = EBADF; - break; - case ERROR_DISK_FULL: - errno = ENOSPC; - break; - default: - errno = EINVAL; - break; - } - // write failed - return(-1); -} - -// redirect call -#define write _write64 - -#endif // OS2 - /* Write a chunk of bytes to a file */ diff --git a/sql/handler.h b/sql/handler.h index ef78f0af39b..4ce743a5edd 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -77,7 +77,7 @@ #define HA_NO_FULLTEXT_KEY (HA_NO_PREFIX_CHAR_KEYS*2) /* Parameters for open() (in register form->filestat) */ - /* HA_GET_INFO does a implicit HA_ABORT_IF_LOCKED */ + /* HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED */ #define HA_OPEN_KEYFILE 1 #define HA_OPEN_RNDFILE 2 diff --git a/sql/mini_client.cc b/sql/mini_client.cc index fe8a0a161b3..3dfd58375a5 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -98,16 +98,10 @@ static void mc_free_old_query(MYSQL *mysql); #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES) #if defined(MSDOS) || defined(__WIN__) -#define ERRNO WSAGetLastError() #define perror(A) -#elif defined(OS2) -#define ERRNO sock_errno() -#define SOCKET_ERROR -1 #else -#include -#define ERRNO errno +#include #define SOCKET_ERROR -1 -#define closesocket(A) close(A) #endif #ifdef __WIN__ @@ -351,7 +345,7 @@ mc_net_safe_read(MYSQL *mysql) { DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %d", vio_description(net->vio),len)); - if (socket_errno != EINTR) + if (socket_errno != SOCKET_EINTR) { mc_end_server(mysql); if(net->last_errno != ER_NET_PACKET_TOO_LARGE) @@ -544,7 +538,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR) { net->last_errno=CR_SOCKET_CREATE_ERROR; - sprintf(net->last_error,ER(net->last_errno),ERRNO); + sprintf(net->last_error,ER(net->last_errno),socket_errno); goto error; } net->vio = vio_new(sock, VIO_TYPE_SOCKET, TRUE); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b7cd101695a..9aa56ea7fc1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1455,10 +1455,6 @@ static int my_message_sql(uint error, const char *str, } #ifdef __WIN__ -#undef errno -#undef EINTR -#define errno WSAGetLastError() -#define EINTR WSAEINTR struct utsname { @@ -1571,18 +1567,26 @@ int main(int argc, char **argv) tzset(); // Set tzname start_time=time((time_t*) 0); +#ifdef OS2 + { + // fix timezone for daylight saving + struct tm *ts = localtime(&start_time); + if (ts->tm_isdst > 0) + _timezone -= 3600; + } +#endif #ifdef HAVE_TZNAME #if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT) { struct tm tm_tmp; localtime_r(&start_time,&tm_tmp); - strmov(time_zone,tzname[tm_tmp.tm_isdst == 1 ? 1 : 0]); + strmov(time_zone,tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]); } #else { struct tm *start_tm; start_tm=localtime(&start_time); - strmov(time_zone,tzname[start_tm->tm_isdst == 1 ? 1 : 0]); + strmov(time_zone,tzname[start_tm->tm_isdst != 0 ? 1 : 0]); } #endif #endif @@ -2263,7 +2267,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) #else if (select((int) max_used_connection,&readFDs,0,0,0) < 0) { - if (socket_errno != EINTR) + if (socket_errno != SOCKET_EINTR) { if (!select_errors++ && !abort_loop) /* purecov: inspected */ sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */ @@ -2306,7 +2310,8 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) size_socket length=sizeof(struct sockaddr_in); new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr), &length); - if (new_sock != INVALID_SOCKET || (errno != EINTR && errno != EAGAIN)) + if (new_sock != INVALID_SOCKET || + (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN)) break; #if !defined(NO_FCNTL_NONBLOCK) if (!(test_flags & TEST_BLOCKING)) @@ -2324,7 +2329,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) { if ((error_count++ & 255) == 0) // This can happen often sql_perror("Error in accept"); - if (errno == ENFILE || errno == EMFILE) + if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE) sleep(1); // Give other threads some time continue; } diff --git a/sql/net_serv.cc b/sql/net_serv.cc index c9bfd977e78..4d4603ed586 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -277,7 +277,7 @@ net_real_write(NET *net,const char *packet,ulong len) int length; char *pos,*end; thr_alarm_t alarmed; -#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) +#if !defined(__WIN__) ALARM alarm_buff; #endif uint retry_count=0; @@ -372,7 +372,7 @@ net_real_write(NET *net,const char *packet,ulong len) #endif /* EXTRA_DEBUG */ } #if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) - if (vio_errno(net->vio) == EINTR) + if (vio_errno(net->vio) == SOCKET_EINTR) { DBUG_PRINT("warning",("Interrupted write. Retrying...")); continue; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8f4082c6688..4735e8a08ec 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -182,7 +182,7 @@ int quick_rm_table(enum db_type base,const char *db, } /***************************************************************************** - * Create at table. + * Create a table. * If one creates a temporary table, this is automaticly opened ****************************************************************************/ diff --git a/sql/unireg.cc b/sql/unireg.cc index d02af0ef0d0..c5bfbbbea88 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -18,7 +18,7 @@ /* Functions to create a unireg form-file from a FIELD and a fieldname-fieldinfo struct. - In the following functions FIELD * is a ordinary field-structure with + In the following functions FIELD * is an ordinary field-structure with the following exeptions: sc_length,typepos,row,kol,dtype,regnr and field nead not to be set. str is a (long) to record position where 0 is the first position. @@ -502,7 +502,7 @@ static bool pack_fields(File file,List &create_fields) } - /* save a empty record on start of formfile */ + /* save an empty record on start of formfile */ static bool make_empty_rec(File file,enum db_type table_type, uint table_options,