diff options
32 files changed, 265 insertions, 118 deletions
diff --git a/BUILD/compile-pentium-debug-max b/BUILD/compile-pentium-debug-max index 1684686ce8c..af9bed1569f 100755 --- a/BUILD/compile-pentium-debug-max +++ b/BUILD/compile-pentium-debug-max @@ -8,6 +8,6 @@ c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" extra_configs="$pentium_configs $debug_configs" -extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-embedded-server --with-openssl" +extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-embedded-server --with-openssl --with-vio --with-raid" . "$path/FINISH.sh" diff --git a/configure.in b/configure.in index c05329a1680..a50d89c8655 100644 --- a/configure.in +++ b/configure.in @@ -1012,7 +1012,7 @@ case $SYSTEM_TYPE in *darwin5*) if test "$ac_cv_prog_gcc" = "yes" then - FLAGS="-traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH -DFN_NO_CASE_SENCE" + FLAGS="-traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH" CFLAGS="$CFLAGS $FLAGS" CXXFLAGS="$CXXFLAGS $FLAGS" MAX_C_OPTIMIZE="-O" @@ -1022,7 +1022,7 @@ case $SYSTEM_TYPE in *darwin6*) if test "$ac_cv_prog_gcc" = "yes" then - FLAGS="-DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH -DFN_NO_CASE_SENCE" + FLAGS="-DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH" CFLAGS="$CFLAGS $FLAGS" CXXFLAGS="$CXXFLAGS $FLAGS" MAX_C_OPTIMIZE="-O" @@ -1031,7 +1031,7 @@ case $SYSTEM_TYPE in *darwin7*) if test "$ac_cv_prog_gcc" = "yes" then - FLAGS="-DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DFN_NO_CASE_SENCE" + FLAGS="-DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ" CFLAGS="$CFLAGS $FLAGS" CXXFLAGS="$CXXFLAGS $FLAGS" MAX_C_OPTIMIZE="-O" diff --git a/include/my_sys.h b/include/my_sys.h index 75e22629a19..8f0040055d6 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -612,7 +612,7 @@ extern void pack_dirname(my_string to,const char *from); extern uint unpack_dirname(my_string to,const char *from); extern uint cleanup_dirname(my_string to,const char *from); extern uint system_filename(my_string to,const char *from); -extern my_string unpack_filename(my_string to,const char *from); +extern uint unpack_filename(my_string to,const char *from); extern my_string intern_filename(my_string to,const char *from); extern my_string directory_file_name(my_string dst, const char *src); extern int pack_filename(my_string to, const char *name, size_s max_length); @@ -682,9 +682,9 @@ extern int my_b_safe_write(IO_CACHE *info,const byte *Buffer,uint Count); extern int my_block_write(IO_CACHE *info, const byte *Buffer, uint Count, my_off_t pos); -extern int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock); +extern int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock); -#define flush_io_cache(info) _flush_io_cache((info),1) +#define flush_io_cache(info) my_b_flush_io_cache((info),1) extern int end_io_cache(IO_CACHE *info); extern uint my_b_fill(IO_CACHE *info); diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index 8f90301d2d8..dcac79a6cf4 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -208,7 +208,7 @@ then fi mysqld_boot=" $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \ - --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $EXTRA_ARG" + --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb --skip-warnings $EXTRA_ARG" echo "running $mysqld_boot" if $mysqld_boot << END_OF_DATA diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index cbb4987040d..d362e885dee 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -315,6 +315,8 @@ while test $# -gt 0; do $ECHO "Note: you will get more meaningful output on a source distribution compiled with debugging option when running tests with --gdb option" fi DO_GDB=1 + EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --gdb" + EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb" # This needs to be checked properly # USE_MANAGER=1 USE_RUNNING_SERVER="" @@ -1025,7 +1027,7 @@ start_slave() if [ x$DO_DDD = x1 ] then - $ECHO "set args $master_args" > $GDB_SLAVE_INIT + $ECHO "set args $slave_args" > $GDB_SLAVE_INIT manager_launch $slave_ident ddd -display $DISPLAY --debugger \ "gdb -x $GDB_SLAVE_INIT" $SLAVE_MYSQLD elif [ x$DO_GDB = x1 ] diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result index e582978c126..737d49fc340 100644 --- a/mysql-test/r/lowercase_table2.result +++ b/mysql-test/r/lowercase_table2.result @@ -106,3 +106,18 @@ SELECT * from T1; a 1 DROP TABLE T1; +create table T1 (EVENT_ID int auto_increment primary key, LOCATION char(20)); +insert into T1 values (NULL,"Mic-4"),(NULL,"Mic-5"),(NULL,"Mic-6"); +SELECT LOCATION FROM T1 WHERE EVENT_ID=2 UNION ALL SELECT LOCATION FROM T1 WHERE EVENT_ID=3; +LOCATION +Mic-5 +Mic-6 +SELECT LOCATION FROM T1 WHERE EVENT_ID=2 UNION ALL SELECT LOCATION FROM T1 WHERE EVENT_ID=3; +LOCATION +Mic-5 +Mic-6 +SELECT LOCATION FROM T1 WHERE EVENT_ID=2 UNION ALL SELECT LOCATION FROM T1 WHERE EVENT_ID=3; +LOCATION +Mic-5 +Mic-6 +drop table T1; diff --git a/mysql-test/r/lowercase_table3.result b/mysql-test/r/lowercase_table3.result index 0676c42e12b..362d17e0461 100644 --- a/mysql-test/r/lowercase_table3.result +++ b/mysql-test/r/lowercase_table3.result @@ -6,5 +6,5 @@ drop table t1; flush tables; CREATE TABLE t1 (a int) type=INNODB; SELECT * from T1; -Table 'test.T1' doesn't exist +Can't open file: 'T1.InnoDB'. (errno: 1) drop table t1; diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 31be96fc0fd..21035c8bc60 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -360,3 +360,29 @@ where 0=1; delete t1, t2 from t2,t1 where t1.id1=t2.id2 and 0=1; drop table t1,t2; +CREATE TABLE t1 ( a int ); +CREATE TABLE t2 ( a int ); +DELETE t1 FROM t1, t2 AS t3; +DELETE t4 FROM t1, t1 AS t4; +Not unique table/alias: 't4' +DELETE t3 FROM t1 AS t3, t1 AS t4; +Not unique table/alias: 't3' +DELETE t1 FROM t1 AS t3, t2 AS t4; +INSERT INTO t1 values (1),(2); +INSERT INTO t2 values (1),(2); +DELETE t1 FROM t1 AS t2, t2 AS t1 where t1.a=t2.a and t1.a=1; +SELECT * from t1; +a +2 +SELECT * from t2; +a +1 +2 +DELETE t2 FROM t1 AS t2, t2 AS t1 where t1.a=t2.a and t1.a=2; +SELECT * from t1; +a +2 +SELECT * from t2; +a +1 +DROP TABLE t1,t2; diff --git a/mysql-test/t/lowercase_table2.test b/mysql-test/t/lowercase_table2.test index 86bb26f0cf9..8f542a7af78 100644 --- a/mysql-test/t/lowercase_table2.test +++ b/mysql-test/t/lowercase_table2.test @@ -78,3 +78,14 @@ RENAME TABLE T2 TO T1; SHOW TABLES LIKE "T1"; SELECT * from T1; DROP TABLE T1; + +# +# Test problem with temporary tables (Bug #2858) +# + +create table T1 (EVENT_ID int auto_increment primary key, LOCATION char(20)); +insert into T1 values (NULL,"Mic-4"),(NULL,"Mic-5"),(NULL,"Mic-6"); +SELECT LOCATION FROM T1 WHERE EVENT_ID=2 UNION ALL SELECT LOCATION FROM T1 WHERE EVENT_ID=3; +SELECT LOCATION FROM T1 WHERE EVENT_ID=2 UNION ALL SELECT LOCATION FROM T1 WHERE EVENT_ID=3; +SELECT LOCATION FROM T1 WHERE EVENT_ID=2 UNION ALL SELECT LOCATION FROM T1 WHERE EVENT_ID=3; +drop table T1; diff --git a/mysql-test/t/lowercase_table3.test b/mysql-test/t/lowercase_table3.test index 83ffaaad2d1..735a0b390f9 100644 --- a/mysql-test/t/lowercase_table3.test +++ b/mysql-test/t/lowercase_table3.test @@ -32,6 +32,6 @@ flush tables; # CREATE TABLE t1 (a int) type=INNODB; ---error 1146 +--error 1016 SELECT * from T1; drop table t1; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index be82870cccd..283637912a1 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -302,3 +302,26 @@ delete t1, t2 from t2,t1 where t1.id1=t2.id2 and 0=1; drop table t1,t2; + +# +# Test alias (this is not correct in 4.0) +# + +CREATE TABLE t1 ( a int ); +CREATE TABLE t2 ( a int ); +DELETE t1 FROM t1, t2 AS t3; +--error 1066 +DELETE t4 FROM t1, t1 AS t4; +--error 1066 +DELETE t3 FROM t1 AS t3, t1 AS t4; +#--error 1066 +DELETE t1 FROM t1 AS t3, t2 AS t4; +INSERT INTO t1 values (1),(2); +INSERT INTO t2 values (1),(2); +DELETE t1 FROM t1 AS t2, t2 AS t1 where t1.a=t2.a and t1.a=1; +SELECT * from t1; +SELECT * from t2; +DELETE t2 FROM t1 AS t2, t2 AS t1 where t1.a=t2.a and t1.a=2; +SELECT * from t1; +SELECT * from t2; +DROP TABLE t1,t2; diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index d96d4c0db3c..c5bd7db9677 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -962,7 +962,7 @@ int my_b_append(register IO_CACHE *info, const byte *Buffer, uint Count) Buffer+=rest_length; Count-=rest_length; info->write_pos+=rest_length; - if (_flush_io_cache(info,0)) + if (my_b_flush_io_cache(info,0)) { unlock_append_buffer(info); return 1; @@ -1069,12 +1069,12 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count, #endif -int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) +int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) { uint length; my_bool append_cache; my_off_t pos_in_file; - DBUG_ENTER("_flush_io_cache"); + DBUG_ENTER("my_b_flush_io_cache"); if (!(append_cache = (info->type == SEQ_READ_APPEND))) need_append_buffer_lock=0; diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index e2e811fe89a..95a1d68507e 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -347,11 +347,25 @@ static my_string NEAR_F expand_tilde(my_string *path) return (my_string) 0; } - /* fix filename so it can be used by open, create .. */ - /* to may be == from */ - /* Returns to */ -my_string unpack_filename(my_string to, const char *from) +/* + Fix filename so it can be used by open, create + + SYNOPSIS + unpack_filename() + to Store result here. Must be at least of size FN_REFLEN. + from Filename in unix format (with ~) + + RETURN + # length of to + + NOTES + to may be == from + ~ will only be expanded if total length < FN_REFLEN +*/ + + +uint unpack_filename(my_string to, const char *from) { uint length,n_length; char buff[FN_REFLEN]; @@ -362,17 +376,17 @@ my_string unpack_filename(my_string to, const char *from) if (n_length+strlen(from+length) < FN_REFLEN) { (void) strmov(buff+n_length,from+length); - (void) system_filename(to,buff); /* Fix to usably filename */ + length= system_filename(to,buff); /* Fix to usably filename */ } else - (void) system_filename(to,from); /* Fix to usably filename */ - DBUG_RETURN(to); + length= system_filename(to,from); /* Fix to usably filename */ + DBUG_RETURN(length); } /* unpack_filename */ /* Convert filename (unix standard) to system standard */ /* Used before system command's like open(), create() .. */ - /* Returns to */ + /* Returns length of to */ uint system_filename(my_string to, const char *from) { diff --git a/mysys/test_fn.c b/mysys/test_fn.c index 5a0546392ab..d0fb9f59fd6 100644 --- a/mysys/test_fn.c +++ b/mysys/test_fn.c @@ -59,7 +59,8 @@ int main(int argc __attribute__((unused)), char **argv) printf("org : '%s'\n",*pos); printf("pack: '%s'\n",fn_format(buff,*pos,"","",8)); printf("unpack: '%s'\n",fn_format(buff2,*pos,"","",4)); - if (strcmp(unpack_filename(buff,buff),buff2) != 0) + unpack_filename(buff,buff); + if (strcmp(buff,buff2) != 0) { printf("error on cmp: '%s' != '%s'\n",buff,buff2); } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index d630e9774a5..d5bbf9b5a92 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1210,6 +1210,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, create_info.data_file_name= info->data_file_name; create_info.index_file_name=info->index_file_name; + /* TODO: Check that the following fn_format is really needed */ error=mi_create(fn_format(buff,name,"","",2+4), table_arg->keys,keydef, (uint) (recinfo_pos-recinfo), recinfo, diff --git a/sql/lock.cc b/sql/lock.cc index 41a76007289..5010d115a6c 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -490,11 +490,14 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) char *db= table_list->db ? table_list->db : (thd->db ? thd->db : (char*) ""); uint key_length; DBUG_ENTER("lock_table_name"); + DBUG_PRINT("enter",("db: %s name: %s", db, table_list->real_name)); + safe_mutex_assert_owner(&LOCK_open); key_length=(uint) (strmov(strmov(key,db)+1,table_list->real_name) -key)+ 1; + /* Only insert the table if we haven't insert it already */ for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; table ; @@ -526,6 +529,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(0); } + void unlock_table_name(THD *thd, TABLE_LIST *table_list) { if (table_list->table) @@ -535,6 +539,7 @@ void unlock_table_name(THD *thd, TABLE_LIST *table_list) } } + static bool locked_named_table(THD *thd, TABLE_LIST *table_list) { for (; table_list ; table_list=table_list->next) diff --git a/sql/log.cc b/sql/log.cc index 559d30f28ba..7b402421951 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -695,7 +695,7 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) sizeof(rli->relay_log_name)-1); /* Store where we are in the new file for the execution thread */ - flush_relay_log_info(rli); + flush_relay_log_info(rli, 0); err: pthread_mutex_unlock(&LOCK_index); diff --git a/sql/log_event.cc b/sql/log_event.cc index 603c8431b03..1b8976df8dc 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -231,7 +231,7 @@ int Log_event::exec_event(struct st_relay_log_info* rli) else { rli->inc_pos(get_event_len(),log_pos); - flush_relay_log_info(rli); + flush_relay_log_info(rli, 1); } } return 0; @@ -2201,7 +2201,7 @@ int Stop_log_event::exec_event(struct st_relay_log_info* rli) the target position when in fact we have not. */ rli->inc_pos(get_event_len(), 0); - flush_relay_log_info(rli); + flush_relay_log_info(rli, 0); return 0; } @@ -2248,7 +2248,7 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli) } pthread_mutex_unlock(&rli->data_lock); pthread_cond_broadcast(&rli->data_cond); - flush_relay_log_info(rli); + flush_relay_log_info(rli, 0); DBUG_RETURN(0); } diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc index c79317cfeb3..5c63820a6ae 100644 --- a/sql/mf_iocache.cc +++ b/sql/mf_iocache.cc @@ -30,14 +30,7 @@ flush_io_cache(). */ -#define MAP_TO_USE_RAID #include "mysql_priv.h" -#ifdef HAVE_AIOWAIT -#include <mysys_err.h> -#include <errno.h> -static void my_aiowait(my_aio_result *result); -#endif -#include <assert.h> extern "C" { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6699a502604..6037155794b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1040,8 +1040,8 @@ static void set_user(const char *user) { /* Don't give a warning, if real user is same as given with --user */ struct passwd *user_info= getpwnam(user); - - if (!user_info || user_id != user_info->pw_uid) + if ((!user_info || user_id != user_info->pw_uid) && + global_system_variables.log_warnings) fprintf(stderr, "Warning: One can only use the --user switch if running as root\n"); } @@ -2108,22 +2108,25 @@ int main(int argc, char **argv) insensitive names. If this is not done the users MyISAM tables will get corrupted if accesses with names of different case. */ + DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names)); if (!lower_case_table_names && (lower_case_file_system= (test_if_case_insensitive(mysql_real_data_home) == 1))) { if (lower_case_table_names_used) { - sql_print_error("\ + if (global_system_variables.log_warnings) + sql_print_error("\ Warning: You have forced lower_case_table_names to 0 through a command line \ option, even if your file system '%s' is case insensitive. This means that \ you can corrupt an MyISAM table by accessing it with different cases. You \ should consider changing lower_case_table_names to 1 or 2", - mysql_real_data_home); + mysql_real_data_home); } else { - sql_print_error("Warning: Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home); + if (global_system_variables.log_warnings) + sql_print_error("Warning: Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home); lower_case_table_names= 2; } } @@ -2187,7 +2190,8 @@ should consider changing lower_case_table_names to 1 or 2", DBUG_PRINT("warning", ("Changed limits: max_connections: %ld table_cache: %ld", max_connections,table_cache_size)); - sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size); + if (global_system_variables.log_warnings) + sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size); } open_files_limit= files; } @@ -2277,7 +2281,8 @@ should consider changing lower_case_table_names to 1 or 2", { if (mlockall(MCL_CURRENT)) { - sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno); + if (global_system_variables.log_warnings) + sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno); } else locked_in_memory=1; @@ -2428,7 +2433,7 @@ Now disabling --log-slave-updates."); (!have_tcpip || opt_disable_networking)) { sql_print_error("TCP/IP or --enable-named-pipe should be configured on NT OS"); - unireg_abort(1); + unireg_abort(1); } else { @@ -5032,14 +5037,16 @@ static uint set_maximum_open_files(uint max_file_limit) rlimit.rlim_cur=rlimit.rlim_max=max_file_limit; if (setrlimit(RLIMIT_NOFILE,&rlimit)) { - sql_print_error("Warning: setrlimit couldn't increase number of open files to more than %lu (request: %u)", - old_cur, max_file_limit); /* purecov: inspected */ + if (global_system_variables.log_warnings) + sql_print_error("Warning: setrlimit couldn't increase number of open files to more than %lu (request: %u)", + old_cur, max_file_limit); /* purecov: inspected */ max_file_limit=old_cur; } else { (void) getrlimit(RLIMIT_NOFILE,&rlimit); - if ((uint) rlimit.rlim_cur != max_file_limit) + if ((uint) rlimit.rlim_cur != max_file_limit && + global_system_variables.log_warnings) sql_print_error("Warning: setrlimit returned ok, but didn't change limits. Max open files is %ld (request: %u)", (ulong) rlimit.rlim_cur, max_file_limit); /* purecov: inspected */ @@ -5064,10 +5071,12 @@ static uint set_maximum_open_files(uint max_file_limit) // set new limit cbReqCount = max_file_limit - cbCurMaxFH0; ulrc = DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH); - if (ulrc) { - sql_print_error("Warning: DosSetRelMaxFH couldn't increase number of open files to more than %d", - cbCurMaxFH0); - cbCurMaxFH = cbCurMaxFH0; + if (ulrc) + { + if (global_system_variables.log_warnings) + sql_print_error("Warning: DosSetRelMaxFH couldn't increase number of open files to more than %d", + cbCurMaxFH0); + cbCurMaxFH = cbCurMaxFH0; } return cbCurMaxFH; @@ -5153,6 +5162,7 @@ static int test_if_case_insensitive(const char *dir_name) File file; char buff[FN_REFLEN], buff2[FN_REFLEN]; MY_STAT stat_info; + DBUG_ENTER("test_if_case_insensitive"); fn_format(buff, glob_hostname, dir_name, ".lower-test", MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR); @@ -5162,13 +5172,14 @@ static int test_if_case_insensitive(const char *dir_name) if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0) { sql_print_error("Warning: Can't create test file %s", buff); - return -1; + DBUG_RETURN(-1); } my_close(file, MYF(0)); if (my_stat(buff2, &stat_info, MYF(0))) result= 1; // Can access file (void) my_delete(buff, MYF(MY_WME)); - return result; + DBUG_PRINT("exit", ("result: %d", result)); + DBUG_RETURN(result); } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 071c83bb6d2..dfed08479f9 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2144,6 +2144,7 @@ static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key) void SEL_ARG::test_use_count(SEL_ARG *root) { + uint e_count=0; if (this == root && use_count != 1) { sql_print_error("Note: Use_count: Wrong count %lu for root",use_count); @@ -2151,7 +2152,6 @@ void SEL_ARG::test_use_count(SEL_ARG *root) } if (this->type != SEL_ARG::KEY_RANGE) return; - uint e_count=0; for (SEL_ARG *pos=first(); pos ; pos=pos->next) { e_count++; @@ -2168,8 +2168,8 @@ void SEL_ARG::test_use_count(SEL_ARG *root) } } if (e_count != elements) - sql_print_error("Warning: Wrong use count: %u for tree at %lx", e_count, - (gptr) this); + sql_print_error("Warning: Wrong use count: %u (should be %u) for tree at %lx", + e_count, elements, (gptr) this); } #endif diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 6599516044a..61d4cee4c09 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -920,7 +920,7 @@ int load_master_data(THD* thd) active_mi->rli.master_log_pos = active_mi->master_log_pos; strmake(active_mi->rli.master_log_name,active_mi->master_log_name, sizeof(active_mi->rli.master_log_name)-1); - flush_relay_log_info(&active_mi->rli); + flush_relay_log_info(&active_mi->rli, 0); pthread_cond_broadcast(&active_mi->rli.data_cond); pthread_mutex_unlock(&active_mi->rli.data_lock); thd->proc_info = "starting slave"; diff --git a/sql/slave.cc b/sql/slave.cc index d6510b26271..21337e0476e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -584,19 +584,26 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start, lock_cond_sql = &mi->rli.run_lock; } - if (thread_mask & SLAVE_IO) - error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io, - cond_io, - &mi->slave_running, &mi->slave_run_id, - mi); - if (!error && (thread_mask & SLAVE_SQL)) - { + /* + We must first start the SQL thread, becasue for lock_slave_threads() to work + we must first unlock mi->rli.run_lock and then mi->run_lock + If we don't do this, we will get a deadlock if two threads calls START SLAVE + at the same time. + */ + + if (thread_mask & SLAVE_SQL) error=start_slave_thread(handle_slave_sql,lock_sql,lock_cond_sql, cond_sql, &mi->rli.slave_running, &mi->rli.slave_run_id, mi); + if (!error && (thread_mask & SLAVE_IO)) + { + error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io, + cond_io, + &mi->slave_running, &mi->slave_run_id, + mi); if (error) - terminate_slave_threads(mi, thread_mask & SLAVE_IO, 0); + terminate_slave_threads(mi, thread_mask & SLAVE_SQL, 0); } DBUG_RETURN(error); } @@ -1431,7 +1438,7 @@ Failed to open the existing relay log info file '%s' (errno %d)", before flush_relay_log_info */ reinit_io_cache(&rli->info_file, WRITE_CACHE,0L,0,1); - if ((error= flush_relay_log_info(rli))) + if ((error= flush_relay_log_info(rli, 0))) sql_print_error("Failed to flush relay log info file"); if (count_relay_log_space(rli)) { @@ -1650,9 +1657,9 @@ file '%s')", fname); mi->master_log_name, (ulong) mi->master_log_pos)); + mi->rli.mi = mi; if (init_relay_log_info(&mi->rli, slave_info_fname)) goto err; - mi->rli.mi = mi; mi->inited = 1; // now change cache READ -> WRITE - must do this before flush_master_info @@ -2279,7 +2286,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) rli->inc_pos(ev->get_event_len(), type_code != STOP_EVENT ? ev->log_pos : LL(0), 1/* skip lock*/); - flush_relay_log_info(rli); + flush_relay_log_info(rli, 0); /* Protect against common user error of setting the counter to 1 @@ -3239,6 +3246,7 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi, SYNOPSIS flush_relay_log_info() rli Relay log information + flush_cur_log Flush the current log if it's a hot log. NOTES - As this is only called by the slave thread, we don't need to @@ -3251,6 +3259,8 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi, If this would not be the case, we would have to ensure that we don't delete the relay log file where the transaction started when we switch to a new relay log file. + - The reason for flushing current log is to ensure that we have saved on + disk the last query the SQL thread read TODO - Change the log file information to a binary format to avoid calling @@ -3261,7 +3271,7 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi, 1 write error */ -bool flush_relay_log_info(RELAY_LOG_INFO* rli) +bool flush_relay_log_info(RELAY_LOG_INFO* rli, bool flush_cur_log) { bool error=0; IO_CACHE *file = &rli->info_file; @@ -3284,8 +3294,23 @@ bool flush_relay_log_info(RELAY_LOG_INFO* rli) error=1; if (flush_io_cache(file)) error=1; - if (flush_io_cache(rli->cur_log)) // QQ Why this call ? - error=1; + + /* + We want to flush the io log here if this is a hot cache to ensure + that we have the execute SQL statement on disk. + */ + if (flush_cur_log) + { + /* + The following mutex is to protect us against log changes in middle of + the flush_io_cache() call + */ + pthread_mutex_lock(&rli->mi->data_lock); + /* Only flush hot logs */ + if (rli->cur_log != &rli->cache_buf && flush_io_cache(rli->cur_log)) + error=1; + pthread_mutex_unlock(&rli->mi->data_lock); + } return error; } @@ -3506,7 +3531,7 @@ rli->relay_log_pos=%s rli->pending=%lu", rli->pending=0; strmake(rli->relay_log_name,rli->linfo.log_file_name, sizeof(rli->relay_log_name)-1); - flush_relay_log_info(rli); + flush_relay_log_info(rli, 0); } /* diff --git a/sql/slave.h b/sql/slave.h index 8331e722a51..0ae0c7d6de4 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -362,7 +362,7 @@ typedef struct st_table_rule_ent int init_slave(); void init_slave_skip_errors(const char* arg); bool flush_master_info(MASTER_INFO* mi); -bool flush_relay_log_info(RELAY_LOG_INFO* rli); +bool flush_relay_log_info(RELAY_LOG_INFO* rli, bool flush_cur_log); int register_slave_on_master(MYSQL* mysql); int terminate_slave_threads(MASTER_INFO* mi, int thread_mask, bool skip_lock = 0); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 95ef7acb5ab..9da1f4e2231 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1706,7 +1706,11 @@ bool rm_temporary_table(enum db_type base, char *path) *fn_ext(path)='\0'; // remove extension handler *file=get_new_handler((TABLE*) 0, base); if (file && file->delete_table(path)) + { error=1; + sql_print_error("Warning: Could not remove tmp table: '%s', error: %d", + path, my_errno); + } delete file; return error; } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index ca9989d986c..a88cff0cd9b 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -242,6 +242,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, idx++) { FILEINFO *file=dirp->dir_entry+idx; + char *extension; DBUG_PRINT("info",("Examining: %s", file->name)); /* Check if file is a raid directory */ @@ -251,59 +252,55 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, (file->name[1] >= 'a' && file->name[1] <= 'f')) && !file->name[2] && !level) { - char newpath[FN_REFLEN]; + char newpath[FN_REFLEN], *copy_of_path; MY_DIR *new_dirp; String *dir; + uint length; strxmov(newpath,org_path,"/",file->name,NullS); - unpack_filename(newpath,newpath); + length= unpack_filename(newpath,newpath); if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT)))) { DBUG_PRINT("my",("New subdir found: %s", newpath)); if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1)) < 0) - { - my_dirend(dirp); - DBUG_RETURN(-1); - } - raid_dirs.push_back(dir=new String(newpath)); - dir->copy(); + goto err; + if (!(copy_of_path= thd->memdup(newpath, length+1)) || + !(dir= new String(copy_of_path, length)) || + raid_dirs.push_back(dir)) + goto err; continue; } found_other_files++; continue; } - if (find_type(fn_ext(file->name),&deletable_extentions,1+2) <= 0) + extension= fn_ext(file->name); + if (find_type(extension, &deletable_extentions,1+2) <= 0) { - if (find_type(fn_ext(file->name),&known_extentions,1+2) <= 0) + if (find_type(extension, &known_extentions,1+2) <= 0) found_other_files++; continue; } - strxmov(filePath,org_path,"/",file->name,NullS); - if (db && !my_strcasecmp(fn_ext(file->name), reg_ext)) + if (db && !my_strcasecmp(extension, reg_ext)) { /* Drop the table nicely */ - *fn_ext(file->name)=0; // Remove extension + *extension= 0; // Remove extension TABLE_LIST *table_list=(TABLE_LIST*) thd->calloc(sizeof(*table_list)+ strlen(db)+strlen(file->name)+2); if (!table_list) - { - my_dirend(dirp); - DBUG_RETURN(-1); - } + goto err; table_list->db= (char*) (table_list+1); - strmov(table_list->real_name=strmov(table_list->db,db)+1, - file->name); + strmov(table_list->real_name= strmov(table_list->db,db)+1, file->name); + table_list->alias= table_list->real_name; // If lower_case_table_names=2 /* Link into list */ (*tot_list_next)= table_list; tot_list_next= &table_list->next; } else { - + strxmov(filePath, org_path, "/", file->name, NullS); if (my_delete_with_symlink(filePath,MYF(MY_WME))) { - my_dirend(dirp); - DBUG_RETURN(-1); + goto err; } deleted++; } @@ -311,14 +308,17 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, if (thd->killed || (tot_list && mysql_rm_table_part2_with_lock(thd, tot_list, 1, 1))) { - my_dirend(dirp); - DBUG_RETURN(-1); + goto err; + } + + /* Remove RAID directories */ + { + List_iterator<String> it(raid_dirs); + String *dir; + while ((dir= it++)) + if (rmdir(dir->c_ptr()) < 0) + found_other_files++; } - List_iterator<String> it(raid_dirs); - String *dir; - while ((dir= it++)) - if (rmdir(dir->c_ptr()) < 0) - found_other_files++; my_dirend(dirp); /* @@ -328,7 +328,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, if (!found_other_files) { char tmp_path[FN_REFLEN], *pos; - char *path=unpack_filename(tmp_path,org_path); + char *path= tmp_path; + unpack_filename(tmp_path,org_path); #ifdef HAVE_READLINK int error; @@ -365,6 +366,10 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, } } DBUG_RETURN(deleted); + +err: + my_dirend(dirp); + DBUG_RETURN(-1); } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 963111015da..a80b4040882 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -36,7 +36,7 @@ But !!! do_command calls free_root at the end of every query and frees up all the sql_alloc'ed memory. It's harder to work around... - */ +*/ #define HANDLER_TABLES_HACK(thd) { \ TABLE *tmp=thd->open_tables; \ diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index c95cdc1b04e..85dcd3b5236 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1011,14 +1011,14 @@ int change_master(THD* thd, MASTER_INFO* mi) mi->rli.abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */ /* Clear the error, for a clean start. */ clear_last_slave_error(&mi->rli); - /* - If we don't write new coordinates to disk now, then old will remain in - relay-log.info until START SLAVE is issued; but if mysqld is shutdown - before START SLAVE, then old will remain in relay-log.info, and will be the - in-memory value at restart (thus causing errors, as the old relay log does - not exist anymore). + /* + If we don't write new coordinates to disk now, then old will remain in + relay-log.info until START SLAVE is issued; but if mysqld is shutdown + before START SLAVE, then old will remain in relay-log.info, and will be the + in-memory value at restart (thus causing errors, as the old relay log + does not exist anymore). */ - flush_relay_log_info(&mi->rli); + flush_relay_log_info(&mi->rli, 0); pthread_cond_broadcast(&mi->data_cond); pthread_mutex_unlock(&mi->rli.data_lock); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 012be95c381..3ffa4e6a92c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4463,13 +4463,22 @@ free_tmp_table(THD *thd, TABLE *entry) save_proc_info=thd->proc_info; thd->proc_info="removing tmp table"; free_blobs(entry); - if (entry->db_stat && entry->file) + if (entry->file) { - (void) entry->file->close(); + if (entry->db_stat) + { + (void) entry->file->close(); + } + /* + We can't call ha_delete_table here as the table may created in mixed case + here and we have to ensure that delete_table gets the table name in + the original case. + */ + if (!(test_flags & TEST_KEEP_TMP_TABLES) || entry->db_type == DB_TYPE_HEAP) + entry->file->delete_table(entry->real_name); delete entry->file; } - if (!(test_flags & TEST_KEEP_TMP_TABLES) || entry->db_type == DB_TYPE_HEAP) - (void) ha_delete_table(entry->db_type,entry->real_name); + /* free blobs */ for (Field **ptr=entry->field ; *ptr ; ptr++) delete *ptr; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c738eb0a3e7..48151ef55b9 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1987,10 +1987,11 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } + /* - ** Data is copied. Now we rename the old table to a temp name, - ** rename the new one to the old name, remove all entries from the old table - ** from the cash, free all locks, close the old table and remove it. + Data is copied. Now we rename the old table to a temp name, + rename the new one to the old name, remove all entries from the old table + from the cash, free all locks, close the old table and remove it. */ thd->proc_info="rename result table"; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5add9199ad4..52334b4830e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3246,7 +3246,7 @@ table_ident: ; table_ident_ref: - ident { LEX_STRING db={"",0}; $$=new Table_ident(db,$1,0); } + ident { LEX_STRING db={(char*) "",0}; $$=new Table_ident(db,$1,0); } | ident '.' ident { $$=new Table_ident($1,$3,0);} ; diff --git a/sql/table.cc b/sql/table.cc index a90220fa55b..bc9d046f617 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -618,8 +618,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (db_stat) { int err; + unpack_filename(index_file,index_file); if ((err=(outparam->file-> - ha_open(unpack_filename(index_file,index_file), + ha_open(index_file, (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : ((db_stat & HA_WAIT_IF_LOCKED) || |