1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00
This commit is contained in:
serg@serg.mysql.com
2001-07-02 21:52:22 +02:00
403 changed files with 15011 additions and 5330 deletions

View File

@ -12,10 +12,12 @@
.*.swp .*.swp
.deps .deps
.gdb_history .gdb_history
.gdbinit
.libs .libs
.o .o
.out .out
.snprj/* .snprj/*
.vimrc
BitKeeper/etc/config BitKeeper/etc/config
BitKeeper/etc/csets BitKeeper/etc/csets
BitKeeper/etc/csets-in BitKeeper/etc/csets-in
@ -119,6 +121,7 @@ bdb/include/gen_server_ext.h
bdb/include/hash_auto.h bdb/include/hash_auto.h
bdb/include/log_auto.h bdb/include/log_auto.h
bdb/include/qam_auto.h bdb/include/qam_auto.h
bdb/include/rpc_server_ext.h
bdb/include/txn_auto.h bdb/include/txn_auto.h
bdb/java/src/com/sleepycat/db/DbConstants.java bdb/java/src/com/sleepycat/db/DbConstants.java
bdb/log/log_auto.c bdb/log/log_auto.c
@ -183,6 +186,7 @@ libmysql_r/acconfig.h
libmysql_r/conf_to_src libmysql_r/conf_to_src
libmysql_r/my_static.h libmysql_r/my_static.h
libmysql_r/mysys_priv.h libmysql_r/mysys_priv.h
libmysqld/backup_dir
libmysqld/convert.cc libmysqld/convert.cc
libmysqld/derror.cc libmysqld/derror.cc
libmysqld/errmsg.c libmysqld/errmsg.c
@ -197,6 +201,7 @@ libmysqld/ha_isammrg.cc
libmysqld/ha_myisam.cc libmysqld/ha_myisam.cc
libmysqld/ha_myisammrg.cc libmysqld/ha_myisammrg.cc
libmysqld/handler.cc libmysqld/handler.cc
libmysqld/hash_filo.cc
libmysqld/hostname.cc libmysqld/hostname.cc
libmysqld/init.cc libmysqld/init.cc
libmysqld/item.cc libmysqld/item.cc
@ -222,12 +227,14 @@ libmysqld/opt_sum.cc
libmysqld/password.c libmysqld/password.c
libmysqld/procedure.cc libmysqld/procedure.cc
libmysqld/records.cc libmysqld/records.cc
libmysqld/simple-test
libmysqld/slave.cc libmysqld/slave.cc
libmysqld/sql_acl.cc libmysqld/sql_acl.cc
libmysqld/sql_analyse.cc libmysqld/sql_analyse.cc
libmysqld/sql_base.cc libmysqld/sql_base.cc
libmysqld/sql_cache.cc libmysqld/sql_cache.cc
libmysqld/sql_class.cc libmysqld/sql_class.cc
libmysqld/sql_command
libmysqld/sql_crypt.cc libmysqld/sql_crypt.cc
libmysqld/sql_db.cc libmysqld/sql_db.cc
libmysqld/sql_delete.cc libmysqld/sql_delete.cc
@ -247,11 +254,14 @@ libmysqld/sql_string.cc
libmysqld/sql_table.cc libmysqld/sql_table.cc
libmysqld/sql_test.cc libmysqld/sql_test.cc
libmysqld/sql_udf.cc libmysqld/sql_udf.cc
libmysqld/sql_unions.cc
libmysqld/sql_update.cc libmysqld/sql_update.cc
libmysqld/sql_yacc.cc libmysqld/sql_yacc.cc
libmysqld/stacktrace.c
libmysqld/table.cc libmysqld/table.cc
libmysqld/thr_malloc.cc libmysqld/thr_malloc.cc
libmysqld/time.cc libmysqld/time.cc
libmysqld/uniques.cc
libmysqld/unireg.cc libmysqld/unireg.cc
libtool libtool
linked_client_sources linked_client_sources
@ -260,6 +270,7 @@ linked_libmysql_r_sources
linked_libmysql_sources linked_libmysql_sources
linked_libmysqld_sources linked_libmysqld_sources
linked_server_sources linked_server_sources
locked
myisam/ft_dump myisam/ft_dump
myisam/ft_eval myisam/ft_eval
myisam/ft_test1 myisam/ft_test1
@ -274,6 +285,7 @@ mysql-test/gmon.out
mysql-test/install_test_db mysql-test/install_test_db
mysql-test/mysql-test-run mysql-test/mysql-test-run
mysql-test/r/*.reject mysql-test/r/*.reject
mysql-test/r/rpl_log.eval
mysql-test/share/mysql mysql-test/share/mysql
mysql-test/var/* mysql-test/var/*
mysql.proj mysql.proj
@ -302,6 +314,7 @@ scripts/mysql_zap
scripts/mysqlaccess scripts/mysqlaccess
scripts/mysqlbug scripts/mysqlbug
scripts/mysqld_multi scripts/mysqld_multi
scripts/mysqld_safe
scripts/mysqldumpslow scripts/mysqldumpslow
scripts/mysqlhotcopy scripts/mysqlhotcopy
scripts/safe_mysqld scripts/safe_mysqld
@ -309,11 +322,15 @@ sql-bench/Results-linux/ATIS-mysql_bdb-Linux_2.2.14_my_SMP_i686
sql-bench/bench-count-distinct sql-bench/bench-count-distinct
sql-bench/bench-init.pl sql-bench/bench-init.pl
sql-bench/compare-results sql-bench/compare-results
sql-bench/compare-results-all
sql-bench/copy-db sql-bench/copy-db
sql-bench/crash-me sql-bench/crash-me
sql-bench/gif/*
sql-bench/graph-compare-results
sql-bench/output/* sql-bench/output/*
sql-bench/run-all-tests sql-bench/run-all-tests
sql-bench/server-cfg sql-bench/server-cfg
sql-bench/template.html
sql-bench/test-ATIS sql-bench/test-ATIS
sql-bench/test-alter-table sql-bench/test-alter-table
sql-bench/test-big-tables sql-bench/test-big-tables
@ -332,6 +349,7 @@ sql/mysqld
sql/share/*.sys sql/share/*.sys
sql/share/charsets/gmon.out sql/share/charsets/gmon.out
sql/share/gmon.out sql/share/gmon.out
sql/share/mysql
sql/share/norwegian-ny/errmsg.sys sql/share/norwegian-ny/errmsg.sys
sql/share/norwegian/errmsg.sys sql/share/norwegian/errmsg.sys
sql/sql_yacc.cc sql/sql_yacc.cc

View File

@ -15,6 +15,10 @@ $make -k clean || true
aclocal && autoheader && aclocal && automake && autoconf aclocal && autoheader && aclocal && automake && autoconf
(cd bdb/dist && sh s_all) (cd bdb/dist && sh s_all)
(cd innobase && aclocal && autoheader && aclocal && automake && autoconf) (cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
if [ -d gemini ]
then
(cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
fi
CFLAGS=\"$cflags\" CXX=gcc CXXFLAGS=\"$cxxflags\" $configure" CFLAGS=\"$cflags\" CXX=gcc CXXFLAGS=\"$cxxflags\" $configure"

View File

@ -43,13 +43,17 @@ alpha_cflags="-mcpu=ev6 -Wa,-mev6" # Not used yet
pentium_cflags="-mpentiumpro" pentium_cflags="-mpentiumpro"
sparc_cflags="" sparc_cflags=""
# be as fast as we can be without losing our ability to backtrace
fast_cflags="-O3 -fno-omit-frame-pointer" fast_cflags="-O3 -fno-omit-frame-pointer"
reckless_cflags="-O3 -fomit-frame-pointer -ffixed-ebp" # this is one is for someone who thinks 1% speedup is worth not being
# able to backtrace
reckless_cflags="-O3 -fomit-frame-pointer "
debug_cflags="-DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DSAFE_MUTEX -O2" debug_cflags="-DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DSAFE_MUTEX -O2"
base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti" base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti"
base_configs="--prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-all-static" base_configs="--prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-all-static \
--with-client-ldflags=-all-static"
alpha_configs="" # Not used yet alpha_configs="" # Not used yet
pentium_configs="" pentium_configs=""
sparc_configs="" sparc_configs=""

View File

@ -3,7 +3,7 @@
path=`dirname $0` path=`dirname $0`
. "$path/SETUP.sh" . "$path/SETUP.sh"
extra_flags="$pentium_cflags $reckless_cflags" extra_flags="$pentium_cflags $fast_cflags"
extra_configs="$pentium_configs" extra_configs="$pentium_configs"
strip=yes strip=yes

View File

@ -8,6 +8,6 @@ c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs" extra_configs="$pentium_configs $debug_configs"
extra_configs="$extra_configs --with-berkeley-db --with-innodb" extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-embedded-server"
. "$path/FINISH.sh" . "$path/FINISH.sh"

View File

@ -0,0 +1,13 @@
#! /bin/sh
path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium_cflags $debug_cflags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs"
extra_configs="$extra_configs --with-debug=full --with-vio --with-openssl"
. "$path/FINISH.sh"

View File

@ -1,3 +1,4 @@
Sinisa@sinisa.nasamreza.org
heikki@donna.mysql.fi heikki@donna.mysql.fi
jani@hynda.mysql.fi jani@hynda.mysql.fi
jani@janikt.pp.saunalahti.fi jani@janikt.pp.saunalahti.fi
@ -5,13 +6,18 @@ jcole@abel.spaceapes.com
jcole@main.burghcom.com jcole@main.burghcom.com
jcole@tetra.spaceapes.com jcole@tetra.spaceapes.com
monty@donna.mysql.fi monty@donna.mysql.fi
monty@hundin.mysql.fi
monty@tik.mysql.fi monty@tik.mysql.fi
monty@work.mysql.com monty@work.mysql.com
mwagner@evoq.mwagner.org mwagner@evoq.mwagner.org
paul@central.snake.net paul@central.snake.net
paul@teton.kitebird.com
root@x3.internalnet root@x3.internalnet
sasha@mysql.sashanet.com sasha@mysql.sashanet.com
serg@serg.mysql.com serg@serg.mysql.com
tim@hundin.mysql.fi
tim@threads.polyesthetic.msg tim@threads.polyesthetic.msg
tim@white.box
tim@work.mysql.com tim@work.mysql.com
tonu@hundin.mysql.fi
tonu@x3.internalnet tonu@x3.internalnet

View File

@ -1,8 +1,9 @@
#!/bin/sh #!/bin/sh
#shift #shift
TO=dev@mysql.com TO=dev-public@mysql.com
FROM=$USER@mysql.com FROM=$USER@mysql.com
INTERNALS=internals@lists.mysql.com
LIMIT=10000 LIMIT=10000
if [ "$REAL_EMAIL" = "" ] if [ "$REAL_EMAIL" = "" ]
@ -24,6 +25,24 @@ From: $FROM
To: $TO To: $TO
Subject: bk commit - 4.0 tree Subject: bk commit - 4.0 tree
EOF
bk changes -v -r+
bk cset -r+ -d
) | head -n $LIMIT | /usr/sbin/sendmail -t
echo "Notifying internals list at $INTERNALS"
(
cat <<EOF
List-ID: <bk.mysql>
From: $FROM
To: $INTERNALS
Subject: bk commit into 4.0 tree
Below is the list of changes that have just been committed into a
4.0 repository of $USER. When $USER does a push, they will be propogated to
the main repository and within 24 hours after the push to the public repository.
For information on how to access the public repository
see http://www.mysql.com/doc/I/n/Installing_source_tree.html
EOF EOF
bk changes -v -r+ bk changes -v -r+
bk cset -r+ -d bk cset -r+ -d

View File

@ -0,0 +1,3 @@
#! /bin/sh
echo "Test: post-incoming works"

View File

@ -0,0 +1,3 @@
#! /bin/sh
echo "Test: post-outgoing works"

View File

@ -4,10 +4,10 @@ use Getopt::Long;
$opt_distribution=$opt_user=$opt_result=$opt_config_options=$opt_config_env=""; $opt_distribution=$opt_user=$opt_result=$opt_config_options=$opt_config_env="";
$opt_dbd_options=$opt_perl_options=$opt_suffix=""; $opt_dbd_options=$opt_perl_options=$opt_suffix="";
$opt_tmp=$version_suffix=""; $opt_tmp=$version_suffix="";
$opt_help=$opt_Information=$opt_no_delete=$opt_debug=$opt_stage=$opt_rsh_mail=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_no_mysqltest=$opt_use_old_distribution=0; $opt_help=$opt_Information=$opt_no_delete=$opt_debug=$opt_stage=$opt_rsh_mail=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_no_mysqltest=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=0;
$opt_innodb=$opt_bdb=0; $opt_innodb=$opt_bdb=0;
GetOptions("Information","help","distribution=s","user=s","result=s","no-delete","no-test","no-mysqltest","perl-files=s","debug","config-options=s","config-env=s","stage=i","rsh-mail","with-low-memory","fast-benchmark","tmp=s","static-client","static-server","static-perl","no-perl","local-perl","perl-options=s","sur","with-small-disk","dbd-options=s","tcpip","suffix=s","build-thread=i","innodb","bdb","use-old-distribution") || usage(); GetOptions("Information","help","distribution=s","user=s","result=s","no-delete","no-test","no-mysqltest","perl-files=s","debug","config-options=s","config-env=s","stage=i","rsh-mail","with-low-memory","fast-benchmark","tmp=s","static-client","static-server","static-perl","no-perl","local-perl","perl-options=s","sur","with-small-disk","dbd-options=s","tcpip","suffix=s","build-thread=i","innodb","bdb","use-old-distribution","enable-shared","no-crash-me","no-strip") || usage();
usage() if ($opt_help || $opt_Information); usage() if ($opt_help || $opt_Information);
usage() if (!$opt_distribution); usage() if (!$opt_distribution);
@ -19,7 +19,7 @@ if ($opt_innodb || $opt_bdb)
chomp($host=`hostname`); chomp($host=`hostname`);
$full_host_name=$host; $full_host_name=$host;
print "$host: Compiling MySQL$version_suffix at $host$suffix, stage: $opt_stage\n" if ($opt_debug); info("Compiling MySQL$version_suffix at $host$suffix, stage: $opt_stage\n");
$connect_option= ($opt_tcpip ? "--host=$host" : ""); $connect_option= ($opt_tcpip ? "--host=$host" : "");
$host =~ /^([^.-]*)/; $host =~ /^([^.-]*)/;
$host=$1 . $opt_suffix; $host=$1 . $opt_suffix;
@ -119,7 +119,10 @@ if ($opt_stage <= 1)
{ {
$opt_config_options.=" --with-client-ldflags=-all-static"; $opt_config_options.=" --with-client-ldflags=-all-static";
} }
$opt_config_options.= " --disable-shared"; # Default for binary versions if (!$opt_enable_shared)
{
$opt_config_options.= " --disable-shared"; # Default for binary versions
}
if ($opt_bdb) if ($opt_bdb)
{ {
$opt_config_options.= " --with-berkeley-db" $opt_config_options.= " --with-berkeley-db"
@ -146,10 +149,13 @@ if ($opt_stage <= 2)
# #
if ($opt_stage <= 3) if ($opt_stage <= 3)
{ {
my ($flags);
log_system("rm -fr mysql-3* mysql-4* $pwd/$host/*.tar.gz"); log_system("rm -fr mysql-3* mysql-4* $pwd/$host/*.tar.gz");
log_system("nm -n sql/mysqld | gzip -9 -v 2>&1 > sql/mysqld.sym.gz | cat"); log_system("nm -n sql/mysqld | gzip -9 -v 2>&1 > sql/mysqld.sym.gz | cat");
log_system("strip sql/mysqld extra/comp_err client/mysql sql/mysqld client/mysqlshow extra/replace isam/isamchk client/mysqladmin client/mysqldump extra/perror");
check_system("scripts/make_binary_distribution $opt_tmp $opt_suffix",".tar.gz created"); $flags="";
$flags.="--no-strip" if ($opt_no_strip);
check_system("scripts/make_binary_distribution --tmp=$opt_tmp --suffix=$opt_suffix $flags",".tar.gz created");
safe_system("mv mysql*.tar.gz $pwd/$host"); safe_system("mv mysql*.tar.gz $pwd/$host");
safe_system("cp client/mysqladmin $pwd/$host/bin"); safe_system("cp client/mysqladmin $pwd/$host/bin");
safe_system("$make clean") if ($opt_with_small_disk); safe_system("$make clean") if ($opt_with_small_disk);
@ -174,6 +180,7 @@ if ($opt_stage <= 4 && !$opt_no_test)
$tar_file =~ /(mysql-[^\/]*)\.tar/; $tar_file =~ /(mysql-[^\/]*)\.tar/;
$ver=$1; $ver=$1;
$test_dir="$pwd/$host/test/$ver"; $test_dir="$pwd/$host/test/$ver";
$ENV{"LD_LIBRARY_PATH"}= "$testdir/lib:" . $ENV{"LD_LIBRARY_PATH"};
if ($opt_stage <= 5 && !$opt_no_test && !$opt_no_mysqltest) if ($opt_stage <= 5 && !$opt_no_test && !$opt_no_mysqltest)
{ {
@ -237,7 +244,7 @@ if ($opt_stage <= 7 && $opt_perl_files && !$opt_no_perl && !$opt_no_test)
} }
if ($opt_stage <= 8 && !$opt_no_test) if ($opt_stage <= 8 && !$opt_no_test && !$opt_no_crash_me)
{ {
safe_cd("$test_dir/sql-bench"); safe_cd("$test_dir/sql-bench");
log_system("rm -f limits/mysql.cfg"); log_system("rm -f limits/mysql.cfg");

0
Docs/Flags/australia.eps Executable file → Normal file
View File

0
Docs/Flags/australia.txt Executable file → Normal file
View File

0
Docs/Flags/austria.eps Executable file → Normal file
View File

0
Docs/Flags/austria.txt Executable file → Normal file
View File

0
Docs/Flags/canada.eps Executable file → Normal file
View File

0
Docs/Flags/canada.txt Executable file → Normal file
View File

0
Docs/Flags/czech-republic.eps Executable file → Normal file
View File

0
Docs/Flags/czech-republic.txt Executable file → Normal file
View File

0
Docs/Flags/germany.eps Executable file → Normal file
View File

0
Docs/Flags/germany.txt Executable file → Normal file
View File

0
Docs/Flags/great-britain.eps Executable file → Normal file
View File

0
Docs/Flags/great-britain.txt Executable file → Normal file
View File

0
Docs/Flags/hungary.eps Executable file → Normal file
View File

0
Docs/Flags/hungary.txt Executable file → Normal file
View File

0
Docs/Flags/israel.eps Executable file → Normal file
View File

0
Docs/Flags/israel.txt Executable file → Normal file
View File

0
Docs/Flags/italy.eps Executable file → Normal file
View File

0
Docs/Flags/italy.txt Executable file → Normal file
View File

0
Docs/Flags/japan.eps Executable file → Normal file
View File

0
Docs/Flags/japan.txt Executable file → Normal file
View File

99
Docs/Flags/latvia.eps Normal file
View File

@ -0,0 +1,99 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
%%Title: latvia.ps
%%Pages: 1
%%BoundingBox: 295 365 317 396
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
/rpicstr 32 string def
/gpicstr 32 string def
/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
295.44 365.64 translate
21.12 30.72 scale
0.5 0.5 translate 90 rotate -0.5 -0.5 translate
32 22 8
[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000009494949494949494949494949494949494949494949494
949494949494940000101010101010101010101010101010101010101010
101010101010101010000018181818181818181818181818181818181818
181818181818181818181800009494949494949494949494949494949494
949494949494949494949494940000101010101010101010101010101010
101010101010101010101010101010000018181818181818181818181818
181818181818181818181818181818181800009494949494949494949494
949494949494949494949494949494949494940000101010101010101010
101010101010101010101010101010101010101010000018181818181818
181818181818181818181818181818181818181818181800009494949494
949494949494949494949494949494949494949494949494940000101010
101010101010101010101010101010101010101010101010101010000018
181818181818181818181818181818181818181818181818181818181800
009494949494949494949494949494949494949494949494949494949494
940000101010101010101010101010101010101010101010101010101010
101010000018181818181818181818181818181818181818181818181818
181818181800009494949494949494949494949494949494949494949494
949494949494940000101010101010101010101010101010101010101010
101010101010101010000018181818181818181818181818181818181818
181818181818181818181800009494949494949494949494949494949494
949494949494949494949494940000101010101010101010101010101010
101010101010101010101010101010000018181818181818181818181818
181818181818181818181818181818181800009494949494949494949494
949494949494949494949494949494949494940000101010101010101010
101010101010101010101010101010101010101010000018181818181818
18181818181818181818181818181818181818181818180000ffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffff00009494949494949494949494
949494949494949494949494949494949494940000101010101010101010
101010101010101010101010101010101010101010000018181818181818
181818181818181818181818181818181818181818181800009494949494
949494949494949494949494949494949494949494949494940000101010
101010101010101010101010101010101010101010101010101010000018
181818181818181818181818181818181818181818181818181818181800
009494949494949494949494949494949494949494949494949494949494
940000101010101010101010101010101010101010101010101010101010
101010000018181818181818181818181818181818181818181818181818
181818181800009494949494949494949494949494949494949494949494
949494949494940000101010101010101010101010101010101010101010
101010101010101010000018181818181818181818181818181818181818
181818181818181818181800009494949494949494949494949494949494
949494949494949494949494940000101010101010101010101010101010
101010101010101010101010101010000018181818181818181818181818
181818181818181818181818181818181800009494949494949494949494
949494949494949494949494949494949494940000101010101010101010
101010101010101010101010101010101010101010000018181818181818
181818181818181818181818181818181818181818181800009494949494
949494949494949494949494949494949494949494949494940000101010
101010101010101010101010101010101010101010101010101010000018
181818181818181818181818181818181818181818181818181818181800
009494949494949494949494949494949494949494949494949494949494
940000101010101010101010101010101010101010101010101010101010
101010000018181818181818181818181818181818181818181818181818
181818181800000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000
grestore
showpage
%%Trailer

BIN
Docs/Flags/latvia.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

0
Docs/Flags/latvia.txt Normal file
View File

0
Docs/Flags/russia.eps Executable file → Normal file
View File

0
Docs/Flags/russia.txt Executable file → Normal file
View File

0
Docs/Flags/south-korea.eps Executable file → Normal file
View File

0
Docs/Flags/south-korea.txt Executable file → Normal file
View File

0
Docs/Flags/sweden.eps Executable file → Normal file
View File

0
Docs/Flags/sweden.txt Executable file → Normal file
View File

0
Docs/Flags/taiwan.eps Executable file → Normal file
View File

0
Docs/Flags/taiwan.txt Executable file → Normal file
View File

0
Docs/Flags/usa.eps Executable file → Normal file
View File

0
Docs/Flags/usa.txt Executable file → Normal file
View File

View File

@ -47,7 +47,7 @@ This is a manual about @strong{MySQL} internals.
@menu @menu
@end menu @end menu
@node caching @node caching,,,
@chapter How MySQL handles caching @chapter How MySQL handles caching
@strong{MySQL} has the following caches: @strong{MySQL} has the following caches:
@ -89,7 +89,7 @@ found rows are cached in a join cache. One SELECT query can use many
join caches in the worst case. join caches in the worst case.
@end itemize @end itemize
@node flush tables @node flush tables,,,
@chapter How MySQL handles flush tables @chapter How MySQL handles flush tables
@itemize @bullet @itemize @bullet
@ -134,7 +134,7 @@ After this it will give other threads a chance to open the same tables.
@end itemize @end itemize
@node Filesort @node Filesort,,,
@chapter How MySQL does sorting (filesort) @chapter How MySQL does sorting (filesort)
@itemize @bullet @itemize @bullet
@ -174,7 +174,7 @@ and then we read the rows in the sorted order into a row buffer
@end itemize @end itemize
@node Coding guidelines @node Coding guidelines,,,
@chapter Coding guidelines @chapter Coding guidelines
@itemize @bullet @itemize @bullet
@ -289,7 +289,7 @@ Use pointers rather than array indexing when operating on strings.
@end itemize @end itemize
@node mysys functions @node mysys functions,,,
@chapter mysys functions @chapter mysys functions
Functions i mysys: (For flags se my_sys.h) Functions i mysys: (For flags se my_sys.h)
@ -433,6 +433,205 @@ Functions i mysys: (For flags se my_sys.h)
void end_key_cache _A((void)); void end_key_cache _A((void));
- End key-cacheing. - End key-cacheing.
@node protocol,,,
@chapter MySQL client/server protocol
Raw packet without compression
==============================
-------------------------------------------------
| Packet Length | Packet no | Data |
| 3 Bytes | 1 Byte | n Bytes |
-------------------------------------------------
3 Byte packet length
The length is calculated with int3store
See include/global.h for details.
The max packetsize can be 16 MB.
1 Byte packet no
If no compression is used the first 4 bytes of each paket
is the header of the paket.
The packet number is incremented for each sent packet. The first
packet starts with 0
n Byte data
The packet length can be recalculated with:
length = byte1 + (256 * byte2) + (256 * 256 * byte3)
Raw packet with compression
===========================
-----------------------------------------------------
| Packet Length | Packet no | Uncomp. Packet Length |
| 3 Bytes | 1 Byte | 3 Bytes |
-----------------------------------------------------
3 Byte packet length
The length is calculated with int3store
See include/global.h for details.
The max packetsize can be 16 MB.
1 Byte packet no
3 Byte uncompressed packet length
If compression is used the first 7 bytes of each paket
is the header of the paket.
Basic packets
==============
OK-packet
For details see sql/net_pkg.cc
function send_ok
-------------------------------------------------
| Header | No of Rows | Affected Rows |
| | 1 Byte | 1-8 Byte |
-------------------------------------------------
| ID (last_insert_id) | Status | Length |
| 1-8 Byte | 2 Byte | 1-8 Byte |
-------------------------------------------------
| Messagetext |
| n Byte |
-------------------------------------------------
Header
1 byte number of rows ? (always 0 ?)
1-8 bytes affected rows
1-8 byte id (last_insert_id)
2 byte Status (usually 0)
If the OK-packege includes a message:
1-8 bytes length of message
n bytes messagetext
Error-packet
-------------------------------------------------
| Header | Statuscode | Error no |
| | 1 Byte | 2 Byte |
-------------------------------------------------
| Messagetext | 0x00 |
| n Byte | 1 Byte |
-------------------------------------------------
Header
1 byte status code (0xFF = ERROR)
2 byte error number (is only sent to new 3.23 clients.
n byte errortext
1 byte 0x00
The communication
=================
> Packet from server to client
< Paket from client tor server
Login
------
> 1. packet
Header
1 byte protocolversion
n byte serverversion
1 byte 0x00
4 byte threadnumber
8 byte crypt seed
1 byte 0x00
2 byte CLIENT_xxx options (see include/mysql_com.h
that is supported by the server
1 byte number of current server charset
2 byte server status variables (SERVER_STATUS_xxx flags)
13 byte 0x00 (not used yet).
< 2. packet
Header
2 byte CLIENT_xxx options
3 byte max_allowed_packet for the client
n byte username
1 byte 0x00
8 byte crypted password
1 byte 0x00
n byte databasename
1 byte 0x00
> 3. packet
OK-packet
Command
--------
< 1. packet
Header
1 byte command type (e.g.0x03 = query)
n byte query
Result set (after command)
--------------------------
> 2. packet
Header
1-8 byte field_count (packed with net_store_length())
If field_count == 0 (command):
1-8 byte affected rows
1-8 byte insert id
2 bytes server_status (SERVER_STATUS_xx)
If field_count == NULL_LENGTH (251)
LOAD DATA LOCAL INFILE
If field_count > 0 Result Set:
> n packets
Header Info
Column description: 5 data object /column
(See code in unpack_fields())
Columninfo for each column:
1 data block table_name
1 byte length of block
n byte data
1 data block field_name
1 byte length of block...
n byte data
1 data block display length of field
1 byte length of block
3 bytes display length of filed
1 data block type field of type (enum_field_types)
1 byte length of block
1 bytexs field of type
1 data block flags
1 byte length of block
2 byte flags for the columns (NOT_NULL_FLAG, ZEROFILL_FLAG....)
1 byte decimals
if table definition:
1 data block default value
Actual result (one packet per row):
4 byte header
1-8 byte length of data
n data
Fieldtype Codes:
================
display_length |enum_field_type |flags
----------------------------------------------------
Blob 03 FF FF 00 |01 FC |03 90 00 00
Mediumblob 03 FF FF FF |01 FC |03 90 00 00
Tinyblob 03 FF 00 00 |01 FC |03 90 00 00
Text 03 FF FF 00 |01 FC |03 10 00 00
Mediumtext 03 FF FF FF |01 FC |03 10 00 00
Tinytext 03 FF 00 00 |01 FC |03 10 00 00
Integer 03 0B 00 00 |01 03 |03 03 42 00
Mediumint 03 09 00 00 |01 09 |03 00 00 00
Smallint 03 06 00 00 |01 02 |03 00 00 00
Tinyint 03 04 00 00 |01 01 |03 00 00 00
Varchar 03 XX 00 00 |01 FD |03 00 00 00
Enum 03 05 00 00 |01 FE |03 00 01 00
Datetime 03 13 00 00 |01 0C |03 00 00 00
Timestamp 03 0E 00 00 |01 07 |03 61 04 00
Time 03 08 00 00 |01 0B |03 00 00 00
Date 03 0A 00 00 |01 0A |03 00 00 00
@c The Index was empty, and ugly, so I removed it. (jcole, Sep 7, 2000) @c The Index was empty, and ugly, so I removed it. (jcole, Sep 7, 2000)

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@ TAR = gtar
EXTRA_DIST = INSTALL-SOURCE README \ EXTRA_DIST = INSTALL-SOURCE README \
COPYING COPYING.LIB MIRRORS COPYING COPYING.LIB MIRRORS
SUBDIRS = include @docs_dirs@ @readline_dir@ \ SUBDIRS = include @docs_dirs@ @readline_dir@ \
@thread_dirs@ @pstack_dirs@ @sql_client_dirs@ \ @thread_dirs@ @pstack_dirs@ vio @sql_client_dirs@ \
@sql_server_dirs@ @libmysqld_dirs@ scripts tests man \ @sql_server_dirs@ @libmysqld_dirs@ scripts tests man \
@bench_dirs@ support-files @fs_dirs@ @bench_dirs@ support-files @fs_dirs@

View File

@ -1097,10 +1097,10 @@ dnl echo "DBG_GEM1: gemini='$gemini'"
gemini_includes= gemini_includes=
gemini_libs= gemini_libs=
case "$gemini" in case "$gemini" in
no | default | *) no)
AC_MSG_RESULT([Not using Gemini DB]) AC_MSG_RESULT([Not using Gemini DB])
;; ;;
yes ) yes | default | *)
have_gemini_db="yes" have_gemini_db="yes"
gemini_includes="-I../gemini/incl -I../gemini" gemini_includes="-I../gemini/incl -I../gemini"
gemini_libs="\ gemini_libs="\

View File

@ -1,21 +0,0 @@
/* DO NOT EDIT: automatically built by dist/s_include. */
#ifndef _rpc_server_ext_h_
#define _rpc_server_ext_h_
#if defined(__cplusplus)
extern "C" {
#endif
void __db_stats_freelist __P((__db_stat_statsreplist **));
void __dbsrv_settimeout __P((ct_entry *, u_int32_t));
void __dbsrv_timeout __P((int));
void __dbclear_ctp __P((ct_entry *));
void __dbdel_ctp __P((ct_entry *));
ct_entry *new_ct_ent __P((u_int32_t *));
ct_entry *get_tableent __P((long));
void __dbsrv_active __P((ct_entry *));
int __dbc_close_int __P((ct_entry *));
int __dbenv_close_int __P((long, int));
char *get_home __P((char *));
#if defined(__cplusplus)
}
#endif
#endif /* _rpc_server_ext_h_ */

View File

@ -20,7 +20,7 @@ INCLUDES = -I$(srcdir)/../include \
-I../include -I$(srcdir)/.. -I$(top_srcdir) \ -I../include -I$(srcdir)/.. -I$(top_srcdir) \
-I.. -I..
LIBS = @CLIENT_LIBS@ LIBS = @CLIENT_LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la
bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow mysqldump mysqlimport mysqltest bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow mysqldump mysqlimport mysqltest
noinst_PROGRAMS = insert_test select_test thread_test noinst_PROGRAMS = insert_test select_test thread_test
noinst_HEADERS = sql_string.h completion_hash.h my_readline.h noinst_HEADERS = sql_string.h completion_hash.h my_readline.h

View File

@ -47,6 +47,44 @@ const char *client_errors[]=
"Can't initialize character set %-.64s (path: %-.64s)", "Can't initialize character set %-.64s (path: %-.64s)",
"Got packet bigger than 'max_allowed_packet'", "Got packet bigger than 'max_allowed_packet'",
"Embedded server", "Embedded server",
"Error on SHOW SLAVE STATUS:",
"Error on SHOW SLAVE HOSTS:",
"Error connecting to slave:",
"Error connecting to master:"
};
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
#elif defined PORTUGUESE
const char *client_errors[]=
{
"Erro desconhecido do MySQL",
"N<EFBFBD>o pode criar 'UNIX socket' (%d)",
"N<EFBFBD>o pode se conectar ao servidor MySQL local atrav<61>s do 'socket' '%-.64s' (%d)",
"N<EFBFBD>o pode se conectar ao servidor MySQL em '%-.64s' (%d)",
"N<EFBFBD>o pode criar 'socket TCP/IP' (%d)",
"'Host' servidor MySQL '%-.64s' (%d) desconhecido",
"Servidor MySQL desapareceu",
"Incompatibilidade de protocolos. Vers<72>o do Servidor: %d - Vers<72>o do Cliente: %d",
"Cliente do MySQL com falta de mem<65>ria",
"Informa<EFBFBD><EFBFBD>o inv<6E>lida de 'host'",
"Localhost via 'UNIX socket'",
"%-.64s via 'TCP/IP'",
"Erro na negocia<69><61>o de acesso ao servidor",
"Conex<EFBFBD>o perdida com servidor MySQL durante 'query'",
"Comandos fora de sincronismo. Voc<6F> n<>o pode executar este comando agora",
"%-.64s via 'named pipe'",
"N<EFBFBD>o pode esperar pelo 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"N<EFBFBD>o pode abrir 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"N<EFBFBD>o pode estabelecer o estado do 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"N<EFBFBD>o pode inicializar conjunto de caracteres %-.64s (caminho %-.64s)",
"Obteve pacote maior do que 'max_allowed_packet'",
"Embedded server",
"Error on SHOW SLAVE STATUS:",
"Error on SHOW SLAVE HOSTS:",
"Error connecting to slave:",
"Error connecting to master:"
}; };
#else /* ENGLISH */ #else /* ENGLISH */
@ -74,6 +112,10 @@ const char *client_errors[]=
"Can't initialize character set %-.64s (path: %-.64s)", "Can't initialize character set %-.64s (path: %-.64s)",
"Got packet bigger than 'max_allowed_packet'", "Got packet bigger than 'max_allowed_packet'",
"Embedded server", "Embedded server",
"Error on SHOW SLAVE STATUS:",
"Error on SHOW SLAVE HOSTS:",
"Error connecting to slave:",
"Error connecting to master:"
}; };
#endif #endif

View File

@ -28,7 +28,7 @@
#include <my_pthread.h> /* because of signal() */ #include <my_pthread.h> /* because of signal() */
#endif #endif
#define ADMIN_VERSION "8.20" #define ADMIN_VERSION "8.21"
#define MAX_MYSQL_VAR 64 #define MAX_MYSQL_VAR 64
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */ #define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3 #define MAX_TRUNC_LENGTH 3
@ -870,7 +870,7 @@ static int drop_db(MYSQL *mysql, const char *db)
return -1; return -1;
} }
} }
sprintf(name_buff,"drop database %.*s",FN_REFLEN,db); sprintf(name_buff,"drop database `%.*s`",FN_REFLEN,db);
if (mysql_query(mysql,name_buff)) if (mysql_query(mysql,name_buff))
{ {
my_printf_error(0,"DROP DATABASE %s failed;\nerror: '%s'",MYF(ME_BELL), my_printf_error(0,"DROP DATABASE %s failed;\nerror: '%s'",MYF(ME_BELL),

View File

@ -16,7 +16,7 @@
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */ /* By Jani Tolonen, 2001-04-20, MySQL Development Team */
#define CHECK_VERSION "1.01" #define CHECK_VERSION "1.02"
#include <global.h> #include <global.h>
#include <my_sys.h> #include <my_sys.h>
@ -338,7 +338,7 @@ static int get_options(int *argc, char ***argv)
{ {
int pnlen = strlen(my_progname); int pnlen = strlen(my_progname);
if (pnlen < 6) // name too short if (pnlen < 6) /* name too short */
what_to_do = DO_CHECK; what_to_do = DO_CHECK;
else if (!strcmp("repair", my_progname + pnlen - 6)) else if (!strcmp("repair", my_progname + pnlen - 6))
what_to_do = DO_REPAIR; what_to_do = DO_REPAIR;
@ -503,25 +503,24 @@ static int use_db(char *database)
static int handle_request_for_tables(char *tables, uint length) static int handle_request_for_tables(char *tables, uint length)
{ {
char *query, *end, options[100]; char *query, *end, options[100], message[100];
const char *op = 0; const char *op = 0;
options[0] = 0; options[0] = 0;
end = options;
switch (what_to_do) { switch (what_to_do) {
case DO_CHECK: case DO_CHECK:
op = "CHECK"; op = "CHECK";
end = options; if (opt_quick) end = strmov(end, " QUICK");
if (opt_quick) end = strmov(end, "QUICK"); if (opt_fast) end = strmov(end, " FAST");
if (opt_fast) end = strmov(end, "FAST"); if (opt_medium_check) end = strmov(end, " MEDIUM"); /* Default */
if (opt_medium_check) end = strmov(end, "MEDIUM"); /* Default */ if (opt_extended) end = strmov(end, " EXTENDED");
if (opt_extended) end = strmov(end, "EXTENDED"); if (opt_check_only_changed) end = strmov(end, " CHANGED");
if (opt_check_only_changed) end = strmov(end, "CHANGED");
break; break;
case DO_REPAIR: case DO_REPAIR:
op = "REPAIR"; op = "REPAIR";
end = options; if (opt_quick) end = strmov(end, " QUICK");
if (opt_quick) end = strmov(end, "QUICK"); if (opt_extended) end = strmov(end, " EXTENDED");
if (opt_extended) end = strmov(end, "EXTENDED");
break; break;
case DO_ANALYZE: case DO_ANALYZE:
op = "ANALYZE"; op = "ANALYZE";
@ -533,11 +532,11 @@ static int handle_request_for_tables(char *tables, uint length)
if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME)))) if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))
return 1; return 1;
sprintf(query, "%s TABLE %s %s", op, options, tables); sprintf(query, "%s TABLE %s %s", op, tables, options);
if (mysql_query(sock, query)) if (mysql_query(sock, query))
{ {
sprintf(options, "when executing '%s TABLE'", op); sprintf(message, "when executing '%s TABLE ... %s", op, options);
DBerror(sock, options); DBerror(sock, message);
return 1; return 1;
} }
print_result(); print_result();
@ -551,23 +550,34 @@ static void print_result()
MYSQL_RES *res; MYSQL_RES *res;
MYSQL_ROW row; MYSQL_ROW row;
char prev[NAME_LEN*2+2]; char prev[NAME_LEN*2+2];
int i; uint i;
my_bool found_error=0;
res = mysql_use_result(sock); res = mysql_use_result(sock);
prev[0] = '\0'; prev[0] = '\0';
for (i = 0; (row = mysql_fetch_row(res)); i++) for (i = 0; (row = mysql_fetch_row(res)); i++)
{ {
int changed = strcmp(prev, row[0]); int changed = strcmp(prev, row[0]);
int status = !strcmp(row[2], "status"); my_bool status = !strcmp(row[2], "status");
if (opt_silent && status)
continue; if (status)
{
if (found_error)
{
if (what_to_do != DO_REPAIR && opt_auto_repair &&
(!opt_fast || strcmp(row[3],"OK")))
insert_dynamic(&tables4repair, row[0]);
}
found_error=0;
if (opt_silent)
continue;
}
if (status && changed) if (status && changed)
printf("%-50s %s", row[0], row[3]); printf("%-50s %s", row[0], row[3]);
else if (!status && changed) else if (!status && changed)
{ {
printf("%s\n%-9s: %s", row[0], row[2], row[3]); printf("%s\n%-9s: %s", row[0], row[2], row[3]);
if (what_to_do != DO_REPAIR && opt_auto_repair) found_error=1;
insert_dynamic(&tables4repair, row[0]);
} }
else else
printf("%-9s: %s", row[2], row[3]); printf("%-9s: %s", row[2], row[3]);

View File

@ -16,7 +16,7 @@
/* Show databases, tables or columns */ /* Show databases, tables or columns */
#define SHOW_VERSION "8.2" #define SHOW_VERSION "8.3"
#include <global.h> #include <global.h>
#include <my_sys.h> #include <my_sys.h>
@ -30,6 +30,7 @@
static my_string host=0,opt_password=0,user=0; static my_string host=0,opt_password=0,user=0;
static my_bool opt_show_keys=0,opt_compress=0,opt_status=0; static my_bool opt_show_keys=0,opt_compress=0,opt_status=0;
static uint opt_verbose=0;
static void get_options(int *argc,char ***argv); static void get_options(int *argc,char ***argv);
static uint opt_mysql_port=0; static uint opt_mysql_port=0;
@ -140,6 +141,7 @@ static struct option long_options[] =
#ifndef DONT_ALLOW_USER_CHANGE #ifndef DONT_ALLOW_USER_CHANGE
{"user", required_argument, 0, 'u'}, {"user", required_argument, 0, 'u'},
#endif #endif
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'}, {"version", no_argument, 0, 'V'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
@ -181,6 +183,8 @@ static void usage(void)
-u, --user=# user for login if not current user\n"); -u, --user=# user for login if not current user\n");
#endif #endif
printf("\ printf("\
-v, --verbose more verbose output; You can use this multiple times\n\
to get even more verbose output.\n\
-V, --version output version information and exit\n"); -V, --version output version information and exit\n");
puts("\n\ puts("\n\
@ -200,7 +204,7 @@ get_options(int *argc,char ***argv)
int c,option_index; int c,option_index;
my_bool tty_password=0; my_bool tty_password=0;
while ((c=getopt_long(*argc,*argv,"c:h:p::u:#::P:S:Ck?VWi",long_options, while ((c=getopt_long(*argc,*argv,"c:h:p::u:#::P:S:Ck?vVWi",long_options,
&option_index)) != EOF) &option_index)) != EOF)
{ {
switch(c) { switch(c) {
@ -210,6 +214,9 @@ get_options(int *argc,char ***argv)
case 'c': case 'c':
charsets_dir= optarg; charsets_dir= optarg;
break; break;
case 'v':
opt_verbose++;
break;
case 'h': case 'h':
host = optarg; host = optarg;
break; break;
@ -277,10 +284,13 @@ static int
list_dbs(MYSQL *mysql,const char *wild) list_dbs(MYSQL *mysql,const char *wild)
{ {
const char *header; const char *header;
uint length; uint length, counter = 0;
ulong rowcount = 0L;
char tables[NAME_LEN+1], rows[NAME_LEN+1];
char query[255];
MYSQL_FIELD *field; MYSQL_FIELD *field;
MYSQL_RES *result; MYSQL_RES *result;
MYSQL_ROW row; MYSQL_ROW row, trow, rrow;
if (!(result=mysql_list_dbs(mysql,wild))) if (!(result=mysql_list_dbs(mysql,wild)))
{ {
@ -297,10 +307,79 @@ list_dbs(MYSQL *mysql,const char *wild)
if (length < field->max_length) if (length < field->max_length)
length=field->max_length; length=field->max_length;
print_header(header,length,NullS); if (!opt_verbose)
print_header(header,length,NullS);
else if (opt_verbose == 1)
print_header(header,length,"Tables",6,NullS);
else
print_header(header,length,"Tables",6,"Total Rows",12,NullS);
while ((row = mysql_fetch_row(result))) while ((row = mysql_fetch_row(result)))
print_row(row[0],length,0); {
print_trailer(length,0); counter++;
if (opt_verbose)
{
/*
* Original code by MG16373; Slightly modified by Monty.
* Print now the count of tables and rows for each database.
*/
if (!(mysql_select_db(mysql,row[0])))
{
MYSQL_RES *tresult = mysql_list_tables(mysql,(char*)NULL);
if (mysql_affected_rows(mysql) > 0)
{
sprintf(tables,"%6lu",(ulong) mysql_affected_rows(mysql));
rowcount = 0;
if (opt_verbose > 1)
{
while ((trow = mysql_fetch_row(tresult)))
{
sprintf(query,"SELECT COUNT(*) FROM `%s`",trow[0]);
if (!(mysql_query(mysql,query)))
{
MYSQL_RES *rresult;
if ((rresult = mysql_store_result(mysql)))
{
rrow = mysql_fetch_row(rresult);
rowcount += (ulong) strtoull(rrow[0], (char**) 0, 10);
mysql_free_result(rresult);
}
}
}
sprintf(rows,"%12lu",rowcount);
}
}
else
{
sprintf(tables,"%6d",0);
sprintf(rows,"%12d",0);
}
mysql_free_result(tresult);
}
else
{
strmov(tables,"N/A");
strmov(rows,"N/A");
}
}
if (!opt_verbose)
print_row(row[0],length,0);
else if (opt_verbose == 1)
print_row(row[0],length,tables,6,NullS);
else
print_row(row[0],length,tables,6,rows,12,NullS);
}
print_trailer(length,
(opt_verbose > 0 ? 6 : 0),
(opt_verbose > 1 ? 12 :0),
0);
if (counter && opt_verbose)
printf("%u row%s in set.\n",counter,(counter > 1) ? "s" : "");
mysql_free_result(result); mysql_free_result(result);
return 0; return 0;
} }
@ -310,10 +389,11 @@ static int
list_tables(MYSQL *mysql,const char *db,const char *table) list_tables(MYSQL *mysql,const char *db,const char *table)
{ {
const char *header; const char *header;
uint head_length; uint head_length, counter = 0;
char query[255], rows[64], fields[16];
MYSQL_FIELD *field; MYSQL_FIELD *field;
MYSQL_RES *result; MYSQL_RES *result;
MYSQL_ROW row; MYSQL_ROW row, rrow;
if (mysql_select_db(mysql,db)) if (mysql_select_db(mysql,db))
{ {
@ -338,14 +418,81 @@ list_tables(MYSQL *mysql,const char *db,const char *table)
if (head_length < field->max_length) if (head_length < field->max_length)
head_length=field->max_length; head_length=field->max_length;
print_header(header,head_length,NullS); if (!opt_verbose)
print_header(header,head_length,NullS);
else if (opt_verbose == 1)
print_header(header,head_length,"Columns",8,NullS);
else
print_header(header,head_length,"Columns",8, "Total Rows",10,NullS);
while ((row = mysql_fetch_row(result))) while ((row = mysql_fetch_row(result)))
print_row(row[0],head_length,0); {
print_trailer(head_length,0); /*
* Modified by MG16373
* Print now the count of rows for each table.
*/
counter++;
if (opt_verbose > 0)
{
if (!(mysql_select_db(mysql,db)))
{
MYSQL_RES *rresult = mysql_list_fields(mysql,row[0],NULL);
ulong rowcount=0L;
if (!rresult)
{
strmov(fields,"N/A");
strmov(rows,"N/A");
}
else
{
sprintf(fields,"%8u",(uint) mysql_num_fields(rresult));
mysql_free_result(rresult);
if (opt_verbose > 1)
{
sprintf(query,"SELECT COUNT(*) FROM `%s`",row[0]);
if (!(mysql_query(mysql,query)))
{
if ((rresult = mysql_store_result(mysql)))
{
rrow = mysql_fetch_row(rresult);
rowcount += (unsigned long) strtoull(rrow[0], (char**) 0, 10);
mysql_free_result(rresult);
}
sprintf(rows,"%10lu",rowcount);
}
else
sprintf(rows,"%10d",0);
}
}
}
else
{
strmov(fields,"N/A");
strmov(rows,"N/A");
}
}
if (!opt_verbose)
print_row(row[0],head_length,NullS);
else if (opt_verbose == 1)
print_row(row[0],head_length, fields,8, NullS);
else
print_row(row[0],head_length, fields,8, rows,10, NullS);
}
print_trailer(head_length,
(opt_verbose > 0 ? 8 : 0),
(opt_verbose > 1 ? 10 :0),
0);
if (counter && opt_verbose)
printf("%u row%s in set.\n\n",counter,(counter > 1) ? "s" : "");
mysql_free_result(result); mysql_free_result(result);
return 0; return 0;
} }
static int static int
list_table_status(MYSQL *mysql,const char *db,const char *wild) list_table_status(MYSQL *mysql,const char *db,const char *wild)
{ {

View File

@ -43,7 +43,7 @@
**********************************************************************/ **********************************************************************/
#define MTEST_VERSION "1.8" #define MTEST_VERSION "1.10"
#include <global.h> #include <global.h>
#include <my_sys.h> #include <my_sys.h>
@ -84,7 +84,7 @@
static int record = 0, verbose = 0, silent = 0, opt_sleep=0; static int record = 0, verbose = 0, silent = 0, opt_sleep=0;
static char *db = 0, *pass=0; static char *db = 0, *pass=0;
const char* user = 0, *host = 0, *unix_sock = 0; const char* user = 0, *host = 0, *unix_sock = 0;
static int port = 0; static int port = 0, opt_big_test=0;
static uint start_lineno, *lineno; static uint start_lineno, *lineno;
static char **default_argv; static char **default_argv;
@ -95,9 +95,13 @@ static FILE** cur_file;
static FILE** file_stack_end; static FILE** file_stack_end;
static uint lineno_stack[MAX_INCLUDE_DEPTH]; static uint lineno_stack[MAX_INCLUDE_DEPTH];
static char TMPDIR[FN_REFLEN]; static char TMPDIR[FN_REFLEN];
static int *block_ok_stack_end;
static int block_stack[BLOCK_STACK_DEPTH];
static int *cur_block, *block_stack_end; static int *cur_block, *block_stack_end;
static int block_stack[BLOCK_STACK_DEPTH];
static int block_ok_stack[BLOCK_STACK_DEPTH];
static uint global_expected_errno[MAX_EXPECTED_ERRORS]; static uint global_expected_errno[MAX_EXPECTED_ERRORS];
DYNAMIC_ARRAY q_lines; DYNAMIC_ARRAY q_lines;
@ -121,7 +125,7 @@ typedef struct
PARSER parser; PARSER parser;
MASTER_POS master_pos; MASTER_POS master_pos;
int block_ok = 1; /* set to 0 if the current block should not be executed */ int* block_ok; /* set to 0 if the current block should not be executed */
int false_block_depth = 0; int false_block_depth = 0;
const char* result_file = 0; /* if set, all results are concated and const char* result_file = 0; /* if set, all results are concated and
compared against this file*/ compared against this file*/
@ -159,6 +163,8 @@ Q_SYNC_WITH_MASTER, Q_ERROR,
Q_SEND, Q_REAP, Q_SEND, Q_REAP,
Q_DIRTY_CLOSE, Q_REPLACE, Q_DIRTY_CLOSE, Q_REPLACE,
Q_PING, Q_EVAL, Q_PING, Q_EVAL,
Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
Q_UNKNOWN, /* Unknown command. */ Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */ Q_COMMENT, /* Comments, ignored. */
Q_COMMENT_WITH_COMMAND Q_COMMENT_WITH_COMMAND
@ -167,7 +173,7 @@ Q_COMMENT_WITH_COMMAND
/* this should really be called command */ /* this should really be called command */
struct st_query struct st_query
{ {
char *query, *query_buf,*first_argument; char *query, *query_buf,*first_argument,*end;
int first_word_len; int first_word_len;
my_bool abort_on_error, require_file; my_bool abort_on_error, require_file;
uint expected_errno[MAX_EXPECTED_ERRORS]; uint expected_errno[MAX_EXPECTED_ERRORS];
@ -188,6 +194,8 @@ const char *command_names[] = {
"send", "reap", "send", "reap",
"dirty_close", "replace_result", "dirty_close", "replace_result",
"ping", "eval", "ping", "eval",
"rpl_probe", "enable_rpl_parse",
"disable_rpl_parse", "eval_result",
0 0
}; };
@ -230,10 +238,12 @@ void free_pointer_array(POINTER_ARRAY *pa);
static int initialize_replace_buffer(void); static int initialize_replace_buffer(void);
static void free_replace_buffer(void); static void free_replace_buffer(void);
static void do_eval(DYNAMIC_STRING* query_eval, const char* query); static void do_eval(DYNAMIC_STRING* query_eval, const char* query);
void str_to_file(const char* fname, char* str, int size);
struct st_replace *glob_replace; struct st_replace *glob_replace;
static char *out_buff; static char *out_buff;
static uint out_length; static uint out_length;
static int eval_result = 0;
static void do_eval(DYNAMIC_STRING* query_eval, const char* query) static void do_eval(DYNAMIC_STRING* query_eval, const char* query)
{ {
@ -290,7 +300,7 @@ static void close_files()
{ {
do do
{ {
if (*cur_file != stdin) if (*cur_file != stdin && *cur_file)
my_fclose(*cur_file,MYF(0)); my_fclose(*cur_file,MYF(0));
} while (cur_file-- != file_stack); } while (cur_file-- != file_stack);
} }
@ -352,7 +362,9 @@ static void abort_not_supported_test()
static void verbose_msg(const char* fmt, ...) static void verbose_msg(const char* fmt, ...)
{ {
va_list args; va_list args;
if (!verbose) return; DBUG_ENTER("verbose_msg");
if (!verbose)
DBUG_VOID_RETURN;
va_start(args, fmt); va_start(args, fmt);
@ -360,6 +372,7 @@ static void verbose_msg(const char* fmt, ...)
vfprintf(stderr, fmt, args); vfprintf(stderr, fmt, args);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
va_end(args); va_end(args);
DBUG_VOID_RETURN;
} }
@ -382,25 +395,53 @@ int hex_val(int c)
int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname) int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname)
{ {
MY_STAT stat_info; MY_STAT stat_info;
char *tmp; char *tmp, *res_ptr;
char eval_file[FN_REFLEN];
int res; int res;
uint res_len;
int fd; int fd;
DYNAMIC_STRING res_ds;
DBUG_ENTER("dyn_string_cmp"); DBUG_ENTER("dyn_string_cmp");
if (!my_stat(fname, &stat_info, MYF(MY_WME))) if (!my_stat(fname, &stat_info, MYF(MY_WME)))
die(NullS); die(NullS);
if (stat_info.st_size != ds->length) if (!eval_result && stat_info.st_size != ds->length)
DBUG_RETURN(2); DBUG_RETURN(2);
if (!(tmp = (char*) my_malloc(ds->length, MYF(MY_WME)))) if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME))))
die(NullS); die(NullS);
if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0) if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0)
die(NullS); die(NullS);
if (my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP))) if (my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP)))
die(NullS); die(NullS);
res = (memcmp(tmp, ds->str, stat_info.st_size)) ? 1 : 0; tmp[stat_info.st_size] = 0;
init_dynamic_string(&res_ds, "", 0, 65536);
if (eval_result)
{
do_eval(&res_ds, tmp);
res_ptr = res_ds.str;
if((res_len = res_ds.length) != ds->length)
{
res = 2;
goto err;
}
}
else
{
res_ptr = tmp;
res_len = stat_info.st_size;
}
res = (memcmp(res_ptr, ds->str, res_len)) ? 1 : 0;
err:
if(res && eval_result)
str_to_file(fn_format(eval_file, fname, "", ".eval",2), res_ptr,
res_len);
my_free((gptr) tmp, MYF(0)); my_free((gptr) tmp, MYF(0));
my_close(fd, MYF(MY_WME)); my_close(fd, MYF(MY_WME));
dynstr_free(&res_ds);
DBUG_RETURN(res); DBUG_RETURN(res);
} }
@ -446,12 +487,12 @@ VAR* var_get(const char* var_name, const char** var_name_end, int raw)
{ {
const char* save_var_name = var_name, *end; const char* save_var_name = var_name, *end;
end = (var_name_end) ? *var_name_end : 0; end = (var_name_end) ? *var_name_end : 0;
while(isalnum(*var_name) || *var_name == '_') while (isvar(*var_name))
{ {
if(end && var_name == end) if(end && var_name == end)
break; break;
++var_name; ++var_name;
} }
if(var_name == save_var_name) if(var_name == save_var_name)
die("Empty variable"); die("Empty variable");
@ -497,7 +538,6 @@ int var_set(char* var_name, char* var_name_end, char* var_val,
char* var_val_end) char* var_val_end)
{ {
int digit; int digit;
int val_len;
VAR* v; VAR* v;
if (*var_name++ != '$') if (*var_name++ != '$')
{ {
@ -512,21 +552,8 @@ int var_set(char* var_name, char* var_name_end, char* var_val,
} }
else else
v = var_reg + digit; v = var_reg + digit;
if (v->alloced_len < (val_len = (int)(var_val_end - var_val)+1))
{ return eval_expr(v, var_val, (const char**)&var_val_end);
v->alloced_len = (val_len < MIN_VAR_ALLOC) ? MIN_VAR_ALLOC : val_len;
if (!(v->str_val =
v->str_val ? my_realloc(v->str_val, v->alloced_len, MYF(MY_WME)) :
my_malloc(v->alloced_len, MYF(MY_WME))))
die("Out of memory");
}
val_len--;
memcpy(v->str_val, var_val, val_len);
v->str_val_len = val_len;
v->str_val[val_len] = 0;
v->int_val = atoi(v->str_val);
v->int_dirty=0;
return 0;
} }
int open_file(const char* name) int open_file(const char* name)
@ -554,6 +581,35 @@ int do_source(struct st_query* q)
return open_file(name); return open_file(name);
} }
int var_query_set(VAR* v, const char* p, const char** p_end)
{
char* end = (char*)((p_end && *p_end) ? *p_end : p + strlen(p));
MYSQL_RES *res;
MYSQL_ROW row;
MYSQL* mysql = &cur_con->mysql;
LINT_INIT(res);
while (end > p && *end != '`')
--end;
if (p == end)
die("Syntax error in query, missing '`'");
++p;
if (mysql_real_query(mysql, p, (int)(end - p)) ||
!(res = mysql_store_result(mysql)))
{
*end = 0;
die("Error running query '%s': %s", p, mysql_error(mysql));
}
if ((row = mysql_fetch_row(res)) && row[0])
eval_expr(v, row[0], 0);
else
eval_expr(v, "", 0);
mysql_free_result(res);
return 0;
}
int eval_expr(VAR* v, const char* p, const char** p_end) int eval_expr(VAR* v, const char* p, const char** p_end)
{ {
@ -566,10 +622,27 @@ int eval_expr(VAR* v, const char* p, const char** p_end)
return 0; return 0;
} }
} }
else if(*p == '`')
{
return var_query_set(v, p, p_end);
}
else else
{ {
v->str_val = (char*)p; int new_val_len = (p_end && *p_end) ?
v->str_val_len = (p_end && *p_end) ? (int) (*p_end - p) : (int) strlen(p); (int) (*p_end - p) : (int) strlen(p);
if (new_val_len + 1 >= v->alloced_len)
{
v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
MIN_VAR_ALLOC : new_val_len + 1;
if (!(v->str_val =
v->str_val ? my_realloc(v->str_val, v->alloced_len,
MYF(MY_WME)) :
my_malloc(v->alloced_len, MYF(MY_WME))))
die("Out of memory");
}
v->str_val_len = new_val_len;
memcpy(v->str_val, p, new_val_len);
v->str_val[new_val_len] = 0;
v->int_val=atoi(p); v->int_val=atoi(p);
v->int_dirty=0; v->int_dirty=0;
return 0; return 0;
@ -642,6 +715,11 @@ int do_sync_with_master(struct st_query* q)
char query_buf[FN_REFLEN+128]; char query_buf[FN_REFLEN+128];
int offset = 0; int offset = 0;
char* p = q->first_argument; char* p = q->first_argument;
int rpl_parse;
rpl_parse = mysql_rpl_parse_enabled(mysql);
mysql_disable_rpl_parse(mysql);
if(*p) if(*p)
offset = atoi(p); offset = atoi(p);
@ -658,7 +736,10 @@ int do_sync_with_master(struct st_query* q)
if(!row[0]) if(!row[0])
die("Error on slave while syncing with master"); die("Error on slave while syncing with master");
mysql_free_result(res); mysql_free_result(res);
if(rpl_parse)
mysql_enable_rpl_parse(mysql);
return 0; return 0;
} }
@ -667,6 +748,11 @@ int do_save_master_pos()
MYSQL_RES* res; MYSQL_RES* res;
MYSQL_ROW row; MYSQL_ROW row;
MYSQL* mysql = &cur_con->mysql; MYSQL* mysql = &cur_con->mysql;
int rpl_parse;
rpl_parse = mysql_rpl_parse_enabled(mysql);
mysql_disable_rpl_parse(mysql);
if(mysql_query(mysql, "show master status")) if(mysql_query(mysql, "show master status"))
die("At line %u: failed in show master status: %d: %s", start_lineno, die("At line %u: failed in show master status: %d: %s", start_lineno,
mysql_errno(mysql), mysql_error(mysql)); mysql_errno(mysql), mysql_error(mysql));
@ -678,6 +764,9 @@ int do_save_master_pos()
strncpy(master_pos.file, row[0], sizeof(master_pos.file)); strncpy(master_pos.file, row[0], sizeof(master_pos.file));
master_pos.pos = strtoul(row[1], (char**) 0, 10); master_pos.pos = strtoul(row[1], (char**) 0, 10);
mysql_free_result(res); mysql_free_result(res);
if(rpl_parse)
mysql_enable_rpl_parse(mysql);
return 0; return 0;
} }
@ -697,11 +786,29 @@ int do_let(struct st_query* q)
while(*p && isspace(*p)) while(*p && isspace(*p))
p++; p++;
var_val_start = p; var_val_start = p;
while(*p && !isspace(*p)) return var_set(var_name, var_name_end, var_val_start, q->end);
p++;
return var_set(var_name, var_name_end, var_val_start, p);
} }
int do_rpl_probe(struct st_query* __attribute__((unused)) q)
{
if(mysql_rpl_probe(&cur_con->mysql))
die("Failed in mysql_rpl_probe(): %s", mysql_error(&cur_con->mysql));
return 0;
}
int do_enable_rpl_parse(struct st_query* __attribute__((unused)) q)
{
mysql_enable_rpl_parse(&cur_con->mysql);
return 0;
}
int do_disable_rpl_parse(struct st_query* __attribute__((unused)) q)
{
mysql_disable_rpl_parse(&cur_con->mysql);
return 0;
}
int do_sleep(struct st_query* q) int do_sleep(struct st_query* q)
{ {
char* p=q->first_argument; char* p=q->first_argument;
@ -1015,7 +1122,8 @@ int do_connect(struct st_query* q)
if (!mysql_init(&next_con->mysql)) if (!mysql_init(&next_con->mysql))
die("Failed on mysql_init()"); die("Failed on mysql_init()");
con_sock=fn_format(buff, con_sock, TMPDIR, "",0); if (con_sock)
con_sock=fn_format(buff, con_sock, TMPDIR, "",0);
if (!con_db[0]) if (!con_db[0])
con_db=db; con_db=db;
con_error = 1; con_error = 1;
@ -1047,13 +1155,14 @@ int do_done(struct st_query* q)
q->type = Q_END_BLOCK; q->type = Q_END_BLOCK;
if (cur_block == block_stack) if (cur_block == block_stack)
die("Stray '}' - end of block before beginning"); die("Stray '}' - end of block before beginning");
if (block_ok) if (*block_ok--)
{
parser.current_line = *--cur_block; parser.current_line = *--cur_block;
}
else else
{ {
if (!--false_block_depth)
block_ok = 1;
++parser.current_line; ++parser.current_line;
--cur_block;
} }
return 0; return 0;
} }
@ -1065,11 +1174,14 @@ int do_while(struct st_query* q)
VAR v; VAR v;
if (cur_block == block_stack_end) if (cur_block == block_stack_end)
die("Nesting too deeply"); die("Nesting too deeply");
if (!block_ok) if (!*block_ok)
{ {
++false_block_depth; ++false_block_depth;
*++block_ok = 0;
*cur_block++ = parser.current_line++;
return 0; return 0;
} }
expr_start = strchr(p, '('); expr_start = strchr(p, '(');
if (!expr_start) if (!expr_start)
die("missing '(' in while"); die("missing '(' in while");
@ -1080,9 +1192,11 @@ int do_while(struct st_query* q)
*cur_block++ = parser.current_line++; *cur_block++ = parser.current_line++;
if (!v.int_val) if (!v.int_val)
{ {
block_ok = 0; *++block_ok = 0;
false_block_depth = 1; false_block_depth++;
} }
else
*++block_ok = 1;
return 0; return 0;
} }
@ -1346,7 +1460,7 @@ int read_query(struct st_query** q_ptr)
q->first_word_len = (uint) (p - q->query); q->first_word_len = (uint) (p - q->query);
while (*p && isspace(*p)) p++; while (*p && isspace(*p)) p++;
q->first_argument=p; q->first_argument=p;
q->end = strend(q->query);
parser.read_lines++; parser.read_lines++;
return 0; return 0;
} }
@ -1356,6 +1470,7 @@ struct option long_options[] =
{ {
{"debug", optional_argument, 0, '#'}, {"debug", optional_argument, 0, '#'},
{"database", required_argument, 0, 'D'}, {"database", required_argument, 0, 'D'},
{"big-test", no_argument, 0, 'B'},
{"help", no_argument, 0, '?'}, {"help", no_argument, 0, '?'},
{"host", required_argument, 0, 'h'}, {"host", required_argument, 0, 'h'},
{"password", optional_argument, 0, 'p'}, {"password", optional_argument, 0, 'p'},
@ -1366,6 +1481,7 @@ struct option long_options[] =
{"silent", no_argument, 0, 'q'}, {"silent", no_argument, 0, 'q'},
{"sleep", required_argument, 0, 'T'}, {"sleep", required_argument, 0, 'T'},
{"socket", required_argument, 0, 'S'}, {"socket", required_argument, 0, 'S'},
{"test-file", required_argument, 0, 'x'},
{"tmpdir", required_argument, 0, 't'}, {"tmpdir", required_argument, 0, 't'},
{"user", required_argument, 0, 'u'}, {"user", required_argument, 0, 'u'},
{"verbose", no_argument, 0, 'v'}, {"verbose", no_argument, 0, 'v'},
@ -1398,6 +1514,7 @@ void usage()
-u, --user=... User for login.\n\ -u, --user=... User for login.\n\
-p[password], --password[=...]\n\ -p[password], --password[=...]\n\
Password to use when connecting to server.\n\ Password to use when connecting to server.\n\
-B, --big-test Define BIG_TEST to 1\n\
-D, --database=... Database to use.\n\ -D, --database=... Database to use.\n\
-P, --port=... Port number to use for connection.\n\ -P, --port=... Port number to use for connection.\n\
-S, --socket=... Socket file to use for connection.\n\ -S, --socket=... Socket file to use for connection.\n\
@ -1405,6 +1522,7 @@ void usage()
-T, --sleep=# Sleep always this many seconds on sleep commands\n\ -T, --sleep=# Sleep always this many seconds on sleep commands\n\
-r, --record Record output of test_file into result file.\n\ -r, --record Record output of test_file into result file.\n\
-R, --result-file=... Read/Store result from/in this file.\n\ -R, --result-file=... Read/Store result from/in this file.\n\
-x, --test-file=... Read test from/in this file (default stdin).\n\
-v, --verbose Write more.\n\ -v, --verbose Write more.\n\
-q, --quiet, --silent Suppress all normal output.\n\ -q, --quiet, --silent Suppress all normal output.\n\
-V, --version Output version information and exit.\n\ -V, --version Output version information and exit.\n\
@ -1419,7 +1537,7 @@ int parse_args(int argc, char **argv)
load_defaults("my",load_default_groups,&argc,&argv); load_defaults("my",load_default_groups,&argc,&argv);
default_argv= argv; default_argv= argv;
while((c = getopt_long(argc, argv, "h:p::u:P:D:S:R:t:T:#:?rvVq", while((c = getopt_long(argc, argv, "h:p::u:BP:D:S:R:x:t:T:#:?rvVq",
long_options, &option_index)) != EOF) long_options, &option_index)) != EOF)
{ {
switch(c) { switch(c) {
@ -1438,6 +1556,10 @@ int parse_args(int argc, char **argv)
case 'R': case 'R':
result_file = optarg; result_file = optarg;
break; break;
case 'x':
if (!(*cur_file = my_fopen(optarg, O_RDONLY, MYF(MY_WME))))
die("Could not open %s: errno = %d", optarg, errno);
break;
case 'p': case 'p':
if (optarg) if (optarg)
{ {
@ -1448,6 +1570,9 @@ int parse_args(int argc, char **argv)
else else
tty_password=1; tty_password=1;
break; break;
case 'B':
opt_big_test=1;
break;
case 'P': case 'P':
port = atoi(optarg); port = atoi(optarg);
break; break;
@ -1522,10 +1647,12 @@ void reject_dump(const char* record_file, char* buf, int size)
str_to_file(fn_format(reject_file, record_file,"",".reject",2), buf, size); str_to_file(fn_format(reject_file, record_file,"",".reject",2), buf, size);
} }
/* flags control the phased/stages of query execution to be performed /*
* flags control the phased/stages of query execution to be performed
* if QUERY_SEND bit is on, the query will be sent. If QUERY_REAP is on * if QUERY_SEND bit is on, the query will be sent. If QUERY_REAP is on
* the result will be read - for regular query, both bits must be on * the result will be read - for regular query, both bits must be on
*/ */
int run_query(MYSQL* mysql, struct st_query* q, int flags) int run_query(MYSQL* mysql, struct st_query* q, int flags)
{ {
MYSQL_RES* res = 0; MYSQL_RES* res = 0;
@ -1576,8 +1703,6 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
if (q->abort_on_error) if (q->abort_on_error)
die("At line %u: query '%s' failed: %d: %s", start_lineno, query, die("At line %u: query '%s' failed: %d: %s", start_lineno, query,
mysql_errno(mysql), mysql_error(mysql)); mysql_errno(mysql), mysql_error(mysql));
/*die("At line %u: Failed in mysql_store_result for query '%s' (%d)",
start_lineno, query, mysql_errno(mysql));*/
else else
{ {
for (i=0 ; q->expected_errno[i] ; i++) for (i=0 ; q->expected_errno[i] ; i++)
@ -1587,13 +1712,15 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
} }
if (i) if (i)
{ {
verbose_msg("query '%s' failed with wrong errno\ verbose_msg("query '%s' failed with wrong errno %d instead of %d...",
%d instead of %d...", q->query, mysql_errno(mysql), q->expected_errno[0]); q->query, mysql_errno(mysql), q->expected_errno[0]);
error=1;
goto end; goto end;
} }
verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql), verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql),
mysql_error(mysql)); mysql_error(mysql));
/* if we do not abort on error, failure to run the query does /*
if we do not abort on error, failure to run the query does
not fail the whole test case not fail the whole test case
*/ */
goto end; goto end;
@ -1720,11 +1847,13 @@ static VAR* var_init(const char* name, int name_len, const char* val,
if(!val_len) if(!val_len)
val_len = strlen(val) ; val_len = strlen(val) ;
val_alloc_len = val_len + 16; /* room to grow */ val_alloc_len = val_len + 16; /* room to grow */
if(!(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var) + val_alloc_len if(!(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
+ name_len, MYF(MY_WME)))) + name_len, MYF(MY_WME))))
die("Out of memory"); die("Out of memory");
tmp_var->name = (char*)tmp_var + sizeof(*tmp_var); tmp_var->name = (char*)tmp_var + sizeof(*tmp_var);
tmp_var->str_val = tmp_var->name + name_len; if(!(tmp_var->str_val = my_malloc(val_alloc_len, MYF(MY_WME))))
die("Out of memory");
memcpy(tmp_var->name, name, name_len); memcpy(tmp_var->name, name, name_len);
memcpy(tmp_var->str_val, val, val_len + 1); memcpy(tmp_var->str_val, val, val_len + 1);
tmp_var->name_len = name_len; tmp_var->name_len = name_len;
@ -1737,6 +1866,7 @@ static VAR* var_init(const char* name, int name_len, const char* val,
static void var_free(void* v) static void var_free(void* v)
{ {
my_free(((VAR*)v)->str_val, MYF(MY_WME));
my_free(v, MYF(MY_WME)); my_free(v, MYF(MY_WME));
} }
@ -1752,13 +1882,15 @@ static void var_from_env(const char* name, const char* def_val)
hash_insert(&var_hash, (byte*)v); hash_insert(&var_hash, (byte*)v);
} }
static void init_var_hash() static void init_var_hash()
{ {
if(hash_init(&var_hash, 1024, 0, 0, get_var_key, var_free, MYF(0))) if (hash_init(&var_hash, 1024, 0, 0, get_var_key, var_free, MYF(0)))
die("Variable hash initialization failed"); die("Variable hash initialization failed");
var_from_env("MASTER_MYPORT", "9306"); var_from_env("MASTER_MYPORT", "9306");
var_from_env("SLAVE_MYPORT", "9307"); var_from_env("SLAVE_MYPORT", "9307");
var_from_env("MYSQL_TEST_DIR", ""); var_from_env("MYSQL_TEST_DIR", "/tmp");
var_from_env("BIG_TEST", opt_big_test ? "1" : "0");
} }
int main(int argc, char** argv) int main(int argc, char** argv)
@ -1785,7 +1917,11 @@ int main(int argc, char** argv)
INIT_Q_LINES); INIT_Q_LINES);
memset(block_stack, 0, sizeof(block_stack)); memset(block_stack, 0, sizeof(block_stack));
block_stack_end = block_stack + BLOCK_STACK_DEPTH; block_stack_end = block_stack + BLOCK_STACK_DEPTH;
memset(block_ok_stack, 0, sizeof(block_stack));
block_ok_stack_end = block_ok_stack + BLOCK_STACK_DEPTH;
cur_block = block_stack; cur_block = block_stack;
block_ok = block_ok_stack;
*block_ok = 1;
init_dynamic_string(&ds_res, "", 0, 65536); init_dynamic_string(&ds_res, "", 0, 65536);
parse_args(argc, argv); parse_args(argc, argv);
init_var_hash(); init_var_hash();
@ -1809,7 +1945,7 @@ int main(int argc, char** argv)
int current_line_inc = 1, processed = 0; int current_line_inc = 1, processed = 0;
if (q->type == Q_UNKNOWN || q->type == Q_COMMENT_WITH_COMMAND) if (q->type == Q_UNKNOWN || q->type == Q_COMMENT_WITH_COMMAND)
get_query_type(q); get_query_type(q);
if (block_ok) if (*block_ok)
{ {
processed = 1; processed = 1;
switch (q->type) { switch (q->type) {
@ -1818,6 +1954,9 @@ int main(int argc, char** argv)
case Q_DISCONNECT: case Q_DISCONNECT:
case Q_DIRTY_CLOSE: case Q_DIRTY_CLOSE:
close_connection(q); break; close_connection(q); break;
case Q_RPL_PROBE: do_rpl_probe(q); break;
case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break;
case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
case Q_SOURCE: do_source(q); break; case Q_SOURCE: do_source(q); break;
case Q_SLEEP: do_sleep(q); break; case Q_SLEEP: do_sleep(q); break;
case Q_INC: do_inc(q); break; case Q_INC: do_inc(q); break;
@ -1825,6 +1964,7 @@ int main(int argc, char** argv)
case Q_ECHO: do_echo(q); break; case Q_ECHO: do_echo(q); break;
case Q_SYSTEM: do_system(q); break; case Q_SYSTEM: do_system(q); break;
case Q_LET: do_let(q); break; case Q_LET: do_let(q); break;
case Q_EVAL_RESULT: eval_result = 1; break;
case Q_EVAL: case Q_EVAL:
if (q->query == q->query_buf) if (q->query == q->query_buf)
q->query += q->first_word_len; q->query += q->first_word_len;
@ -1885,7 +2025,7 @@ int main(int argc, char** argv)
case Q_SAVE_MASTER_POS: do_save_master_pos(); break; case Q_SAVE_MASTER_POS: do_save_master_pos(); break;
case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break; case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break;
case Q_COMMENT: /* Ignore row */ case Q_COMMENT: /* Ignore row */
case Q_COMMENT_WITH_COMMAND: case Q_COMMENT_WITH_COMMAND:
case Q_PING: case Q_PING:
(void) mysql_ping(&cur_con->mysql); (void) mysql_ping(&cur_con->mysql);
break; break;

View File

@ -285,8 +285,10 @@ export CC CFLAGS LD LDFLAGS
if test "$GXX" = "yes" if test "$GXX" = "yes"
then then
# mysqld requires this when compiled with gcc # mysqld requires -fno-implicit-templates.
CXXFLAGS="$CXXFLAGS -fno-implicit-templates" # Disable exceptions as they seams to create problems with gcc and threads.
# mysqld doesn't use run-time-type-checking, so we disable it.
CXXFLAGS="$CXXFLAGS -fno-implicit-templates -fno-exceptions -fno-rtti"
fi fi
# Avoid bug in fcntl on some versions of linux # Avoid bug in fcntl on some versions of linux
@ -401,7 +403,7 @@ AM_PROG_CC_STDC
if test "$am_cv_prog_cc_stdc" = "no" if test "$am_cv_prog_cc_stdc" = "no"
then then
AC_MSG_ERROR([MySQL requiers a ANSI C compiler (and a C++ compiler). Try gcc. See the Installation chapter in the Reference Manual.]) AC_MSG_ERROR([MySQL requires a ANSI C compiler (and a C++ compiler). Try gcc. See the Installation chapter in the Reference Manual.])
fi fi
NOINST_LDFLAGS= NOINST_LDFLAGS=
@ -786,6 +788,11 @@ case $SYSTEM_TYPE in
echo "Enabling snprintf workaround for hpux 10.20" echo "Enabling snprintf workaround for hpux 10.20"
CFLAGS="$CFLAGS -DHAVE_BROKEN_SNPRINTF -DSIGNALS_DONT_BREAK_READ" CFLAGS="$CFLAGS -DHAVE_BROKEN_SNPRINTF -DSIGNALS_DONT_BREAK_READ"
CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_SNPRINTF -D_INCLUDE_LONGLONG -DSIGNALS_DONT_BREAK_READ" CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_SNPRINTF -D_INCLUDE_LONGLONG -DSIGNALS_DONT_BREAK_READ"
if test "$with_named_thread" = "no"
then
echo "Using --with-named-thread=-lpthread"
with_named_thread="-lcma"
fi
;; ;;
*hpux11.*) *hpux11.*)
echo "Enabling pread/pwrite workaround for hpux 11" echo "Enabling pread/pwrite workaround for hpux 11"
@ -1082,7 +1089,7 @@ fi
AC_MSG_CHECKING("named thread libs:") AC_MSG_CHECKING("named thread libs:")
if test "$with_named_thread" != "no" if test "$with_named_thread" != "no"
then then
LIBS="$LIBS $with_named_thread" LIBS="$with_named_thread $LIBS $with_named_thread"
with_posix_threads="yes" with_posix_threads="yes"
with_mit_threads="no" with_mit_threads="no"
AC_MSG_RESULT("$with_named_thread") AC_MSG_RESULT("$with_named_thread")
@ -1995,7 +2002,7 @@ then
THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o" THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o"
AC_SUBST(THREAD_LOBJECTS) AC_SUBST(THREAD_LOBJECTS)
sql_server_dirs="strings dbug mysys extra regex isam merge myisam myisammrg heap sql" sql_server_dirs="strings dbug mysys extra regex isam merge myisam myisammrg heap sql"
server_scripts="safe_mysqld mysql_install_db" server_scripts="mysqld_safe mysql_install_db"
if test X"$have_berkeley_db" != Xno; then if test X"$have_berkeley_db" != Xno; then
if test X"$have_berkeley_db" != Xyes; then if test X"$have_berkeley_db" != Xyes; then
# we must build berkeley db from source # we must build berkeley db from source
@ -2074,6 +2081,17 @@ EOF
echo "END OF INNODB CONFIGURATION" echo "END OF INNODB CONFIGURATION"
fi fi
if test "X$have_gemini_db" = "Xyes"; then
sql_server_dirs="gemini $sql_server_dirs"
echo "CONFIGURING FOR GEMINI DB"
(cd gemini && sh ./configure) \
|| AC_MSG_ERROR([could not configure Gemini DB])
echo "END OF GEMINI DB CONFIGURATION"
AC_DEFINE(HAVE_GEMINI_DB)
fi
if test "$with_posix_threads" = "no" -o "$with_mit_threads" = "yes" if test "$with_posix_threads" = "no" -o "$with_mit_threads" = "yes"
then then
# MIT user level threads # MIT user level threads

View File

@ -54,3 +54,10 @@ extern const char *client_errors[]; /* Error messages */
#define CR_CANT_READ_CHARSET 2019 #define CR_CANT_READ_CHARSET 2019
#define CR_NET_PACKET_TOO_LARGE 2020 #define CR_NET_PACKET_TOO_LARGE 2020
#define CR_EMBEDDED_CONNECTION 2021 #define CR_EMBEDDED_CONNECTION 2021
#define CR_PROBE_SLAVE_STATUS 2022
#define CR_PROBE_SLAVE_HOSTS 2023
#define CR_PROBE_SLAVE_CONNECT 2024
#define CR_PROBE_MASTER_CONNECT 2025

View File

@ -69,10 +69,6 @@
# define memmove(d, s, n) bmove((d), (s), (n)) /* our bmove */ # define memmove(d, s, n) bmove((d), (s), (n)) /* our bmove */
#endif #endif
#if defined(HAVE_STPCPY) && !defined(HAVE_mit_thread)
#define strmov(A,B) stpcpy((A),(B))
#endif
/* Unixware 7 */ /* Unixware 7 */
#if !defined(HAVE_BFILL) #if !defined(HAVE_BFILL)
# define bfill(A,B,C) memset((A),(C),(B)) # define bfill(A,B,C) memset((A),(C),(B))
@ -90,6 +86,13 @@
extern "C" { extern "C" {
#endif #endif
#if defined(HAVE_STPCPY) && !defined(HAVE_mit_thread)
#define strmov(A,B) stpcpy((A),(B))
#ifndef stpcpy
extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */
#endif
#endif
extern char NEAR _dig_vec[]; /* Declared in int2str() */ extern char NEAR _dig_vec[]; /* Declared in int2str() */
#ifdef BAD_STRING_COMPILER #ifdef BAD_STRING_COMPILER
@ -148,7 +151,7 @@ extern void bchange(char *dst,uint old_len,const char *src,
uint new_len,uint tot_len); uint new_len,uint tot_len);
extern void strappend(char *s,uint len,pchar fill); extern void strappend(char *s,uint len,pchar fill);
extern char *strend(const char *s); extern char *strend(const char *s);
extern char *strcend(const char *, pchar); extern char *strcend(const char *, pchar);
extern char *strfield(char *src,int fields,int chars,int blanks, extern char *strfield(char *src,int fields,int chars,int blanks,
int tabch); int tabch);
extern char *strfill(my_string s,uint len,pchar fill); extern char *strfill(my_string s,uint len,pchar fill);

View File

@ -215,6 +215,7 @@ enum ha_base_keytype {
#define HA_ERR_CRASHED_ON_USAGE 145 /* Table must be repaired */ #define HA_ERR_CRASHED_ON_USAGE 145 /* Table must be repaired */
#define HA_ERR_LOCK_WAIT_TIMEOUT 146 #define HA_ERR_LOCK_WAIT_TIMEOUT 146
#define HA_ERR_LOCK_TABLE_FULL 147 #define HA_ERR_LOCK_TABLE_FULL 147
#define HA_ERR_READ_ONLY_TRANSACTION 148 /* Updates not allowed */
/* Other constants */ /* Other constants */

View File

@ -62,6 +62,8 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */ #define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */
#define MY_LINK_WARNING 32 /* my_redel() gives warning if links */ #define MY_LINK_WARNING 32 /* my_redel() gives warning if links */
#define MY_COPYTIME 64 /* my_redel() copys time */ #define MY_COPYTIME 64 /* my_redel() copys time */
#define MY_DELETE_OLD 256 /* my_create_with_symlink() */
#define MY_RESOLVE_LINK 128 /* my_realpath(); Only resolve links */
#define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */ #define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */
#define MY_REDEL_MAKE_BACKUP 256 #define MY_REDEL_MAKE_BACKUP 256
#define MY_SEEK_NOT_DONE 32 /* my_lock may have to do a seek */ #define MY_SEEK_NOT_DONE 32 /* my_lock may have to do a seek */
@ -108,10 +110,7 @@ extern int NEAR my_errno; /* Last error in mysys */
/* root_alloc flags */ /* root_alloc flags */
#define MY_KEEP_PREALLOC 1 #define MY_KEEP_PREALLOC 1
#define MY_MARK_BLOCKS_FREE 2 /* do not my_free() blocks, #define MY_MARK_BLOCKS_FREE 2 /* move used to free list and reuse them */
just move used into free list
and mark all blocks as fully free
*/
/* defines when allocating data */ /* defines when allocating data */
@ -210,7 +209,7 @@ extern long lCurMemory,lMaxMemory; /* from safemalloc */
extern ulong my_default_record_cache_size; extern ulong my_default_record_cache_size;
extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io, extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
NEAR my_disable_flush_key_blocks; NEAR my_disable_flush_key_blocks, NEAR my_disable_symlinks;
extern char wild_many,wild_one,wild_prefix; extern char wild_many,wild_one,wild_prefix;
extern const char *charsets_dir; extern const char *charsets_dir;
extern char *defaults_extra_file; extern char *defaults_extra_file;
@ -382,6 +381,14 @@ extern File my_create(const char *FileName,int CreateFlags,
int AccsesFlags, myf MyFlags); int AccsesFlags, myf MyFlags);
extern int my_close(File Filedes,myf MyFlags); extern int my_close(File Filedes,myf MyFlags);
extern int my_mkdir(const char *dir, int Flags, myf MyFlags); extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
extern int my_readlink(char *to, const char *filename, myf MyFlags);
extern int my_realpath(char *to, const char *filename, myf MyFlags);
extern File my_create_with_symlink(const char *linkname, const char *filename,
int createflags, int access_flags,
myf MyFlags);
extern int my_delete_with_symlink(const char *name, myf MyFlags);
extern int my_rename_with_symlink(const char *from,const char *to,myf MyFlags);
extern int my_symlink(const char *content, const char *linkname, myf MyFlags);
extern uint my_read(File Filedes,byte *Buffer,uint Count,myf MyFlags); extern uint my_read(File Filedes,byte *Buffer,uint Count,myf MyFlags);
extern uint my_pread(File Filedes,byte *Buffer,uint Count,my_off_t offset, extern uint my_pread(File Filedes,byte *Buffer,uint Count,my_off_t offset,
myf MyFlags); myf MyFlags);
@ -432,8 +439,14 @@ extern int my_redel(const char *from, const char *to, int MyFlags);
extern int my_copystat(const char *from, const char *to, int MyFlags); extern int my_copystat(const char *from, const char *to, int MyFlags);
extern my_string my_filename(File fd); extern my_string my_filename(File fd);
#ifndef THREAD
extern void dont_break(void); extern void dont_break(void);
extern void allow_break(void); extern void allow_break(void);
#else
#define dont_break()
#define allow_break()
#endif
extern void my_remember_signal(int signal_number,sig_handler (*func)(int)); extern void my_remember_signal(int signal_number,sig_handler (*func)(int));
extern void caseup(my_string str,uint length); extern void caseup(my_string str,uint length);
extern void casedn(my_string str,uint length); extern void casedn(my_string str,uint length);

View File

@ -68,6 +68,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */
ulong mean_reclength; /* Mean recordlength (if packed) */ ulong mean_reclength; /* Mean recordlength (if packed) */
ulonglong auto_increment; ulonglong auto_increment;
ulonglong key_map; /* Which keys are used */ ulonglong key_map; /* Which keys are used */
char *data_file_name, *index_file_name;
uint keys; /* Number of keys in use */ uint keys; /* Number of keys in use */
uint options; /* HA_OPTIONS_... used */ uint options; /* HA_OPTIONS_... used */
int errkey, /* With key was dupplicated on err */ int errkey, /* With key was dupplicated on err */
@ -86,6 +87,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */
typedef struct st_mi_create_info typedef struct st_mi_create_info
{ {
char *index_file_name, *data_file_name; /* If using symlinks */
ha_rows max_rows; ha_rows max_rows;
ha_rows reloc_rows; ha_rows reloc_rows;
ulonglong auto_increment; ulonglong auto_increment;

View File

@ -127,6 +127,15 @@ typedef struct st_mysql_data {
struct st_mysql_options { struct st_mysql_options {
unsigned int connect_timeout,client_flag; unsigned int connect_timeout,client_flag;
my_bool compress,named_pipe; my_bool compress,named_pipe;
my_bool rpl_probe; /* on connect, find out the replication
role of the server, and establish connections
to all the peers */
my_bool rpl_parse; /* each call to mysql_real_query() will parse
it to tell if it is a read or a write, and
direct it to the slave or the master */
my_bool no_master_reads; /* if set, never read from
a master,only from slave, when doing
a read that is replication-aware */
unsigned int port; unsigned int port;
char *host,*init_command,*user,*password,*unix_socket,*db; char *host,*init_command,*user,*password,*unix_socket,*db;
char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name; char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
@ -145,6 +154,14 @@ enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS,
enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT, enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,
MYSQL_STATUS_USE_RESULT}; MYSQL_STATUS_USE_RESULT};
/* there are three types of queries - the ones that have to go to
the master, the ones that go to a slave, and the adminstrative
type which must happen on the pivot connectioin
*/
enum mysql_rpl_type { MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE,
MYSQL_RPL_ADMIN };
typedef struct st_mysql { typedef struct st_mysql {
NET net; /* Communication parameters */ NET net; /* Communication parameters */
gptr connector_fd; /* ConnectorFd for SSL */ gptr connector_fd; /* ConnectorFd for SSL */
@ -168,6 +185,21 @@ typedef struct st_mysql {
char scramble_buff[9]; char scramble_buff[9];
struct charset_info_st *charset; struct charset_info_st *charset;
unsigned int server_language; unsigned int server_language;
/* pointers to the master, and the next slave
connections, points to itself if lone connection */
struct st_mysql* master, *next_slave;
struct st_mysql* last_used_slave; /* needed for round-robin slave pick */
struct st_mysql* last_used_con; /* needed for send/read/store/use
result to work
correctly with replication
*/
my_bool rpl_pivot; /* set if this is the original connection,
not a master or a slave we have added though
mysql_rpl_probe() or mysql_set_master()/
mysql_add_slave()
*/
} MYSQL; } MYSQL;
@ -242,6 +274,46 @@ int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
int STDCALL mysql_read_query_result(MYSQL *mysql); int STDCALL mysql_read_query_result(MYSQL *mysql);
int STDCALL mysql_real_query(MYSQL *mysql, const char *q, int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
unsigned int length); unsigned int length);
/* perform query on master */
int STDCALL mysql_master_query(MYSQL *mysql, const char *q,
unsigned int length);
int STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
unsigned int length);
/* perform query on slave */
int STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
unsigned int length);
int STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
unsigned int length);
/* enable/disable parsing of all queries to decide
if they go on master or slave */
void STDCALL mysql_enable_rpl_parse(MYSQL* mysql);
void STDCALL mysql_disable_rpl_parse(MYSQL* mysql);
/* get the value of the parse flag */
int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql);
/* enable/disable reads from master */
void STDCALL mysql_enable_reads_from_master(MYSQL* mysql);
void STDCALL mysql_disable_reads_from_master(MYSQL* mysql);
/* get the value of the master read flag */
int STDCALL mysql_reads_from_master_enabled(MYSQL* mysql);
enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len);
/* discover the master and its slaves */
int STDCALL mysql_rpl_probe(MYSQL* mysql);
/* set the master, close/free the old one, if it is not a pivot */
int STDCALL mysql_set_master(MYSQL* mysql, const char* host,
unsigned int port,
const char* user,
const char* passwd);
int STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
unsigned int port,
const char* user,
const char* passwd);
int STDCALL mysql_create_db(MYSQL *mysql, const char *DB); int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
int STDCALL mysql_shutdown(MYSQL *mysql); int STDCALL mysql_shutdown(MYSQL *mysql);

View File

@ -42,7 +42,8 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL, COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL,
COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT, COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT,
COM_CHANGE_USER, COM_BINLOG_DUMP, COM_CHANGE_USER, COM_BINLOG_DUMP,
COM_TABLE_DUMP, COM_CONNECT_OUT}; COM_TABLE_DUMP, COM_CONNECT_OUT,
COM_REGISTER_SLAVE};
#define NOT_NULL_FLAG 1 /* Field can't be NULL */ #define NOT_NULL_FLAG 1 /* Field can't be NULL */
#define PRI_KEY_FLAG 2 /* Field is part of a primary key */ #define PRI_KEY_FLAG 2 /* Field is part of a primary key */
@ -100,15 +101,8 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
#define NET_WRITE_TIMEOUT 60 /* Timeout on write */ #define NET_WRITE_TIMEOUT 60 /* Timeout on write */
#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */ #define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */
#ifndef Vio_defined
#define Vio_defined
#ifdef HAVE_VIO
class Vio; /* Fill Vio class in C++ */
#else
struct st_vio; /* Only C */ struct st_vio; /* Only C */
typedef struct st_vio Vio; typedef struct st_vio Vio;
#endif
#endif
typedef struct st_net { typedef struct st_net {
Vio* vio; Vio* vio;
@ -226,9 +220,6 @@ my_bool check_scramble(const char *, const char *message,
unsigned long *salt,my_bool old_ver); unsigned long *salt,my_bool old_ver);
char *get_tty_password(char *opt_message); char *get_tty_password(char *opt_message);
void hash_password(unsigned long *result, const char *password); void hash_password(unsigned long *result, const char *password);
#ifdef __cplusplus
}
#endif
/* Some other useful functions */ /* Some other useful functions */
@ -236,6 +227,10 @@ void my_init(void);
void load_defaults(const char *conf_file, const char **groups, void load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv); int *argc, char ***argv);
#ifdef __cplusplus
}
#endif
#define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */ #define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */
#ifdef __WIN__ #ifdef __WIN__

View File

@ -205,4 +205,12 @@
#define ER_SLAVE_THREAD 1202 #define ER_SLAVE_THREAD 1202
#define ER_TOO_MANY_USER_CONNECTIONS 1203 #define ER_TOO_MANY_USER_CONNECTIONS 1203
#define ER_SET_CONSTANTS_ONLY 1204 #define ER_SET_CONSTANTS_ONLY 1204
#define ER_ERROR_MESSAGES 205 #define ER_LOCK_WAIT_TIMEOUT 1205
#define ER_LOCK_TABLE_FULL 1206
#define ER_READ_ONLY_TRANSACTION 1207
#define ER_DROP_DB_WITH_READ_LOCK 1208
#define ER_CREATE_DB_WITH_READ_LOCK 1209
#define ER_CONNECT_TO_MASTER 1210
#define ER_QUERY_ON_MASTER 1211
#define ER_SHOW_BINLOG_EVENTS 1212
#define ER_ERROR_MESSAGES 213

View File

@ -22,7 +22,7 @@ extern "C" {
#endif #endif
#define GLOB 0 /* Error maps */ #define GLOB 0 /* Error maps */
#define GLOBERRS 24 /* Max number of error messages in map's */ #define GLOBERRS 27 /* Max number of error messages in map's */
#define EE(X) globerrs[ X ] /* Defines to add error to right map */ #define EE(X) globerrs[ X ] /* Defines to add error to right map */
extern const char * NEAR globerrs[]; /* my_error_messages is here */ extern const char * NEAR globerrs[]; /* my_error_messages is here */
@ -51,6 +51,9 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */
#define EE_CANT_MKDIR 21 #define EE_CANT_MKDIR 21
#define EE_UNKNOWN_CHARSET 22 #define EE_UNKNOWN_CHARSET 22
#define EE_OUT_OF_FILERESOURCES 23 #define EE_OUT_OF_FILERESOURCES 23
#define EE_CANT_READLINK 24
#define EE_CANT_SYMLINK 25
#define EE_REALPATH 26
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,278 +0,0 @@
/* 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 */
/* We implement virtual IO by trapping needed vio_* calls and mapping
* them to different function pointers by type
*/
/*
* Purpose: include file for st_vio that will work with C and C++
*/
#ifndef vio_violite_h_
#define vio_violite_h_
#include "my_net.h" /* needed because of struct in_addr */
/* Simple vio interface in C; The functions are implemented in violite.c */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
#ifndef st_vio_defined
#define st_vio_defined
struct st_vio; /* Only C */
typedef struct st_vio st_vio;
#endif
st_vio* vio_new(my_socket sd,
enum enum_vio_type type,
my_bool localhost);
#ifdef __WIN__
st_vio* vio_new_win32pipe(HANDLE hPipe);
#endif
void vio_delete(st_vio* vio);
#ifdef EMBEDDED_LIBRARY
void vio_reset(st_vio *vio);
#endif
/*
* vio_read and vio_write should have the same semantics
* as read(2) and write(2).
*/
int vio_read( st_vio* vio,
gptr buf, int size);
int vio_write( st_vio* vio,
const gptr buf,
int size);
/*
* Whenever the socket is set to blocking mode or not.
*/
int vio_blocking( st_vio* vio,
my_bool onoff);
my_bool vio_is_blocking( st_vio* vio);
/*
* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible.
*/
int vio_fastsend( st_vio* vio);
/*
* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible.
*/
int vio_keepalive( st_vio* vio,
my_bool onoff);
/*
* Whenever we should retry the last read/write operation.
*/
my_bool vio_should_retry( st_vio* vio);
/*
* When the workday is over...
*/
int vio_close(st_vio* vio);
/*
* Short text description of the socket for those, who are curious..
*/
const char* vio_description( st_vio* vio);
/* Return the type of the connection */
enum enum_vio_type vio_type(st_vio* vio);
/* Return last error number */
int vio_errno(st_vio *vio);
/* Get socket number */
my_socket vio_fd(st_vio *vio);
/*
* Remote peer's address and name in text form.
*/
my_bool vio_peer_addr(st_vio * vio, char *buf);
/* Remotes in_addr */
void vio_in_addr(st_vio *vio, struct in_addr *in);
/* Return 1 if there is data to be read */
my_bool vio_poll_read(st_vio *vio,uint timeout);
#ifdef __cplusplus
}
#endif
#endif /* vio_violite_h_ */
#ifdef HAVE_VIO
#ifndef DONT_MAP_VIO
#define vio_delete(vio) (vio)->viodelete(vio)
#define vio_errno(vio) (vio)->vioerrno(vio)
#define vio_read(vio, buf, size) (vio)->read(vio,buf,size)
#define vio_write(vio, buf, size) (vio)->write(vio, buf, size)
#define vio_blocking(vio, set_blocking_mode) (vio)->vioblocking(vio, set_blocking_mode)
#define vio_is_blocking(vio) (vio)->is_blocking(vio)
#define vio_fastsend(vio) (vio)->fastsend(vio)
#define vio_keepalive(vio, set_keep_alive) (vio)->viokeepalive(vio, set_keep_alive)
#define vio_should_retry(vio) (vio)->should_retry(vio)
#define vio_close(vio) ((vio)->vioclose)(vio)
#define vio_peer_addr(vio, buf) (vio)->peer_addr(vio, buf)
#define vio_in_addr(vio, in) (vio)->in_addr(vio, in)
#define vio_poll_read(vio,timeout) (vio)->poll_read(vio,timeout)
#endif /* !DONT_MAP_VIO */
#endif /* HAVE_VIO */
#ifdef HAVE_OPENSSL
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/asn1.h>
#include "my_net.h" /* needed because of struct in_addr */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef st_vio_defined
#define st_vio_defined
struct st_vio; /* Only C */
typedef struct st_vio st_vio;
#endif
void vio_ssl_delete(st_vio* vio);
#ifdef EMBEDDED_LIBRARY
void vio_reset(st_vio *vio);
#endif
int vio_ssl_read(st_vio* vio,gptr buf, int size);
int vio_ssl_write(st_vio* vio,const gptr buf,int size);
int vio_ssl_blocking(st_vio* vio,my_bool onoff);
my_bool vio_ssl_is_blocking(st_vio* vio);
/* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. */
int vio_ssl_fastsend(st_vio* vio);
/* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible. */
int vio_ssl_keepalive(st_vio* vio, my_bool onoff);
/* Whenever we should retry the last read/write operation. */
my_bool vio_ssl_should_retry(st_vio* vio);
/* When the workday is over... */
int vio_ssl_close(st_vio* vio);
/* Return last error number */
int vio_ssl_errno(st_vio *vio);
my_bool vio_ssl_peer_addr(st_vio * vio, char *buf);
void vio_ssl_in_addr(st_vio *vio, struct in_addr *in);
/* Return 1 if there is data to be read */
my_bool vio_ssl_poll_read(st_vio *vio,uint timeout);
#ifdef HAVE_OPENSSL
/* Single copy for server */
struct st_VioSSLAcceptorFd
{
SSL_CTX* ssl_context_;
SSL_METHOD* ssl_method_;
struct st_VioSSLAcceptorFd* session_id_context_;
enum {
state_connect = 1,
state_accept = 2
};
BIO* bio_;
char *ssl_cip_;
char desc_[100];
st_vio* sd_;
/* function pointers which are only once for SSL server */
// struct st_vio *(*sslaccept)(struct st_VioSSLAcceptorFd*,st_vio*);
};
/* One copy for client */
struct st_VioSSLConnectorFd
{
BIO* bio_;
gptr ssl_;
SSL_CTX* ssl_context_;
SSL_METHOD* ssl_method_;
/* function pointers which are only once for SSL client */
};
struct st_vio *sslaccept(struct st_VioSSLAcceptorFd*, struct st_vio*);
struct st_vio *sslconnect(struct st_VioSSLConnectorFd*, struct st_vio*);
#else /* HAVE_OPENSSL */
/* This dummy is required to maintain proper size of st_mysql in mysql.h */
struct st_VioSSLConnectorFd {};
#endif /* HAVE_OPENSSL */
struct st_VioSSLConnectorFd *new_VioSSLConnectorFd(
const char* key_file,const char* cert_file,const char* ca_file,const char* ca_path);
struct st_VioSSLAcceptorFd *new_VioSSLAcceptorFd(
const char* key_file,const char* cert_file,const char* ca_file,const char* ca_path);
struct st_vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, struct st_vio * sd,int state);
static int
init_bio_(struct st_VioSSLAcceptorFd* fd, struct st_vio* sd, int state, int bio_flags);
static void
report_errors();
#ifdef __cplusplus
}
#endif
#endif /* HAVE_OPENSSL */
#ifndef __WIN__
#define HANDLE void *
#endif
/* This structure is for every connection on both sides */
struct st_vio
{
my_socket sd; /* my_socket - real or imaginary */
HANDLE hPipe;
my_bool localhost; /* Are we from localhost? */
int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
struct sockaddr_in local; /* Local internet address */
struct sockaddr_in remote; /* Remote internet address */
enum enum_vio_type type; /* Type of connection */
char desc[30]; /* String description */
#ifdef HAVE_VIO
/* function pointers. They are similar for socket/SSL/whatever */
void (*viodelete)(st_vio *);
int(*vioerrno)(st_vio*);
int(*read)(st_vio*, gptr, int);
int(*write)(st_vio*, gptr, int);
int(*vioblocking)(st_vio*, my_bool);
my_bool(*is_blocking)(st_vio*);
int(*viokeepalive)(st_vio *, my_bool);
int(*fastsend)(st_vio *);
my_bool(*peer_addr)(st_vio*, gptr);
void(*in_addr)(st_vio*, struct in_addr*);
my_bool(*should_retry)(st_vio *);
int(*vioclose)(st_vio *);
my_bool(*poll_read)(st_vio *,uint);
#ifdef HAVE_OPENSSL
BIO* bio_;
SSL* ssl_;
my_bool open_;
#endif /* HAVE_OPENSSL */
#endif /* HAVE_VIO */
};

View File

@ -25,9 +25,6 @@
#include "my_net.h" /* needed because of struct in_addr */ #include "my_net.h" /* needed because of struct in_addr */
#ifdef HAVE_VIO
#include <Vio.h> /* Full VIO interface */
#else
/* Simple vio interface in C; The functions are implemented in violite.c */ /* Simple vio interface in C; The functions are implemented in violite.c */
@ -35,14 +32,12 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#ifndef Vio_defined
#define Vio_defined
struct st_vio; /* Only C */
typedef struct st_vio Vio;
#endif
enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET, enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL}; VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
#ifndef __WIN__
#define HANDLE void *
#endif
Vio* vio_new(my_socket sd, Vio* vio_new(my_socket sd,
enum enum_vio_type type, enum enum_vio_type type,
@ -54,6 +49,10 @@ void vio_delete(Vio* vio);
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
void vio_reset(Vio *vio); void vio_reset(Vio *vio);
#else
void vio_reset(Vio* vio, enum enum_vio_type type,
my_socket sd, HANDLE hPipe,
my_bool localhost);
#endif #endif
/* /*
@ -87,7 +86,7 @@ my_bool vio_should_retry( Vio* vio);
/* /*
* When the workday is over... * When the workday is over...
*/ */
int vio_close( Vio* vio); int vio_close(Vio* vio);
/* /*
* Short text description of the socket for those, who are curious.. * Short text description of the socket for those, who are curious..
*/ */
@ -97,15 +96,15 @@ const char* vio_description( Vio* vio);
enum enum_vio_type vio_type(Vio* vio); enum enum_vio_type vio_type(Vio* vio);
/* Return last error number */ /* Return last error number */
int vio_errno(Vio *vio); int vio_errno(Vio*vio);
/* Get socket number */ /* Get socket number */
my_socket vio_fd(Vio *vio); my_socket vio_fd(Vio*vio);
/* /*
* Remote peer's address and name in text form. * Remote peer's address and name in text form.
*/ */
my_bool vio_peer_addr(Vio * vio, char *buf); my_bool vio_peer_addr(Vio* vio, char *buf);
/* Remotes in_addr */ /* Remotes in_addr */
@ -117,5 +116,142 @@ my_bool vio_poll_read(Vio *vio,uint timeout);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* HAVE_VIO */
#endif /* vio_violite_h_ */ #endif /* vio_violite_h_ */
#ifdef HAVE_VIO
#ifndef DONT_MAP_VIO
#define vio_delete(vio) (vio)->viodelete(vio)
#define vio_errno(vio) (vio)->vioerrno(vio)
#define vio_read(vio, buf, size) (vio)->read(vio,buf,size)
#define vio_write(vio, buf, size) (vio)->write(vio, buf, size)
#define vio_blocking(vio, set_blocking_mode) (vio)->vioblocking(vio, set_blocking_mode)
#define vio_is_blocking(vio) (vio)->is_blocking(vio)
#define vio_fastsend(vio) (vio)->fastsend(vio)
#define vio_keepalive(vio, set_keep_alive) (vio)->viokeepalive(vio, set_keep_alive)
#define vio_should_retry(vio) (vio)->should_retry(vio)
#define vio_close(vio) ((vio)->vioclose)(vio)
#define vio_peer_addr(vio, buf) (vio)->peer_addr(vio, buf)
#define vio_in_addr(vio, in) (vio)->in_addr(vio, in)
#define vio_poll_read(vio,timeout) (vio)->poll_read(vio,timeout)
#endif /* !DONT_MAP_VIO */
#endif /* HAVE_VIO */
#ifdef HAVE_OPENSSL
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/asn1.h>
#include "my_net.h" /* needed because of struct in_addr */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void vio_ssl_delete(Vio* vio);
int vio_ssl_read(Vio* vio,gptr buf, int size);
int vio_ssl_write(Vio* vio,const gptr buf,int size);
int vio_ssl_blocking(Vio* vio,my_bool onoff);
my_bool vio_ssl_is_blocking(Vio* vio);
/* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. */
int vio_ssl_fastsend(Vio* vio);
/* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible. */
int vio_ssl_keepalive(Vio* vio, my_bool onoff);
/* Whenever we should retry the last read/write operation. */
my_bool vio_ssl_should_retry(Vio* vio);
/* When the workday is over... */
int vio_ssl_close(Vio* vio);
/* Return last error number */
int vio_ssl_errno(Vio *vio);
my_bool vio_ssl_peer_addr(Vio* vio, char *buf);
void vio_ssl_in_addr(Vio *vio, struct in_addr *in);
/* Return 1 if there is data to be read */
my_bool vio_ssl_poll_read(Vio *vio,uint timeout);
#ifdef HAVE_OPENSSL
/* Single copy for server */
struct st_VioSSLAcceptorFd
{
SSL_CTX* ssl_context_;
SSL_METHOD* ssl_method_;
struct st_VioSSLAcceptorFd* session_id_context_;
enum {
state_connect = 1,
state_accept = 2
};
BIO* bio_;
char *ssl_cip_;
char desc_[100];
Vio* sd_;
/* function pointers which are only once for SSL server
Vio*(*sslaccept)(struct st_VioSSLAcceptorFd*,Vio*); */
};
/* One copy for client */
struct st_VioSSLConnectorFd
{
SSL_CTX* ssl_context_;
SSL_METHOD* ssl_method_;
/* function pointers which are only once for SSL client */
};
Vio *sslaccept(struct st_VioSSLAcceptorFd*, Vio*);
Vio *sslconnect(struct st_VioSSLConnectorFd*, Vio*);
#else /* HAVE_OPENSSL */
/* This dummy is required to maintain proper size of st_mysql in mysql.h */
struct st_VioSSLConnectorFd {};
#endif /* HAVE_OPENSSL */
struct st_VioSSLConnectorFd *new_VioSSLConnectorFd(
const char* key_file,const char* cert_file,const char* ca_file,const char* ca_path);
struct st_VioSSLAcceptorFd *new_VioSSLAcceptorFd(
const char* key_file,const char* cert_file,const char* ca_file,const char* ca_path);
Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state);
#ifdef __cplusplus
}
#endif
#endif /* HAVE_OPENSSL */
#ifndef EMBEDDED_LIBRARY
/* This structure is for every connection on both sides */
struct st_vio
{
my_socket sd; /* my_socket - real or imaginary */
HANDLE hPipe;
my_bool localhost; /* Are we from localhost? */
int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
struct sockaddr_in local; /* Local internet address */
struct sockaddr_in remote; /* Remote internet address */
enum enum_vio_type type; /* Type of connection */
char desc[30]; /* String description */
#ifdef HAVE_VIO
/* function pointers. They are similar for socket/SSL/whatever */
void (*viodelete)(Vio*);
int(*vioerrno)(Vio*);
int(*read)(Vio*, gptr, int);
int(*write)(Vio*, gptr, int);
int(*vioblocking)(Vio*, my_bool);
my_bool(*is_blocking)(Vio*);
int(*viokeepalive)(Vio*, my_bool);
int(*fastsend)(Vio*);
my_bool(*peer_addr)(Vio*, gptr);
void(*in_addr)(Vio*, struct in_addr*);
my_bool(*should_retry)(Vio*);
int(*vioclose)(Vio*);
my_bool(*poll_read)(Vio*,uint);
#ifdef HAVE_OPENSSL
BIO* bio_;
SSL* ssl_;
my_bool open_;
#endif /* HAVE_OPENSSL */
#endif /* HAVE_VIO */
};
#endif /* EMBEDDED_LIBRARY */

View File

@ -2238,12 +2238,93 @@ btr_check_node_ptr(
return(TRUE); return(TRUE);
} }
/****************************************************************
Checks the size and number of fields in a record based on the definition of
the index. */
static
ibool
btr_index_rec_validate(
/*====================*/
/* out: TRUE if ok */
rec_t* rec, /* in: index record */
dict_index_t* index) /* in: index */
{
dtype_t* type;
byte* data;
ulint len;
ulint n;
ulint i;
n = dict_index_get_n_fields(index);
if (rec_get_n_fields(rec) != n) {
fprintf(stderr, "Record has %lu fields, should have %lu\n",
rec_get_n_fields(rec), n);
return(FALSE);
}
for (i = 0; i < n; i++) {
data = rec_get_nth_field(rec, i, &len);
type = dict_index_get_nth_type(index, i);
if (len != UNIV_SQL_NULL && dtype_is_fixed_size(type)
&& len != dtype_get_fixed_size(type)) {
fprintf(stderr,
"Record field %lu len is %lu, should be %lu\n",
i, len, dtype_get_fixed_size(type));
return(FALSE);
}
}
return(TRUE);
}
/****************************************************************
Checks the size and number of fields in records based on the definition of
the index. */
static
ibool
btr_index_page_validate(
/*====================*/
/* out: TRUE if ok */
page_t* page, /* in: index page */
dict_index_t* index) /* in: index */
{
rec_t* rec;
page_cur_t cur;
ibool ret = TRUE;
page_cur_set_before_first(page, &cur);
page_cur_move_to_next(&cur);
for (;;) {
rec = (&cur)->rec;
if (page_cur_is_after_last(&cur)) {
break;
}
if (!btr_index_rec_validate(rec, index)) {
ret = FALSE;
}
page_cur_move_to_next(&cur);
}
return(ret);
}
/**************************************************************** /****************************************************************
Validates index tree level. */ Validates index tree level. */
static static
void ibool
btr_validate_level( btr_validate_level(
/*===============*/ /*===============*/
/* out: TRUE if ok */
dict_tree_t* tree, /* in: index tree */ dict_tree_t* tree, /* in: index tree */
ulint level) /* in: level number */ ulint level) /* in: level number */
{ {
@ -2260,7 +2341,9 @@ btr_validate_level(
page_cur_t cursor; page_cur_t cursor;
mem_heap_t* heap; mem_heap_t* heap;
dtuple_t* node_ptr_tuple; dtuple_t* node_ptr_tuple;
ibool ret = TRUE;
dict_index_t* index;
mtr_start(&mtr); mtr_start(&mtr);
page = btr_root_get(tree, &mtr); page = btr_root_get(tree, &mtr);
@ -2278,13 +2361,31 @@ btr_validate_level(
page = btr_node_ptr_get_child(node_ptr, &mtr); page = btr_node_ptr_get_child(node_ptr, &mtr);
} }
index = UT_LIST_GET_FIRST(tree->tree_indexes);
/* Now we are on the desired level */ /* Now we are on the desired level */
loop: loop:
mtr_x_lock(dict_tree_get_lock(tree), &mtr); mtr_x_lock(dict_tree_get_lock(tree), &mtr);
/* Check ordering of records */ /* Check ordering etc. of records */
page_validate(page, UT_LIST_GET_FIRST(tree->tree_indexes));
if (!page_validate(page, index)) {
fprintf(stderr, "Error in page %lu in index %s\n",
buf_frame_get_page_no(page), index->name);
ret = FALSE;
}
if (level == 0) {
if (!btr_index_page_validate(page, index)) {
fprintf(stderr,
"Error in page %lu in index %s\n",
buf_frame_get_page_no(page), index->name);
ret = FALSE;
}
}
ut_a(btr_page_get_level(page, &mtr) == level); ut_a(btr_page_get_level(page, &mtr) == level);
right_page_no = btr_page_get_next(page, &mtr); right_page_no = btr_page_get_next(page, &mtr);
@ -2374,14 +2475,17 @@ loop:
goto loop; goto loop;
} }
return(ret);
} }
/****************************************************************** /******************************************************************
Checks the consistency of an index tree. */ Checks the consistency of an index tree. */
void ibool
btr_validate_tree( btr_validate_tree(
/*==============*/ /*==============*/
/* out: TRUE if ok */
dict_tree_t* tree) /* in: tree */ dict_tree_t* tree) /* in: tree */
{ {
mtr_t mtr; mtr_t mtr;
@ -2397,8 +2501,15 @@ btr_validate_tree(
for (i = 0; i <= n; i++) { for (i = 0; i <= n; i++) {
btr_validate_level(tree, n - i); if (!btr_validate_level(tree, n - i)) {
mtr_commit(&mtr);
return(FALSE);
}
} }
mtr_commit(&mtr); mtr_commit(&mtr);
return(TRUE);
} }

View File

@ -163,9 +163,14 @@ btr_cur_search_to_nth_level(
BTR_INSERT and BTR_ESTIMATE; BTR_INSERT and BTR_ESTIMATE;
cursor->left_page is used to store a pointer cursor->left_page is used to store a pointer
to the left neighbor page, in the cases to the left neighbor page, in the cases
BTR_SEARCH_PREV and BTR_MODIFY_PREV */ BTR_SEARCH_PREV and BTR_MODIFY_PREV;
NOTE that if has_search_latch
is != 0, we maybe do not have a latch set
on the cursor page, we assume
the caller uses his search latch
to protect the record! */
btr_cur_t* cursor, /* in/out: tree cursor; the cursor page is btr_cur_t* cursor, /* in/out: tree cursor; the cursor page is
s- or x-latched */ s- or x-latched, but see also above! */
ulint has_search_latch,/* in: info on the latch mode the ulint has_search_latch,/* in: info on the latch mode the
caller currently has on btr_search_latch: caller currently has on btr_search_latch:
RW_S_LATCH, or 0 */ RW_S_LATCH, or 0 */

View File

@ -246,6 +246,12 @@ btr_pcur_restore_position(
&& btr_pcur_is_on_user_rec(cursor, mtr) && btr_pcur_is_on_user_rec(cursor, mtr)
&& (0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor)))) { && (0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor)))) {
/* We have to store the NEW value for the modify clock, since
the cursor can now be on a different page! */
cursor->modify_clock = buf_frame_get_modify_clock(
buf_frame_align(
btr_pcur_get_rec(cursor)));
mem_heap_free(heap); mem_heap_free(heap);
return(TRUE); return(TRUE);

View File

@ -601,7 +601,12 @@ btr_search_guess_on_hash(
btr_search_t* info, /* in: index search info */ btr_search_t* info, /* in: index search info */
dtuple_t* tuple, /* in: logical record */ dtuple_t* tuple, /* in: logical record */
ulint mode, /* in: PAGE_CUR_L, ... */ ulint mode, /* in: PAGE_CUR_L, ... */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */ ulint latch_mode, /* in: BTR_SEARCH_LEAF, ...;
NOTE that only if has_search_latch
is 0, we will have a latch set on
the cursor page, otherwise we assume
the caller uses his search latch
to protect the record! */
btr_cur_t* cursor, /* out: tree cursor */ btr_cur_t* cursor, /* out: tree cursor */
ulint has_search_latch,/* in: latch mode the caller ulint has_search_latch,/* in: latch mode the caller
currently has on btr_search_latch: currently has on btr_search_latch:
@ -722,7 +727,9 @@ btr_search_guess_on_hash(
} }
if (!success) { if (!success) {
btr_leaf_page_release(page, latch_mode, mtr); if (!has_search_latch) {
btr_leaf_page_release(page, latch_mode, mtr);
}
goto failure; goto failure;
} }

View File

@ -241,6 +241,8 @@ buf_block_init(
block->modify_clock = ut_dulint_zero; block->modify_clock = ut_dulint_zero;
block->file_page_was_freed = FALSE;
rw_lock_create(&(block->lock)); rw_lock_create(&(block->lock));
ut_ad(rw_lock_validate(&(block->lock))); ut_ad(rw_lock_validate(&(block->lock)));
@ -542,6 +544,64 @@ buf_page_peek(
return(FALSE); return(FALSE);
} }
/************************************************************************
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
reallocated. */
buf_block_t*
buf_page_set_file_page_was_freed(
/*=============================*/
/* out: control block if found from page hash table,
otherwise NULL */
ulint space, /* in: space id */
ulint offset) /* in: page number */
{
buf_block_t* block;
mutex_enter_fast(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset);
if (block) {
block->file_page_was_freed = TRUE;
}
mutex_exit(&(buf_pool->mutex));
return(block);
}
/************************************************************************
Sets file_page_was_freed FALSE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
reallocated. */
buf_block_t*
buf_page_reset_file_page_was_freed(
/*===============================*/
/* out: control block if found from page hash table,
otherwise NULL */
ulint space, /* in: space id */
ulint offset) /* in: page number */
{
buf_block_t* block;
mutex_enter_fast(&(buf_pool->mutex));
block = buf_page_hash_get(space, offset);
if (block) {
block->file_page_was_freed = FALSE;
}
mutex_exit(&(buf_pool->mutex));
return(block);
}
/************************************************************************ /************************************************************************
This is the general function used to get access to a database page. */ This is the general function used to get access to a database page. */
@ -646,6 +706,9 @@ loop:
block->accessed = TRUE; block->accessed = TRUE;
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->file_page_was_freed == FALSE);
#endif
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
@ -842,6 +905,9 @@ buf_page_optimistic_get_func(
ut_ad(block->buf_fix_count > 0); ut_ad(block->buf_fix_count > 0);
ut_ad(block->state == BUF_BLOCK_FILE_PAGE); ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->file_page_was_freed == FALSE);
#endif
if (!accessed) { if (!accessed) {
/* In the case of a first access, try to apply linear /* In the case of a first access, try to apply linear
read-ahead */ read-ahead */
@ -949,6 +1015,9 @@ buf_page_get_known_nowait(
#endif #endif
ut_ad(block->buf_fix_count > 0); ut_ad(block->buf_fix_count > 0);
ut_ad(block->state == BUF_BLOCK_FILE_PAGE); ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->file_page_was_freed == FALSE);
#endif
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
ut_a((mode == BUF_KEEP_OLD) ut_a((mode == BUF_KEEP_OLD)
@ -996,6 +1065,8 @@ buf_page_init(
block->n_hash_helps = 0; block->n_hash_helps = 0;
block->is_hashed = FALSE; block->is_hashed = FALSE;
block->file_page_was_freed = FALSE;
} }
/************************************************************************ /************************************************************************
@ -1126,6 +1197,8 @@ buf_page_create(
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
ut_a(ibuf_count_get(block->space, block->offset) == 0); ut_a(ibuf_count_get(block->space, block->offset) == 0);
#endif #endif
block->file_page_was_freed = FALSE;
/* Page can be found in buf_pool */ /* Page can be found in buf_pool */
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));

View File

@ -182,8 +182,8 @@ buf_flush_write_complete(
buf_pool->LRU_flush_ended++; buf_pool->LRU_flush_ended++;
} }
/* printf("n pending flush %lu\n", /* printf("n pending flush %lu\n",
buf_pool->n_flush[block->flush_type]); */ buf_pool->n_flush[block->flush_type]); */
if ((buf_pool->n_flush[block->flush_type] == 0) if ((buf_pool->n_flush[block->flush_type] == 0)
&& (buf_pool->init_flush[block->flush_type] == FALSE)) { && (buf_pool->init_flush[block->flush_type] == FALSE)) {
@ -421,6 +421,8 @@ buf_flush_try_neighbors(
/* In simulated aio we wake up the i/o-handler threads now that /* In simulated aio we wake up the i/o-handler threads now that
we have posted a batch of writes: */ we have posted a batch of writes: */
/* printf("Flush count %lu ; Waking i/o handlers\n", count); */
os_aio_simulated_wake_handler_threads(); os_aio_simulated_wake_handler_threads();
return(count); return(count);

View File

@ -260,9 +260,9 @@ loop:
*/ */
if (n_iterations > 30) { if (n_iterations > 30) {
fprintf(stderr, fprintf(stderr,
"Innobase: Warning: difficult to find free blocks from\n" "InnoDB: Warning: difficult to find free blocks from\n"
"Innobase: the buffer pool! Consider increasing the\n" "InnoDB: the buffer pool (%lu search iterations)! Consider\n"
"Innobase: buffer pool size.\n"); "InnoDB: increasing the buffer pool size.\n", n_iterations);
} }
} }

View File

@ -18,6 +18,7 @@ Created 11/5/1995 Heikki Tuuri
#include "log0recv.h" #include "log0recv.h"
#include "trx0sys.h" #include "trx0sys.h"
#include "os0file.h" #include "os0file.h"
#include "srv0start.h"
/* The size in blocks of the area where the random read-ahead algorithm counts /* The size in blocks of the area where the random read-ahead algorithm counts
the accessed pages when deciding whether to read-ahead */ the accessed pages when deciding whether to read-ahead */
@ -132,10 +133,16 @@ buf_read_ahead_random(
ulint low, high; ulint low, high;
ulint i; ulint i;
if (ibuf_bitmap_page(offset)) { if (srv_startup_is_before_trx_rollback_phase) {
/* No read-ahead to avoid thread deadlocks */
return(0);
}
/* If it is an ibuf bitmap page, we do no read-ahead, as if (ibuf_bitmap_page(offset) || trx_sys_hdr_page(space, offset)) {
that could break the ibuf page access order */
/* If it is an ibuf bitmap page or trx sys hdr, we do
no read-ahead, as that could break the ibuf page access
order */
return(0); return(0);
} }
@ -301,9 +308,16 @@ buf_read_ahead_linear(
ulint low, high; ulint low, high;
ulint i; ulint i;
if (ibuf_bitmap_page(offset)) { if (srv_startup_is_before_trx_rollback_phase) {
/* If it is an ibuf bitmap page, we do no read-ahead, as /* No read-ahead to avoid thread deadlocks */
that could break the ibuf page access order */ return(0);
}
if (ibuf_bitmap_page(offset) || trx_sys_hdr_page(space, offset)) {
/* If it is an ibuf bitmap page or trx sys hdr, we do
no read-ahead, as that could break the ibuf page access
order */
return(0); return(0);
} }

View File

@ -38,6 +38,7 @@ AC_CHECK_HEADERS(aio.h sched.h)
AC_CHECK_SIZEOF(int, 4) AC_CHECK_SIZEOF(int, 4)
AC_CHECK_FUNCS(sched_yield) AC_CHECK_FUNCS(sched_yield)
AC_CHECK_FUNCS(fdatasync) AC_CHECK_FUNCS(fdatasync)
AC_CHECK_FUNCS(localtime_r)
#AC_C_INLINE Already checked in MySQL #AC_C_INLINE Already checked in MySQL
AC_C_BIGENDIAN AC_C_BIGENDIAN
@ -95,6 +96,11 @@ case "$target_os" in
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";; CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
esac esac
case "$target" in
i[[4567]]86-*-*)
CFLAGS="$CFLAGS -DUNIV_INTEL_X86";;
esac
AC_OUTPUT(Makefile os/Makefile ut/Makefile btr/Makefile AC_OUTPUT(Makefile os/Makefile ut/Makefile btr/Makefile
buf/Makefile com/Makefile data/Makefile buf/Makefile com/Makefile data/Makefile
dict/Makefile dyn/Makefile dict/Makefile dyn/Makefile

View File

@ -313,6 +313,11 @@ dict_boot(void)
mtr_commit(&mtr); mtr_commit(&mtr);
/*-------------------------*/ /*-------------------------*/
/* Initialize the insert buffer table and index for each tablespace */
ibuf_init_at_db_start();
/* Load definitions of other indexes on system tables */ /* Load definitions of other indexes on system tables */
dict_load_sys_table(dict_sys->sys_tables); dict_load_sys_table(dict_sys->sys_tables);
@ -320,10 +325,6 @@ dict_boot(void)
dict_load_sys_table(dict_sys->sys_indexes); dict_load_sys_table(dict_sys->sys_indexes);
dict_load_sys_table(dict_sys->sys_fields); dict_load_sys_table(dict_sys->sys_fields);
/* Initialize the insert buffer table and index for each tablespace */
ibuf_init_at_db_start();
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
} }

View File

@ -127,11 +127,9 @@ typedef byte fseg_inode_t;
page number within space, FIL_NULL page number within space, FIL_NULL
means that the slot is not in use */ means that the slot is not in use */
/*-------------------------------------*/ /*-------------------------------------*/
#define FSEG_INODE_SIZE (16 + 3 * FLST_BASE_NODE_SIZE +\ #define FSEG_INODE_SIZE (16 + 3 * FLST_BASE_NODE_SIZE + FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
#define FSP_SEG_INODES_PER_PAGE ((UNIV_PAGE_SIZE - FSEG_ARR_OFFSET - 10)\ #define FSP_SEG_INODES_PER_PAGE ((UNIV_PAGE_SIZE - FSEG_ARR_OFFSET - 10) / FSEG_INODE_SIZE)
/ FSEG_INODE_SIZE)
/* Number of segment inodes which fit on a /* Number of segment inodes which fit on a
single page */ single page */
@ -198,8 +196,7 @@ the extent are free and which contain old tuple version to clean. */
/* File extent data structure size in bytes. The "+ 7 ) / 8" part in the /* File extent data structure size in bytes. The "+ 7 ) / 8" part in the
definition rounds the number of bytes upward. */ definition rounds the number of bytes upward. */
#define XDES_SIZE (XDES_BITMAP +\ #define XDES_SIZE (XDES_BITMAP + (FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE + 7) / 8)
(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE + 7) / 8)
/* Offset of the descriptor array on a descriptor page */ /* Offset of the descriptor array on a descriptor page */
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE) #define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
@ -2539,6 +2536,10 @@ fseg_free_page(
seg_inode = fseg_inode_get(seg_header, mtr); seg_inode = fseg_inode_get(seg_header, mtr);
fseg_free_page_low(seg_inode, space, page, mtr); fseg_free_page_low(seg_inode, space, page, mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
buf_page_set_file_page_was_freed(space, page);
#endif
} }
/************************************************************************** /**************************************************************************
@ -2602,6 +2603,14 @@ fseg_free_extent(
} }
fsp_free_extent(space, page, mtr); fsp_free_extent(space, page, mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
for (i = 0; i < FSP_EXTENT_SIZE; i++) {
buf_page_set_file_page_was_freed(space,
first_page_in_extent + i);
}
#endif
} }
/************************************************************************** /**************************************************************************
@ -2633,6 +2642,14 @@ fseg_free_step(
MTR_MEMO_X_LOCK)); MTR_MEMO_X_LOCK));
mtr_x_lock(fil_space_get_latch(space), mtr); mtr_x_lock(fil_space_get_latch(space), mtr);
descr = xdes_get_descriptor(space, buf_frame_get_page_no(header), mtr);
/* Check that the header resides on a page which has not been
freed yet */
ut_a(descr);
ut_a(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header)
% FSP_EXTENT_SIZE, mtr) == FALSE);
inode = fseg_inode_get(header, mtr); inode = fseg_inode_get(header, mtr);
descr = fseg_get_first_extent(inode, mtr); descr = fseg_get_first_extent(inode, mtr);
@ -2647,7 +2664,6 @@ fseg_free_step(
} }
/* Free a frag page */ /* Free a frag page */
n = fseg_find_last_used_frag_page_slot(inode, mtr); n = fseg_find_last_used_frag_page_slot(inode, mtr);
if (n == ULINT_UNDEFINED) { if (n == ULINT_UNDEFINED) {
@ -2659,6 +2675,16 @@ fseg_free_step(
fseg_free_page_low(inode, space, fseg_free_page_low(inode, space,
fseg_get_nth_frag_page_no(inode, n, mtr), mtr); fseg_get_nth_frag_page_no(inode, n, mtr), mtr);
n = fseg_find_last_used_frag_page_slot(inode, mtr);
if (n == ULINT_UNDEFINED) {
/* Freeing completed: free the segment inode */
fsp_free_seg_inode(space, inode, mtr);
return(TRUE);
}
return(FALSE); return(FALSE);
} }

View File

@ -1382,6 +1382,9 @@ ibuf_remove_free_page(
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
space, page_no, &mtr); space, page_no, &mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
buf_page_reset_file_page_was_freed(space, page_no);
#endif
ibuf_enter(); ibuf_enter();
mutex_enter(&ibuf_mutex); mutex_enter(&ibuf_mutex);
@ -1413,6 +1416,9 @@ ibuf_remove_free_page(
ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF, ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
FALSE, &mtr); FALSE, &mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
buf_page_set_file_page_was_freed(space, page_no);
#endif
mtr_commit(&mtr); mtr_commit(&mtr);
mutex_exit(&ibuf_mutex); mutex_exit(&ibuf_mutex);
@ -2431,6 +2437,8 @@ ibuf_merge_or_delete_for_page(
block = buf_block_align(page); block = buf_block_align(page);
rw_lock_x_lock_move_ownership(&(block->lock)); rw_lock_x_lock_move_ownership(&(block->lock));
ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX);
} }
n_inserts = 0; n_inserts = 0;

View File

@ -376,9 +376,10 @@ btr_print_tree(
/****************************************************************** /******************************************************************
Checks the consistency of an index tree. */ Checks the consistency of an index tree. */
void ibool
btr_validate_tree( btr_validate_tree(
/*==============*/ /*==============*/
/* out: TRUE if ok */
dict_tree_t* tree); /* in: tree */ dict_tree_t* tree); /* in: tree */
#define BTR_N_LEAF_PAGES 1 #define BTR_N_LEAF_PAGES 1

View File

@ -98,12 +98,18 @@ btr_cur_search_to_nth_level(
the previous page of the record! Inserts the previous page of the record! Inserts
should always be made using PAGE_CUR_LE to should always be made using PAGE_CUR_LE to
search the position! */ search the position! */
ulint latch_mode, /* in: BTR_SEARCH_LEAF, ...; ulint latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with
BTR_INSERT and BTR_ESTIMATE;
cursor->left_page is used to store a pointer cursor->left_page is used to store a pointer
to the left neighbor page, in the cases to the left neighbor page, in the cases
BTR_SEARCH_PREV and BTR_MODIFY_PREV */ BTR_SEARCH_PREV and BTR_MODIFY_PREV;
btr_cur_t* cursor, /* out: tree cursor; the cursor page is s- or NOTE that if has_search_latch
x-latched */ is != 0, we maybe do not have a latch set
on the cursor page, we assume
the caller uses his search latch
to protect the record! */
btr_cur_t* cursor, /* in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
ulint has_search_latch,/* in: latch mode the caller ulint has_search_latch,/* in: latch mode the caller
currently has on btr_search_latch: currently has on btr_search_latch:
RW_S_LATCH, or 0 */ RW_S_LATCH, or 0 */

View File

@ -87,7 +87,11 @@ btr_pcur_open_with_no_init(
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page of the may end up on the previous page of the
record! */ record! */
ulint latch_mode,/* in: BTR_SEARCH_LEAF, ... */ ulint latch_mode,/* in: BTR_SEARCH_LEAF, ...;
NOTE that if has_search_latch != 0 then
we maybe do not acquire a latch on the cursor
page, but assume that the caller uses his
btr search latch to protect the record! */
btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */ btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
ulint has_search_latch,/* in: latch mode the caller ulint has_search_latch,/* in: latch mode the caller
currently has on btr_search_latch: currently has on btr_search_latch:

View File

@ -492,7 +492,11 @@ btr_pcur_open_with_no_init(
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page of the may end up on the previous page of the
record! */ record! */
ulint latch_mode,/* in: BTR_SEARCH_LEAF, ... */ ulint latch_mode,/* in: BTR_SEARCH_LEAF, ...;
NOTE that if has_search_latch != 0 then
we maybe do not acquire a latch on the cursor
page, but assume that the caller uses his
btr search latch to protect the record! */
btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */ btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
ulint has_search_latch,/* in: latch mode the caller ulint has_search_latch,/* in: latch mode the caller
currently has on btr_search_latch: currently has on btr_search_latch:

View File

@ -293,6 +293,32 @@ buf_page_peek_block(
ulint space, /* in: space id */ ulint space, /* in: space id */
ulint offset);/* in: page number */ ulint offset);/* in: page number */
/************************************************************************ /************************************************************************
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
reallocated. */
buf_block_t*
buf_page_set_file_page_was_freed(
/*=============================*/
/* out: control block if found from page hash table,
otherwise NULL */
ulint space, /* in: space id */
ulint offset); /* in: page number */
/************************************************************************
Sets file_page_was_freed FALSE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
reallocated. */
buf_block_t*
buf_page_reset_file_page_was_freed(
/*===============================*/
/* out: control block if found from page hash table,
otherwise NULL */
ulint space, /* in: space id */
ulint offset); /* in: page number */
/************************************************************************
Recommends a move of a block to the start of the LRU list if there is danger Recommends a move of a block to the start of the LRU list if there is danger
of dropping from the buffer pool. NOTE: does not reserve the buffer pool of dropping from the buffer pool. NOTE: does not reserve the buffer pool
mutex. */ mutex. */
@ -706,6 +732,9 @@ struct buf_block_struct{
which bufferfixes the block acquires which bufferfixes the block acquires
an s-latch here; so we can use the an s-latch here; so we can use the
debug utilities in sync0rw */ debug utilities in sync0rw */
ibool file_page_was_freed;
/* this is set to TRUE when fsp
frees a page in buffer pool */
}; };
/* The buffer pool structure. NOTE! The definition appears here only for /* The buffer pool structure. NOTE! The definition appears here only for

View File

@ -31,7 +31,8 @@ struct mem_area_struct{
}; };
/* Each memory area takes this many extra bytes for control information */ /* Each memory area takes this many extra bytes for control information */
#define MEM_AREA_EXTRA_SIZE (sizeof(struct mem_area_struct)) #define MEM_AREA_EXTRA_SIZE (ut_calc_align(sizeof(struct mem_area_struct),\
UNIV_MEM_ALIGNMENT))
/************************************************************************ /************************************************************************
Creates a memory pool. */ Creates a memory pool. */

View File

@ -171,10 +171,10 @@ page_cur_search(
ut_ad(dtuple_check_typed(tuple)); ut_ad(dtuple_check_typed(tuple));
page_cur_search_with_match(page, tuple, mode, page_cur_search_with_match(page, tuple, mode,
&low_matched_fields,
&low_matched_bytes,
&up_matched_fields, &up_matched_fields,
&up_matched_bytes, &up_matched_bytes,
&low_matched_fields,
&low_matched_bytes,
cursor); cursor);
return(low_matched_fields); return(low_matched_fields);
} }

View File

@ -229,6 +229,15 @@ row_rename_table_for_mysql(
char* old_name, /* in: old table name */ char* old_name, /* in: old table name */
char* new_name, /* in: new table name */ char* new_name, /* in: new table name */
trx_t* trx); /* in: transaction handle */ trx_t* trx); /* in: transaction handle */
/*************************************************************************
Checks a table for corruption. */
ulint
row_check_table_for_mysql(
/*======================*/
/* out: DB_ERROR or DB_SUCCESS */
row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
handle */
/* A struct describing a place for an individual column in the MySQL /* A struct describing a place for an individual column in the MySQL
row format which is presented to the table handler in ha_innobase. row format which is presented to the table handler in ha_innobase.
@ -281,7 +290,8 @@ struct row_prebuilt_struct {
is set to TRUE */ is set to TRUE */
dict_index_t* index; /* current index for a search, if any */ dict_index_t* index; /* current index for a search, if any */
ulint template_type; /* ROW_MYSQL_WHOLE_ROW, ulint template_type; /* ROW_MYSQL_WHOLE_ROW,
ROW_MYSQL_REC_FIELDS or ROW_MYSQL_REC_FIELDS,
ROW_MYSQL_DUMMY_TEMPLATE, or
ROW_MYSQL_NO_TEMPLATE */ ROW_MYSQL_NO_TEMPLATE */
ulint n_template; /* number of elements in the ulint n_template; /* number of elements in the
template */ template */
@ -359,6 +369,8 @@ struct row_prebuilt_struct {
#define ROW_MYSQL_WHOLE_ROW 0 #define ROW_MYSQL_WHOLE_ROW 0
#define ROW_MYSQL_REC_FIELDS 1 #define ROW_MYSQL_REC_FIELDS 1
#define ROW_MYSQL_NO_TEMPLATE 2 #define ROW_MYSQL_NO_TEMPLATE 2
#define ROW_MYSQL_DUMMY_TEMPLATE 3 /* dummy template used in
row_scan_and_check_index */
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "row0mysql.ic" #include "row0mysql.ic"

View File

@ -28,4 +28,7 @@ int
innobase_shutdown_for_mysql(void); innobase_shutdown_for_mysql(void);
/*=============================*/ /*=============================*/
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
extern ibool srv_startup_is_before_trx_rollback_phase;
#endif #endif

View File

@ -86,6 +86,22 @@ mutex_test_and_set(
/* mutex_fence(); */ /* mutex_fence(); */
return(res); return(res);
#elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
ulint* lw;
ulint res;
lw = &(mutex->lock_word);
/* In assembly we use the so-called AT & T syntax where
the order of operands is inverted compared to the ordinary Intel
syntax. The 'l' after the mnemonics denotes a 32-bit operation.
The line after the code tells which values come out of the asm
code, and the second line tells the input to the asm code. */
asm volatile("movl $1, %%eax; xchgl (%%ecx), %%eax" :
"=eax" (res), "=m" (*lw) :
"ecx" (lw));
return(res);
#else #else
ibool ret; ibool ret;
@ -118,6 +134,21 @@ mutex_reset_lock_word(
__asm MOV EDX, 0 __asm MOV EDX, 0
__asm MOV ECX, lw __asm MOV ECX, lw
__asm XCHG EDX, DWORD PTR [ECX] __asm XCHG EDX, DWORD PTR [ECX]
#elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
ulint* lw;
lw = &(mutex->lock_word);
/* In assembly we use the so-called AT & T syntax where
the order of operands is inverted compared to the ordinary Intel
syntax. The 'l' after the mnemonics denotes a 32-bit operation. */
asm volatile("movl $0, %%eax; xchgl (%%ecx), %%eax" :
"=m" (*lw) :
"ecx" (lw) :
"eax"); /* gcc does not seem to understand
that our asm code resets eax: tell it
explicitly that after the third ':' */
#else #else
mutex->lock_word = 0; mutex->lock_word = 0;

View File

@ -24,6 +24,13 @@ saving CPU time. The kernel mutex contention is increased, however. */
extern ulint trx_n_mysql_transactions; extern ulint trx_n_mysql_transactions;
/************************************************************************
Releases the search latch if trx has reserved it. */
void
trx_search_latch_release_if_reserved(
/*=================================*/
trx_t* trx); /* in: transaction */
/******************************************************************** /********************************************************************
Retrieves the error_info field from a trx. */ Retrieves the error_info field from a trx. */
@ -282,6 +289,13 @@ struct trx_struct{
ulint n_mysql_tables_in_use; /* number of Innobase tables ulint n_mysql_tables_in_use; /* number of Innobase tables
used in the processing of the current used in the processing of the current
SQL statement in MySQL */ SQL statement in MySQL */
ulint mysql_n_tables_locked;
/* how many tables the current SQL
statement uses, except those
in consistent read */
ibool has_search_latch;
/* TRUE if this trx has latched the
search system latch in S-mode */
ibool ignore_duplicates_in_insert; ibool ignore_duplicates_in_insert;
/* in an insert roll back only insert /* in an insert roll back only insert
of the latest row in case of the latest row in case

View File

@ -9,6 +9,8 @@ Created 1/20/1994 Heikki Tuuri
#ifndef univ_i #ifndef univ_i
#define univ_i #define univ_i
#undef UNIV_INTEL_X86
#if (defined(_WIN32) || defined(_WIN64)) && !defined(MYSQL_SERVER) #if (defined(_WIN32) || defined(_WIN64)) && !defined(MYSQL_SERVER)
#define __WIN__ #define __WIN__
#include <windows.h> #include <windows.h>
@ -72,6 +74,8 @@ subdirectory of 'mysql'. */
#define UNIV_SYNC_PERF_STAT #define UNIV_SYNC_PERF_STAT
#define UNIV_SEARCH_PERF_STAT #define UNIV_SEARCH_PERF_STAT
#define UNIV_DEBUG_FILE_ACCESSES
*/ */
#define UNIV_LIGHT_MEM_DEBUG #define UNIV_LIGHT_MEM_DEBUG

View File

@ -136,6 +136,13 @@ ut_difftime(
/* out: time2 - time1 expressed in seconds */ /* out: time2 - time1 expressed in seconds */
ib_time_t time2, /* in: time */ ib_time_t time2, /* in: time */
ib_time_t time1); /* in: time */ ib_time_t time1); /* in: time */
/**************************************************************
Prints a timestamp to a file. */
void
ut_print_timestamp(
/*===============*/
FILE* file); /* in: file where to print */
/***************************************************************** /*****************************************************************
Runs an idle loop on CPU. The argument gives the desired delay Runs an idle loop on CPU. The argument gives the desired delay
in microseconds on 100 MHz Pentium + Visual C++. */ in microseconds on 100 MHz Pentium + Visual C++. */

View File

@ -2634,8 +2634,9 @@ logs_empty_and_mark_files_at_shutdown(void)
{ {
dulint lsn; dulint lsn;
ulint arch_log_no; ulint arch_log_no;
fprintf(stderr, "InnoDB: Starting shutdown...\n"); ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Starting shutdown...\n");
/* Wait until the master thread and all other operations are idle: our /* Wait until the master thread and all other operations are idle: our
algorithm only works if the server is idle at shutdown */ algorithm only works if the server is idle at shutdown */
@ -2725,7 +2726,8 @@ loop:
fil_flush_file_spaces(FIL_TABLESPACE); fil_flush_file_spaces(FIL_TABLESPACE);
fprintf(stderr, "InnoDB: Shutdown completed\n"); ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Shutdown completed\n");
} }
/********************************************************** /**********************************************************

View File

@ -944,9 +944,9 @@ recv_read_in_area(
} }
buf_read_recv_pages(FALSE, space, page_nos, n); buf_read_recv_pages(FALSE, space, page_nos, n);
/*
/* printf("Recv pages at %lu n %lu\n", page_nos[0], n); */ printf("Recv pages at %lu n %lu\n", page_nos[0], n);
*/
return(n); return(n);
} }

View File

@ -11,6 +11,7 @@ Created 10/21/1995 Heikki Tuuri
#include "ut0mem.h" #include "ut0mem.h"
#include "srv0srv.h" #include "srv0srv.h"
#undef HAVE_FDATASYNC
#ifdef POSIX_ASYNC_IO #ifdef POSIX_ASYNC_IO
/* We assume in this case that the OS has standard Posix aio (at least SunOS /* We assume in this case that the OS has standard Posix aio (at least SunOS
@ -562,6 +563,11 @@ os_file_flush(
return(TRUE); return(TRUE);
} }
fprintf(stderr,
"InnoDB: Error: the OS said file flush did not succeed\n");
os_file_handle_error(file, NULL);
return(FALSE); return(FALSE);
#endif #endif
} }

View File

@ -1199,8 +1199,16 @@ page_rec_validate(
n_owned = rec_get_n_owned(rec); n_owned = rec_get_n_owned(rec);
heap_no = rec_get_heap_no(rec); heap_no = rec_get_heap_no(rec);
ut_a(n_owned <= PAGE_DIR_SLOT_MAX_N_OWNED); if (!(n_owned <= PAGE_DIR_SLOT_MAX_N_OWNED)) {
ut_a(heap_no < page_header_get_field(page, PAGE_N_HEAP)); fprintf(stderr, "Dir slot n owned too big %lu\n", n_owned);
return(FALSE);
}
if (!(heap_no < page_header_get_field(page, PAGE_N_HEAP))) {
fprintf(stderr, "Heap no too big %lu %lu\n", heap_no,
page_header_get_field(page, PAGE_N_HEAP));
return(FALSE);
}
return(TRUE); return(TRUE);
} }
@ -1216,20 +1224,21 @@ page_validate(
dict_index_t* index) /* in: data dictionary index containing dict_index_t* index) /* in: data dictionary index containing
the page record type definition */ the page record type definition */
{ {
page_dir_slot_t* slot;
mem_heap_t* heap; mem_heap_t* heap;
page_cur_t cur;
byte* buf; byte* buf;
ulint i; ulint i;
ulint count; ulint count;
ulint own_count; ulint own_count;
ulint slot_no; ulint slot_no;
ulint data_size; ulint data_size;
page_cur_t cur;
rec_t* rec; rec_t* rec;
rec_t* old_rec = NULL; rec_t* old_rec = NULL;
page_dir_slot_t* slot;
ulint offs; ulint offs;
ulint n_slots; ulint n_slots;
ibool ret = FALSE;
heap = mem_heap_create(UNIV_PAGE_SIZE); heap = mem_heap_create(UNIV_PAGE_SIZE);
/* The following buffer is used to check that the /* The following buffer is used to check that the
@ -1244,8 +1253,16 @@ page_validate(
overlap. */ overlap. */
n_slots = page_dir_get_n_slots(page); n_slots = page_dir_get_n_slots(page);
ut_ad(page_header_get_ptr(page, PAGE_HEAP_TOP) <=
page_dir_get_nth_slot(page, n_slots - 1)); if (!(page_header_get_ptr(page, PAGE_HEAP_TOP) <=
page_dir_get_nth_slot(page, n_slots - 1))) {
fprintf(stderr,
"Record heap and dir overlap on a page in index %s, %lu, %lu\n",
index->name, page_header_get_ptr(page, PAGE_HEAP_TOP),
page_dir_get_nth_slot(page, n_slots - 1));
goto func_exit;
}
/* Validate the record list in a loop checking also that /* Validate the record list in a loop checking also that
it is consistent with the directory. */ it is consistent with the directory. */
@ -1259,11 +1276,20 @@ page_validate(
for (;;) { for (;;) {
rec = (&cur)->rec; rec = (&cur)->rec;
page_rec_validate(rec);
if (!page_rec_validate(rec)) {
goto func_exit;
}
/* Check that the records are in the ascending order */ /* Check that the records are in the ascending order */
if ((count >= 2) && (!page_cur_is_after_last(&cur))) { if ((count >= 2) && (!page_cur_is_after_last(&cur))) {
ut_a(1 == cmp_rec_rec(rec, old_rec, index)); if (!(1 == cmp_rec_rec(rec, old_rec, index))) {
fprintf(stderr,
"Records in wrong order in index %s\n",
index->name);
goto func_exit;
}
} }
if ((rec != page_get_supremum_rec(page)) if ((rec != page_get_supremum_rec(page))
@ -1275,16 +1301,38 @@ page_validate(
offs = rec_get_start(rec) - page; offs = rec_get_start(rec) - page;
for (i = 0; i < rec_get_size(rec); i++) { for (i = 0; i < rec_get_size(rec); i++) {
ut_a(buf[offs + i] == 0); /* No other record may if (!buf[offs + i] == 0) {
overlap this */ /* No other record may overlap this */
fprintf(stderr,
"Record overlaps another in index %s \n",
index->name);
goto func_exit;
}
buf[offs + i] = 1; buf[offs + i] = 1;
} }
if (rec_get_n_owned(rec) != 0) { if (rec_get_n_owned(rec) != 0) {
/* This is a record pointed to by a dir slot */ /* This is a record pointed to by a dir slot */
ut_a(rec_get_n_owned(rec) == own_count); if (rec_get_n_owned(rec) != own_count) {
fprintf(stderr,
"Wrong owned count %lu, %lu, in index %s\n",
rec_get_n_owned(rec), own_count,
index->name);
ut_a(page_dir_slot_get_rec(slot) == rec); goto func_exit;
}
if (page_dir_slot_get_rec(slot) != rec) {
fprintf(stderr,
"Dir slot does not point to right rec in %s\n",
index->name);
goto func_exit;
}
page_dir_slot_check(slot); page_dir_slot_check(slot);
own_count = 0; own_count = 0;
@ -1297,45 +1345,89 @@ page_validate(
if (page_cur_is_after_last(&cur)) { if (page_cur_is_after_last(&cur)) {
break; break;
} }
count++; if (rec_get_next_offs(rec) < FIL_PAGE_DATA
|| rec_get_next_offs(rec) >= UNIV_PAGE_SIZE) {
fprintf(stderr,
"Next record offset wrong %lu in index %s\n",
rec_get_next_offs(rec), index->name);
goto func_exit;
}
count++;
page_cur_move_to_next(&cur); page_cur_move_to_next(&cur);
own_count++; own_count++;
old_rec = rec; old_rec = rec;
} }
ut_a(rec_get_n_owned(rec) != 0); if (rec_get_n_owned(rec) == 0) {
ut_a(slot_no == n_slots - 1); fprintf(stderr, "n owned is zero in index %s\n", index->name);
ut_a(page_header_get_field(page, PAGE_N_RECS) + 2 == count + 1);
goto func_exit;
}
if (slot_no != n_slots - 1) {
fprintf(stderr, "n slots wrong %lu %lu in index %s\n",
slot_no, n_slots - 1, index->name);
goto func_exit;
}
if (page_header_get_field(page, PAGE_N_RECS) + 2 != count + 1) {
fprintf(stderr, "n recs wrong %lu %lu in index %s\n",
page_header_get_field(page, PAGE_N_RECS) + 2, count + 1,
index->name);
goto func_exit;
}
if (data_size != page_get_data_size(page)) { if (data_size != page_get_data_size(page)) {
printf("Summed data size %lu, returned by func %lu\n", fprintf(stderr, "Summed data size %lu, returned by func %lu\n",
data_size, page_get_data_size(page)); data_size, page_get_data_size(page));
ut_error; goto func_exit;
} }
/* Check then the free list */ /* Check then the free list */
rec = page_header_get_ptr(page, PAGE_FREE); rec = page_header_get_ptr(page, PAGE_FREE);
while (rec != NULL) { while (rec != NULL) {
page_rec_validate(rec); if (!page_rec_validate(rec)) {
goto func_exit;
}
count++; count++;
offs = rec_get_start(rec) - page; offs = rec_get_start(rec) - page;
for (i = 0; i < rec_get_size(rec); i++) { for (i = 0; i < rec_get_size(rec); i++) {
ut_a(buf[offs + i] == 0);
if (buf[offs + i] != 0) {
fprintf(stderr,
"Record overlaps another in free list, index %s \n",
index->name);
goto func_exit;
}
buf[offs + i] = 1; buf[offs + i] = 1;
} }
rec = page_rec_get_next(rec); rec = page_rec_get_next(rec);
} }
ut_a(page_header_get_field(page, PAGE_N_HEAP) == count + 1); if (page_header_get_field(page, PAGE_N_HEAP) != count + 1) {
fprintf(stderr, "N heap is wrong %lu %lu in index %s\n",
page_header_get_field(page, PAGE_N_HEAP), count + 1,
index->name);
}
ret = TRUE;
func_exit:
mem_heap_free(heap); mem_heap_free(heap);
return(TRUE); return(ret);
} }
/******************************************************************* /*******************************************************************

View File

@ -177,7 +177,9 @@ cmp_whole_field(
(int)(type->prtype & ~DATA_NOT_NULL), (int)(type->prtype & ~DATA_NOT_NULL),
a, a_length, b, b_length)); a, a_length, b, b_length));
default: default:
assert(0); fprintf(stderr,
"InnoDB: unknown type number %lu\n", data_type);
ut_a(0);
} }
return(0); return(0);

View File

@ -24,6 +24,7 @@ Created 9/17/2000 Heikki Tuuri
#include "trx0roll.h" #include "trx0roll.h"
#include "trx0purge.h" #include "trx0purge.h"
#include "lock0lock.h" #include "lock0lock.h"
#include "rem0cmp.h"
/*********************************************************************** /***********************************************************************
Reads a MySQL format variable-length field (like VARCHAR) length and Reads a MySQL format variable-length field (like VARCHAR) length and
@ -823,7 +824,11 @@ row_create_table_for_mysql(
} else { } else {
assert(err == DB_DUPLICATE_KEY); assert(err == DB_DUPLICATE_KEY);
fprintf(stderr, fprintf(stderr,
"Innobase: error: table %s already exists in Innobase data dictionary\n", "InnoDB: Error: table %s already exists in InnoDB internal\n"
"InnoDB: data dictionary. Have you deleted the .frm file\n"
"InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n"
"InnoDB: for InnoDB tables in MySQL version <= 3.23.39?\n"
"InnoDB: See the Restrictions section of the InnoDB manual.\n",
table->name); table->name);
} }
@ -1129,3 +1134,146 @@ funct_exit:
return((int) err); return((int) err);
} }
/*************************************************************************
Checks that the index contains entries in an ascending order, unique
constraint is not broken, and calculates the number of index entries
in the read view of the current transaction. */
static
ibool
row_scan_and_check_index(
/*=====================*/
/* out: TRUE if ok */
row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL */
dict_index_t* index, /* in: index */
ulint* n_rows) /* out: number of entries seen in the
current consistent read */
{
mem_heap_t* heap;
dtuple_t* prev_entry = NULL;
ulint matched_fields;
ulint matched_bytes;
byte* buf;
ulint ret;
rec_t* rec;
ibool is_ok = TRUE;
int cmp;
*n_rows = 0;
buf = mem_alloc(UNIV_PAGE_SIZE);
heap = mem_heap_create(100);
/* Make a dummy template in prebuilt, which we will use
in scanning the index entries */
prebuilt->index = index;
prebuilt->sql_stat_start = TRUE;
prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE;
prebuilt->n_template = 0;
prebuilt->need_to_access_clustered = FALSE;
dtuple_set_n_fields(prebuilt->search_tuple, 0);
prebuilt->select_lock_type = LOCK_NONE;
ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, 0);
loop:
if (ret != DB_SUCCESS) {
mem_free(buf);
mem_heap_free(heap);
return(is_ok);
}
*n_rows = *n_rows + 1;
/* row_search... returns the index record in buf, record origin offset
within buf stored in the first 4 bytes, because we have built a dummy
template */
rec = buf + mach_read_from_4(buf);
if (prev_entry != NULL) {
matched_fields = 0;
matched_bytes = 0;
cmp = cmp_dtuple_rec_with_match(prev_entry, rec,
&matched_fields,
&matched_bytes);
if (cmp > 0) {
fprintf(stderr,
"Error: index records in a wrong order in index %s\n",
index->name);
is_ok = FALSE;
} else if ((index->type & DICT_UNIQUE)
&& matched_fields >=
dict_index_get_n_ordering_defined_by_user(index)) {
fprintf(stderr,
"Error: duplicate key in index %s\n",
index->name);
is_ok = FALSE;
}
}
mem_heap_empty(heap);
prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, ROW_SEL_NEXT);
goto loop;
}
/*************************************************************************
Checks a table for corruption. */
ulint
row_check_table_for_mysql(
/*======================*/
/* out: DB_ERROR or DB_SUCCESS */
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
handle */
{
dict_table_t* table = prebuilt->table;
dict_index_t* index;
ulint n_rows;
ulint n_rows_in_table;
ulint ret = DB_SUCCESS;
index = dict_table_get_first_index(table);
while (index != NULL) {
/* fprintf(stderr, "Validating index %s\n", index->name); */
if (!btr_validate_tree(index->tree)) {
ret = DB_ERROR;
} else {
if (!row_scan_and_check_index(prebuilt,
index, &n_rows)) {
ret = DB_ERROR;
}
/* fprintf(stderr, "%lu entries in index %s\n", n_rows,
index->name); */
if (index == dict_table_get_first_index(table)) {
n_rows_in_table = n_rows;
} else if (n_rows != n_rows_in_table) {
ret = DB_ERROR;
fprintf(stderr,
"Error: index %s contains %lu entries, should be %lu\n",
index->name, n_rows, n_rows_in_table);
}
}
index = dict_table_get_next_index(index);
}
return(ret);
}

View File

@ -2207,11 +2207,11 @@ row_sel_get_clust_rec_for_mysql(
visit through secondary index records that would not really visit through secondary index records that would not really
exist in our snapshot. */ exist in our snapshot. */
if ((old_vers || rec_get_deleted_flag(rec)) if (clust_rec && (old_vers || rec_get_deleted_flag(rec))
&& !row_sel_sec_rec_is_for_clust_rec(rec, sec_index, && !row_sel_sec_rec_is_for_clust_rec(rec, sec_index,
clust_rec, clust_index)) { clust_rec, clust_index)) {
clust_rec = NULL; clust_rec = NULL;
} }
} }
*out_rec = clust_rec; *out_rec = clust_rec;
@ -2341,6 +2341,65 @@ row_sel_push_cache_row_for_mysql(
prebuilt->n_fetch_cached++; prebuilt->n_fetch_cached++;
} }
/*************************************************************************
Tries to do a shortcut to fetch a clustered index record with a unique key,
using the hash index if possible (not always). We assume that the search
mode is PAGE_CUR_GE, it is a consistent read, trx has already a read view,
btr search latch has been locked in S-mode. */
static
ulint
row_sel_try_search_shortcut_for_mysql(
/*==================================*/
/* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
rec_t** out_rec,/* out: record if found */
row_prebuilt_t* prebuilt,/* in: prebuilt struct */
mtr_t* mtr) /* in: started mtr */
{
dict_index_t* index = prebuilt->index;
dtuple_t* search_tuple = prebuilt->search_tuple;
btr_pcur_t* pcur = prebuilt->pcur;
trx_t* trx = prebuilt->trx;
rec_t* rec;
ut_ad(index->type & DICT_CLUSTERED);
btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, pcur,
RW_S_LATCH, mtr);
rec = btr_pcur_get_rec(pcur);
if (!page_rec_is_user_rec(rec)) {
return(SEL_RETRY);
}
/* As the cursor is now placed on a user record after a search with
the mode PAGE_CUR_GE, the up_match field in the cursor tells how many
fields in the user record matched to the search tuple */
if (btr_pcur_get_up_match(pcur) < dtuple_get_n_fields(search_tuple)) {
return(SEL_EXHAUSTED);
}
/* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */
if (!lock_clust_rec_cons_read_sees(rec, index, trx->read_view)) {
return(SEL_RETRY);
}
if (rec_get_deleted_flag(rec)) {
return(SEL_EXHAUSTED);
}
*out_rec = rec;
return(SEL_FOUND);
}
/************************************************************************ /************************************************************************
Searches for rows in the database. This is used in the interface to Searches for rows in the database. This is used in the interface to
MySQL. This function opens a cursor, and also implements fetch next MySQL. This function opens a cursor, and also implements fetch next
@ -2387,6 +2446,7 @@ row_search_for_mysql(
ibool cons_read_requires_clust_rec; ibool cons_read_requires_clust_rec;
ibool was_lock_wait; ibool was_lock_wait;
ulint ret; ulint ret;
ulint shortcut;
ibool unique_search_from_clust_index = FALSE; ibool unique_search_from_clust_index = FALSE;
ibool mtr_has_extra_clust_latch = FALSE; ibool mtr_has_extra_clust_latch = FALSE;
ibool moves_up = FALSE; ibool moves_up = FALSE;
@ -2452,6 +2512,8 @@ row_search_for_mysql(
mode = pcur->search_mode; mode = pcur->search_mode;
} }
mtr_start(&mtr);
if (match_mode == ROW_SEL_EXACT && index->type & DICT_UNIQUE if (match_mode == ROW_SEL_EXACT && index->type & DICT_UNIQUE
&& index->type & DICT_CLUSTERED && index->type & DICT_CLUSTERED
&& dtuple_get_n_fields(search_tuple) && dtuple_get_n_fields(search_tuple)
@ -2464,6 +2526,8 @@ row_search_for_mysql(
restore cursor position, and must return restore cursor position, and must return
immediately */ immediately */
mtr_commit(&mtr);
return(DB_RECORD_NOT_FOUND); return(DB_RECORD_NOT_FOUND);
} }
@ -2472,8 +2536,51 @@ row_search_for_mysql(
mode = PAGE_CUR_GE; mode = PAGE_CUR_GE;
unique_search_from_clust_index = TRUE; unique_search_from_clust_index = TRUE;
if (trx->mysql_n_tables_locked == 0
&& !prebuilt->sql_stat_start) {
/* This is a SELECT query done as a consistent read,
and the read view has already been allocated:
let us try a search shortcut through the hash
index */
if (!trx->has_search_latch) {
rw_lock_s_lock(&btr_search_latch);
trx->has_search_latch = TRUE;
} else if (btr_search_latch.writer_is_wait_ex) {
/* There is an x-latch request waiting:
release the s-latch for a moment to reduce
starvation */
rw_lock_s_unlock(&btr_search_latch);
rw_lock_s_lock(&btr_search_latch);
}
shortcut = row_sel_try_search_shortcut_for_mysql(&rec,
prebuilt, &mtr);
if (shortcut == SEL_FOUND) {
row_sel_store_mysql_rec(buf, prebuilt, rec);
mtr_commit(&mtr);
return(DB_SUCCESS);
} else if (shortcut == SEL_EXHAUSTED) {
mtr_commit(&mtr);
return(DB_RECORD_NOT_FOUND);
}
}
} }
if (trx->has_search_latch) {
rw_lock_s_unlock(&btr_search_latch);
trx->has_search_latch = FALSE;
}
/* Note that if the search mode was GE or G, then the cursor /* Note that if the search mode was GE or G, then the cursor
naturally moves upward (in fetch next) in alphabetical order, naturally moves upward (in fetch next) in alphabetical order,
otherwise downward */ otherwise downward */
@ -2485,8 +2592,6 @@ row_search_for_mysql(
} else if (direction == ROW_SEL_NEXT) { } else if (direction == ROW_SEL_NEXT) {
moves_up = TRUE; moves_up = TRUE;
} }
mtr_start(&mtr);
thr = que_fork_get_first_thr(prebuilt->sel_graph); thr = que_fork_get_first_thr(prebuilt->sel_graph);
@ -2711,7 +2816,9 @@ rec_loop:
if (prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD if (prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD
&& !prebuilt->templ_contains_blob && !prebuilt->templ_contains_blob
&& prebuilt->select_lock_type == LOCK_NONE && prebuilt->select_lock_type == LOCK_NONE
&& !prebuilt->clust_index_was_generated) { && !prebuilt->clust_index_was_generated
&& prebuilt->template_type
!= ROW_MYSQL_DUMMY_TEMPLATE) {
/* Inside an update, for example, we do not cache rows, /* Inside an update, for example, we do not cache rows,
since we may use the cursor position to do the actual since we may use the cursor position to do the actual
@ -2726,7 +2833,13 @@ rec_loop:
goto next_rec; goto next_rec;
} else { } else {
row_sel_store_mysql_rec(buf, prebuilt, rec); if (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE) {
ut_memcpy(buf + 4, rec - rec_get_extra_size(rec),
rec_get_size(rec));
mach_write_to_4(buf, rec_get_extra_size(rec) + 4);
} else {
row_sel_store_mysql_rec(buf, prebuilt, rec);
}
if (prebuilt->clust_index_was_generated) { if (prebuilt->clust_index_was_generated) {
row_sel_store_row_id_to_prebuilt(prebuilt, index_rec, row_sel_store_row_id_to_prebuilt(prebuilt, index_rec,

View File

@ -361,6 +361,7 @@ row_undo_mod_del_unmark_sec(
btr_cur_t* btr_cur; btr_cur_t* btr_cur;
ulint err; ulint err;
ibool found; ibool found;
char* err_buf;
UT_NOT_USED(node); UT_NOT_USED(node);
@ -369,13 +370,31 @@ row_undo_mod_del_unmark_sec(
found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur, found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
&mtr); &mtr);
ut_a(found); if (!found) {
err_buf = mem_alloc(1000);
dtuple_sprintf(err_buf, 900, entry);
btr_cur = btr_pcur_get_btr_cur(&pcur); fprintf(stderr, "InnoDB: error in sec index entry del undo in\n"
"InnoDB: index %s table %s\n", index->name,
index->table->name);
fprintf(stderr, "InnoDB: tuple %s\n", err_buf);
err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG, rec_sprintf(err_buf, 900, btr_pcur_get_rec(&pcur));
fprintf(stderr, "InnoDB: record %s\n", err_buf);
fprintf(stderr, "InnoDB: Make a detailed bug report and send it\n");
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
mem_free(err_buf);
} else {
btr_cur = btr_pcur_get_btr_cur(&pcur);
err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG,
btr_cur, FALSE, thr, &mtr); btr_cur, FALSE, thr, &mtr);
ut_ad(err == DB_SUCCESS); ut_ad(err == DB_SUCCESS);
}
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);

Some files were not shown because too many files have changed in this diff Show More