diff options
114 files changed, 1355 insertions, 593 deletions
diff --git a/Build-tools/mysql-copyright b/Build-tools/mysql-copyright index b403fdf8c0a..adc4ae34a50 100755 --- a/Build-tools/mysql-copyright +++ b/Build-tools/mysql-copyright @@ -141,13 +141,15 @@ sub main # remove temporary directory chdir($WD) or print "$! Unable to move up one dir\n"; + `cd $WD`; my $cwd = getcwd(); print "current dir is $cwd\n" if $opt_verbose ; - print "deleting temp dir $dir\n" if $opt_verbose; - if (-d $dir) { - system("rm -rf $dir") or print "$! Unable to delete $dir!\n"; + if (-e $dir) { + print "Trying to delete $dir\n" if $opt_verbose; + if ( system("rm -rf $dir")){ + print "$! Unable to delete $dir!\n"; + } } - } exit(0); } @@ -156,14 +158,17 @@ sub main #### mysqld and MySQL client programs have a usage printed with --help. #### This usage includes a copyright, which needs to be modified #### - sub fix_usage_copyright { - my @Cfiles = `find . -type f -name \"*.c*\"`; - foreach my $Cfile (@Cfiles) + my $findlist = `find . -type f -name \"*.c*\"`; + my @files = split("\n", $findlist); + my $cwd = getcwd(); + + foreach my $file (@files) { - chop $Cfile; - `replace "This is free software," "This is commercial software," "and you are welcome to modify and redistribute it under the GPL license" "please see the file MySQLEULA.txt for details" -- "$Cfile"` if -f $Cfile; + next if ! -f $file; + print "processing file $file in cwd $cwd\n" if $opt_verbose; + `replace "This is free software," "This is commercial software," "and you are welcome to modify and redistribute it under the GPL license" "please see the file MySQLEULA.txt for details" -- "$file"` ; } } @@ -173,12 +178,15 @@ sub fix_usage_copyright sub add_copyright { - my @files = `find . -type f -name "*"`; + my $findlist = `find . -type f -name "*"`; + my @files = split("\n", $findlist); + my $cwd = getcwd(); + foreach my $file (@files) { - chop $file; next if ! -f $file; next if -B $file; + print "processing file $file in cwd $cwd\n" if $opt_verbose; `$WD/Build-tools/mysql-copyright-2 "$file"`; } } diff --git a/Build-tools/mysql-copyright-2 b/Build-tools/mysql-copyright-2 index e946ed217d1..a1a870526da 100755 --- a/Build-tools/mysql-copyright-2 +++ b/Build-tools/mysql-copyright-2 @@ -89,6 +89,7 @@ sub add_copyright elsif ($ARGV =~ /\.c$/ || $ARGV =~ /\.cc$/ || $ARGV =~ /\.h$/ || + $ARGV =~ /\.cpp$/ || $ARGV =~ /\.yy$/) { $start_copyright="/* "; diff --git a/VC++Files/InstallShield/4.0.XX-classic/File Groups/Servers.fgl b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Servers.fgl index 8a626c56253..b51c37f8db2 100755 --- a/VC++Files/InstallShield/4.0.XX-classic/File Groups/Servers.fgl +++ b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Servers.fgl @@ -41,31 +41,55 @@ file1=C:\mysql\share\korean\errmsg.txt fulldirectory= [share\charsets] -file15=C:\mysql\share\charsets\latin1.conf -file16=C:\mysql\share\charsets\latin2.conf -file0=C:\mysql\share\charsets\win1251ukr.conf -file17=C:\mysql\share\charsets\latin5.conf +file0=C:\mysql\share\charsets\cp1250.xml +file1=C:\mysql\share\charsets\cp1251.conf +file2=C:\mysql\share\charsets\cp1251.xml +file3=C:\mysql\share\charsets\cp1256.xml file1=C:\mysql\share\charsets\cp1257.conf -file18=C:\mysql\share\charsets\Readme -file2=C:\mysql\share\charsets\croat.conf -file19=C:\mysql\share\charsets\swe7.conf -file3=C:\mysql\share\charsets\danish.conf -file4=C:\mysql\share\charsets\dec8.conf -file5=C:\mysql\share\charsets\dos.conf -file6=C:\mysql\share\charsets\estonia.conf -file7=C:\mysql\share\charsets\german1.conf -file8=C:\mysql\share\charsets\greek.conf -file9=C:\mysql\share\charsets\hebrew.conf -file20=C:\mysql\share\charsets\usa7.conf -file21=C:\mysql\share\charsets\win1250.conf -file10=C:\mysql\share\charsets\hp8.conf -fulldirectory= -file22=C:\mysql\share\charsets\win1251.conf -file11=C:\mysql\share\charsets\hungarian.conf -file23=C:\mysql\share\charsets\cp1251.conf -file12=C:\mysql\share\charsets\Index -file13=C:\mysql\share\charsets\koi8_ru.conf -file14=C:\mysql\share\charsets\koi8_ukr.conf +file4=C:\mysql\share\charsets\cp1257.xml +file5=C:\mysql\share\charsets\cp850.xml +file6=C:\mysql\share\charsets\cp852.xml +file7=C:\mysql\share\charsets\cp866.xml +file8=C:\mysql\share\charsets\croat.conf +file9=C:\mysql\share\charsets\danish.conf +file10=C:\mysql\share\charsets\dec8.conf +file10=C:\mysql\share\charsets\dec8.xml +file11=C:\mysql\share\charsets\dos.conf +file12=C:\mysql\share\charsets\estonia.conf +file13=C:\mysql\share\charsets\geostd8.xml +file14=C:\mysql\share\charsets\german1.conf +file15=C:\mysql\share\charsets\greek.xml +file16=C:\mysql\share\charsets\greek.conf +file17=C:\mysql\share\charsets\hebrew.xml +file18=C:\mysql\share\charsets\hebrew.conf +file19=C:\mysql\share\charsets\hp8.xml +file20=C:\mysql\share\charsets\hp8.conf +file21=C:\mysql\share\charsets\hungarian.conf +file22=C:\mysql\share\charsets\keybcs2.xml +file23=C:\mysql\share\charsets\koi8_ru.conf +file24=C:\mysql\share\charsets\koi8_ukr.conf +file25=C:\mysql\share\charsets\koi8r.xml +file26=C:\mysql\share\charsets\koi8u.xml +file27=C:\mysql\share\charsets\latin1.conf +file28=C:\mysql\share\charsets\latin1.xml +file29=C:\mysql\share\charsets\latin2.conf +file30=C:\mysql\share\charsets\latin2.xml +file31=C:\mysql\share\charsets\latin5.conf +file32=C:\mysql\share\charsets\latin5.xml +file33=C:\mysql\share\charsets\latin7.xml +file34=C:\mysql\share\charsets\macce.xml +file35=C:\mysql\share\charsets\macroman.xml +file36=C:\mysql\share\charsets\swe7.conf +file37=C:\mysql\share\charsets\swe7.xml +file38=C:\mysql\share\charsets\usa7.conf +file39=C:\mysql\share\charsets\win1250.conf +file40=C:\mysql\share\charsets\win1251ukr.conf +file41=C:\mysql\share\charsets\win1251.conf +file42=C:\mysql\share\charsets\Index +file43=C:\mysql\share\charsets\Index.xml +file44=C:\mysql\share\charsets\Readme +file45=C:\mysql\share\charsets\languages.html +fulldirectory= [Embedded\DLL\debug] file0=C:\mysql\embedded\DLL\debug\libmysqld.dll diff --git a/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Servers.fgl b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Servers.fgl index c54ff378a55..6564512de2c 100755 --- a/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Servers.fgl +++ b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Servers.fgl @@ -43,31 +43,55 @@ file1=C:\mysql\share\korean\errmsg.txt fulldirectory= [share\charsets] -file15=C:\mysql\share\charsets\latin1.conf -file16=C:\mysql\share\charsets\latin2.conf -file0=C:\mysql\share\charsets\win1251ukr.conf -file17=C:\mysql\share\charsets\latin5.conf +file0=C:\mysql\share\charsets\cp1250.xml +file1=C:\mysql\share\charsets\cp1251.conf +file2=C:\mysql\share\charsets\cp1251.xml +file3=C:\mysql\share\charsets\cp1256.xml file1=C:\mysql\share\charsets\cp1257.conf -file18=C:\mysql\share\charsets\Readme -file2=C:\mysql\share\charsets\croat.conf -file19=C:\mysql\share\charsets\swe7.conf -file3=C:\mysql\share\charsets\danish.conf -file4=C:\mysql\share\charsets\dec8.conf -file5=C:\mysql\share\charsets\dos.conf -file6=C:\mysql\share\charsets\estonia.conf -file7=C:\mysql\share\charsets\german1.conf -file8=C:\mysql\share\charsets\greek.conf -file9=C:\mysql\share\charsets\hebrew.conf -file20=C:\mysql\share\charsets\usa7.conf -file21=C:\mysql\share\charsets\win1250.conf -file10=C:\mysql\share\charsets\hp8.conf -fulldirectory= -file22=C:\mysql\share\charsets\win1251.conf -file11=C:\mysql\share\charsets\hungarian.conf -file23=C:\mysql\share\charsets\cp1251.conf -file12=C:\mysql\share\charsets\Index -file13=C:\mysql\share\charsets\koi8_ru.conf -file14=C:\mysql\share\charsets\koi8_ukr.conf +file4=C:\mysql\share\charsets\cp1257.xml +file5=C:\mysql\share\charsets\cp850.xml +file6=C:\mysql\share\charsets\cp852.xml +file7=C:\mysql\share\charsets\cp866.xml +file8=C:\mysql\share\charsets\croat.conf +file9=C:\mysql\share\charsets\danish.conf +file10=C:\mysql\share\charsets\dec8.conf +file10=C:\mysql\share\charsets\dec8.xml +file11=C:\mysql\share\charsets\dos.conf +file12=C:\mysql\share\charsets\estonia.conf +file13=C:\mysql\share\charsets\geostd8.xml +file14=C:\mysql\share\charsets\german1.conf +file15=C:\mysql\share\charsets\greek.xml +file16=C:\mysql\share\charsets\greek.conf +file17=C:\mysql\share\charsets\hebrew.xml +file18=C:\mysql\share\charsets\hebrew.conf +file19=C:\mysql\share\charsets\hp8.xml +file20=C:\mysql\share\charsets\hp8.conf +file21=C:\mysql\share\charsets\hungarian.conf +file22=C:\mysql\share\charsets\keybcs2.xml +file23=C:\mysql\share\charsets\koi8_ru.conf +file24=C:\mysql\share\charsets\koi8_ukr.conf +file25=C:\mysql\share\charsets\koi8r.xml +file26=C:\mysql\share\charsets\koi8u.xml +file27=C:\mysql\share\charsets\latin1.conf +file28=C:\mysql\share\charsets\latin1.xml +file29=C:\mysql\share\charsets\latin2.conf +file30=C:\mysql\share\charsets\latin2.xml +file31=C:\mysql\share\charsets\latin5.conf +file32=C:\mysql\share\charsets\latin5.xml +file33=C:\mysql\share\charsets\latin7.xml +file34=C:\mysql\share\charsets\macce.xml +file35=C:\mysql\share\charsets\macroman.xml +file36=C:\mysql\share\charsets\swe7.conf +file37=C:\mysql\share\charsets\swe7.xml +file38=C:\mysql\share\charsets\usa7.conf +file39=C:\mysql\share\charsets\win1250.conf +file40=C:\mysql\share\charsets\win1251ukr.conf +file41=C:\mysql\share\charsets\win1251.conf +file42=C:\mysql\share\charsets\Index +file43=C:\mysql\share\charsets\Index.xml +file44=C:\mysql\share\charsets\Readme +file45=C:\mysql\share\charsets\languages.html +fulldirectory= [Embedded\DLL\debug] file0=C:\mysql\embedded\DLL\debug\libmysqld.dll diff --git a/VC++Files/InstallShield/4.0.XX-pro/File Groups/Servers.fgl b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Servers.fgl index 8a626c56253..b51c37f8db2 100755 --- a/VC++Files/InstallShield/4.0.XX-pro/File Groups/Servers.fgl +++ b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Servers.fgl @@ -41,31 +41,55 @@ file1=C:\mysql\share\korean\errmsg.txt fulldirectory= [share\charsets] -file15=C:\mysql\share\charsets\latin1.conf -file16=C:\mysql\share\charsets\latin2.conf -file0=C:\mysql\share\charsets\win1251ukr.conf -file17=C:\mysql\share\charsets\latin5.conf +file0=C:\mysql\share\charsets\cp1250.xml +file1=C:\mysql\share\charsets\cp1251.conf +file2=C:\mysql\share\charsets\cp1251.xml +file3=C:\mysql\share\charsets\cp1256.xml file1=C:\mysql\share\charsets\cp1257.conf -file18=C:\mysql\share\charsets\Readme -file2=C:\mysql\share\charsets\croat.conf -file19=C:\mysql\share\charsets\swe7.conf -file3=C:\mysql\share\charsets\danish.conf -file4=C:\mysql\share\charsets\dec8.conf -file5=C:\mysql\share\charsets\dos.conf -file6=C:\mysql\share\charsets\estonia.conf -file7=C:\mysql\share\charsets\german1.conf -file8=C:\mysql\share\charsets\greek.conf -file9=C:\mysql\share\charsets\hebrew.conf -file20=C:\mysql\share\charsets\usa7.conf -file21=C:\mysql\share\charsets\win1250.conf -file10=C:\mysql\share\charsets\hp8.conf -fulldirectory= -file22=C:\mysql\share\charsets\win1251.conf -file11=C:\mysql\share\charsets\hungarian.conf -file23=C:\mysql\share\charsets\cp1251.conf -file12=C:\mysql\share\charsets\Index -file13=C:\mysql\share\charsets\koi8_ru.conf -file14=C:\mysql\share\charsets\koi8_ukr.conf +file4=C:\mysql\share\charsets\cp1257.xml +file5=C:\mysql\share\charsets\cp850.xml +file6=C:\mysql\share\charsets\cp852.xml +file7=C:\mysql\share\charsets\cp866.xml +file8=C:\mysql\share\charsets\croat.conf +file9=C:\mysql\share\charsets\danish.conf +file10=C:\mysql\share\charsets\dec8.conf +file10=C:\mysql\share\charsets\dec8.xml +file11=C:\mysql\share\charsets\dos.conf +file12=C:\mysql\share\charsets\estonia.conf +file13=C:\mysql\share\charsets\geostd8.xml +file14=C:\mysql\share\charsets\german1.conf +file15=C:\mysql\share\charsets\greek.xml +file16=C:\mysql\share\charsets\greek.conf +file17=C:\mysql\share\charsets\hebrew.xml +file18=C:\mysql\share\charsets\hebrew.conf +file19=C:\mysql\share\charsets\hp8.xml +file20=C:\mysql\share\charsets\hp8.conf +file21=C:\mysql\share\charsets\hungarian.conf +file22=C:\mysql\share\charsets\keybcs2.xml +file23=C:\mysql\share\charsets\koi8_ru.conf +file24=C:\mysql\share\charsets\koi8_ukr.conf +file25=C:\mysql\share\charsets\koi8r.xml +file26=C:\mysql\share\charsets\koi8u.xml +file27=C:\mysql\share\charsets\latin1.conf +file28=C:\mysql\share\charsets\latin1.xml +file29=C:\mysql\share\charsets\latin2.conf +file30=C:\mysql\share\charsets\latin2.xml +file31=C:\mysql\share\charsets\latin5.conf +file32=C:\mysql\share\charsets\latin5.xml +file33=C:\mysql\share\charsets\latin7.xml +file34=C:\mysql\share\charsets\macce.xml +file35=C:\mysql\share\charsets\macroman.xml +file36=C:\mysql\share\charsets\swe7.conf +file37=C:\mysql\share\charsets\swe7.xml +file38=C:\mysql\share\charsets\usa7.conf +file39=C:\mysql\share\charsets\win1250.conf +file40=C:\mysql\share\charsets\win1251ukr.conf +file41=C:\mysql\share\charsets\win1251.conf +file42=C:\mysql\share\charsets\Index +file43=C:\mysql\share\charsets\Index.xml +file44=C:\mysql\share\charsets\Readme +file45=C:\mysql\share\charsets\languages.html +fulldirectory= [Embedded\DLL\debug] file0=C:\mysql\embedded\DLL\debug\libmysqld.dll diff --git a/VC++Files/examples/udf_example/udf_example.def b/VC++Files/examples/udf_example/udf_example.def index c1cfeea63f8..9764343e5f2 100644 --- a/VC++Files/examples/udf_example/udf_example.def +++ b/VC++Files/examples/udf_example/udf_example.def @@ -2,8 +2,17 @@ LIBRARY MYUDF DESCRIPTION 'MySQL Sample for UDF' VERSION 1.0 EXPORTS - metaphon - myfunc_double - myfunc_int - sequence - avgcost
\ No newline at end of file + metaphon_init + metaphon_deinit + metaphon + myfunc_double_init + myfunc_double + myfunc_int + sequence_init + sequence_deinit + sequence + avgcost_init + avgcost_deinit + avgcost_reset + avgcost_add + avgcost diff --git a/client/mysqltest.c b/client/mysqltest.c index 5ff152bd1c9..1f97b581765 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -59,8 +59,7 @@ #include <sys/stat.h> #include <violite.h> -#define MAX_VAR_NAME 256 -#define MAX_QUERY 65536 +#define MAX_QUERY 131072 #define MAX_COLUMNS 256 #define PAD_SIZE 128 #define MAX_CONS 128 diff --git a/include/my_global.h b/include/my_global.h index 3d1a770d877..6c6d3ef6dd5 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1178,16 +1178,6 @@ do { doubleget_union _tmp; \ #define statistic_add(V,C,L) (V)+=(C) #endif -#ifdef HAVE_OPENSSL -#include <openssl/opensslv.h> -#if OPENSSL_VERSION_NUMBER < 0x0090700f -#define DES_cblock des_cblock -#define DES_key_schedule des_key_schedule -#define DES_set_key_unchecked(k,ks) des_set_key_unchecked((k),*(ks)) -#define DES_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e) des_ede3_cbc_encrypt((i),(o),(l),*(k1),*(k2),*(k3),(iv),(e)) -#endif -#endif - #ifdef HAVE_CHARSET_utf8 #define MYSQL_UNIVERSAL_CLIENT_CHARSET "utf8" #else diff --git a/include/violite.h b/include/violite.h index b4b9f724d89..ba7de3ee175 100644 --- a/include/violite.h +++ b/include/violite.h @@ -83,6 +83,14 @@ my_bool vio_poll_read(Vio *vio,uint timeout); void vio_timeout(Vio *vio,uint timeout); #ifdef HAVE_OPENSSL +#include <openssl/opensslv.h> +#if OPENSSL_VERSION_NUMBER < 0x0090700f +#define DES_cblock des_cblock +#define DES_key_schedule des_key_schedule +#define DES_set_key_unchecked(k,ks) des_set_key_unchecked((k),*(ks)) +#define DES_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e) des_ede3_cbc_encrypt((i),(o),(l),*(k1),*(k2),*(k3),(iv),(e)) +#endif + #define HEADER_DES_LOCL_H dummy_something #include <openssl/ssl.h> #include <openssl/err.h> diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 09f5c66f687..27d798f925a 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -2165,7 +2165,6 @@ btr_discard_page( ut_ad(btr_check_node_ptr(tree, merge_page, mtr)); } -#ifdef UNIV_DEBUG /***************************************************************** Prints size info of a B-tree. */ @@ -2287,7 +2286,6 @@ btr_print_tree( btr_validate_tree(tree); } -#endif /* UNIV_DEBUG */ /**************************************************************** Checks that the node pointer to a page is appropriate. */ diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index 268d6f8e16d..5ec8998473d 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -223,14 +223,12 @@ in the free list to the frames. buf_pool_t* buf_pool = NULL; /* The buffer buf_pool of the database */ -#ifdef UNIV_DEBUG -static ulint buf_dbg_counter = 0; /* This is used to insert validation +ulint buf_dbg_counter = 0; /* This is used to insert validation operations in excution in the debug version */ ibool buf_debug_prints = FALSE; /* If this is set TRUE, the program prints info whenever read-ahead or flush occurs */ -#endif /* UNIV_DEBUG */ /************************************************************************ Calculates a page checksum which is stored to the page when it is written @@ -1729,12 +1727,10 @@ buf_page_create( /* If we get here, the page was not in buf_pool: init it there */ -#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Creating space %lu page %lu to buffer\n", (ulong) space, (ulong) offset); } -#endif /* UNIV_DEBUG */ block = free_block; @@ -1885,11 +1881,9 @@ buf_page_io_complete( rw_lock_x_unlock_gen(&(block->lock), BUF_IO_READ); -#ifdef UNIV_DEBUG if (buf_debug_prints) { fputs("Has read ", stderr); } -#endif /* UNIV_DEBUG */ } else { ut_ad(io_type == BUF_IO_WRITE); @@ -1902,21 +1896,17 @@ buf_page_io_complete( buf_pool->n_pages_written++; -#ifdef UNIV_DEBUG if (buf_debug_prints) { fputs("Has written ", stderr); } -#endif /* UNIV_DEBUG */ } mutex_exit(&(buf_pool->mutex)); -#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "page space %lu page no %lu\n", (ulong) block->space, (ulong) block->offset); } -#endif /* UNIV_DEBUG */ } /************************************************************************* @@ -1945,7 +1935,6 @@ buf_pool_invalidate(void) mutex_exit(&(buf_pool->mutex)); } -#ifdef UNIV_DEBUG /************************************************************************* Validates the buffer buf_pool data structure. */ @@ -2145,7 +2134,6 @@ buf_print(void) ut_a(buf_validate()); } -#endif /* UNIV_DEBUG */ /************************************************************************* Returns the number of pending buf pool ios. */ diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index 885bcf06456..6cefdb60956 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -32,7 +32,6 @@ flushed along with the original page. */ #define BUF_FLUSH_AREA ut_min(BUF_READ_AHEAD_AREA,\ buf_pool->curr_size / 16) -#ifdef UNIV_DEBUG /********************************************************************** Validates the flush list. */ static @@ -40,7 +39,6 @@ ibool buf_flush_validate_low(void); /*========================*/ /* out: TRUE if ok */ -#endif /* UNIV_DEBUG */ /************************************************************************ Inserts a modified block into the flush list. */ @@ -513,13 +511,11 @@ buf_flush_try_page( rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE); } -#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Flushing page space %lu, page no %lu \n", (ulong) block->space, (ulong) block->offset); } -#endif /* UNIV_DEBUG */ buf_flush_write_block_low(block); @@ -603,14 +599,12 @@ buf_flush_try_page( rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE); -#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Flushing single page space %lu, page no %lu \n", (ulong) block->space, (ulong) block->offset); } -#endif /* UNIV_DEBUG */ buf_flush_write_block_low(block); @@ -837,7 +831,6 @@ buf_flush_batch( buf_flush_buffered_writes(); -#ifdef UNIV_DEBUG if (buf_debug_prints && page_count > 0) { ut_a(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST); @@ -846,7 +839,6 @@ buf_flush_batch( : "Flushed %lu pages in flush list flush\n", (ulong) page_count); } -#endif /* UNIV_DEBUG */ return(page_count); } @@ -938,7 +930,6 @@ buf_flush_free_margin(void) } } -#ifdef UNIV_DEBUG /********************************************************************** Validates the flush list. */ static @@ -988,4 +979,3 @@ buf_flush_validate(void) return(ret); } -#endif /* UNIV_DEBUG */ diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c index 053161986e4..796311f0157 100644 --- a/innobase/buf/buf0lru.c +++ b/innobase/buf/buf0lru.c @@ -209,14 +209,12 @@ buf_LRU_search_and_free_block( ut_a(block->in_LRU_list); if (buf_flush_ready_for_replace(block)) { -#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Putting space %lu page %lu to free list\n", (ulong) block->space, (ulong) block->offset); } -#endif /* UNIV_DEBUG */ buf_LRU_block_remove_hashed_page(block); @@ -888,7 +886,6 @@ buf_LRU_block_free_hashed_page( buf_LRU_block_free_non_file_page(block); } -#ifdef UNIV_DEBUG /************************************************************************** Validates the LRU list. */ @@ -1019,4 +1016,3 @@ buf_LRU_print(void) mutex_exit(&(buf_pool->mutex)); } -#endif /* UNIV_DEBUG */ diff --git a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c index 63e078f3f6e..71e885ff439 100644 --- a/innobase/buf/buf0rea.c +++ b/innobase/buf/buf0rea.c @@ -284,14 +284,12 @@ buf_read_ahead_random( os_aio_simulated_wake_handler_threads(); -#ifdef UNIV_DEBUG if (buf_debug_prints && (count > 0)) { fprintf(stderr, "Random read-ahead space %lu offset %lu pages %lu\n", (ulong) space, (ulong) offset, (ulong) count); } -#endif /* UNIV_DEBUG */ return(count); } @@ -571,13 +569,11 @@ buf_read_ahead_linear( /* Flush pages from the end of the LRU list if necessary */ buf_flush_free_margin(); -#ifdef UNIV_DEBUG if (buf_debug_prints && (count > 0)) { fprintf(stderr, "LINEAR read-ahead space %lu offset %lu pages %lu\n", (ulong) space, (ulong) offset, (ulong) count); } -#endif /* UNIV_DEBUG */ return(count); } @@ -636,13 +632,11 @@ buf_read_ibuf_merge_pages( /* Flush pages from the end of the LRU list if necessary */ buf_flush_free_margin(); -#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Ibuf merge read-ahead space %lu pages %lu\n", (ulong) space_ids[0], (ulong) n_stored); } -#endif /* UNIV_DEBUG */ } /************************************************************************ @@ -706,10 +700,8 @@ buf_read_recv_pages( /* Flush pages from the end of the LRU list if necessary */ buf_flush_free_margin(); -#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "Recovery applies read-ahead pages %lu\n", (ulong) n_stored); } -#endif /* UNIV_DEBUG */ } diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c index 698b5361dfa..1e08bb41c36 100644 --- a/innobase/data/data0type.c +++ b/innobase/data/data0type.c @@ -123,7 +123,6 @@ dtype_validate( return(TRUE); } -#endif /* UNIV_DEBUG */ /************************************************************************* Prints a data type structure. */ diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index aa5787ee30e..71cf908db4e 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -3488,9 +3488,9 @@ dict_tree_create( tree->id = index->id; UT_LIST_INIT(tree->tree_indexes); -#ifdef UNIV_DEBUG + tree->magic_n = DICT_TREE_MAGIC_N; -#endif /* UNIV_DEBUG */ + rw_lock_create(&(tree->lock)); rw_lock_set_level(&(tree->lock), SYNC_INDEX_TREE); @@ -3929,7 +3929,6 @@ dict_foreign_print_low( fputs(" )\n", stderr); } -#ifdef UNIV_DEBUG /************************************************************************** Prints a table data. */ @@ -3962,7 +3961,6 @@ dict_table_print_by_name( dict_table_print_low(table); mutex_exit(&(dict_sys->mutex)); } -#endif /* UNIV_DEBUG */ /************************************************************************** Prints a table data. */ diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c index 936b06b1905..8f05475df47 100644 --- a/innobase/dict/dict0mem.c +++ b/innobase/dict/dict0mem.c @@ -87,9 +87,9 @@ dict_mem_table_create( mutex_set_level(&(table->autoinc_mutex), SYNC_DICT_AUTOINC_MUTEX); table->autoinc_inited = FALSE; -#ifdef UNIV_DEBUG + table->magic_n = DICT_TABLE_MAGIC_N; -#endif /* UNIV_DEBUG */ + return(table); } @@ -205,9 +205,7 @@ dict_mem_index_create( index->stat_n_diff_key_vals = NULL; index->cached = FALSE; -#ifdef UNIV_DEBUG index->magic_n = DICT_INDEX_MAGIC_N; -#endif /* UNIV_DEBUG */ return(index); } diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c index e7b97e88f32..34b6de76ff4 100644 --- a/innobase/fsp/fsp0fsp.c +++ b/innobase/fsp/fsp0fsp.c @@ -3476,8 +3476,7 @@ fseg_validate_low( return(TRUE); } - -#ifdef UNIV_DEBUG + /*********************************************************************** Validates a segment. */ @@ -3502,7 +3501,6 @@ fseg_validate( return(ret); } -#endif /* UNIV_DEBUG */ /*********************************************************************** Writes info of a segment. */ @@ -3554,7 +3552,6 @@ fseg_print_low( (ulong) n_used); } -#ifdef UNIV_DEBUG /*********************************************************************** Writes info of a segment. */ @@ -3575,7 +3572,6 @@ fseg_print( fseg_print_low(inode, mtr); } -#endif /* UNIV_DEBUG */ /*********************************************************************** Validates the file space system and its segments. */ diff --git a/innobase/fut/fut0lst.c b/innobase/fut/fut0lst.c index 3d92aaba1ef..8deaa8adb3f 100644 --- a/innobase/fut/fut0lst.c +++ b/innobase/fut/fut0lst.c @@ -490,7 +490,6 @@ flst_validate( return(TRUE); } -#ifdef UNIV_DEBUG /************************************************************************ Prints info of a file-based list. */ @@ -517,4 +516,3 @@ flst_print( (ulong) buf_frame_get_page_no(frame), (ulong) (base - frame), (ulong) len); } -#endif /* UNIV_DEBUG */ diff --git a/innobase/ha/hash0hash.c b/innobase/ha/hash0hash.c index 372104e54b3..facdea66198 100644 --- a/innobase/ha/hash0hash.c +++ b/innobase/ha/hash0hash.c @@ -22,7 +22,6 @@ hash_mutex_enter( hash_table_t* table, /* in: hash table */ ulint fold) /* in: fold */ { - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); mutex_enter(hash_get_mutex(table, fold)); } @@ -35,10 +34,41 @@ hash_mutex_exit( hash_table_t* table, /* in: hash table */ ulint fold) /* in: fold */ { - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); mutex_exit(hash_get_mutex(table, fold)); } +/**************************************************************** +Reserves all the mutexes of a hash table, in an ascending order. */ + +void +hash_mutex_enter_all( +/*=================*/ + hash_table_t* table) /* in: hash table */ +{ + ulint i; + + for (i = 0; i < table->n_mutexes; i++) { + + mutex_enter(table->mutexes + i); + } +} + +/**************************************************************** +Releases all the mutexes of a hash table. */ + +void +hash_mutex_exit_all( +/*================*/ + hash_table_t* table) /* in: hash table */ +{ + ulint i; + + for (i = 0; i < table->n_mutexes; i++) { + + mutex_exit(table->mutexes + i); + } +} + /***************************************************************** Creates a hash table with >= n array cells. The actual number of cells is chosen to be a prime number slightly bigger than n. */ @@ -68,9 +98,7 @@ hash_create( table->mutexes = NULL; table->heaps = NULL; table->heap = NULL; -#ifdef UNIV_DEBUG table->magic_n = HASH_TABLE_MAGIC_N; -#endif /* UNIV_DEBUG */ /* Initialize the cell array */ @@ -91,7 +119,6 @@ hash_table_free( /*============*/ hash_table_t* table) /* in, own: hash table */ { - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); ut_a(table->mutexes == NULL); ut_free(table->array); @@ -113,7 +140,6 @@ hash_create_mutexes( ulint i; ut_a(n_mutexes == ut_2_power_up(n_mutexes)); - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); table->mutexes = mem_alloc(n_mutexes * sizeof(mutex_t)); diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index 931fb7f4168..f05e69863a3 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -201,15 +201,13 @@ because ibuf merge is done to a page when it is read in, and it is still physically like the index page even if the index would have been dropped! So, there seems to be no problem. */ -#ifdef UNIV_DEBUG /********************************************************************** Validates the ibuf data structures when the caller owns ibuf_mutex. */ -static + ibool ibuf_validate_low(void); /*===================*/ /* out: TRUE if ok */ -#endif /* UNIV_DEBUG */ /********************************************************************** Sets the flag in the current OS thread local storage denoting that it is @@ -3278,10 +3276,10 @@ leave_loop: mem_heap_free(heap); } -#ifdef UNIV_DEBUG + /********************************************************************** Validates the ibuf data structures when the caller owns ibuf_mutex. */ -static + ibool ibuf_validate_low(void) /*===================*/ @@ -3308,7 +3306,6 @@ ibuf_validate_low(void) return(TRUE); } -#endif /* UNIV_DEBUG */ /********************************************************************** Looks if the insert buffer is empty. */ diff --git a/innobase/include/Makefile.am b/innobase/include/Makefile.am index 5ec70da97a2..102d25566da 100644 --- a/innobase/include/Makefile.am +++ b/innobase/include/Makefile.am @@ -43,7 +43,7 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \ row0purge.ic row0row.h row0row.ic row0sel.h row0sel.ic \ row0types.h row0uins.h row0uins.ic row0umod.h row0umod.ic \ row0undo.h row0undo.ic row0upd.h row0upd.ic row0vers.h \ - row0vers.ic srv0srv.h srv0srv.ic srv0start.h \ + row0vers.ic srv0que.h srv0srv.h srv0srv.ic srv0start.h \ sync0arr.h sync0arr.ic sync0rw.h \ sync0rw.ic sync0sync.h sync0sync.ic sync0types.h \ thr0loc.h thr0loc.ic trx0purge.h trx0purge.ic trx0rec.h \ diff --git a/innobase/include/btr0btr.h b/innobase/include/btr0btr.h index e904db3272f..8606fcd2a5c 100644 --- a/innobase/include/btr0btr.h +++ b/innobase/include/btr0btr.h @@ -392,7 +392,6 @@ btr_page_free_low( page_t* page, /* in: page to be freed, x-latched */ ulint level, /* in: page level */ mtr_t* mtr); /* in: mtr */ -#ifdef UNIV_DEBUG /***************************************************************** Prints size info of a B-tree. */ @@ -409,7 +408,6 @@ btr_print_tree( dict_tree_t* tree, /* in: tree */ ulint width); /* in: print this many entries from start and end */ -#endif /* UNIV_DEBUG */ /**************************************************************** Checks the size and number of fields in a record based on the definition of the index. */ diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index 9590fea1276..53599d03c73 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -54,11 +54,9 @@ Created 11/5/1995 Heikki Tuuri #define BUF_KEEP_OLD 52 extern buf_pool_t* buf_pool; /* The buffer pool of the database */ -#ifdef UNIV_DEBUG extern ibool buf_debug_prints;/* If this is set TRUE, the program prints info whenever read or flush occurs */ -#endif /* UNIV_DEBUG */ /************************************************************************ Creates the buffer pool. */ @@ -478,14 +476,12 @@ buf_pool_is_block( /*==============*/ /* out: TRUE if pointer to block */ void* ptr); /* in: pointer to memory */ -#ifdef UNIV_DEBUG /************************************************************************* Validates the buffer pool data structure. */ ibool buf_validate(void); /*==============*/ -#endif /* UNIV_DEBUG */ /************************************************************************ Prints a page to stderr. */ @@ -897,7 +893,7 @@ struct buf_pool_struct{ ulint n_pend_reads; /* number of pending read operations */ - time_t last_printout_time; /* when buf_print_io was last time + time_t last_printout_time; /* when buf_print was last time called */ ulint n_pages_read; /* number read operations */ ulint n_pages_written;/* number write operations */ @@ -912,10 +908,10 @@ struct buf_pool_struct{ ulint n_pages_awe_remapped; /* if AWE is enabled, the number of remaps of blocks to buffer frames */ - ulint n_page_gets_old;/* n_page_gets when buf_print_io was + ulint n_page_gets_old;/* n_page_gets when buf_print was last time called: used to calculate hit rate */ - ulint n_pages_read_old;/* n_pages_read when buf_print_io was + ulint n_pages_read_old;/* n_pages_read when buf_print was last time called */ ulint n_pages_written_old;/* number write operations */ ulint n_pages_created_old;/* number of pages created in diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index fa8421b63ad..681a0ef000a 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -11,6 +11,10 @@ Created 11/5/1995 Heikki Tuuri #include "buf0rea.h" #include "mtr0mtr.h" +extern ulint buf_dbg_counter; /* This is used to insert validation + operations in execution in the + debug version */ + /************************************************************************ 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 diff --git a/innobase/include/buf0flu.h b/innobase/include/buf0flu.h index 6f39eef7210..1b40acaa269 100644 --- a/innobase/include/buf0flu.h +++ b/innobase/include/buf0flu.h @@ -97,7 +97,6 @@ buf_flush_ready_for_replace( /* out: TRUE if can replace immediately */ buf_block_t* block); /* in: buffer control block, must be in state BUF_BLOCK_FILE_PAGE and in the LRU list */ -#ifdef UNIV_DEBUG /********************************************************************** Validates the flush list. */ @@ -105,7 +104,6 @@ ibool buf_flush_validate(void); /*====================*/ /* out: TRUE if ok */ -#endif /* UNIV_DEBUG */ /* When buf_flush_free_margin is called, it tries to make this many blocks available to replacement in the free list and at the end of the LRU list (to diff --git a/innobase/include/buf0lru.h b/innobase/include/buf0lru.h index 98aa0252e12..69a376f8cab 100644 --- a/innobase/include/buf0lru.h +++ b/innobase/include/buf0lru.h @@ -112,7 +112,6 @@ void buf_LRU_make_block_old( /*===================*/ buf_block_t* block); /* in: control block */ -#ifdef UNIV_DEBUG /************************************************************************** Validates the LRU list. */ @@ -125,7 +124,6 @@ Prints the LRU list. */ void buf_LRU_print(void); /*===============*/ -#endif /* UNIV_DEBUG */ #ifndef UNIV_NONINL #include "buf0lru.ic" diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h index e2de13d0520..2136de0f9b3 100644 --- a/innobase/include/data0data.h +++ b/innobase/include/data0data.h @@ -395,11 +395,9 @@ struct dtuple_struct { UT_LIST_NODE_T(dtuple_t) tuple_list; /* data tuples can be linked into a list using this field */ -#ifdef UNIV_DEBUG - ulint magic_n; -#define DATA_TUPLE_MAGIC_N 65478679 -#endif /* UNIV_DEBUG */ + ulint magic_n; }; +#define DATA_TUPLE_MAGIC_N 65478679 /* A slot for a field in a big rec vector */ diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h index 2138df97392..fe38a224a66 100644 --- a/innobase/include/data0type.h +++ b/innobase/include/data0type.h @@ -305,7 +305,7 @@ dtype_new_read_for_order_and_null_size( /*===================================*/ dtype_t* type, /* in: type struct */ byte* buf); /* in: buffer for stored type order info */ -#ifdef UNIV_DEBUG + /************************************************************************* Validates a data type structure. */ @@ -314,7 +314,6 @@ dtype_validate( /*===========*/ /* out: TRUE if ok */ dtype_t* type); /* in: type struct to validate */ -#endif /* UNIV_DEBUG */ /************************************************************************* Prints a data type structure. */ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index fe04359d6f1..ebb34f7dda0 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -325,19 +325,18 @@ dict_table_get_index_noninline( dict_table_t* table, /* in: table */ const char* name); /* in: index name */ /************************************************************************** -Prints a table data. */ +Prints a table definition. */ void -dict_table_print_low( -/*=================*/ +dict_table_print( +/*=============*/ dict_table_t* table); /* in: table */ -#ifdef UNIV_DEBUG /************************************************************************** -Prints a table definition. */ +Prints a table data. */ void -dict_table_print( -/*=============*/ +dict_table_print_low( +/*=================*/ dict_table_t* table); /* in: table */ /************************************************************************** Prints a table data when we know the table name. */ @@ -346,7 +345,6 @@ void dict_table_print_by_name( /*=====================*/ const char* name); -#endif /* UNIV_DEBUG */ /************************************************************************** Outputs info on foreign keys of a table. */ diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index f141ea9da09..3fc3e850987 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -188,12 +188,11 @@ struct dict_tree_struct{ the list; if the tree is of the mixed type, the first index in the list is the index of the cluster which owns the tree */ -#ifdef UNIV_DEBUG ulint magic_n;/* magic number */ -#define DICT_TREE_MAGIC_N 7545676 -#endif /* UNIV_DEBUG */ }; +#define DICT_TREE_MAGIC_N 7545676 + /* Data structure for an index */ struct dict_index_struct{ dulint id; /* id of the index */ @@ -238,10 +237,7 @@ struct dict_index_struct{ ulint stat_n_leaf_pages; /* approximate number of leaf pages in the index tree */ -#ifdef UNIV_DEBUG ulint magic_n;/* magic number */ -#define DICT_INDEX_MAGIC_N 76789786 -#endif /* UNIV_DEBUG */ }; /* Data structure for a foreign key constraint; an example: @@ -292,6 +288,9 @@ a foreign key constraint is enforced, therefore RESTRICT just means no flag */ #define DICT_FOREIGN_ON_DELETE_NO_ACTION 16 #define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32 + +#define DICT_INDEX_MAGIC_N 76789786 + /* Data structure for a database table */ struct dict_table_struct{ dulint id; /* id of the table or cluster */ @@ -410,12 +409,10 @@ struct dict_table_struct{ inited; MySQL gets the init value by executing SELECT MAX(auto inc column) */ ib_longlong autoinc;/* autoinc counter value to give to the - next inserted row */ -#ifdef UNIV_DEBUG + next inserted row */ ulint magic_n;/* magic number */ -#define DICT_TABLE_MAGIC_N 76333786 -#endif /* UNIV_DEBUG */ }; +#define DICT_TABLE_MAGIC_N 76333786 #ifndef UNIV_NONINL #include "dict0mem.ic" diff --git a/innobase/include/fsp0fsp.h b/innobase/include/fsp0fsp.h index 20f4f4c2abd..2fcde882df7 100644 --- a/innobase/include/fsp0fsp.h +++ b/innobase/include/fsp0fsp.h @@ -332,7 +332,6 @@ void fsp_print( /*======*/ ulint space); /* in: space id */ -#ifdef UNIV_DEBUG /*********************************************************************** Validates a segment. */ @@ -350,7 +349,6 @@ fseg_print( /*=======*/ fseg_header_t* header, /* in: segment header */ mtr_t* mtr); /* in: mtr */ -#endif /* UNIV_DEBUG */ /* Flags for fsp_reserve_free_extents */ #define FSP_NORMAL 1000000 diff --git a/innobase/include/fut0lst.h b/innobase/include/fut0lst.h index 3f679d61ab5..5427e2248da 100644 --- a/innobase/include/fut0lst.h +++ b/innobase/include/fut0lst.h @@ -181,7 +181,6 @@ flst_validate( /* out: TRUE if ok */ flst_base_node_t* base, /* in: pointer to base node of list */ mtr_t* mtr1); /* in: mtr */ -#ifdef UNIV_DEBUG /************************************************************************ Prints info of a file-based list. */ @@ -190,7 +189,7 @@ flst_print( /*=======*/ flst_base_node_t* base, /* in: pointer to base node of list */ mtr_t* mtr); /* in: mtr */ -#endif /* UNIV_DEBUG */ + #ifndef UNIV_NONINL #include "fut0lst.ic" diff --git a/innobase/include/hash0hash.h b/innobase/include/hash0hash.h index 79efe016324..51315e40875 100644 --- a/innobase/include/hash0hash.h +++ b/innobase/include/hash0hash.h @@ -283,6 +283,21 @@ hash_mutex_exit( /*============*/ hash_table_t* table, /* in: hash table */ ulint fold); /* in: fold */ +/**************************************************************** +Reserves all the mutexes of a hash table, in an ascending order. */ + +void +hash_mutex_enter_all( +/*=================*/ + hash_table_t* table); /* in: hash table */ +/**************************************************************** +Releases all the mutexes of a hash table. */ + +void +hash_mutex_exit_all( +/*================*/ + hash_table_t* table); /* in: hash table */ + struct hash_cell_struct{ void* node; /* hash chain node, NULL if none */ @@ -303,12 +318,11 @@ struct hash_table_struct { memory heaps; there are then n_mutexes many of these heaps */ mem_heap_t* heap; -#ifdef UNIV_DEBUG ulint magic_n; -#define HASH_TABLE_MAGIC_N 76561114 -#endif /* UNIV_DEBUG */ }; +#define HASH_TABLE_MAGIC_N 76561114 + #ifndef UNIV_NONINL #include "hash0hash.ic" #endif diff --git a/innobase/include/hash0hash.ic b/innobase/include/hash0hash.ic index 1b9acfa2f34..0d713140c13 100644 --- a/innobase/include/hash0hash.ic +++ b/innobase/include/hash0hash.ic @@ -18,7 +18,6 @@ hash_get_nth_cell( hash_table_t* table, /* in: hash table */ ulint n) /* in: cell index */ { - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); ut_ad(n < table->n_cells); return(table->array + n); @@ -33,7 +32,6 @@ hash_get_n_cells( /* out: number of cells */ hash_table_t* table) /* in: table */ { - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); return(table->n_cells); } @@ -47,7 +45,6 @@ hash_calc_hash( ulint fold, /* in: folded value */ hash_table_t* table) /* in: hash table */ { - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); return(ut_hash_ulint(fold, table->n_cells)); } @@ -61,7 +58,6 @@ hash_get_mutex_no( hash_table_t* table, /* in: hash table */ ulint fold) /* in: fold */ { - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); return(ut_2pow_remainder(fold, table->n_mutexes)); } @@ -75,7 +71,6 @@ hash_get_nth_heap( hash_table_t* table, /* in: hash table */ ulint i) /* in: index of the heap */ { - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); ut_ad(i < table->n_mutexes); return(table->heaps[i]); @@ -93,8 +88,6 @@ hash_get_heap( { ulint i; - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); - if (table->heap) { return(table->heap); } @@ -114,7 +107,6 @@ hash_get_nth_mutex( hash_table_t* table, /* in: hash table */ ulint i) /* in: index of the mutex */ { - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); ut_ad(i < table->n_mutexes); return(table->mutexes + i); diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index b1f9a10ee05..9c5f35c6674 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -19,9 +19,7 @@ Created 5/7/1996 Heikki Tuuri #include "read0types.h" #include "hash0hash.h" -#ifdef UNIV_DEBUG extern ibool lock_print_waits; -#endif /* UNIV_DEBUG */ /* Buffer for storing information about the most recent deadlock error */ extern FILE* lock_latest_err_file; @@ -475,7 +473,6 @@ lock_check_trx_id_sanity( dict_index_t* index, /* in: clustered index */ ibool has_kernel_mutex);/* in: TRUE if the caller owns the kernel mutex */ -#ifdef UNIV_DEBUG /************************************************************************* Validates the lock queue on a single record. */ @@ -485,7 +482,6 @@ lock_rec_queue_validate( /* out: TRUE if ok */ rec_t* rec, /* in: record to look at */ dict_index_t* index); /* in: index, or NULL if not known */ -#endif /* UNIV_DEBUG */ /************************************************************************* Prints info of a table lock. */ @@ -509,7 +505,6 @@ void lock_print_info( /*============*/ FILE* file); /* in: file where to print */ -#ifdef UNIV_DEBUG /************************************************************************* Validates the lock queue on a table. */ @@ -534,7 +529,6 @@ ibool lock_validate(void); /*===============*/ /* out: TRUE if ok */ -#endif /* UNIV_DEBUG */ /* The lock system */ extern lock_sys_t* lock_sys; diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h index 25adc3b24b7..d14a116072d 100644 --- a/innobase/include/log0log.h +++ b/innobase/include/log0log.h @@ -18,9 +18,7 @@ typedef struct log_struct log_t; typedef struct log_group_struct log_group_t; extern ibool log_do_write; -#ifdef UNIV_LOG_DEBUG extern ibool log_debug_writes; -#endif /* UNIV_LOG_DEBUG */ /* Wait modes for log_write_up_to */ #define LOG_NO_WAIT 91 @@ -691,13 +689,11 @@ struct log_struct{ ulint max_buf_free; /* recommended maximum value of buf_free, after which the buffer is flushed */ -#ifdef UNIV_LOG_DEBUG ulint old_buf_free; /* value of buf free when log was last time opened; only in the debug version */ dulint old_lsn; /* value of lsn when log was last time opened; only in the debug version */ -#endif /* UNIV_LOG_DEBUG */ ibool check_flush_or_checkpoint; /* this is set to TRUE when there may be need to flush the log buffer, or diff --git a/innobase/include/log0log.ic b/innobase/include/log0log.ic index 3a4a3c6a5e6..ca7531783a2 100644 --- a/innobase/include/log0log.ic +++ b/innobase/include/log0log.ic @@ -10,7 +10,6 @@ Created 12/9/1995 Heikki Tuuri #include "mach0data.h" #include "mtr0mtr.h" -#ifdef UNIV_LOG_DEBUG /********************************************************** Checks by parsing that the catenated log segment for a single mtr is consistent. */ @@ -22,7 +21,6 @@ log_check_log_recs( in the log_sys->buf log buffer */ ulint len, /* in: segment length in bytes */ dulint buf_start_lsn); /* in: buffer start lsn */ -#endif /* UNIV_LOG_DEBUG */ /**************************************************************** Gets a log block flush bit. */ diff --git a/innobase/include/mem0dbg.h b/innobase/include/mem0dbg.h index 61c66cc218c..96f30842df6 100644 --- a/innobase/include/mem0dbg.h +++ b/innobase/include/mem0dbg.h @@ -31,7 +31,6 @@ check fields at the both ends of the field. */ #define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT) #endif -#ifdef UNIV_DEBUG /******************************************************************* Checks a memory heap for consistency and prints the contents if requested. Outputs the sum of sizes of buffers given to the user (only in @@ -61,7 +60,6 @@ mem_heap_validate_or_print( ulint* n_blocks); /* out: number of blocks in the heap, if a NULL pointer is passed as this argument, it is ignored */ -#endif /* UNIV_DEBUG */ #ifdef UNIV_MEM_DEBUG /****************************************************************** Prints the contents of a memory heap. */ @@ -71,7 +69,6 @@ mem_heap_print( /*===========*/ mem_heap_t* heap); /* in: memory heap */ #endif /* UNIV_MEM_DEBUG */ -#ifdef UNIV_DEBUG /****************************************************************** Checks that an object is a memory heap (or a block of it) */ @@ -88,7 +85,6 @@ mem_heap_validate( /*==============*/ /* out: TRUE if ok */ mem_heap_t* heap); /* in: memory heap */ -#endif /* UNIV_DEBUG */ #ifdef UNIV_MEM_DEBUG /********************************************************************* TRUE if no memory is currently allocated. */ @@ -120,4 +116,17 @@ void mem_analyze_corruption( /*===================*/ byte* ptr); /* in: pointer to place of possible corruption */ +/********************************************************************* +Prints information of dynamic memory usage and currently allocated memory +heaps or buffers. Can only be used in the debug version. */ +void +mem_print_info(void); +/*================*/ +/********************************************************************* +Prints information of dynamic memory usage and currently allocated memory +heaps or buffers since the last ..._print_info or..._print_new_info. */ + +void +mem_print_new_info(void); +/*====================*/ diff --git a/innobase/include/mem0dbg.ic b/innobase/include/mem0dbg.ic index 00db22eb518..7ce5f6f1ba5 100644 --- a/innobase/include/mem0dbg.ic +++ b/innobase/include/mem0dbg.ic @@ -56,7 +56,6 @@ mem_hash_insert( mem_heap_t* heap, /* in: the created heap */ const char* file_name, /* in: file name of creation */ ulint line); /* in: line where created */ -#ifdef UNIV_MEM_DEBUG /******************************************************************* Removes a memory heap (which is going to be freed by the caller) from the list of live memory heaps. Returns the size of the heap @@ -72,7 +71,7 @@ mem_hash_remove( mem_heap_t* heap, /* in: the heap to be freed */ const char* file_name, /* in: file name of freeing */ ulint line); /* in: line where freed */ -#endif /* UNIV_MEM_DEBUG */ + void mem_field_header_set_len(byte* field, ulint len); diff --git a/innobase/include/mem0mem.h b/innobase/include/mem0mem.h index 18bffe5732e..cd01ac77bf3 100644 --- a/innobase/include/mem0mem.h +++ b/innobase/include/mem0mem.h @@ -261,18 +261,6 @@ mem_free_func( const char* file_name, /* in: file name where created */ ulint line /* in: line where created */ ); -/******************************************************************* -Implements realloc. */ -UNIV_INLINE -void* -mem_realloc( -/*========*/ - /* out, own: free storage, - NULL if did not succeed */ - void* buf, /* in: pointer to an old buffer */ - ulint n, /* in: desired number of bytes */ - const char* file_name, /* in: file name where called */ - ulint line); /* in: line where called */ /************************************************************************** Duplicates a NUL-terminated string. */ diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic index df3dbf9b576..d97b7d6c4dd 100644 --- a/innobase/include/mem0mem.ic +++ b/innobase/include/mem0mem.ic @@ -562,24 +562,6 @@ mem_heap_get_size( return(size); } -/******************************************************************* -Implements realloc. */ -UNIV_INLINE -void* -mem_realloc( -/*========*/ - /* out, own: free storage, - NULL if did not succeed */ - void* buf, /* in: pointer to an old buffer */ - ulint n, /* in: desired number of bytes */ - const char* file_name, /* in: file name where called */ - ulint line) /* in: line where called */ -{ - mem_free(buf); - - return(mem_alloc_func(n, file_name, line)); -} - /************************************************************************** Duplicates a NUL-terminated string. */ UNIV_INLINE diff --git a/innobase/include/mem0pool.h b/innobase/include/mem0pool.h index 95cf19676fb..43707bd5f61 100644 --- a/innobase/include/mem0pool.h +++ b/innobase/include/mem0pool.h @@ -83,7 +83,6 @@ Releases the mem pool mutex. */ void mem_pool_mutex_exit(void); /*=====================*/ -#ifdef UNIV_DEBUG /************************************************************************ Validates a memory pool. */ @@ -100,7 +99,7 @@ mem_pool_print_info( /*================*/ FILE* outfile,/* in: output file to write to */ mem_pool_t* pool); /* in: memory pool */ -#endif /* UNIV_DEBUG */ + #ifndef UNIV_NONINL #include "mem0pool.ic" diff --git a/innobase/include/mtr0mtr.h b/innobase/include/mtr0mtr.h index 55fa3d80a42..e8c68a91dad 100644 --- a/innobase/include/mtr0mtr.h +++ b/innobase/include/mtr0mtr.h @@ -246,7 +246,6 @@ mtr_memo_contains( mtr_t* mtr, /* in: mtr */ void* object, /* in: object to search */ ulint type); /* in: type of object */ -#ifdef UNIV_DEBUG /************************************************************* Prints info of an mtr handle. */ @@ -254,7 +253,6 @@ void mtr_print( /*======*/ mtr_t* mtr); /* in: mtr */ -#endif /* UNIV_DEBUG */ /*######################################################################*/ #define MTR_BUF_MEMO_SIZE 200 /* number of slots in memo */ @@ -287,12 +285,7 @@ struct mtr_memo_slot_struct{ /* Mini-transaction handle and buffer */ struct mtr_struct{ -#ifdef UNIV_DEBUG ulint state; /* MTR_ACTIVE, MTR_COMMITTING, MTR_COMMITTED */ -#define MTR_ACTIVE 12231 -#define MTR_COMMITTING 56456 -#define MTR_COMMITTED 34676 -#endif /* UNIV_DEBUG */ dyn_array_t memo; /* memo stack for locks etc. */ dyn_array_t log; /* mini-transaction log */ ibool modifications; @@ -307,12 +300,15 @@ struct mtr_struct{ this mtr */ dulint end_lsn;/* end lsn of the possible log entry for this mtr */ -#ifdef UNIV_DEBUG ulint magic_n; -#define MTR_MAGIC_N 54551 -#endif /* UNIV_DEBUG */ }; +#define MTR_MAGIC_N 54551 + +#define MTR_ACTIVE 12231 +#define MTR_COMMITTING 56456 +#define MTR_COMMITTED 34676 + #ifndef UNIV_NONINL #include "mtr0mtr.ic" #endif diff --git a/innobase/include/pars0opt.h b/innobase/include/pars0opt.h index ac0e885d05a..d091c3ee2d0 100644 --- a/innobase/include/pars0opt.h +++ b/innobase/include/pars0opt.h @@ -43,7 +43,6 @@ opt_find_all_cols( to add new found columns */ plan_t* plan, /* in: plan or NULL */ que_node_t* exp); /* in: expression or condition */ -#ifdef UNIV_SQL_DEBUG /************************************************************************ Prints info of a query plan. */ @@ -51,7 +50,6 @@ void opt_print_query_plan( /*=================*/ sel_node_t* sel_node); /* in: select node */ -#endif /* UNIV_SQL_DEBUG */ #ifndef UNIV_NONINL #include "pars0opt.ic" diff --git a/innobase/include/que0que.h b/innobase/include/que0que.h index a438116781f..e1874edcaf2 100644 --- a/innobase/include/que0que.h +++ b/innobase/include/que0que.h @@ -152,6 +152,17 @@ que_run_threads( /*============*/ que_thr_t* thr); /* in: query thread which is run initially */ /************************************************************************** +After signal handling is finished, returns control to a query graph error +handling routine. (Currently, just returns the control to the root of the +graph so that the graph can communicate an error message to the client.) */ + +void +que_fork_error_handle( +/*==================*/ + trx_t* trx, /* in: trx */ + que_t* fork); /* in: query graph which was run before signal + handling started, NULL not allowed */ +/************************************************************************** Handles an SQL error noticed during query thread execution. At the moment, does nothing! */ @@ -170,15 +181,18 @@ a single worker thread to execute it. This function should be used to end the wait state of a query thread waiting for a lock or a stored procedure completion. */ -que_thr_t* +void que_thr_end_wait( /*=============*/ - /* out: next query thread to run; - NULL if none */ - que_thr_t* thr); /* in: query thread in the + que_thr_t* thr, /* in: query thread in the QUE_THR_LOCK_WAIT, or QUE_THR_PROCEDURE_WAIT, or QUE_THR_SIG_REPLY_WAIT state */ + que_thr_t** next_thr); /* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread */ /************************************************************************** Same as que_thr_end_wait, but no parameter next_thr available. */ @@ -293,6 +307,22 @@ que_thr_peek_stop( mutex reserved is necessary before deciding the actual stopping */ que_thr_t* thr); /* in: query thread */ +/*************************************************************************** +Returns TRUE if the query graph is for a SELECT statement. */ +UNIV_INLINE +ibool +que_graph_is_select( +/*================*/ + /* out: TRUE if a select */ + que_t* graph); /* in: graph */ +/************************************************************************** +Prints info of an SQL query graph node. */ + +void +que_node_print_info( +/*================*/ + que_node_t* node); /* in: query graph node */ + /* Query graph query thread node: the fields are protected by the kernel mutex with the exceptions named below */ diff --git a/innobase/include/que0que.ic b/innobase/include/que0que.ic index a63922f8c80..ae4ed10560f 100644 --- a/innobase/include/que0que.ic +++ b/innobase/include/que0que.ic @@ -238,3 +238,21 @@ que_thr_peek_stop( return(FALSE); } + +/*************************************************************************** +Returns TRUE if the query graph is for a SELECT statement. */ +UNIV_INLINE +ibool +que_graph_is_select( +/*================*/ + /* out: TRUE if a select */ + que_t* graph) /* in: graph */ +{ + if (graph->fork_type == QUE_FORK_SELECT_SCROLL + || graph->fork_type == QUE_FORK_SELECT_NON_SCROLL) { + + return(TRUE); + } + + return(FALSE); +} diff --git a/innobase/include/row0ins.h b/innobase/include/row0ins.h index f3f0b7e8eca..a5b4b74e7fc 100644 --- a/innobase/include/row0ins.h +++ b/innobase/include/row0ins.h @@ -145,12 +145,11 @@ struct ins_node_struct{ entry_list and sys fields are stored here; if this is NULL, entry list should be created and buffers for sys fields in row allocated */ -#ifdef UNIV_DEBUG ulint magic_n; -#define INS_NODE_MAGIC_N 15849075 -#endif /* UNIV_DEBUG */ }; +#define INS_NODE_MAGIC_N 15849075 + /* Insert node types */ #define INS_SEARCHED 0 /* INSERT INTO ... SELECT ... */ #define INS_VALUES 1 /* INSERT INTO ... VALUES ... */ diff --git a/innobase/include/row0upd.h b/innobase/include/row0upd.h index 687e90deee5..f5e0a88231f 100644 --- a/innobase/include/row0upd.h +++ b/innobase/include/row0upd.h @@ -384,12 +384,11 @@ struct upd_node_struct{ sym_node_t* table_sym;/* table node in symbol table */ que_node_t* col_assign_list; /* column assignment list */ -#ifdef UNIV_DEBUG ulint magic_n; -#define UPD_NODE_MAGIC_N 1579975 -#endif /* UNIV_DEBUG */ }; +#define UPD_NODE_MAGIC_N 1579975 + /* Node execution states */ #define UPD_NODE_SET_IX_LOCK 1 /* execution came to the node from a node above and if the field diff --git a/innobase/include/srv0que.h b/innobase/include/srv0que.h new file mode 100644 index 00000000000..05c339cdd32 --- /dev/null +++ b/innobase/include/srv0que.h @@ -0,0 +1,53 @@ +/****************************************************** +Server query execution + +(c) 1996 Innobase Oy + +Created 6/5/1996 Heikki Tuuri +*******************************************************/ + + +#ifndef srv0que_h +#define srv0que_h + +#include "univ.i" +#include "que0types.h" + +/************************************************************************** +Checks if there is work to do in the server task queue. If there is, the +thread starts processing a task. Before leaving, it again checks the task +queue and picks a new task if any exists. This is called by a SRV_WORKER +thread. */ + +void +srv_que_task_queue_check(void); +/*==========================*/ +/************************************************************************** +Performs round-robin on the server tasks. This is called by a SRV_WORKER +thread every second or so. */ + +que_thr_t* +srv_que_round_robin( +/*================*/ + /* out: the new (may be == thr) query thread + to run */ + que_thr_t* thr); /* in: query thread */ +/************************************************************************** +Enqueues a task to server task queue and releases a worker thread, if +there exists one suspended. */ + +void +srv_que_task_enqueue( +/*=================*/ + que_thr_t* thr); /* in: query thread */ +/************************************************************************** +Enqueues a task to server task queue and releases a worker thread, if +there exists one suspended. */ + +void +srv_que_task_enqueue_low( +/*=====================*/ + que_thr_t* thr); /* in: query thread */ + +#endif + diff --git a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h index 63b01ffac80..9a988a03e92 100644 --- a/innobase/include/sync0rw.h +++ b/innobase/include/sync0rw.h @@ -85,7 +85,6 @@ void rw_lock_free( /*=========*/ rw_lock_t* lock); /* in: rw-lock */ -#ifdef UNIV_DEBUG /********************************************************************** Checks that the rw-lock has been initialized and that there are no simultaneous shared and exclusive locks. */ @@ -94,7 +93,6 @@ ibool rw_lock_validate( /*=============*/ rw_lock_t* lock); -#endif /* UNIV_DEBUG */ /****************************************************************** NOTE! The following macros should be used in rw s-locking, not the corresponding function. */ diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index 4307ca5ba0c..8e0ec715b12 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -143,7 +143,6 @@ void sync_print( /*=======*/ FILE* file); /* in: file where to print */ -#ifdef UNIV_DEBUG /********************************************************************** Checks that the mutex has been initialized. */ @@ -151,7 +150,6 @@ ibool mutex_validate( /*===========*/ mutex_t* mutex); -#endif /* UNIV_DEBUG */ /********************************************************************** Sets the mutex latching level field. */ diff --git a/innobase/include/trx0roll.h b/innobase/include/trx0roll.h index aa88fc249fc..6004551f456 100644 --- a/innobase/include/trx0roll.h +++ b/innobase/include/trx0roll.h @@ -91,12 +91,16 @@ trx_undo_rec_release( /************************************************************************* Starts a rollback operation. */ -que_thr_t* +void trx_rollback( /*=========*/ - /* out: next query thread to run */ trx_t* trx, /* in: transaction */ - trx_sig_t* sig); /* in: signal starting the rollback */ + trx_sig_t* sig, /* in: signal starting the rollback */ + que_thr_t** next_thr);/* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread */ /*********************************************************************** Rollback or clean up transactions which have no user session. If the transaction already was committed, then we clean up a possible insert @@ -108,12 +112,17 @@ trx_rollback_or_clean_all_without_sess(void); /******************************************************************** Finishes a transaction rollback. */ -que_thr_t* +void trx_finish_rollback_off_kernel( /*===========================*/ - /* out: next query thread to run */ que_t* graph, /* in: undo graph which can now be freed */ - trx_t* trx); /* in: transaction */ + trx_t* trx, /* in: transaction */ + que_thr_t** next_thr);/* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread; if this parameter is + NULL, it is ignored */ /******************************************************************** Builds an undo 'query' graph for a transaction. The actual rollback is performed by executing this query graph like a query subprocedure call. diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 9b7ac22e617..a8c1df534da 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -194,10 +194,9 @@ trx_end_lock_wait( /******************************************************************** Sends a signal to a trx object. */ -que_thr_t* +ibool trx_sig_send( /*=========*/ - /* out: next query thread to run */ /* out: TRUE if the signal was successfully delivered */ trx_t* trx, /* in: trx handle */ @@ -207,17 +206,27 @@ trx_sig_send( que_thr_t* receiver_thr, /* in: query thread which wants the reply, or NULL; if type is TRX_SIG_END_WAIT, this must be NULL */ - trx_savept_t* savept); /* in: possible rollback savepoint, or + trx_savept_t* savept, /* in: possible rollback savepoint, or NULL */ + que_thr_t** next_thr); /* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread; if the parameter + is NULL, it is ignored */ /******************************************************************** Send the reply message when a signal in the queue of the trx has been handled. */ -que_thr_t* +void trx_sig_reply( /*==========*/ - /* out: next query thread to run */ - trx_sig_t* sig); /* in: signal */ + trx_sig_t* sig, /* in: signal */ + que_thr_t** next_thr); /* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread */ /******************************************************************** Removes the signal object from a trx signal queue. */ @@ -229,11 +238,15 @@ trx_sig_remove( /******************************************************************** Starts handling of a trx signal. */ -que_thr_t* +void trx_sig_start_handle( /*=================*/ - /* out: next query thread to run, or NULL */ - trx_t* trx); /* in: trx handle */ + trx_t* trx, /* in: trx handle */ + que_thr_t** next_thr); /* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread */ /******************************************************************** Ends signal handling. If the session is in the error state, and trx->graph_before_signal_handling != NULL, returns control to the error diff --git a/innobase/include/usr0sess.h b/innobase/include/usr0sess.h index aeff7191e68..c7bcfb20fed 100644 --- a/innobase/include/usr0sess.h +++ b/innobase/include/usr0sess.h @@ -38,6 +38,7 @@ sess_try_close( /* The session handle. All fields are protected by the kernel mutex */ struct sess_struct{ + ulint state; /* state of the session */ trx_t* trx; /* transaction object permanently assigned for the session: the transaction instance designated by the @@ -48,6 +49,11 @@ struct sess_struct{ session */ }; +/* Session states */ +#define SESS_ACTIVE 1 +#define SESS_ERROR 2 /* session contains an error message + which has not yet been communicated + to the client */ #ifndef UNIV_NONINL #include "usr0sess.ic" #endif diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index 85b99efff68..2e02b3f0b6b 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -67,6 +67,37 @@ ut_free( /*====*/ void* ptr); /* in, own: memory block */ /************************************************************************** +Implements realloc. This is needed by /pars/lexyy.c. Otherwise, you should not +use this function because the allocation functions in mem0mem.h are the +recommended ones in InnoDB. + +man realloc in Linux, 2004: + + realloc() changes the size of the memory block pointed to + by ptr to size bytes. The contents will be unchanged to + the minimum of the old and new sizes; newly allocated mem + ory will be uninitialized. If ptr is NULL, the call is + equivalent to malloc(size); if size is equal to zero, the + call is equivalent to free(ptr). Unless ptr is NULL, it + must have been returned by an earlier call to malloc(), + calloc() or realloc(). + +RETURN VALUE + realloc() returns a pointer to the newly allocated memory, + which is suitably aligned for any kind of variable and may + be different from ptr, or NULL if the request fails. If + size was equal to 0, either NULL or a pointer suitable to + be passed to free() is returned. If realloc() fails the + original block is left untouched - it is not freed or + moved. */ + +void* +ut_realloc( +/*=======*/ + /* out, own: pointer to new mem block or NULL */ + void* ptr, /* in: pointer to old block or NULL */ + ulint size); /* in: desired size */ +/************************************************************************** Frees in shutdown all allocated memory not freed yet. */ void diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 58c88f67017..be0806590a9 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -292,9 +292,7 @@ waiting, in its lock queue. Solution: We can copy the locks as gap type locks, so that also the waiting locks are transformed to granted gap type locks on the inserted record. */ -#ifdef UNIV_DEBUG ibool lock_print_waits = FALSE; -#endif /* UNIV_DEBUG */ /* The lock system */ lock_sys_t* lock_sys = NULL; @@ -1354,8 +1352,7 @@ lock_rec_has_expl( return(NULL); } - -#ifdef UNIV_DEBUG + /************************************************************************* Checks if some other transaction has a lock request in the queue. */ static @@ -1398,7 +1395,6 @@ lock_rec_other_has_expl_req( return(NULL); } -#endif /* UNIV_DEBUG */ /************************************************************************* Checks if some other transaction has a conflicting explicit lock request @@ -1688,13 +1684,11 @@ lock_rec_enqueue_waiting( ut_a(que_thr_stop(thr)); -#ifdef UNIV_DEBUG if (lock_print_waits) { fprintf(stderr, "Lock wait for trx %lu in index ", (ulong) ut_dulint_get_low(trx->id)); ut_print_name(stderr, index->name); } -#endif /* UNIV_DEBUG */ return(DB_LOCK_WAIT); } @@ -2034,12 +2028,10 @@ lock_grant( lock->trx->n_tables_locked++; } -#ifdef UNIV_DEBUG if (lock_print_waits) { fprintf(stderr, "Lock wait for trx %lu ends\n", (ulong) ut_dulint_get_low(lock->trx->id)); } -#endif /* UNIV_DEBUG */ /* If we are resolving a deadlock by choosing another transaction as a victim, then our original transaction may not be in the @@ -3110,11 +3102,9 @@ lock_deadlock_recursive( lock_table_print(ef, start->wait_lock); } -#ifdef UNIV_DEBUG if (lock_print_waits) { fputs("Deadlock detected\n", stderr); } -#endif /* UNIV_DEBUG */ if (ut_dulint_cmp(wait_lock->trx->undo_no, start->undo_no) >= 0) { @@ -4177,7 +4167,6 @@ loop: goto loop; } -#ifdef UNIV_DEBUG /************************************************************************* Validates the lock queue on a table. */ @@ -4488,7 +4477,6 @@ lock_validate(void) return(TRUE); } -#endif /* UNIV_DEBUG */ /*============ RECORD LOCK CHECKS FOR ROW OPERATIONS ====================*/ diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index 7d7c7dcf998..923ab448e07 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -32,9 +32,9 @@ ulint log_fsp_current_free_limit = 0; log_t* log_sys = NULL; ibool log_do_write = TRUE; -#ifdef UNIV_LOG_DEBUG + ibool log_debug_writes = FALSE; -#endif /* UNIV_LOG_DEBUG */ + /* These control how often we print warnings if the last checkpoint is too old */ @@ -945,12 +945,10 @@ log_group_check_flush_completion( #endif /* UNIV_SYNC_DEBUG */ if (!log_sys->one_flushed && group->n_pending_writes == 0) { -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "Log flushed first to group %lu\n", (ulong) group->id); } -#endif /* UNIV_LOG_DEBUG */ log_sys->written_to_some_lsn = log_sys->write_lsn; log_sys->one_flushed = TRUE; @@ -958,12 +956,10 @@ log_group_check_flush_completion( return(LOG_UNLOCK_NONE_FLUSHED_LOCK); } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes && (group->n_pending_writes == 0)) { fprintf(stderr, "Log flushed to group %lu\n", (ulong) group->id); } -#endif /* UNIV_LOG_DEBUG */ return(0); } @@ -1041,13 +1037,11 @@ log_io_complete( fil_flush(group->space_id); } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "Checkpoint info written to group %lu\n", group->id); } -#endif /* UNIV_LOG_DEBUG */ log_io_complete_checkpoint(); @@ -1110,13 +1104,11 @@ log_group_file_header_flush( dest_offset = nth_file * group->file_size; -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "Writing log file header to group %lu file %lu\n", (ulong) group->id, (ulong) nth_file); } -#endif /* UNIV_LOG_DEBUG */ if (log_do_write) { log_sys->n_log_ios++; @@ -1200,7 +1192,6 @@ loop: write_len = len; } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, @@ -1224,7 +1215,6 @@ loop: + i * OS_FILE_LOG_BLOCK_SIZE)); } } -#endif /* UNIV_LOG_DEBUG */ /* Calculate the checksums for each log block and write them to the trailer fields of the log blocks */ @@ -1352,7 +1342,6 @@ loop: return; } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "Writing log from %lu %lu up to lsn %lu %lu\n", @@ -1361,7 +1350,6 @@ loop: (ulong) ut_dulint_get_high(log_sys->lsn), (ulong) ut_dulint_get_low(log_sys->lsn)); } -#endif /* UNIV_LOG_DEBUG */ log_sys->n_pending_writes++; @@ -1931,14 +1919,12 @@ log_checkpoint( log_sys->next_checkpoint_lsn = oldest_lsn; -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "Making checkpoint no %lu at lsn %lu %lu\n", (ulong) ut_dulint_get_low(log_sys->next_checkpoint_no), (ulong) ut_dulint_get_high(oldest_lsn), (ulong) ut_dulint_get_low(oldest_lsn)); } -#endif /* UNIV_LOG_DEBUG */ log_groups_write_checkpoint_info(); @@ -2319,11 +2305,9 @@ loop: exit(1); } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "Created archive file %s\n", name); } -#endif /* UNIV_LOG_DEBUG */ ret = os_file_close(file_handle); @@ -2350,7 +2334,6 @@ loop: len = group->file_size - (next_offset % group->file_size); } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "Archiving starting at lsn %lu %lu, len %lu to group %lu\n", @@ -2358,7 +2341,6 @@ loop: (ulong) ut_dulint_get_low(start_lsn), (ulong) len, (ulong) group->id); } -#endif /* UNIV_LOG_DEBUG */ log_sys->n_pending_archive_ios++; @@ -2449,13 +2431,11 @@ log_archive_write_complete_groups(void) trunc_files = n_files - 1; } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes && trunc_files) { fprintf(stderr, "Complete file(s) archived to group %lu\n", (ulong) group->id); } -#endif /* UNIV_LOG_DEBUG */ /* Calculate the archive file space start lsn */ start_lsn = ut_dulint_subtract(log_sys->next_archived_lsn, @@ -2478,11 +2458,9 @@ log_archive_write_complete_groups(void) fil_space_truncate_start(group->archive_space_id, trunc_files * group->file_size); -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fputs("Archiving writes completed\n", stderr); } -#endif /* UNIV_LOG_DEBUG */ } /********************************************************** @@ -2499,11 +2477,9 @@ log_archive_check_completion_low(void) if (log_sys->n_pending_archive_ios == 0 && log_sys->archiving_phase == LOG_ARCHIVE_READ) { -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fputs("Archiving read completed\n", stderr); } -#endif /* UNIV_LOG_DEBUG */ /* Archive buffer has now been read in: start archive writes */ @@ -2647,7 +2623,6 @@ loop: log_sys->next_archived_lsn = limit_lsn; -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "Archiving from lsn %lu %lu to lsn %lu %lu\n", @@ -2656,7 +2631,6 @@ loop: (ulong) ut_dulint_get_high(limit_lsn), (ulong) ut_dulint_get_low(limit_lsn)); } -#endif /* UNIV_LOG_DEBUG */ /* Read the log segment to the archive buffer */ @@ -2759,14 +2733,12 @@ log_archive_close_groups( group->archived_file_no += 2; } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "Incrementing arch file no to %lu in log group %lu\n", (ulong) group->archived_file_no + 2, (ulong) group->id); } -#endif /* UNIV_LOG_DEBUG */ } } @@ -3181,7 +3153,6 @@ loop: ut_a(0 == ut_dulint_cmp(lsn, log_sys->lsn)); } -#ifdef UNIV_LOG_DEBUG /********************************************************** Checks by parsing that the catenated log segment for a single mtr is consistent. */ @@ -3234,7 +3205,6 @@ log_check_log_recs( return(TRUE); } -#endif /* UNIV_LOG_DEBUG */ /********************************************************** Peeks the current lsn. */ diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 49d537d23db..a1e9ae8c288 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -189,7 +189,6 @@ recv_sys_empty_hash(void) recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 256); } -#ifndef UNIV_LOG_DEBUG /************************************************************ Frees the recovery system. */ static @@ -209,7 +208,6 @@ recv_sys_free(void) mutex_exit(&(recv_sys->mutex)); } -#endif /* !UNIV_LOG_DEBUG */ /************************************************************ Truncates possible corrupted or extra records from a log group. */ @@ -491,7 +489,6 @@ recv_find_max_checkpoint( log_group_read_checkpoint_info(group, field); if (!recv_check_cp_is_consistent(buf)) { -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "InnoDB: Checkpoint in group %lu at %lu invalid, %lu\n", @@ -501,7 +498,6 @@ recv_find_max_checkpoint( + LOG_CHECKPOINT_CHECKSUM_1)); } -#endif /* UNIV_LOG_DEBUG */ goto not_consistent; } @@ -515,14 +511,12 @@ recv_find_max_checkpoint( checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO); -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "InnoDB: Checkpoint number %lu found in group %lu\n", (ulong) ut_dulint_get_low(checkpoint_no), (ulong) group->id); } -#endif /* UNIV_LOG_DEBUG */ if (ut_dulint_cmp(checkpoint_no, max_no) >= 0) { *max_group = group; @@ -1146,7 +1140,6 @@ recv_recover_page( start_lsn = recv->start_lsn; } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "InnoDB: Applying log rec type %lu len %lu to space %lu page no %lu\n", @@ -1154,7 +1147,6 @@ recv_recover_page( (ulong) recv_addr->space, (ulong) recv_addr->page_no); } -#endif /* UNIV_LOG_DEBUG */ recv_parse_or_apply_log_rec_body(recv->type, buf, buf + recv->len, page, &mtr); @@ -1397,7 +1389,6 @@ loop: mutex_exit(&(recv_sys->mutex)); } -#ifdef UNIV_HOTBACKUP /* This page is allocated from the buffer pool and used in the function below */ page_t* recv_backup_application_page = NULL; @@ -1524,7 +1515,7 @@ skip_this_recv_addr: } #endif /* UNIV_HOTBACKUP */ -#ifdef UNIV_LOG_REPLICATE +#ifdef notdefined /*********************************************************************** In the debug version, updates the replica of a file page, based on a log record. */ @@ -1820,11 +1811,10 @@ recv_calc_lsn_on_data_add( return(ut_dulint_add(lsn, lsn_len)); } -#ifdef UNIV_LOG_DEBUG /*********************************************************** Checks that the parser recognizes incomplete initial segments of a log record as incomplete. */ -static + void recv_check_incomplete_log_recs( /*===========================*/ @@ -1842,7 +1832,6 @@ recv_check_incomplete_log_recs( &page_no, &body)); } } -#endif /* UNIV_LOG_DEBUG */ /*********************************************************** Prints diagnostic info of corrupt log. */ @@ -1979,14 +1968,12 @@ loop: recv_sys->recovered_offset += len; recv_sys->recovered_lsn = new_recovered_lsn; -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "InnoDB: Parsed a single log rec type %lu len %lu space %lu page no %lu\n", (ulong) type, (ulong) len, (ulong) space, (ulong) page_no); } -#endif /* UNIV_LOG_DEBUG */ if (type == MLOG_DUMMY_RECORD) { /* Do nothing */ @@ -2070,14 +2057,12 @@ loop: #endif /* UNIV_LOG_REPLICATE */ } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "InnoDB: Parsed a multi log rec type %lu len %lu space %lu page no %lu\n", (ulong) type, (ulong) len, (ulong) space, (ulong) page_no); } -#endif /* UNIV_LOG_DEBUG */ total_len += len; n_recs++; @@ -2484,7 +2469,6 @@ recv_group_scan_log_recs( start_lsn = end_lsn; } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "InnoDB: Scanned group %lu up to log sequence number %lu %lu\n", @@ -2492,7 +2476,6 @@ recv_group_scan_log_recs( (ulong) ut_dulint_get_high(*group_scanned_lsn), (ulong) ut_dulint_get_low(*group_scanned_lsn)); } -#endif /* UNIV_LOG_DEBUG */ } /************************************************************ @@ -2879,12 +2862,10 @@ recv_recovery_from_checkpoint_finish(void) recv_apply_hashed_log_recs(TRUE); } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "InnoDB: Log records applied to the database\n"); } -#endif /* UNIV_LOG_DEBUG */ if (recv_needed_recovery) { trx_sys_print_mysql_master_log_pos(); @@ -3214,7 +3195,6 @@ ask_again: break; } -#ifdef UNIV_LOG_DEBUG if (log_debug_writes) { fprintf(stderr, "InnoDB: Archive read starting at lsn %lu %lu, len %lu from file %s\n", @@ -3222,7 +3202,6 @@ ask_again: (ulong) ut_dulint_get_low(start_lsn), (ulong) len, name); } -#endif /* UNIV_LOG_DEBUG */ fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, group->archive_space_id, read_offset / UNIV_PAGE_SIZE, diff --git a/innobase/mem/mem0dbg.c b/innobase/mem/mem0dbg.c index d86784cb048..f46984f6bb3 100644 --- a/innobase/mem/mem0dbg.c +++ b/innobase/mem/mem0dbg.c @@ -373,7 +373,6 @@ mem_hash_remove( } #endif /* UNIV_MEM_DEBUG */ -#ifdef UNIV_DEBUG /******************************************************************* Checks a memory heap for consistency and prints the contents if requested. Outputs the sum of sizes of buffers given to the user (only in @@ -603,7 +602,6 @@ mem_heap_validate( return(TRUE); } -#endif /* UNIV_DEBUG */ #ifdef UNIV_MEM_DEBUG /********************************************************************* @@ -816,3 +814,128 @@ mem_analyze_corruption( dist++; } } + +/********************************************************************* +Prints information of dynamic memory usage and currently allocated +memory heaps or buffers. Can only be used in the debug version. */ +static +void +mem_print_info_low( +/*===============*/ + ibool print_all) /* in: if TRUE, all heaps are printed, + else only the heaps allocated after the + previous call of this function */ +{ +#ifdef UNIV_MEM_DEBUG + mem_hash_node_t* node; + ulint n_heaps = 0; + ulint allocated_mem; + ulint ph_size; + ulint total_allocated_mem = 0; + ibool error; + ulint n_blocks; +#endif + FILE* outfile; + + /* outfile = fopen("ibdebug", "a"); */ + + outfile = stdout; + + fprintf(outfile, "\n"); + fprintf(outfile, + "________________________________________________________\n"); + fprintf(outfile, "MEMORY ALLOCATION INFORMATION\n\n"); + +#ifndef UNIV_MEM_DEBUG + + UT_NOT_USED(print_all); + + mem_pool_print_info(outfile, mem_comm_pool); + + fprintf(outfile, + "Sorry, non-debug version cannot give more memory info\n"); + + /* fclose(outfile); */ + + return; +#else + mutex_enter(&mem_hash_mutex); + + fprintf(outfile, "LIST OF CREATED HEAPS AND ALLOCATED BUFFERS: \n\n"); + + if (!print_all) { + fprintf(outfile, "AFTER THE LAST PRINT INFO\n"); + } + + node = UT_LIST_GET_FIRST(mem_all_list_base); + + while (node != NULL) { + n_heaps++; + + if (!print_all && node->nth_heap < mem_last_print_info) { + + goto next_heap; + } + + mem_heap_validate_or_print(node->heap, NULL, + FALSE, &error, &allocated_mem, + &ph_size, &n_blocks); + total_allocated_mem += allocated_mem; + + fprintf(outfile, + "%lu: file %s line %lu of size %lu phys.size %lu with %lu blocks, type %lu\n", + node->nth_heap, node->file_name, node->line, + allocated_mem, ph_size, n_blocks, + (node->heap)->type); + next_heap: + node = UT_LIST_GET_NEXT(all_list, node); + } + + fprintf(outfile, "\n"); + + fprintf(outfile, "Current allocated memory : %lu\n", + mem_current_allocated_memory); + fprintf(outfile, "Current allocated heaps and buffers : %lu\n", + n_heaps); + fprintf(outfile, "Cumulative allocated memory : %lu\n", + mem_total_allocated_memory); + fprintf(outfile, "Maximum allocated memory : %lu\n", + mem_max_allocated_memory); + fprintf(outfile, "Cumulative created heaps and buffers : %lu\n", + mem_n_created_heaps); + fprintf(outfile, "Cumulative number of allocations : %lu\n", + mem_n_allocations); + + mem_last_print_info = mem_n_created_heaps; + + mutex_exit(&mem_hash_mutex); + + mem_pool_print_info(outfile, mem_comm_pool); + +/* mem_validate(); */ + +/* fclose(outfile); */ +#endif +} + +/********************************************************************* +Prints information of dynamic memory usage and currently allocated memory +heaps or buffers. Can only be used in the debug version. */ + +void +mem_print_info(void) +/*================*/ +{ + mem_print_info_low(TRUE); +} + +/********************************************************************* +Prints information of dynamic memory usage and currently allocated memory +heaps or buffers since the last ..._print_info or..._print_new_info. */ + +void +mem_print_new_info(void) +/*====================*/ +{ + mem_print_info_low(FALSE); +} diff --git a/innobase/mem/mem0pool.c b/innobase/mem/mem0pool.c index 0227c2d0969..023369e8ec5 100644 --- a/innobase/mem/mem0pool.c +++ b/innobase/mem/mem0pool.c @@ -559,7 +559,6 @@ mem_area_free( ut_ad(mem_pool_validate(pool)); } -#ifdef UNIV_DEBUG /************************************************************************ Validates a memory pool. */ @@ -637,7 +636,6 @@ mem_pool_print_info( (ulong) pool->reserved); mutex_exit(&(pool->mutex)); } -#endif /* UNIV_DEBUG */ /************************************************************************ Returns the amount of reserved memory. */ diff --git a/innobase/mtr/mtr0mtr.c b/innobase/mtr/mtr0mtr.c index deb4dabde4b..6e918806eb1 100644 --- a/innobase/mtr/mtr0mtr.c +++ b/innobase/mtr/mtr0mtr.c @@ -319,7 +319,6 @@ mtr_read_dulint( return(mach_read_from_8(ptr)); } -#ifdef UNIV_DEBUG /************************************************************* Prints info of an mtr handle. */ @@ -333,4 +332,3 @@ mtr_print( (ulong) dyn_array_get_data_size(&(mtr->memo)), (ulong) dyn_array_get_data_size(&(mtr->log))); } -#endif /* UNIV_DEBUG */ diff --git a/innobase/pars/lexyy.c b/innobase/pars/lexyy.c index 1b8c69ccc7a..d98d3c9b945 100644 --- a/innobase/pars/lexyy.c +++ b/innobase/pars/lexyy.c @@ -636,9 +636,9 @@ Linux. #include "mem0mem.h" #include "os0proc.h" -#define malloc(A) mem_alloc(A) -#define free(A) mem_free(A) -#define realloc(P, A) mem_realloc(P, A, __FILE__, __LINE__) +#define malloc(A) ut_malloc(A) +#define free(A) ut_free(A) +#define realloc(P, A) ut_realloc(P, A) #define exit(A) ut_error #define YY_INPUT(buf, result, max_size) pars_get_lex_chars(buf, &result, max_size) @@ -655,16 +655,16 @@ string_append( const char* str, /* in: string to be appended */ ulint len) /* in: length of the string */ { + if (stringbuf == NULL) { + stringbuf = malloc(1); + stringbuf_len_alloc = 1; + } + if (stringbuf_len + len > stringbuf_len_alloc) { - if (stringbuf_len_alloc == 0) { - stringbuf_len_alloc++; - } while (stringbuf_len + len > stringbuf_len_alloc) { stringbuf_len_alloc <<= 1; } - stringbuf = stringbuf - ? realloc(stringbuf, stringbuf_len_alloc) - : malloc(stringbuf_len_alloc); + stringbuf = realloc(stringbuf, stringbuf_len_alloc); } memcpy(stringbuf + stringbuf_len, str, len); diff --git a/innobase/pars/pars0lex.l b/innobase/pars/pars0lex.l index 0b1af554bed..4e2399613cb 100644 --- a/innobase/pars/pars0lex.l +++ b/innobase/pars/pars0lex.l @@ -58,9 +58,9 @@ Linux. #include "mem0mem.h" #include "os0proc.h" -#define malloc(A) mem_alloc(A) -#define free(A) mem_free(A) -#define realloc(P, A) mem_realloc(P, A, __FILE__, __LINE__) +#define malloc(A) ut_malloc(A) +#define free(A) ut_free(A) +#define realloc(P, A) ut_realloc(P, A) #define exit(A) ut_error #define YY_INPUT(buf, result, max_size) pars_get_lex_chars(buf, &result, max_size) @@ -77,16 +77,16 @@ string_append( const char* str, /* in: string to be appended */ ulint len) /* in: length of the string */ { + if (stringbuf == NULL) { + stringbuf = malloc(1); + stringbuf_len_alloc = 1; + } + if (stringbuf_len + len > stringbuf_len_alloc) { - if (stringbuf_len_alloc == 0) { - stringbuf_len_alloc++; - } while (stringbuf_len + len > stringbuf_len_alloc) { stringbuf_len_alloc <<= 1; } - stringbuf = stringbuf - ? realloc(stringbuf, stringbuf_len_alloc) - : malloc(stringbuf_len_alloc); + stringbuf = realloc(stringbuf, stringbuf_len_alloc); } memcpy(stringbuf + stringbuf_len, str, len); diff --git a/innobase/pars/pars0opt.c b/innobase/pars/pars0opt.c index 4fb0c937f1e..7ba4af15243 100644 --- a/innobase/pars/pars0opt.c +++ b/innobase/pars/pars0opt.c @@ -1190,7 +1190,6 @@ opt_search_plan( #endif } -#ifdef UNIV_SQL_DEBUG /************************************************************************ Prints info of a query plan. */ @@ -1237,4 +1236,3 @@ opt_print_query_plan( (unsigned long) UT_LIST_GET_LEN(plan->end_conds)); } } -#endif /* UNIV_SQL_DEBUG */ diff --git a/innobase/que/que0que.c b/innobase/que/que0que.c index 363376a72da..22878dec27f 100644 --- a/innobase/que/que0que.c +++ b/innobase/que/que0que.c @@ -12,6 +12,7 @@ Created 5/27/1996 Heikki Tuuri #include "que0que.ic" #endif +#include "srv0que.h" #include "usr0sess.h" #include "trx0trx.h" #include "trx0roll.h" @@ -174,15 +175,19 @@ a single worker thread to execute it. This function should be used to end the wait state of a query thread waiting for a lock or a stored procedure completion. */ -que_thr_t* +void que_thr_end_wait( /*=============*/ - /* out: next query thread to run; - NULL if none */ - que_thr_t* thr) /* in: query thread in the + que_thr_t* thr, /* in: query thread in the QUE_THR_LOCK_WAIT, or QUE_THR_PROCEDURE_WAIT, or QUE_THR_SIG_REPLY_WAIT state */ + que_thr_t** next_thr) /* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread; if NULL is passed + as the parameter, it is ignored */ { ibool was_active; @@ -201,8 +206,18 @@ que_thr_end_wait( que_thr_move_to_run_state(thr); - return(was_active ? NULL : thr); -} + if (was_active) { + + return; + } + + if (next_thr && *next_thr == NULL) { + *next_thr = thr; + } else { + ut_a(0); + srv_que_task_enqueue_low(thr); + } +} /************************************************************************** Same as que_thr_end_wait, but no parameter next_thr available. */ @@ -239,6 +254,8 @@ que_thr_end_wait_no_next_thr( for the lock to be released: */ srv_release_mysql_thread_if_suspended(thr); + + /* srv_que_task_enqueue_low(thr); */ } /************************************************************************** @@ -339,6 +356,49 @@ que_fork_start_command( return(NULL); } +/************************************************************************** +After signal handling is finished, returns control to a query graph error +handling routine. (Currently, just returns the control to the root of the +graph so that the graph can communicate an error message to the client.) */ + +void +que_fork_error_handle( +/*==================*/ + trx_t* trx __attribute__((unused)), /* in: trx */ + que_t* fork) /* in: query graph which was run before signal + handling started, NULL not allowed */ +{ + que_thr_t* thr; + +#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&kernel_mutex)); +#endif /* UNIV_SYNC_DEBUG */ + ut_ad(trx->sess->state == SESS_ERROR); + ut_ad(UT_LIST_GET_LEN(trx->reply_signals) == 0); + ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0); + + thr = UT_LIST_GET_FIRST(fork->thrs); + + while (thr != NULL) { + ut_ad(!thr->is_active); + ut_ad(thr->state != QUE_THR_SIG_REPLY_WAIT); + ut_ad(thr->state != QUE_THR_LOCK_WAIT); + + thr->run_node = thr; + thr->prev_node = thr->child; + thr->state = QUE_THR_COMPLETED; + + thr = UT_LIST_GET_NEXT(thrs, thr); + } + + thr = UT_LIST_GET_FIRST(fork->thrs); + + que_thr_move_to_run_state(thr); + + ut_a(0); + srv_que_task_enqueue_low(thr); +} + /******************************************************************** Tests if all the query threads in the same fork have a given state. */ UNIV_INLINE @@ -707,18 +767,22 @@ this function may only be called from inside que_run_threads or que_thr_check_if_switch! These restrictions exist to make the rollback code easier to maintain. */ static -que_thr_t* +void que_thr_dec_refer_count( /*====================*/ - /* out: next query thread to run */ - que_thr_t* thr) /* in: query thread */ + que_thr_t* thr, /* in: query thread */ + que_thr_t** next_thr) /* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread */ { que_fork_t* fork; trx_t* trx; sess_t* sess; ulint fork_type; - que_thr_t* next_thr = NULL; - + ibool stopped; + fork = thr->common.parent; trx = thr->graph->trx; sess = trx->sess; @@ -729,7 +793,9 @@ que_thr_dec_refer_count( if (thr->state == QUE_THR_RUNNING) { - if (!que_thr_stop(thr)) { + stopped = que_thr_stop(thr); + + if (!stopped) { /* The reason for the thr suspension or wait was already canceled before we came here: continue running the thread */ @@ -737,9 +803,16 @@ que_thr_dec_refer_count( /* fputs("!!!!!!!! Wait already ended: continue thr\n", stderr); */ + if (next_thr && *next_thr == NULL) { + *next_thr = thr; + } else { + ut_a(0); + srv_que_task_enqueue_low(thr); + } + mutex_exit(&kernel_mutex); - return(thr); + return; } } @@ -755,7 +828,7 @@ que_thr_dec_refer_count( mutex_exit(&kernel_mutex); - return(next_thr); + return; } fork_type = fork->fork_type; @@ -771,7 +844,7 @@ que_thr_dec_refer_count( ut_ad(UT_LIST_GET_LEN(trx->signals) > 0); ut_ad(trx->handling_signals == TRUE); - next_thr = trx_finish_rollback_off_kernel(fork, trx); + trx_finish_rollback_off_kernel(fork, trx, next_thr); } else if (fork_type == QUE_FORK_PURGE) { @@ -793,7 +866,7 @@ que_thr_dec_refer_count( zero, then we start processing a signal; from it we may get a new query thread to run */ - next_thr = trx_sig_start_handle(trx); + trx_sig_start_handle(trx, next_thr); } if (trx->handling_signals && UT_LIST_GET_LEN(trx->signals) == 0) { @@ -802,8 +875,6 @@ que_thr_dec_refer_count( } mutex_exit(&kernel_mutex); - - return(next_thr); } /************************************************************************** @@ -968,10 +1039,9 @@ que_thr_stop_for_mysql_no_error( trx->n_active_thrs--; } -#ifdef UNIV_DEBUG /************************************************************************** Prints info of an SQL query graph node. */ -static + void que_node_print_info( /*================*/ @@ -1028,7 +1098,6 @@ que_node_print_info( fprintf(stderr, "Node type %lu: %s, address %p\n", (ulong) type, str, node); } -#endif /* UNIV_DEBUG */ /************************************************************************** Performs an execution step on a query thread. */ @@ -1177,7 +1246,6 @@ loop: /*-------------------------*/ next_thr = que_thr_step(thr); /*-------------------------*/ - ut_a(next_thr == thr || next_thr == NULL); /* Test the effect on performance of adding extra mutex reservations */ @@ -1190,7 +1258,8 @@ loop: loop_count++; if (next_thr != thr) { - next_thr = que_thr_dec_refer_count(thr); + ut_a(next_thr == NULL); + que_thr_dec_refer_count(thr, &next_thr); if (next_thr == NULL) { diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index 254ebeec8c9..6e8f3d82ef3 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -33,12 +33,13 @@ At the present, the comparison functions return 0 in the case, where two records disagree only in the way that one has more fields than the other. */ +#ifdef UNIV_DEBUG /***************************************************************** Used in debug checking of cmp_dtuple_... . This function is used to compare a data tuple to a physical record. If dtuple has n fields then rec must have either m >= n fields, or it must differ from dtuple in some of the m fields rec has. */ - +static int cmp_debug_dtuple_rec_with_match( /*============================*/ @@ -54,6 +55,7 @@ cmp_debug_dtuple_rec_with_match( completely matched fields; when function returns, contains the value for current comparison */ +#endif /* UNIV_DEBUG */ /***************************************************************** This function is used to compare two data fields for which the data type is such that we must use MySQL code to compare them. The prototype here @@ -962,13 +964,14 @@ order_resolved: return(ret); } +#ifdef UNIV_DEBUG /***************************************************************** Used in debug checking of cmp_dtuple_... . This function is used to compare a data tuple to a physical record. If dtuple has n fields then rec must have either m >= n fields, or it must differ from dtuple in some of the m fields rec has. If encounters an externally stored field, returns 0. */ - +static int cmp_debug_dtuple_rec_with_match( /*============================*/ @@ -1064,3 +1067,4 @@ order_resolved: return(ret); } +#endif /* UNIV_DEBUG */ diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index fdd6989479d..c7163f1fd4a 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -81,9 +81,9 @@ ins_node_create( node->trx_id = ut_dulint_zero; node->entry_sys_heap = mem_heap_create(128); -#ifdef UNIV_DEBUG - node->magic_n = INS_NODE_MAGIC_N; -#endif /* UNIV_DEBUG */ + + node->magic_n = INS_NODE_MAGIC_N; + return(node); } @@ -195,7 +195,6 @@ ins_node_set_new_row( ins_node_t* node, /* in: insert node */ dtuple_t* row) /* in: new row (or first row) for the node */ { - ut_ad(node->magic_n == INS_NODE_MAGIC_N); node->state = INS_NODE_SET_IX_LOCK; node->index = NULL; node->entry = NULL; @@ -2012,7 +2011,6 @@ row_ins( ulint err; ut_ad(node && thr); - ut_ad(node->magic_n == INS_NODE_MAGIC_N); if (node->state == INS_NODE_ALLOC_ROW_ID) { @@ -2077,7 +2075,7 @@ row_ins_step( trx_start_if_not_started(trx); node = thr->run_node; - ut_ad(node->magic_n == INS_NODE_MAGIC_N); + ut_ad(que_node_get_type(node) == QUE_NODE_INSERT); parent = que_node_get_parent(node); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 974dfa3e1c8..c4408de2a85 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1414,7 +1414,8 @@ row_create_table_for_mysql( tab_node_t* node; mem_heap_t* heap; que_thr_t* thr; - ulint namelen; + const char* table_name; + ulint table_name_len; ulint err; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -1466,10 +1467,17 @@ row_create_table_for_mysql( return(row_mysql_recover_tmp_table(table, trx)); } - namelen = strlen(table->name) + 1; + /* The table name is prefixed with the database name and a '/'. + Certain table names starting with 'innodb_' have their special + meaning regardless of the database name. Thus, we need to + ignore the database name prefix in the comparisons. */ + table_name = strchr(table->name, '/'); + ut_a(table_name); + table_name++; + table_name_len = strlen(table_name) + 1; - if (namelen == sizeof S_innodb_monitor - && !memcmp(table->name, S_innodb_monitor, + if (table_name_len == sizeof S_innodb_monitor + && !memcmp(table_name, S_innodb_monitor, sizeof S_innodb_monitor)) { /* Table equals "innodb_monitor": @@ -1481,27 +1489,27 @@ row_create_table_for_mysql( of InnoDB monitor prints */ os_event_set(srv_lock_timeout_thread_event); - } else if (namelen == sizeof S_innodb_lock_monitor - && !memcmp(table->name, S_innodb_lock_monitor, + } else if (table_name_len == sizeof S_innodb_lock_monitor + && !memcmp(table_name, S_innodb_lock_monitor, sizeof S_innodb_lock_monitor)) { srv_print_innodb_monitor = TRUE; srv_print_innodb_lock_monitor = TRUE; os_event_set(srv_lock_timeout_thread_event); - } else if (namelen == sizeof S_innodb_tablespace_monitor - && !memcmp(table->name, S_innodb_tablespace_monitor, + } else if (table_name_len == sizeof S_innodb_tablespace_monitor + && !memcmp(table_name, S_innodb_tablespace_monitor, sizeof S_innodb_tablespace_monitor)) { srv_print_innodb_tablespace_monitor = TRUE; os_event_set(srv_lock_timeout_thread_event); - } else if (namelen == sizeof S_innodb_table_monitor - && !memcmp(table->name, S_innodb_table_monitor, + } else if (table_name_len == sizeof S_innodb_table_monitor + && !memcmp(table_name, S_innodb_table_monitor, sizeof S_innodb_table_monitor)) { srv_print_innodb_table_monitor = TRUE; os_event_set(srv_lock_timeout_thread_event); - } else if (namelen == sizeof S_innodb_mem_validate - && !memcmp(table->name, S_innodb_mem_validate, + } else if (table_name_len == sizeof S_innodb_mem_validate + && !memcmp(table_name, S_innodb_mem_validate, sizeof S_innodb_mem_validate)) { /* We define here a debugging feature intended for developers */ @@ -2204,6 +2212,7 @@ row_drop_table_for_mysql( que_thr_t* thr; que_t* graph; ulint err; + const char* table_name; ulint namelen; ibool success; ibool locked_dictionary = FALSE; @@ -2293,10 +2302,17 @@ row_drop_table_for_mysql( trx_start_if_not_started(trx); - namelen = strlen(name) + 1; + /* The table name is prefixed with the database name and a '/'. + Certain table names starting with 'innodb_' have their special + meaning regardless of the database name. Thus, we need to + ignore the database name prefix in the comparisons. */ + table_name = strchr(name, '/'); + ut_a(table_name); + table_name++; + namelen = strlen(table_name) + 1; if (namelen == sizeof S_innodb_monitor - && !memcmp(name, S_innodb_monitor, + && !memcmp(table_name, S_innodb_monitor, sizeof S_innodb_monitor)) { /* Table name equals "innodb_monitor": @@ -2305,17 +2321,17 @@ row_drop_table_for_mysql( srv_print_innodb_monitor = FALSE; srv_print_innodb_lock_monitor = FALSE; } else if (namelen == sizeof S_innodb_lock_monitor - && !memcmp(name, S_innodb_lock_monitor, + && !memcmp(table_name, S_innodb_lock_monitor, sizeof S_innodb_lock_monitor)) { srv_print_innodb_monitor = FALSE; srv_print_innodb_lock_monitor = FALSE; } else if (namelen == sizeof S_innodb_tablespace_monitor - && !memcmp(name, S_innodb_tablespace_monitor, + && !memcmp(table_name, S_innodb_tablespace_monitor, sizeof S_innodb_tablespace_monitor)) { srv_print_innodb_tablespace_monitor = FALSE; } else if (namelen == sizeof S_innodb_table_monitor - && !memcmp(name, S_innodb_table_monitor, + && !memcmp(table_name, S_innodb_table_monitor, sizeof S_innodb_table_monitor)) { srv_print_innodb_table_monitor = FALSE; diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index 724e7bf91e7..d35ae0a3e38 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -287,9 +287,7 @@ upd_node_create( node->select = NULL; node->heap = mem_heap_create(128); -#ifdef UNIV_DEBUG - node->magic_n = UPD_NODE_MAGIC_N; -#endif /* UNIV_DEBUG */ + node->magic_n = UPD_NODE_MAGIC_N; node->cmpl_info = 0; @@ -1806,7 +1804,6 @@ row_upd_step( trx_start_if_not_started(trx); node = thr->run_node; - ut_ad(node->magic_n == UPD_NODE_MAGIC_N); sel_node = node->select; @@ -1926,7 +1923,6 @@ row_upd_in_place_in_select( node = que_node_get_parent(sel_node); - ut_ad(node->magic_n == UPD_NODE_MAGIC_N); ut_ad(que_node_get_type(node) == QUE_NODE_UPDATE); pcur = node->pcur; diff --git a/innobase/srv/Makefile.am b/innobase/srv/Makefile.am index 37fd73a4bf0..752683b82b8 100644 --- a/innobase/srv/Makefile.am +++ b/innobase/srv/Makefile.am @@ -19,6 +19,6 @@ include ../include/Makefile.i noinst_LIBRARIES = libsrv.a -libsrv_a_SOURCES = srv0srv.c srv0start.c +libsrv_a_SOURCES = srv0srv.c srv0que.c srv0start.c EXTRA_PROGRAMS = diff --git a/innobase/srv/srv0que.c b/innobase/srv/srv0que.c new file mode 100644 index 00000000000..9dc9ae453d9 --- /dev/null +++ b/innobase/srv/srv0que.c @@ -0,0 +1,113 @@ +/****************************************************** +Server query execution + +(c) 1996 Innobase Oy + +Created 6/5/1996 Heikki Tuuri +*******************************************************/ + +#include "srv0que.h" + +#include "srv0srv.h" +#include "sync0sync.h" +#include "os0thread.h" +#include "usr0sess.h" +#include "que0que.h" + +/************************************************************************** +Checks if there is work to do in the server task queue. If there is, the +thread starts processing a task. Before leaving, it again checks the task +queue and picks a new task if any exists. This is called by a SRV_WORKER +thread. */ + +void +srv_que_task_queue_check(void) +/*==========================*/ +{ + que_thr_t* thr; + + for (;;) { + mutex_enter(&kernel_mutex); + + thr = UT_LIST_GET_FIRST(srv_sys->tasks); + + if (thr == NULL) { + mutex_exit(&kernel_mutex); + + return; + } + + UT_LIST_REMOVE(queue, srv_sys->tasks, thr); + + mutex_exit(&kernel_mutex); + + que_run_threads(thr); + } +} + +/************************************************************************** +Performs round-robin on the server tasks. This is called by a SRV_WORKER +thread every second or so. */ + +que_thr_t* +srv_que_round_robin( +/*================*/ + /* out: the new (may be == thr) query thread + to run */ + que_thr_t* thr) /* in: query thread */ +{ + que_thr_t* new_thr; + + ut_ad(thr); + ut_ad(thr->state == QUE_THR_RUNNING); + + mutex_enter(&kernel_mutex); + + UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr); + + new_thr = UT_LIST_GET_FIRST(srv_sys->tasks); + + mutex_exit(&kernel_mutex); + + return(new_thr); +} + +/************************************************************************** +Enqueues a task to server task queue and releases a worker thread, if there +is a suspended one. */ + +void +srv_que_task_enqueue_low( +/*=====================*/ + que_thr_t* thr) /* in: query thread */ +{ + ut_ad(thr); + +#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&kernel_mutex)); +#endif /* UNIV_SYNC_DEBUG */ + + UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr); + + srv_release_threads(SRV_WORKER, 1); +} + +/************************************************************************** +Enqueues a task to server task queue and releases a worker thread, if there +is a suspended one. */ + +void +srv_que_task_enqueue( +/*=================*/ + que_thr_t* thr) /* in: query thread */ +{ + ut_ad(thr); + + ut_a(0); /* Under MySQL this is never called */ + + mutex_enter(&kernel_mutex); + + srv_que_task_enqueue_low(thr); + + mutex_exit(&kernel_mutex); +} diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 3817501ae70..fc46c95a8a6 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -34,6 +34,7 @@ Created 10/8/1995 Heikki Tuuri #include "sync0sync.h" #include "thr0loc.h" #include "que0que.h" +#include "srv0que.h" #include "log0recv.h" #include "pars0pars.h" #include "usr0sess.h" diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 3bf39e6422b..dd38eddb20b 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1478,9 +1478,7 @@ NetWare. */ os_thread_create(&srv_master_thread, NULL, thread_ids + 1 + SRV_MAX_N_IO_THREADS); -#ifdef UNIV_DEBUG /* buf_debug_prints = TRUE; */ -#endif /* UNIV_DEBUG */ sum_of_data_file_sizes = 0; diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c index 2d3b48b1d89..77757685208 100644 --- a/innobase/sync/sync0rw.c +++ b/innobase/sync/sync0rw.c @@ -171,7 +171,6 @@ rw_lock_free( mutex_exit(&rw_lock_list_mutex); } -#ifdef UNIV_DEBUG /********************************************************************** Checks that the rw-lock has been initialized and that there are no simultaneous shared and exclusive locks. */ @@ -199,7 +198,6 @@ rw_lock_validate( return(TRUE); } -#endif /* UNIV_DEBUG */ /********************************************************************** Lock an rw-lock in shared mode for the current thread. If the rw-lock is diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 89bfb5dd02e..86306e49cac 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -314,7 +314,6 @@ mutex_enter_nowait( return(1); } -#ifdef UNIV_DEBUG /********************************************************************** Checks that the mutex has been initialized. */ @@ -328,7 +327,6 @@ mutex_validate( return(TRUE); } -#endif /* UNIV_DEBUG */ /********************************************************************** Sets the waiters field in a mutex. */ @@ -1077,12 +1075,8 @@ sync_thread_add_level( } else if (level == SYNC_DICT_HEADER) { ut_a(sync_thread_levels_g(array, SYNC_DICT_HEADER)); } else if (level == SYNC_DICT) { -#ifdef UNIV_DEBUG - ut_a(buf_debug_prints || - sync_thread_levels_g(array, SYNC_DICT)); -#else /* UNIV_DEBUG */ - ut_a(sync_thread_levels_g(array, SYNC_DICT)); -#endif /* UNIV_DEBUG */ + ut_a(buf_debug_prints + || sync_thread_levels_g(array, SYNC_DICT)); } else { ut_error; } diff --git a/innobase/thr/thr0loc.c b/innobase/thr/thr0loc.c index a17d09fcca6..033bb22807f 100644 --- a/innobase/thr/thr0loc.c +++ b/innobase/thr/thr0loc.c @@ -46,12 +46,11 @@ struct thr_local_struct{ ibool in_ibuf;/* TRUE if the the thread is doing an ibuf operation */ hash_node_t hash; /* hash chain node */ -#ifdef UNIV_DEBUG ulint magic_n; -#define THR_LOCAL_MAGIC_N 1231234 -#endif /* UNIV_DEBUG */ }; +#define THR_LOCAL_MAGIC_N 1231234 + /*********************************************************************** Returns the local storage struct for a thread. */ static @@ -170,9 +169,8 @@ thr_local_create(void) local->id = os_thread_get_curr_id(); local->handle = os_thread_get_curr(); -#ifdef UNIV_DEBUG local->magic_n = THR_LOCAL_MAGIC_N; -#endif /* UNIV_DEBUG */ + local->in_ibuf = FALSE; mutex_enter(&thr_local_mutex); @@ -211,7 +209,7 @@ thr_local_free( mutex_exit(&thr_local_mutex); - ut_ad(local->magic_n == THR_LOCAL_MAGIC_N); + ut_a(local->magic_n == THR_LOCAL_MAGIC_N); mem_free(local); } diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c index 002775eaac1..3d5f0d3f03a 100644 --- a/innobase/trx/trx0purge.c +++ b/innobase/trx/trx0purge.c @@ -23,6 +23,7 @@ Created 3/26/1996 Heikki Tuuri #include "row0purge.h" #include "row0upd.h" #include "trx0rec.h" +#include "srv0que.h" #include "os0thread.h" /* The global data structure coordinating a purge */ @@ -1059,6 +1060,8 @@ trx_purge(void) mutex_exit(&kernel_mutex); +/* srv_que_task_enqueue(thr2); */ + if (srv_print_thread_releases) { fputs("Starting purge\n", stderr); diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index 8b8a079bb7f..e65755a0f73 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -20,6 +20,7 @@ Created 3/26/1996 Heikki Tuuri #include "trx0rec.h" #include "que0que.h" #include "usr0sess.h" +#include "srv0que.h" #include "srv0start.h" #include "row0undo.h" #include "row0mysql.h" @@ -931,15 +932,21 @@ trx_undo_rec_release( /************************************************************************* Starts a rollback operation. */ -que_thr_t* +void trx_rollback( /*=========*/ - /* out: next query thread to run */ trx_t* trx, /* in: transaction */ - trx_sig_t* sig) /* in: signal starting the rollback */ + trx_sig_t* sig, /* in: signal starting the rollback */ + que_thr_t** next_thr)/* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread; if the passed value is + NULL, the parameter is ignored */ { que_t* roll_graph; que_thr_t* thr; +/* que_thr_t* thr2; */ #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); @@ -981,7 +988,18 @@ trx_rollback( thr = que_fork_start_command(roll_graph); ut_ad(thr); - return(thr); + +/* thr2 = que_fork_start_command(roll_graph); + + ut_ad(thr2); */ + + if (next_thr && (*next_thr == NULL)) { + *next_thr = thr; +/* srv_que_task_enqueue_low(thr2); */ + } else { + srv_que_task_enqueue_low(thr); +/* srv_que_task_enqueue_low(thr2); */ + } } /******************************************************************** @@ -1053,14 +1071,17 @@ trx_finish_error_processing( /************************************************************************* Finishes a partial rollback operation. */ static -que_thr_t* +void trx_finish_partial_rollback_off_kernel( /*===================================*/ - /* out: next query thread to run */ - trx_t* trx) /* in: transaction */ + trx_t* trx, /* in: transaction */ + que_thr_t** next_thr)/* in/out: next query thread to run; + if the value which is passed in is a pointer + to a NULL pointer, then the calling function + can start running a new query thread; if this + parameter is NULL, it is ignored */ { trx_sig_t* sig; - que_thr_t* next_thr; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); @@ -1071,26 +1092,29 @@ trx_finish_partial_rollback_off_kernel( /* Remove the signal from the signal queue and send reply message to it */ - next_thr = trx_sig_reply(sig); + trx_sig_reply(sig, next_thr); trx_sig_remove(trx, sig); trx->que_state = TRX_QUE_RUNNING; - return(next_thr); } /******************************************************************** Finishes a transaction rollback. */ -que_thr_t* +void trx_finish_rollback_off_kernel( /*===========================*/ - /* out: next query thread to run */ que_t* graph, /* in: undo graph which can now be freed */ - trx_t* trx) /* in: transaction */ + trx_t* trx, /* in: transaction */ + que_thr_t** next_thr)/* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread; if this parameter is + NULL, it is ignored */ { trx_sig_t* sig; trx_sig_t* next_sig; - que_thr_t* next_thr; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); @@ -1105,21 +1129,21 @@ trx_finish_rollback_off_kernel( if (sig->type == TRX_SIG_ROLLBACK_TO_SAVEPT) { - return(trx_finish_partial_rollback_off_kernel(trx)); + trx_finish_partial_rollback_off_kernel(trx, next_thr); + + return; } else if (sig->type == TRX_SIG_ERROR_OCCURRED) { trx_finish_error_processing(trx); - return(NULL); + return; } -#ifdef UNIV_DEBUG if (lock_print_waits) { fprintf(stderr, "Trx %lu rollback finished\n", (ulong) ut_dulint_get_low(trx->id)); } -#endif /* UNIV_DEBUG */ trx_commit_off_kernel(trx); @@ -1127,23 +1151,19 @@ trx_finish_rollback_off_kernel( send reply messages to them */ trx->que_state = TRX_QUE_RUNNING; - - next_thr = NULL; + while (sig != NULL) { next_sig = UT_LIST_GET_NEXT(signals, sig); if (sig->type == TRX_SIG_TOTAL_ROLLBACK) { - ut_a(next_thr == NULL); - next_thr = trx_sig_reply(sig); + trx_sig_reply(sig, next_thr); trx_sig_remove(trx, sig); } sig = next_sig; } - - return(next_thr); } /************************************************************************* @@ -1176,6 +1196,7 @@ trx_rollback_step( que_thr_t* thr) /* in: query thread */ { roll_node_t* node; + ibool success; ulint sig_no; trx_savept_t* savept; @@ -1202,13 +1223,19 @@ trx_rollback_step( /* Send a rollback signal to the transaction */ - trx_sig_send(thr_get_trx(thr), sig_no, TRX_SIG_SELF, - thr, savept); + success = trx_sig_send(thr_get_trx(thr), + sig_no, TRX_SIG_SELF, + thr, savept, NULL); thr->state = QUE_THR_SIG_REPLY_WAIT; mutex_exit(&kernel_mutex); + if (!success) { + /* Error in delivering the rollback signal */ + que_thr_handle_error(thr, DB_ERROR, NULL, 0); + } + return(NULL); } diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index b377bdb9809..5c8ae0952ef 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -619,7 +619,6 @@ trx_sys_update_mysql_binlog_offset( MLOG_4BYTES, mtr); } -#ifdef UNIV_HOTBACKUP /********************************************************************* Prints to stderr the MySQL binlog info in the system header if the magic number shows it valid. */ @@ -647,7 +646,6 @@ trx_sys_print_mysql_binlog_offset_from_page( sys_header + TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME); } } -#endif /* UNIV_HOTBACKUP */ /********************************************************************* Prints to stderr the MySQL binlog offset info in the trx system header if diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index afef08dc100..a9aae48dae6 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -897,15 +897,18 @@ trx_assign_read_view( /******************************************************************** Commits a transaction. NOTE that the kernel mutex is temporarily released. */ static -que_thr_t* +void trx_handle_commit_sig_off_kernel( /*=============================*/ - /* out: next query thread to run */ - trx_t* trx) /* in: transaction */ + trx_t* trx, /* in: transaction */ + que_thr_t** next_thr) /* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread */ { trx_sig_t* sig; trx_sig_t* next_sig; - que_thr_t* next_thr = NULL; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); @@ -927,8 +930,7 @@ trx_handle_commit_sig_off_kernel( if (sig->type == TRX_SIG_COMMIT) { - ut_a(next_thr == NULL); - next_thr = trx_sig_reply(sig); + trx_sig_reply(sig, next_thr); trx_sig_remove(trx, sig); } @@ -936,8 +938,6 @@ trx_handle_commit_sig_off_kernel( } trx->que_state = TRX_QUE_RUNNING; - - return(next_thr); } /*************************************************************** @@ -999,6 +999,39 @@ trx_lock_wait_to_suspended( trx->que_state = TRX_QUE_RUNNING; } +/*************************************************************** +Moves the query threads in the sig reply wait list of trx to the SUSPENDED +state. */ +static +void +trx_sig_reply_wait_to_suspended( +/*============================*/ + trx_t* trx) /* in: transaction */ +{ + trx_sig_t* sig; + que_thr_t* thr; + +#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&kernel_mutex)); +#endif /* UNIV_SYNC_DEBUG */ + + sig = UT_LIST_GET_FIRST(trx->reply_signals); + + while (sig != NULL) { + thr = sig->receiver; + + ut_ad(thr->state == QUE_THR_SIG_REPLY_WAIT); + + thr->state = QUE_THR_SUSPENDED; + + sig->receiver = NULL; + + UT_LIST_REMOVE(reply_signals, trx->reply_signals, sig); + + sig = UT_LIST_GET_FIRST(trx->reply_signals); + } +} + /********************************************************************* Checks the compatibility of a new signal with the other signals in the queue. */ @@ -1078,10 +1111,11 @@ trx_sig_is_compatible( /******************************************************************** Sends a signal to a trx object. */ -que_thr_t* +ibool trx_sig_send( /*=========*/ - /* out: next query thread to run */ + /* out: TRUE if the signal was + successfully delivered */ trx_t* trx, /* in: trx handle */ ulint type, /* in: signal type */ ulint sender, /* in: TRX_SIG_SELF or @@ -1089,8 +1123,14 @@ trx_sig_send( que_thr_t* receiver_thr, /* in: query thread which wants the reply, or NULL; if type is TRX_SIG_END_WAIT, this must be NULL */ - trx_savept_t* savept) /* in: possible rollback savepoint, or + trx_savept_t* savept, /* in: possible rollback savepoint, or NULL */ + que_thr_t** next_thr) /* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread; if the parameter + is NULL, it is ignored */ { trx_sig_t* sig; trx_t* receiver_trx; @@ -1100,7 +1140,14 @@ trx_sig_send( ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ - ut_a(trx_sig_is_compatible(trx, type, sender)); + if (!trx_sig_is_compatible(trx, type, sender)) { + /* The signal is not compatible with the other signals in + the queue: do nothing */ + + ut_error; + + return(FALSE); + } /* Queue the signal object */ @@ -1134,6 +1181,11 @@ trx_sig_send( sig); } + if (trx->sess->state == SESS_ERROR) { + + trx_sig_reply_wait_to_suspended(trx); + } + if ((sender != TRX_SIG_SELF) || (type == TRX_SIG_BREAK_EXECUTION)) { /* The following call will add a TRX_SIG_ERROR_OCCURRED @@ -1148,10 +1200,10 @@ trx_sig_send( if (UT_LIST_GET_FIRST(trx->signals) == sig) { - return(trx_sig_start_handle(trx)); + trx_sig_start_handle(trx, next_thr); } - return(NULL); + return(TRUE); } /******************************************************************** @@ -1173,18 +1225,27 @@ trx_end_signal_handling( trx->handling_signals = FALSE; trx->graph = trx->graph_before_signal_handling; + + if (trx->graph && (trx->sess->state == SESS_ERROR)) { + + que_fork_error_handle(trx, trx->graph); + } } /******************************************************************** Starts handling of a trx signal. */ -que_thr_t* +void trx_sig_start_handle( /*=================*/ - /* out: next query thread to run, or NULL */ - trx_t* trx) /* in: trx handle */ + trx_t* trx, /* in: trx handle */ + que_thr_t** next_thr) /* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread; if the parameter + is NULL, it is ignored */ { - que_thr_t* next_thr = NULL; trx_sig_t* sig; ulint type; loop: @@ -1200,7 +1261,7 @@ loop: trx_end_signal_handling(trx); - return(next_thr); + return; } if (trx->conc_state == TRX_NOT_STARTED) { @@ -1216,13 +1277,23 @@ loop: trx_lock_wait_to_suspended(trx); } + /* If the session is in the error state and this trx has threads + waiting for reply from signals, moves these threads to the suspended + state, canceling wait reservations; note that if the transaction has + sent a commit or rollback signal to itself, and its session is not in + the error state, then nothing is done here. */ + + if (trx->sess->state == SESS_ERROR) { + trx_sig_reply_wait_to_suspended(trx); + } + /* If there are no running query threads, we can start processing of a signal, otherwise we have to wait until all query threads of this transaction are aware of the arrival of the signal. */ if (trx->n_active_thrs > 0) { - return(NULL); + return; } if (trx->handling_signals == FALSE) { @@ -1236,19 +1307,30 @@ loop: if (type == TRX_SIG_COMMIT) { - next_thr = trx_handle_commit_sig_off_kernel(trx); + trx_handle_commit_sig_off_kernel(trx, next_thr); } else if ((type == TRX_SIG_TOTAL_ROLLBACK) - || (type == TRX_SIG_ROLLBACK_TO_SAVEPT) - || (type == TRX_SIG_ERROR_OCCURRED)) { + || (type == TRX_SIG_ROLLBACK_TO_SAVEPT)) { + + trx_rollback(trx, sig, next_thr); + + /* No further signals can be handled until the rollback + completes, therefore we return */ + + return; + + } else if (type == TRX_SIG_ERROR_OCCURRED) { + + trx_rollback(trx, sig, next_thr); + /* No further signals can be handled until the rollback completes, therefore we return */ - return(trx_rollback(trx, sig)); + return; } else if (type == TRX_SIG_BREAK_EXECUTION) { - next_thr = trx_sig_reply(sig); + trx_sig_reply(sig, next_thr); trx_sig_remove(trx, sig); } else { ut_error; @@ -1261,14 +1343,17 @@ loop: Send the reply message when a signal in the queue of the trx has been handled. */ -que_thr_t* +void trx_sig_reply( /*==========*/ - /* out: next query thread to run */ - trx_sig_t* sig) /* in: signal */ + trx_sig_t* sig, /* in: signal */ + que_thr_t** next_thr) /* in/out: next query thread to run; + if the value which is passed in is + a pointer to a NULL pointer, then the + calling function can start running + a new query thread */ { - trx_t* receiver_trx; - que_thr_t* next_thr = NULL; + trx_t* receiver_trx; ut_ad(sig); #ifdef UNIV_SYNC_DEBUG @@ -1282,13 +1367,13 @@ trx_sig_reply( UT_LIST_REMOVE(reply_signals, receiver_trx->reply_signals, sig); - next_thr = que_thr_end_wait(sig->receiver); + ut_ad(receiver_trx->sess->state != SESS_ERROR); + + que_thr_end_wait(sig->receiver, next_thr); sig->receiver = NULL; } - - return(next_thr); } /******************************************************************** @@ -1344,6 +1429,7 @@ trx_commit_step( { commit_node_t* node; que_thr_t* next_thr; + ibool success; node = thr->run_node; @@ -1358,15 +1444,22 @@ trx_commit_step( node->state = COMMIT_NODE_WAIT; + next_thr = NULL; + thr->state = QUE_THR_SIG_REPLY_WAIT; /* Send the commit signal to the transaction */ - next_thr = trx_sig_send(thr_get_trx(thr), TRX_SIG_COMMIT, - TRX_SIG_SELF, thr, NULL); - + success = trx_sig_send(thr_get_trx(thr), TRX_SIG_COMMIT, + TRX_SIG_SELF, thr, NULL, &next_thr); + mutex_exit(&kernel_mutex); + if (!success) { + /* Error in delivering the commit signal */ + que_thr_handle_error(thr, DB_ERROR, NULL, 0); + } + return(next_thr); } diff --git a/innobase/usr/usr0sess.c b/innobase/usr/usr0sess.c index cc016f2b823..359c1552421 100644 --- a/innobase/usr/usr0sess.c +++ b/innobase/usr/usr0sess.c @@ -37,6 +37,8 @@ sess_open(void) #endif /* UNIV_SYNC_DEBUG */ sess = mem_alloc(sizeof(sess_t)); + sess->state = SESS_ACTIVE; + sess->trx = trx_create(sess); UT_LIST_INIT(sess->graphs); diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index 47b612d757e..9a591df9f77 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -203,6 +203,81 @@ ut_free( } /************************************************************************** +Implements realloc. This is needed by /pars/lexyy.c. Otherwise, you should not +use this function because the allocation functions in mem0mem.h are the +recommended ones in InnoDB. + +man realloc in Linux, 2004: + + realloc() changes the size of the memory block pointed to + by ptr to size bytes. The contents will be unchanged to + the minimum of the old and new sizes; newly allocated mem + ory will be uninitialized. If ptr is NULL, the call is + equivalent to malloc(size); if size is equal to zero, the + call is equivalent to free(ptr). Unless ptr is NULL, it + must have been returned by an earlier call to malloc(), + calloc() or realloc(). + +RETURN VALUE + realloc() returns a pointer to the newly allocated memory, + which is suitably aligned for any kind of variable and may + be different from ptr, or NULL if the request fails. If + size was equal to 0, either NULL or a pointer suitable to + be passed to free() is returned. If realloc() fails the + original block is left untouched - it is not freed or + moved. */ + +void* +ut_realloc( +/*=======*/ + /* out, own: pointer to new mem block or NULL */ + void* ptr, /* in: pointer to old block or NULL */ + ulint size) /* in: desired size */ +{ + ut_mem_block_t* block; + ulint old_size; + ulint min_size; + void* new_ptr; + + if (ptr == NULL) { + + return(ut_malloc(size)); + } + + if (size == 0) { + ut_free(ptr); + + return(NULL); + } + + block = (ut_mem_block_t*)((byte*)ptr - sizeof(ut_mem_block_t)); + + ut_a(block->magic_n == UT_MEM_MAGIC_N); + + old_size = block->size - sizeof(ut_mem_block_t); + + if (size < old_size) { + min_size = size; + } else { + min_size = old_size; + } + + new_ptr = ut_malloc(size); + + if (new_ptr == NULL) { + + return(NULL); + } + + /* Copy the old data from ptr */ + ut_memcpy(new_ptr, ptr, min_size); + + ut_free(ptr); + + return(new_ptr); +} + +/************************************************************************** Frees in shutdown all allocated memory not freed yet. */ void diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result index ce26a0bf30a..4c8a0561b0a 100644 --- a/mysql-test/r/func_if.result +++ b/mysql-test/r/func_if.result @@ -77,3 +77,9 @@ select min(if(y -x > 5,y,NULL)), max(if(y - x > 5,y,NULL)) from t1; min(if(y -x > 5,y,NULL)) max(if(y - x > 5,y,NULL)) 6 56 drop table t1; +create table t1 (a int); +insert t1 values (1),(2); +select if(1>2,a,avg(a)) from t1; +if(1>2,a,avg(a)) +1.5000 +drop table t1; diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 290e72d3b55..06a479c964c 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -299,6 +299,27 @@ a b 15 1 47 1 DROP TABLE t1; +CREATE TABLE t1 ( +id int( 11 ) unsigned NOT NULL AUTO_INCREMENT , +line int( 5 ) unsigned NOT NULL default '0', +columnid int( 3 ) unsigned NOT NULL default '0', +owner int( 3 ) unsigned NOT NULL default '0', +ordinal int( 3 ) unsigned NOT NULL default '0', +showid smallint( 6 ) unsigned NOT NULL default '1', +tableid int( 1 ) unsigned NOT NULL default '1', +content int( 5 ) unsigned NOT NULL default '188', +PRIMARY KEY ( owner, id ) , +KEY menu( owner, showid, columnid ) , +KEY `COLUMN` ( owner, columnid, line ) , +KEY `LINES` ( owner, tableid, content, id ) , +KEY recount( owner, line ) +) ENGINE = MYISAM; +INSERT into t1 (owner,id,columnid,line) values (11,15,15,1),(11,13,13,5); +SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30; +id columnid tableid content showid line ordinal +13 13 1 188 1 5 0 +15 15 1 188 1 1 0 +drop table t1; create table t1 (id int(10) primary key); insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9); select id from t1 where id in (2,5,9) ; diff --git a/mysql-test/r/rpl_free_items.result b/mysql-test/r/rpl_free_items.result new file mode 100644 index 00000000000..743fbbc8fc7 --- /dev/null +++ b/mysql-test/r/rpl_free_items.result @@ -0,0 +1,10 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +create table t1 (a int); +create table t2 (a int); +drop table t1; +drop table t2; diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index cebd005c2c8..0ec07cd735f 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -73,3 +73,9 @@ SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2. DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) Wed, 06 March 2002 10:11:12 GMT-0800 Wed, 06 March 2002 10:11:12 GMT-0800 drop table t1,t2; +CREATE TABLE t1 (f1 time default NULL, f2 time default NULL) TYPE=MyISAM; +INSERT INTO t1 (f1, f2) VALUES ('09:00', '12:00'); +SELECT DATE_FORMAT(f1, "%l.%i %p") , DATE_FORMAT(f2, "%l.%i %p") FROM t1; +DATE_FORMAT(f1, "%l.%i %p") DATE_FORMAT(f2, "%l.%i %p") +9.00 AM 12.00 PM +DROP TABLE t1; diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index dc78369f583..3b4e94911b7 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -444,6 +444,13 @@ CREATE TABLE t1 (a_dec DECIMAL(-2,1)); ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '-2,1))' at line 1 CREATE TABLE t1 (a_dec DECIMAL(-1,1)); ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '-1,1))' at line 1 +CREATE TABLE t1 (a_dec DECIMAL(0,11)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a_dec` decimal(12,11) default NULL +) TYPE=MyISAM +DROP TABLE t1; create table t1(a decimal(7,3)); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); select * from t1; diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test index 36c3a38d2fe..7048d188604 100644 --- a/mysql-test/t/func_if.test +++ b/mysql-test/t/func_if.test @@ -47,3 +47,12 @@ create table t1 (x int, y int); insert into t1 values (0,6),(10,16),(20,26),(30,10),(40,46),(50,56); select min(if(y -x > 5,y,NULL)), max(if(y - x > 5,y,NULL)) from t1; drop table t1; + +# +# BUG#3987 +# +create table t1 (a int); +insert t1 values (1),(2); +select if(1>2,a,avg(a)) from t1; +drop table t1; + diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 4665cd02ed8..471af8e4a5b 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -255,7 +255,34 @@ WHERE ); DROP TABLE t1; +# +# Test of problem with IN on many different keyparts. (Bug #4157) +# + +CREATE TABLE t1 ( +id int( 11 ) unsigned NOT NULL AUTO_INCREMENT , +line int( 5 ) unsigned NOT NULL default '0', +columnid int( 3 ) unsigned NOT NULL default '0', +owner int( 3 ) unsigned NOT NULL default '0', +ordinal int( 3 ) unsigned NOT NULL default '0', +showid smallint( 6 ) unsigned NOT NULL default '1', +tableid int( 1 ) unsigned NOT NULL default '1', +content int( 5 ) unsigned NOT NULL default '188', +PRIMARY KEY ( owner, id ) , +KEY menu( owner, showid, columnid ) , +KEY `COLUMN` ( owner, columnid, line ) , +KEY `LINES` ( owner, tableid, content, id ) , +KEY recount( owner, line ) +) ENGINE = MYISAM; + +INSERT into t1 (owner,id,columnid,line) values (11,15,15,1),(11,13,13,5); + +SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30; +drop table t1; + +# # test for a bug with in() and unique key +# create table t1 (id int(10) primary key); insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9); diff --git a/mysql-test/t/rpl_free_items-slave.opt b/mysql-test/t/rpl_free_items-slave.opt new file mode 100644 index 00000000000..b828d03fafb --- /dev/null +++ b/mysql-test/t/rpl_free_items-slave.opt @@ -0,0 +1 @@ +--replicate-wild-ignore-table=test.% diff --git a/mysql-test/t/rpl_free_items.test b/mysql-test/t/rpl_free_items.test new file mode 100644 index 00000000000..3228ffd9cde --- /dev/null +++ b/mysql-test/t/rpl_free_items.test @@ -0,0 +1,20 @@ +source include/master-slave.inc; +create table t1 (a int); +create table t2 (a int); +disable_query_log; +SET @query="INSERT INTO t2 SELECT * FROM t1 WHERE a REGEXP \"0\""; +let $1 = 2000; +while ($1) +{ + eval SET @query=concat(@query, " OR a REGEXP '$1'"); + dec $1; +} +let $1=`select @query`; +eval $1; +enable_query_log; +# I have seen the slave crash either now or at shutdown +sync_slave_with_master; +connection master; +drop table t1; +drop table t2; +sync_slave_with_master; diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 5a53c635e6e..a22299682be 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -79,3 +79,11 @@ SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2. INSERT INTO t1 VALUES(1); SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)), DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) FROM t1,t2 GROUP BY t1.AFIELD; drop table t1,t2; + +# +# Bug 4036 +# +CREATE TABLE t1 (f1 time default NULL, f2 time default NULL) TYPE=MyISAM; +INSERT INTO t1 (f1, f2) VALUES ('09:00', '12:00'); +SELECT DATE_FORMAT(f1, "%l.%i %p") , DATE_FORMAT(f2, "%l.%i %p") FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 3257002ae2c..414a06deaa9 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -244,6 +244,9 @@ CREATE TABLE t1 (a_dec DECIMAL(-1,0)); CREATE TABLE t1 (a_dec DECIMAL(-2,1)); --error 1064 CREATE TABLE t1 (a_dec DECIMAL(-1,1)); +CREATE TABLE t1 (a_dec DECIMAL(0,11)); +SHOW CREATE TABLE t1; +DROP TABLE t1; # # Zero prepend overflow bug diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c index e2ad71654dc..0b337a74c19 100644 --- a/mysys/mf_tempfile.c +++ b/mysys/mf_tempfile.c @@ -83,7 +83,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix, (*free)(res); file=my_create(to, 0, mode, MyFlags); } -#elif defined(HAVE_MKSTEMP) +#elif defined(HAVE_MKSTEMP) && !defined(__NETWARE__) { char prefix_buff[30]; uint pfx_len; diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv index 7eca2711a79..22de9a4ad87 100755 --- a/netware/BUILD/mwenv +++ b/netware/BUILD/mwenv @@ -1,10 +1,10 @@ #! /bin/sh -# WINE_BUILD_DIR, BUILD_DIR, and VERSION must be correct before compiling +# F:/mydev, /home/kp/mydev, and 4.0.21 must be correct before compiling # This values are normally changed by the nwbootstrap script # the default is "F:/mydev" -export MYDEV="WINE_BUILD_DIR" +export MYDEV="F:/mydev" export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.1.4;$MYDEV" export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/fs64/imports;$MYDEV/zlib-1.1.4;$MYDEV/openssl;$MYDEV/mysql-VERSION/netware/BUILD" @@ -13,7 +13,7 @@ export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib; export WINEPATH="$MYDEV/mw/bin" # the default added path is "$HOME/mydev/mysql-x.x-x/netware/BUILD" -export PATH="$PATH:BUILD_DIR/mysql-VERSION/netware/BUILD" +export PATH="$PATH:/home/kp/mydev/mysql-VERSION/netware/BUILD" export AR='mwldnlm' export AR_FLAGS='-type library -o' diff --git a/netware/BUILD/nwbootstrap b/netware/BUILD/nwbootstrap index 7737dd8898a..25e843c87e3 100755 --- a/netware/BUILD/nwbootstrap +++ b/netware/BUILD/nwbootstrap @@ -176,6 +176,11 @@ done echo "generating llibmysql.imp file..." awk 'BEGIN{x=0;} x==1 {print $1;next} /EXPORTS/{x=1}' libmysql/libmysql.def > netware/libmysql.imp +# create the libmysql.imp file in netware folder from libmysql/libmysql.def file +echo "generating llibmysql.imp file..." +awk 'BEGIN{x=0;} x==1 {print $1;next} /EXPORTS/{x=1}' libmysql/libmysql.def > netware/libmysql.imp + + # build linux tools echo "compiling linux tools..." ./netware/BUILD/compile-linux-tools diff --git a/netware/Makefile.am b/netware/Makefile.am index 324c6fd13fa..2467270f27b 100644 --- a/netware/Makefile.am +++ b/netware/Makefile.am @@ -16,6 +16,8 @@ if HAVE_NETWARE INCLUDES = -I$(srcdir)/../include -I../include -I.. +LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \ + ../dbug/libdbug.a ../strings/libmystrings.a bin_PROGRAMS = mysqld_safe mysql_install_db mysql_test_run libmysql mysqld_safe_SOURCES= mysqld_safe.c my_manage.c mysql_install_db_SOURCES= mysql_install_db.c my_manage.c diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c index 9c99e8a64b5..37985b9058e 100644 --- a/netware/mysql_test_run.c +++ b/netware/mysql_test_run.c @@ -16,20 +16,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> +#include <my_global.h> +#include <m_string.h> #include <dirent.h> -#include <string.h> #include <screen.h> #include <nks/vm.h> #include <ctype.h> #include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> #include <sys/mode.h> -#include "my_config.h" #include "my_manage.h" /****************************************************************************** @@ -1286,7 +1281,6 @@ int main(int argc, char **argv) return 0; } - /* Synopsis: This function breaks the string into a sequence of tokens. The difference diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index abde6ecbe73..ff5753d9bad 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -10,6 +10,7 @@ in_rpm=0 windows=0 defaults="" +user="" tmp_file=/tmp/mysql_install_db.$$ case "$1" in @@ -34,7 +35,11 @@ parse_arguments() { --force) force=1 ;; --basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; --ldata=*|--datadir=*) ldata=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; - --user=*) user=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; + --user=*) + # Note that the user will be passed to mysqld so that it runs + # as 'user' (crucial e.g. if log-bin=/some_other_path/ + # where a chown of datadir won't help) + user=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; --skip-name-resolve) ip_only=1 ;; --verbose) verbose=1 ;; --rpm) in_rpm=1 ;; @@ -198,6 +203,10 @@ else create_option="real" fi +if test -n "$user"; then + args="$args --user=$user" +fi + if test "$in_rpm" -eq 0 -a "$windows" -eq 0 then echo "Installing all prepared tables" diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 779438e75c3..7b77bf449cd 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -43,13 +43,7 @@ parse_arguments() { --basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--basedir=;;"` ;; --datadir=*) DATADIR=`echo "$arg" | sed -e "s;--datadir=;;"` ;; --pid-file=*) pid_file=`echo "$arg" | sed -e "s;--pid-file=;;"` ;; - --user=*) - if test $SET_USER -eq 0 - then - user=`echo "$arg" | sed -e "s;--[^=]*=;;"` - fi - SET_USER=1 - ;; + --user=*) user=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; SET_USER=1 ;; # these two might have been set in a [mysqld_safe] section of my.cnf # they are added to mysqld command line to override settings from my.cnf diff --git a/sql/field.cc b/sql/field.cc index 0660e774396..2077a6e5455 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3395,6 +3395,25 @@ String *Field_time::val_str(String *val_buffer, } +bool Field_time::get_date(TIME *ltime, + bool fuzzydate __attribute__((unused))) +{ + long tmp=(long) sint3korr(ptr); + ltime->neg=0; + if (tmp < 0) + { + ltime->neg= 1; + tmp=-tmp; + } + ltime->hour=tmp/10000; + tmp-=ltime->hour*10000; + ltime->minute= tmp/100; + ltime->second= tmp % 100; + ltime->year= ltime->month= ltime->day= ltime->second_part= 0; + return 0; +} + + bool Field_time::get_time(TIME *ltime) { long tmp=(long) sint3korr(ptr); diff --git a/sql/field.h b/sql/field.h index 002a7228164..f4c8c5a9955 100644 --- a/sql/field.h +++ b/sql/field.h @@ -800,6 +800,7 @@ public: double val_real(void); longlong val_int(void); String *val_str(String*,String *); + bool get_date(TIME *ltime,bool fuzzydate); bool send_binary(Protocol *protocol); bool get_time(TIME *ltime); int cmp(const char *,const char*); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 446d72ac143..be509c7ed11 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -922,8 +922,8 @@ Item_func_if::fix_length_and_dec() decimals=max(args[1]->decimals,args[2]->decimals); enum Item_result arg1_type=args[1]->result_type(); enum Item_result arg2_type=args[2]->result_type(); - bool null1=args[1]->null_value; - bool null2=args[2]->null_value; + bool null1=args[1]->const_item() && args[1]->null_value; + bool null2=args[2]->const_item() && args[2]->null_value; if (null1) { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c26d5188fdd..7de00e3c43f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5458,7 +5458,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), mysql_data_home= mysql_real_data_home; break; case 'u': - if (!mysqld_user) + if (!mysqld_user || !strcmp(mysqld_user, argument)) mysqld_user= argument; else fprintf(stderr, "Warning: Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index a5d2450e551..41ba09a3e70 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1561,7 +1561,7 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) { swap_variables(SEL_ARG *,key1,key2); } - else if (!(key1=key1->clone_tree())) + if (key1->use_count > 0 || !(key1=key1->clone_tree())) return 0; // OOM } @@ -1630,10 +1630,10 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) SEL_ARG *next=key2->next; // Keys are not overlapping if (key2_shared) { - SEL_ARG *tmp= new SEL_ARG(*key2); // Must make copy - if (!tmp) + SEL_ARG *cpy= new SEL_ARG(*key2); // Must make copy + if (!cpy) return 0; // OOM - key1=key1->insert(tmp); + key1=key1->insert(cpy); key2->increment_use_count(key1->use_count+1); } else @@ -1869,8 +1869,17 @@ SEL_ARG::find_range(SEL_ARG *key) /* -** Remove a element from the tree -** This also frees all sub trees that is used by the element + Remove a element from the tree + + SYNOPSIS + tree_delete() + key Key that is to be deleted from tree (this) + + NOTE + This also frees all sub trees that is used by the element + + RETURN + root of new tree (with key deleted) */ SEL_ARG * @@ -1878,7 +1887,10 @@ SEL_ARG::tree_delete(SEL_ARG *key) { enum leaf_color remove_color; SEL_ARG *root,*nod,**par,*fix_par; - root=this; this->parent= 0; + DBUG_ENTER("tree_delete"); + + root=this; + this->parent= 0; /* Unlink from list */ if (key->prev) @@ -1925,7 +1937,7 @@ SEL_ARG::tree_delete(SEL_ARG *key) } if (root == &null_element) - return 0; // Maybe root later + DBUG_RETURN(0); // Maybe root later if (remove_color == BLACK) root=rb_delete_fixup(root,nod,fix_par); test_rb_tree(root,root->parent); @@ -1933,7 +1945,7 @@ SEL_ARG::tree_delete(SEL_ARG *key) root->use_count=this->use_count; // Fix root counters root->elements=this->elements-1; root->maybe_flag=this->maybe_flag; - return root; + DBUG_RETURN(root); } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 9d1eb7bc54d..d552429af4b 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2830,7 +2830,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table) if (table->grant.version != grant_version) { table->grant.grant_table= - table_hash_search(thd->host,thd->ip,thd->db, + table_hash_search(thd->host, thd->ip, table->table_cache_key, thd->priv_user, table->real_name,0); /* purecov: inspected */ table->grant.version=grant_version; /* purecov: inspected */ @@ -2943,7 +2943,7 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field) if (table->grant.version != grant_version) { table->grant.grant_table= - table_hash_search(thd->host,thd->ip,thd->db, + table_hash_search(thd->host, thd->ip, table->db, thd->priv_user, table->real_name,0); /* purecov: inspected */ table->grant.version=grant_version; /* purecov: inspected */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 28e833b8421..50a150604ef 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1586,7 +1586,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } mysql_log.write(thd,command,db); - mysql_rm_db(thd,alias,0,0); + mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : db), 0, 0); break; } #ifndef EMBEDDED_LIBRARY @@ -3114,7 +3114,8 @@ purposes internal to the MySQL server", MYF(0)); send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); goto error; } - res=mysql_rm_db(thd,alias,lex->drop_if_exists,0); + res=mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : lex->name), + lex->drop_if_exists, 0); break; } case SQLCOM_ALTER_DB: @@ -4185,7 +4186,12 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, break; case FIELD_TYPE_DECIMAL: if (!length) - new_field->length= 10; // Default length for DECIMAL + { + if ((new_field->length= new_field->decimals)) + new_field->length++; + else + new_field->length= 10; // Default length for DECIMAL + } if (new_field->length < MAX_FIELD_WIDTH) // Skip wrong argument { new_field->length+=sign_len; diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh index 5fdde0d2963..d25686f1c21 100644 --- a/support-files/my-huge.cnf.sh +++ b/support-files/my-huge.cnf.sh @@ -1,6 +1,6 @@ -# Example mysql config file for very large systems. +# Example MySQL config file for very large systems. # -# This is for large system with memory of 1G-2G where the system runs mainly +# This is for a large system with memory of 1G-2G where the system runs mainly # MySQL. # # You can copy this file to @@ -9,9 +9,9 @@ # installation this directory is @localstatedir@) or # ~/.my.cnf to set user-specific options. # -# One can in this file use all long options that the program supports. +# In this file, you can use all long options that a program supports. # If you want to know which options a program supports, run the program -# with the --help option. +# with the "--help" option. # The following options will be passed to all MySQL clients [client] diff --git a/support-files/my-innodb-heavy-4G.cnf.sh b/support-files/my-innodb-heavy-4G.cnf.sh index 54df6a8bfe6..6def311f474 100644 --- a/support-files/my-innodb-heavy-4G.cnf.sh +++ b/support-files/my-innodb-heavy-4G.cnf.sh @@ -13,8 +13,8 @@ # (@localstatedir@ for this installation) or to # ~/.my.cnf to set user-specific options. # -# In this file, you can use all long options that the program supports. -# If you want to know the options a program supports, run the program +# In this file, you can use all long options that a program supports. +# If you want to know which options a program supports, run the program # with the "--help" option. # # More detailed information about the individual options can also be diff --git a/support-files/my-large.cnf.sh b/support-files/my-large.cnf.sh index a17ec7b5227..59aca4b32f2 100644 --- a/support-files/my-large.cnf.sh +++ b/support-files/my-large.cnf.sh @@ -1,6 +1,6 @@ -# Example mysql config file for large systems. +# Example MySQL config file for large systems. # -# This is for large system with memory = 512M where the system runs mainly +# This is for a large system with memory = 512M where the system runs mainly # MySQL. # # You can copy this file to @@ -9,9 +9,9 @@ # installation this directory is @localstatedir@) or # ~/.my.cnf to set user-specific options. # -# One can in this file use all long options that the program supports. +# In this file, you can use all long options that a program supports. # If you want to know which options a program supports, run the program -# with the --help option. +# with the "--help" option. # The following options will be passed to all MySQL clients [client] diff --git a/support-files/my-medium.cnf.sh b/support-files/my-medium.cnf.sh index d50d0717c17..529740d59f0 100644 --- a/support-files/my-medium.cnf.sh +++ b/support-files/my-medium.cnf.sh @@ -1,4 +1,4 @@ -# Example mysql config file for medium systems. +# Example MySQL config file for medium systems. # # This is for a system with little memory (32M - 64M) where MySQL plays # an important part, or systems up to 128M where MySQL is used together with @@ -10,9 +10,9 @@ # installation this directory is @localstatedir@) or # ~/.my.cnf to set user-specific options. # -# One can in this file use all long options that the program supports. +# In this file, you can use all long options that a program supports. # If you want to know which options a program supports, run the program -# with the --help option. +# with the "--help" option. # The following options will be passed to all MySQL clients [client] diff --git a/support-files/my-small.cnf.sh b/support-files/my-small.cnf.sh index 2ae62fb48f1..b2ecca6127e 100644 --- a/support-files/my-small.cnf.sh +++ b/support-files/my-small.cnf.sh @@ -1,4 +1,4 @@ -# Example mysql config file for small systems. +# Example MySQL config file for small systems. # # This is for a system with little memory (<= 64M) where MySQL is only used # from time to time and it's important that the mysqld daemon @@ -10,9 +10,9 @@ # installation this directory is @localstatedir@) or # ~/.my.cnf to set user-specific options. # -# One can in this file use all long options that the program supports. +# In this file, you can use all long options that a program supports. # If you want to know which options a program supports, run the program -# with the --help option. +# with the "--help" option. # The following options will be passed to all MySQL clients [client] diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 8583b623392..c3d74b147f3 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -397,7 +397,7 @@ useradd -M -r -d $mysql_datadir -s /bin/bash -c "MySQL server" mysql 2> /dev/nul chown -R mysql $mysql_datadir # Initiate databases -mysql_install_db --rpm +mysql_install_db -IN-RPM --user=mysql # Change permissions again to fix any new files. chown -R mysql $mysql_datadir |