mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fix for MacOSX and symlinks
Fix for USE_FRM and crashed index file configure.in: Fix for MacOSX and symlinks myisam/mi_open.c: Give better error message in case of of crashed index file mysql-test/r/repair.result: new test case mysql-test/r/update.result: new test case mysql-test/t/repair.test: Added test with crashed MyISAM index header mysql-test/t/update.test: Added test case from bugs system sql/handler.cc: Indentation changes sql/sql_table.cc: Fix for USE_FRM and crashed index file
This commit is contained in:
10
configure.in
10
configure.in
@ -1007,8 +1007,9 @@ case $SYSTEM_TYPE in
|
|||||||
*darwin5*)
|
*darwin5*)
|
||||||
if test "$ac_cv_prog_gcc" = "yes"
|
if test "$ac_cv_prog_gcc" = "yes"
|
||||||
then
|
then
|
||||||
CFLAGS="$CFLAGS -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 -DFN_NO_CASE_SENCE"
|
||||||
CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DFN_NO_CASE_SENCE"
|
CFLAGS="$CFLAGS $FLAGS"
|
||||||
|
CXXFLAGS="$CXXFLAGS $FLAGS"
|
||||||
MAX_C_OPTIMIZE="-O"
|
MAX_C_OPTIMIZE="-O"
|
||||||
with_named_curses=""
|
with_named_curses=""
|
||||||
fi
|
fi
|
||||||
@ -1016,8 +1017,9 @@ case $SYSTEM_TYPE in
|
|||||||
*darwin6*)
|
*darwin6*)
|
||||||
if test "$ac_cv_prog_gcc" = "yes"
|
if test "$ac_cv_prog_gcc" = "yes"
|
||||||
then
|
then
|
||||||
CFLAGS="$CFLAGS -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 -DFN_NO_CASE_SENCE"
|
||||||
CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DFN_NO_CASE_SENCE"
|
CFLAGS="$CFLAGS $FLAGS"
|
||||||
|
CXXFLAGS="$CXXFLAGS $FLAGS"
|
||||||
MAX_C_OPTIMIZE="-O"
|
MAX_C_OPTIMIZE="-O"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
@ -114,8 +114,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
|||||||
errpos=1;
|
errpos=1;
|
||||||
if (my_read(kfile,(char*) share->state.header.file_version,head_length,
|
if (my_read(kfile,(char*) share->state.header.file_version,head_length,
|
||||||
MYF(MY_NABP)))
|
MYF(MY_NABP)))
|
||||||
|
{
|
||||||
|
my_errno= HA_ERR_NOT_A_TABLE;
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
if (memcmp((byte*) share->state.header.file_version,
|
if (memcmp((byte*) share->state.header.file_version,
|
||||||
(byte*) myisam_file_magic, 4))
|
(byte*) myisam_file_magic, 4))
|
||||||
{
|
{
|
||||||
@ -165,7 +167,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
|||||||
}
|
}
|
||||||
errpos=3;
|
errpos=3;
|
||||||
if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
|
if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
|
||||||
|
{
|
||||||
|
my_errno=HA_ERR_CRASHED;
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
len=mi_uint2korr(share->state.header.state_info_length);
|
len=mi_uint2korr(share->state.header.state_info_length);
|
||||||
keys= (uint) share->state.header.keys;
|
keys= (uint) share->state.header.keys;
|
||||||
uniques= (uint) share->state.header.uniques;
|
uniques= (uint) share->state.header.uniques;
|
||||||
|
@ -11,4 +11,5 @@ test.t1 repair error The handler for the table doesn't support repair
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
repair table t1 use_frm;
|
repair table t1 use_frm;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
t1 repair error table is read-only or does not exists
|
test.t1 repair error Table 'test.t1' doesn't exist
|
||||||
|
create table t1 type=myisam SELECT 1,"table 1";
|
||||||
|
8
mysql-test/r/repair_part2.result
Normal file
8
mysql-test/r/repair_part2.result
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
repair table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair error Can't open file: 't1.MYI'. (errno: 130)
|
||||||
|
repair table t1 use_frm;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair warning Number of rows changed from 0 to 1
|
||||||
|
test.t1 repair status OK
|
||||||
|
drop table t1;
|
@ -150,3 +150,19 @@ select * from t1;
|
|||||||
id_param nom_option valid
|
id_param nom_option valid
|
||||||
185 test 1
|
185 test 1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (F1 VARCHAR(30), F2 VARCHAR(30), F3 VARCHAR(30), cnt int, groupid int, KEY groupid_index (groupid));
|
||||||
|
insert into t1 (F1,F2,F3,cnt,groupid) values ('0','0','0',1,6),
|
||||||
|
('0','1','2',1,5), ('0','2','0',1,3), ('1','0','1',1,2),
|
||||||
|
('1','2','1',1,1), ('1','2','2',1,1), ('2','0','1',2,4),
|
||||||
|
('2','2','0',1,7);
|
||||||
|
delete from t1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3);
|
||||||
|
select * from t1;
|
||||||
|
F1 F2 F3 cnt groupid
|
||||||
|
0 0 0 1 6
|
||||||
|
0 1 2 1 5
|
||||||
|
0 2 0 1 3
|
||||||
|
1 0 1 1 2
|
||||||
|
1 2 1 1 1
|
||||||
|
2 0 1 2 4
|
||||||
|
2 2 0 1 7
|
||||||
|
drop table t1;
|
||||||
|
@ -12,4 +12,8 @@ drop table t1;
|
|||||||
# non-existent table
|
# non-existent table
|
||||||
repair table t1 use_frm;
|
repair table t1 use_frm;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Create test table for repair2
|
||||||
|
# The following must be last in this file
|
||||||
|
|
||||||
|
create table t1 type=myisam SELECT 1,"table 1";
|
||||||
|
1
mysql-test/t/repair_part2-master.sh
Normal file
1
mysql-test/t/repair_part2-master.sh
Normal file
@ -0,0 +1 @@
|
|||||||
|
echo "1" > $MYSQL_TEST_DIR/var/master-data/test/t1.MYI
|
7
mysql-test/t/repair_part2.test
Normal file
7
mysql-test/t/repair_part2.test
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
# This test starts with a crashed t1.MYI file left over from repair.test
|
||||||
|
#
|
||||||
|
|
||||||
|
repair table t1;
|
||||||
|
repair table t1 use_frm;
|
||||||
|
drop table t1;
|
@ -108,3 +108,18 @@ INSERT INTO t1 (id_param,nom_option,valid) VALUES (185,'600x1200',1);
|
|||||||
UPDATE t1 SET nom_option='test' WHERE id_param=185 AND nom_option='600x1200' AND valid=1 LIMIT 1;
|
UPDATE t1 SET nom_option='test' WHERE id_param=185 AND nom_option='600x1200' AND valid=1 LIMIT 1;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Multi table update test from bugs
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (F1 VARCHAR(30), F2 VARCHAR(30), F3 VARCHAR(30), cnt int, groupid int, KEY groupid_index (groupid));
|
||||||
|
|
||||||
|
insert into t1 (F1,F2,F3,cnt,groupid) values ('0','0','0',1,6),
|
||||||
|
('0','1','2',1,5), ('0','2','0',1,3), ('1','0','1',1,2),
|
||||||
|
('1','2','1',1,1), ('1','2','2',1,1), ('2','0','1',2,4),
|
||||||
|
('2','2','0',1,7);
|
||||||
|
|
||||||
|
delete from t1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3);
|
||||||
|
select * from t1;
|
||||||
|
drop table t1;
|
||||||
|
@ -830,7 +830,8 @@ void handler::print_error(int error, myf errflag)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return key if error because of duplicated keys */
|
|
||||||
|
/* Return key if error because of duplicated keys */
|
||||||
|
|
||||||
uint handler::get_dup_key(int error)
|
uint handler::get_dup_key(int error)
|
||||||
{
|
{
|
||||||
@ -841,6 +842,7 @@ uint handler::get_dup_key(int error)
|
|||||||
DBUG_RETURN(table->file->errkey);
|
DBUG_RETURN(table->file->errkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int handler::delete_table(const char *name)
|
int handler::delete_table(const char *name)
|
||||||
{
|
{
|
||||||
int error=0;
|
int error=0;
|
||||||
@ -867,9 +869,10 @@ int handler::rename_table(const char * from, const char * to)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell the handler to turn on or off logging to the handler's
|
/*
|
||||||
recovery log
|
Tell the handler to turn on or off logging to the handler's recovery log
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ha_recovery_logging(THD *thd, bool on)
|
int ha_recovery_logging(THD *thd, bool on)
|
||||||
{
|
{
|
||||||
int error=0;
|
int error=0;
|
||||||
@ -914,7 +917,6 @@ int handler::delete_all_rows()
|
|||||||
|
|
||||||
int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
|
int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
|
||||||
bool update_create_info)
|
bool update_create_info)
|
||||||
|
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
TABLE table;
|
TABLE table;
|
||||||
|
142
sql/sql_table.cc
142
sql/sql_table.cc
@ -946,6 +946,7 @@ static void safe_remove_from_cache(THD *thd,TABLE *table)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool close_cached_table(THD *thd,TABLE *table)
|
bool close_cached_table(THD *thd,TABLE *table)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("close_cached_table");
|
DBUG_ENTER("close_cached_table");
|
||||||
@ -957,7 +958,8 @@ bool close_cached_table(THD *thd,TABLE *table)
|
|||||||
/* Close lock if this is not got with LOCK TABLES */
|
/* Close lock if this is not got with LOCK TABLES */
|
||||||
if (thd->lock)
|
if (thd->lock)
|
||||||
{
|
{
|
||||||
mysql_unlock_tables(thd, thd->lock); thd->lock=0; // Start locked threads
|
mysql_unlock_tables(thd, thd->lock);
|
||||||
|
thd->lock=0; // Start locked threads
|
||||||
}
|
}
|
||||||
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
|
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
|
||||||
thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
|
thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
|
||||||
@ -1045,93 +1047,105 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int prepare_for_repair(THD* thd, TABLE_LIST* table,
|
static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
|
||||||
HA_CHECK_OPT *check_opt)
|
HA_CHECK_OPT *check_opt)
|
||||||
{
|
{
|
||||||
|
int error= 0;
|
||||||
|
TABLE tmp_table, *table;
|
||||||
DBUG_ENTER("prepare_for_repair");
|
DBUG_ENTER("prepare_for_repair");
|
||||||
|
|
||||||
if (!table->table)
|
|
||||||
{
|
|
||||||
DBUG_RETURN(send_check_errmsg(thd, table, "repair", "table is read-only or does not exists"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(check_opt->sql_flags & TT_USEFRM))
|
if (!(check_opt->sql_flags & TT_USEFRM))
|
||||||
{
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
|
||||||
else
|
if (!(table= table_list->table)) /* if open_ltable failed */
|
||||||
{
|
{
|
||||||
/*
|
char name[FN_REFLEN];
|
||||||
User gave us USE_FRM which means that the header in the index file is
|
strxmov(name, mysql_data_home, "/", table_list->db, "/",
|
||||||
trashed.
|
table_list->real_name, NullS);
|
||||||
In this case we will try to fix the table the following way:
|
if (openfrm(name, "", 0, 0, 0, &tmp_table))
|
||||||
- Rename the data file to a temporary name
|
DBUG_RETURN(0); // Can't open frm file
|
||||||
- Truncate the table
|
table= &tmp_table;
|
||||||
- Replace the new data file with the old one
|
}
|
||||||
- Run a normal repair using the new index file and the old data file
|
|
||||||
*/
|
|
||||||
|
|
||||||
char from[FN_REFLEN],tmp[FN_REFLEN+32];
|
/*
|
||||||
const char **ext= table->table->file->bas_ext();
|
User gave us USE_FRM which means that the header in the index file is
|
||||||
MY_STAT stat_info;
|
trashed.
|
||||||
|
In this case we will try to fix the table the following way:
|
||||||
|
- Rename the data file to a temporary name
|
||||||
|
- Truncate the table
|
||||||
|
- Replace the new data file with the old one
|
||||||
|
- Run a normal repair using the new index file and the old data file
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
char from[FN_REFLEN],tmp[FN_REFLEN+32];
|
||||||
Check if this is a table type that stores index and data separately,
|
const char **ext= table->file->bas_ext();
|
||||||
like ISAM or MyISAM
|
MY_STAT stat_info;
|
||||||
*/
|
|
||||||
if (!ext[0] || !ext[1])
|
|
||||||
DBUG_RETURN(0); // No data file
|
|
||||||
|
|
||||||
strxmov(from, table->table->path, ext[1], NullS); // Name of data file
|
/*
|
||||||
if (!my_stat(from, &stat_info, MYF(0)))
|
Check if this is a table type that stores index and data separately,
|
||||||
DBUG_RETURN(0); // Can't use USE_FRM flag
|
like ISAM or MyISAM
|
||||||
|
*/
|
||||||
|
if (!ext[0] || !ext[1])
|
||||||
|
goto end; // No data file
|
||||||
|
|
||||||
sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
|
strxmov(from, table->path, ext[1], NullS); // Name of data file
|
||||||
|
if (!my_stat(from, &stat_info, MYF(0)))
|
||||||
|
goto end; // Can't use USE_FRM flag
|
||||||
|
|
||||||
|
sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&LOCK_open);
|
||||||
|
close_cached_table(thd,table_list->table);
|
||||||
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
|
||||||
|
if (lock_and_wait_for_table_name(thd,table_list))
|
||||||
|
{
|
||||||
|
error= -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (my_rename(from, tmp, MYF(MY_WME)))
|
||||||
|
{
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
close_cached_table(thd,table->table);
|
unlock_table_name(thd, table_list);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
error= send_check_errmsg(thd, table_list, "repair",
|
||||||
if (lock_and_wait_for_table_name(thd,table))
|
"Failed renaming data file");
|
||||||
DBUG_RETURN(-1);
|
goto end;
|
||||||
|
}
|
||||||
if (my_rename(from, tmp, MYF(MY_WME)))
|
if (mysql_truncate(thd, table_list, 1))
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
unlock_table_name(thd, table);
|
unlock_table_name(thd, table_list);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
DBUG_RETURN(send_check_errmsg(thd, table, "repair",
|
error= send_check_errmsg(thd, table_list, "repair",
|
||||||
"Failed renaming data file"));
|
"Failed generating table from .frm file");
|
||||||
}
|
goto end;
|
||||||
if (mysql_truncate(thd, table, 1))
|
}
|
||||||
{
|
if (my_rename(tmp, from, MYF(MY_WME)))
|
||||||
pthread_mutex_lock(&LOCK_open);
|
{
|
||||||
unlock_table_name(thd, table);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
unlock_table_name(thd, table_list);
|
||||||
DBUG_RETURN(send_check_errmsg(thd, table, "repair",
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
"Failed generating table from .frm file"));
|
error= send_check_errmsg(thd, table_list, "repair",
|
||||||
}
|
"Failed restoring .MYD file");
|
||||||
if (my_rename(tmp, from, MYF(MY_WME)))
|
goto end;
|
||||||
{
|
|
||||||
pthread_mutex_lock(&LOCK_open);
|
|
||||||
unlock_table_name(thd, table);
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
DBUG_RETURN(send_check_errmsg(thd, table, "repair",
|
|
||||||
"Failed restoring .MYD file"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Now we should be able to open the partially repaired table
|
Now we should be able to open the partially repaired table
|
||||||
to finish the repair in the handler later on.
|
to finish the repair in the handler later on.
|
||||||
*/
|
*/
|
||||||
if (!(table->table = reopen_name_locked_table(thd, table)))
|
if (!(table_list->table = reopen_name_locked_table(thd, table_list)))
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
unlock_table_name(thd, table);
|
unlock_table_name(thd, table_list);
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
|
||||||
|
end:
|
||||||
|
if (table == &tmp_table)
|
||||||
|
closefrm(table); // Free allocated memory
|
||||||
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user