Fixed memory leak in DROP DATABASE when using RAID tables (Bug #2882)

This commit is contained in:
monty@mysql.com 2004-03-10 13:46:11 +02:00
parent 73780de129
commit 4ee44751d9
32 changed files with 265 additions and 118 deletions

View File

@ -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"

View File

@ -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"

View File

@ -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);

View File

@ -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

View File

@ -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 ]

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -32,6 +32,6 @@ flush tables;
#
CREATE TABLE t1 (a int) type=INNODB;
--error 1146
--error 1016
SELECT * from T1;
drop table t1;

View File

@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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);
}

View File

@ -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,

View File

@ -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)

View File

@ -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);

View File

@ -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);
}

View File

@ -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" {

View File

@ -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);
}

View File

@ -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

View File

@ -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";

View File

@ -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);
}
/*

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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; \

View File

@ -1012,13 +1012,13 @@ int change_master(THD* thd, MASTER_INFO* mi)
/* 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);

View File

@ -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;

View File

@ -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";

View File

@ -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);}
;

View File

@ -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) ||