diff options
56 files changed, 832 insertions, 482 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 <<END +cat > $logdir/$TMP_SCRIPT_MYSQL <<END set -x # Check environment @@ -67,32 +149,34 @@ rpm -ba $rpmdir/SPECS/mysql-$VER.spec rm -f /tmp/$TMP_SCRIPT_MYSQL END -TMP_SCRIPT_PERL=00-temp-for-perl-rpm.$$ -cat > $bpath/Logs/$TMP_SCRIPT_PERL <<END -set -x +if [ ! x$skip_perl=x1 ]; then + + TMP_SCRIPT_PERL=00-temp-for-perl-rpm.$$ + cat > $logdir/$TMP_SCRIPT_PERL <<END + set -x -# First clean up so we do not get old versions when wildcard matching -rm -f $rpmdir/SOURCES/DBI-*.spec -rm -f $rpmdir/RPMS/i386/Perl-*.rpm -rm -f $rpmdir/SRPMS/Perl-*.rpm -rm -f $rpmdir/RPMS/i386/MySQL*-$VER_NO_DASH*.rpm -rm -f $rpmdir/SRPMS/MySQL*-$VER_NO_DASH*.rpm + # First clean up so we do not get old versions when wildcard matching + rm -f $rpmdir/SOURCES/DBI-*.spec + rm -f $rpmdir/RPMS/i386/Perl-*.rpm + rm -f $rpmdir/SRPMS/Perl-*.rpm + rm -f $rpmdir/RPMS/i386/MySQL*-$VER_NO_DASH*.rpm + rm -f $rpmdir/SRPMS/MySQL*-$VER_NO_DASH*.rpm -chmod a+x ${MAKERPM} -rm + chmod a+x ${MAKERPM} + rm -${MAKERPM} --verbose --package-name=DBI --package-version ${DBI_VERSION} \ + ${MAKERPM} --verbose --package-name=DBI --package-version ${DBI_VERSION} \ --specs --source=DBI-${DBI_VERSION}.tar$CEXT -rpm -ba $rpmdir/SPECS/DBI-${DBI_VERSION}.spec + rpm -ba $rpmdir/SPECS/DBI-${DBI_VERSION}.spec -${MAKERPM} --verbose --package-name=Data-ShowTable \ + ${MAKERPM} --verbose --package-name=Data-ShowTable \ --package-version ${DATA_SHOWTABLE_VERSION} \ --specs --source=Data-ShowTable-${DATA_SHOWTABLE_VERSION}.tar$CEXT -rpm -ba $rpmdir/SPECS/Data-ShowTable-${DATA_SHOWTABLE_VERSION}.spec + rpm -ba $rpmdir/SPECS/Data-ShowTable-${DATA_SHOWTABLE_VERSION}.spec -for v in ${DBD_MYSQL_VERSION}; do + for v in ${DBD_MYSQL_VERSION}; do ${MAKERPM} --specs \ --source=Msql-Mysql-modules-$v.tar$CEXT \ @@ -103,32 +187,46 @@ for v in ${DBD_MYSQL_VERSION}; do --nomsql-install --nomsql1-install' \ --require=perl-Data-ShowTable --require=perl-DBI rpm -ba $rpmdir/SPECS/DBD-mysql-$v.spec -done + done -for srcrpm in $rpmdir/SRPMS/perl-*.src.rpm -do - rpm --rebuild $srcrpm -done + for srcrpm in $rpmdir/SRPMS/perl-*.src.rpm + do + rpm --rebuild $srcrpm + done -rm -f /tmp/$TMP_SCRIPT_PERL + rm -f /tmp/$TMP_SCRIPT_PERL END +fi + + # scp $bpath/Logs/$TMP_SCRIPT_MYSQL $owner@$bmachine:/tmp/$TMP_SCRIPT_MYSQL + +# ssh $bmachine -l $owner bash $bpath/Logs/$TMP_SCRIPT_MYSQL -# scp $bpath/Logs/$TMP_SCRIPT_MYSQL $owner@$bmachine:/tmp/$TMP_SCRIPT_MYSQL +cmd=$logdir/$TMP_SCRIPT_MYSQL +run_command $cmd -ssh $bmachine -l $owner bash $bpath/Logs/$TMP_SCRIPT_MYSQL +if [ $? != 0 ]; then + echo "$cmd failed, perhaps the following will help figure out why:" + tail $log +fi -# Build perl RPM (we currently need to be root to do this and that is -# not possible) +if [ ! x$local_build=x1 ]; then -#scp $bpath/Logs/$TMP_SCRIPT_PERL $owner@$bmachine:/tmp/$TMP_SCRIPT_PERL -#ssh $bmachine -l root bash /tmp/$TMP_SCRIPT_PERL + # Build perl RPM (we currently need to be root to do this and that is + # not possible) -# Copy RPMs back to the source dir. We must do this here since the -# $bmachine may not have permission to access $smachine. -scp $owner@$bmachine:$rpmdir/RPMS/i386/MySQL*-$VER_NO_DASH*.rpm $bpath/NEW-RPMS -scp $owner@$bmachine:$rpmdir/SRPMS/MySQL*-$VER_NO_DASH*.rpm $bpath/NEW-RPMS + #scp $bpath/Logs/$TMP_SCRIPT_PERL $owner@$bmachine:/tmp/$TMP_SCRIPT_PERL + #ssh $bmachine -l root bash /tmp/$TMP_SCRIPT_PERL -# And the perl ones -#scp $owner@$bmachine:$rpmdir/RPMS/i386/Perl*-*.rpm $bpath/NEW-RPMS -#scp $owner@$bmachine:$rpmdir/SRPMS/Perl*-*.rpm $bpath/NEW-RPMS + # Copy RPMs back to the source dir. We must do this here since the + # $bmachine may not have permission to access $smachine. + scp $owner@$bmachine:$rpmdir/RPMS/i386/MySQL*-$VER_NO_DASH*.rpm $bpath/NEW-RPMS + scp $owner@$bmachine:$rpmdir/SRPMS/MySQL*-$VER_NO_DASH*.rpm $bpath/NEW-RPMS + + # And the perl ones + #scp $owner@$bmachine:$rpmdir/RPMS/i386/Perl*-*.rpm $bpath/NEW-RPMS + #scp $owner@$bmachine:$rpmdir/SRPMS/Perl*-*.rpm $bpath/NEW-RPMS +fi ) > $log 2>&1 + + diff --git a/Docs/manual.texi b/Docs/manual.texi index 8e89c9d09d2..2a2560c003f 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 ********************************************************* @@ -1553,6 +1553,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. @@ -5174,9 +5178,6 @@ 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 PostgreSQL is run under the cygwin emulation. We have heard that @@ -5455,9 +5456,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 @@ -5592,12 +5594,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 @@ -5606,6 +5610,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 @@ -5620,15 +5634,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 @@ -6441,7 +6455,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} @@ -8054,6 +8068,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 @@ -8067,6 +8083,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 @@ -8195,7 +8213,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 @@ -8973,6 +8991,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}. @@ -9213,6 +9233,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: @@ -9220,7 +9241,7 @@ this: @example [mysqld] datadir=/usr/local/mysql/var -socket=/tmp/mysqld.sock +socket=/var/tmp/mysql.sock port=3306 user=mysql @@ -23657,20 +23678,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}: @@ -23681,74 +23711,94 @@ 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-ssl} @tab -Turn SSL on (Example: @code{master-ssl}) +Turn SSL on + +Example: @code{master-ssl}. @item @code{master-ssl-key} @tab -Master SSL keyfile name (Example: @code{master-ssl-key=SSL/master-key.pem}) +Master SSL keyfile name + +Example: @code{master-ssl-key=SSL/master-key.pem}. @item @code{master-ssl-cert} @tab -Master SSL certificate file name (Example: @code{master-ssl-key=SSL/master-cert.pem}) +Master SSL certificate file name + +Example: @code{master-ssl-key=SSL/master-cert.pem}. @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 @@ -23756,19 +23806,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 @@ -23776,8 +23828,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 @@ -28304,18 +28357,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 @@ -31899,9 +31956,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: @@ -31924,6 +31982,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 for @code{LAST_INSERT_ID(expr)} after executing +other SQL statements like @code{SELECT} or @code{SET}. + + @findex FORMAT() @item FORMAT(X,D) Formats the number @code{X} to a format like @code{'#,###,###.##'}, rounded @@ -32688,9 +32752,6 @@ 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 forbidden in ANSI SQL to @code{SELECT} from the same table into which you are @@ -39174,9 +39235,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 @@ -39217,7 +39279,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 @@ -39665,7 +39727,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 @@ -40583,7 +40645,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 @@ -40806,6 +40868,11 @@ 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 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 contains the most recently generated @code{AUTO_INCREMENT} value, and is not reset between queries because the value of that function is maintained @@ -41860,8 +41927,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 + +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()}. -@node C API problems, Building clients, C API functions, C +@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()} @@ -42016,7 +42146,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 @@ -42037,11 +42167,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 @@ -42056,20 +42186,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 @@ -42116,11 +42247,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 @@ -43473,27 +43631,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 @@ -44431,34 +44576,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. @@ -44508,8 +44625,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} @@ -44529,6 +44646,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 @@ -46889,6 +47040,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 @@ -46935,10 +47087,21 @@ 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 +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 @item 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/client/Makefile.am b/client/Makefile.am index 559cb27f01e..e39c663de15 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -19,6 +19,7 @@ INCLUDES = -I$(srcdir)/../include $(openssl_includes) \ -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 <global.h> +#include <my_sys.h> +#include <m_string.h> +#include <mysql.h> +#include <errmsg.h> +#include <getopt.h> + +/* 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 ec8b6689dcd..43df5037a68 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -27,17 +27,12 @@ * **/ -#include <global.h> -#include <my_sys.h> -#include <m_string.h> +#include "client_priv.h" #include <m_ctype.h> -#include "mysql.h" -#include "errmsg.h" #include <my_dir.h> #ifndef __GNU_LIBRARY__ #define __GNU_LIBRARY__ // Skip warnings in getopt.h #endif -#include <getopt.h> #include "my_readline.h" #include <signal.h> #include <violite.h> @@ -405,10 +400,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 <global.h> -#include <my_sys.h> -#include <m_string.h> +#include "client_priv.h" #include <signal.h> -#include "mysql.h" -#include "errmsg.h" -#include <getopt.h> #ifdef THREAD #include <my_pthread.h> /* 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 <global.h> -#include <m_string.h> -#include <my_sys.h> -#include <getopt.h> -#include <mysql.h> +#include "client_priv.h" #include <time.h> #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 <global.h> -#include <my_sys.h> -#include <m_string.h> +#include "client_priv.h" #include <m_ctype.h> - -#include "mysql.h" #include "mysql_version.h" #include "mysqld_error.h" -#include <getopt.h> #include "sslopt-vars.h" -#include <m_string.h> - /* 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 <global.h> -#include <my_sys.h> -#include <m_string.h> -#include "mysql.h" +#include "client_priv.h" #include "mysql_version.h" -#include <getopt.h> - 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/configure.in b/configure.in index 1c7e212939d..35007f502db 100644 --- a/configure.in +++ b/configure.in @@ -830,10 +830,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/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 0f7afca5a93..12bd61474da 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/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/include/global.h b/include/global.h index 0915047fddb..7cd79b3e078 100644 --- a/include/global.h +++ b/include/global.h @@ -654,15 +654,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 14ccd93a96c..577d3dea3b2 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) diff --git a/include/myisam.h b/include/myisam.h index d2cf3822575..1752f9336a5 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -70,7 +70,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */ ulonglong key_map; /* Which keys are used */ char *data_file_name, *index_file_name; 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/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); 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); } 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 753bc1f7883..e7705ee20e4 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 <global.h> #if defined(__WIN__) || defined(_WIN32) || defined(_WIN64) #include <winsock.h> @@ -71,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 <errno.h> -#define ERRNO errno #define SOCKET_ERROR -1 #endif /* __WIN__ */ @@ -472,7 +470,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, @@ -1516,7 +1514,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); @@ -1526,9 +1524,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; } } @@ -1579,7 +1577,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); @@ -1616,7 +1614,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); @@ -1626,9 +1624,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; } } @@ -2227,7 +2225,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 036a941ffae..9b9ce1c4048 100644 --- a/libmysql/net.c +++ b/libmysql/net.c @@ -89,7 +89,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))) @@ -436,7 +436,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/myisam/myisampack.c b/myisam/myisampack.c index 62d9b8e886d..9408198400f 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -111,14 +111,14 @@ 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, @@ -126,7 +126,7 @@ static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees, uint fields); static int compare_tree(void* cmp_arg __attribute__((unused)), 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, @@ -144,7 +144,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); @@ -152,7 +152,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); @@ -160,13 +160,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, @@ -187,7 +187,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]); @@ -252,7 +252,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) @@ -404,7 +404,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; @@ -446,7 +446,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; @@ -722,7 +722,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; @@ -985,7 +985,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; @@ -1464,7 +1464,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; @@ -1642,7 +1642,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, @@ -2028,7 +2028,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; @@ -2063,7 +2063,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; @@ -2093,7 +2093,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) { @@ -2102,7 +2102,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; @@ -2141,7 +2141,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 e79d199fc03..e78ccc8c136 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/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/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/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; - -insert into t values (1,1), (1,2); +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; -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; +# +# This caused a deadlock in BDB internal locks +# -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/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/mysql-test/t/merge.test b/mysql-test/t/merge.test index 90efdfa2d33..188f699cd64 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; 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 <errno.h> -#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/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 25f8148e52f..9a437607729 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, @@ -1304,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)); /* @@ -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 > @@ -1342,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) @@ -1394,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), @@ -1408,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)); @@ -1513,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() @@ -1529,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)); } @@ -1559,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) @@ -1577,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) @@ -1658,12 +1666,15 @@ int ha_berkeley::external_lock(THD *thd, int lock_type) { if (!thd->transaction.bdb_lock_count++) { + 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)) && + if ((thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN | + OPTION_TABLE_LOCK)) && !thd->transaction.all.bdb_tid) { /* 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 +1682,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,12 +1697,12 @@ int ha_berkeley::external_lock(THD *thd, int lock_type) } } transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid; - changed_rows=0; } else { 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) @@ -1722,11 +1735,12 @@ 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); - transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid; } + transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid; DBUG_RETURN(error); } @@ -1931,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/ha_innobase.cc b/sql/ha_innobase.cc index 3493b2f2c89..cb76c034749 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 @@ -2839,7 +2839,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); } } diff --git a/sql/handler.cc b/sql/handler.cc index fbf5144c090..f790417cf79 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,"", @@ -839,8 +839,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); } diff --git a/sql/handler.h b/sql/handler.h index b190cedd040..4b047fb320e 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/lock.cc b/sql/lock.cc index 9ce4137e380..d9bc5d43c79 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -149,8 +149,10 @@ 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); + 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; } @@ -193,7 +195,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 */ @@ -212,7 +214,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; } @@ -294,7 +296,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) { @@ -302,7 +304,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); diff --git a/sql/log_event.cc b/sql/log_event.cc index ce0873f0be6..ecf4e815b49 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -554,7 +554,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 diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 994f788f423..09944959673 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -117,16 +117,10 @@ static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, #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 <sys/errno.h> -#define ERRNO errno +#include <errno.h> #define SOCKET_ERROR -1 -#define closesocket(A) close(A) #endif #ifdef __WIN__ @@ -370,7 +364,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) @@ -563,7 +557,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/mysql_priv.h b/sql/mysql_priv.h index 49ca09098dd..8e38c8174a4 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -165,7 +165,8 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #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/mysqld.cc b/sql/mysqld.cc index 05fdf6316c2..20ccb6d1f76 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -650,9 +650,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; } @@ -684,9 +682,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 } @@ -1493,10 +1489,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 { @@ -1609,18 +1601,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 @@ -2305,7 +2305,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 */ @@ -2348,7 +2348,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)) @@ -2366,7 +2367,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 be08065b589..fded2c3ce32 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -344,7 +344,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; @@ -439,7 +439,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_base.cc b/sql/sql_base.cc index 4c3e113d537..9ba5277a92c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -407,7 +407,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; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 0e77757b13b..bfda57a06ad 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -820,9 +820,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) '@'); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3dd0176c546..a41ad1ba9ab 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -86,7 +86,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; @@ -1931,7 +1932,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) unlock_global_read_lock(thd); @@ -1949,12 +1954,15 @@ mysql_execute_command(void) if (grant_option && check_grant(thd,SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL,tables)) 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: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 07de0dc5b33..38aedbb4193 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2595,6 +2595,7 @@ static void join_free(JOIN *join) { JOIN_TAB *tab,*end; + DBUG_ENTER("join_free"); if (join->table) { @@ -2636,6 +2637,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/sql_table.cc b/sql/sql_table.cc index f50da413f53..ad9bf532268 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -193,7 +193,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_field> &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, diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 1bea22fbad7..f5ce41a1c70 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 |