Bug#8306 - TRUNCATE leads to index corruption
Added a check, if the table, which we are going to create, is open. This can happen if a MERGE mapped table is TRUNCATEd. myisam/mi_open.c: Bug#8306 - TRUNCATE leads to index corruption Made test_if_reopen() globally available. myisam/myisamdef.h: Bug#8306 - TRUNCATE leads to index corruption Declared test_if_reopen() as globally available. mysql-test/r/myisam.result: Bug#8306 - TRUNCATE leads to index corruption The test result. mysql-test/t/myisam.test: Bug#8306 - TRUNCATE leads to index corruption The test case.
This commit is contained in:
parent
22e0b300a4
commit
26f75ffc83
@ -533,6 +533,21 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
create_flag=MY_DELETE_OLD;
|
create_flag=MY_DELETE_OLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
If a MRG_MyISAM table is in use, the mapped MyISAM tables are open,
|
||||||
|
but no entry is made in the table cache for them.
|
||||||
|
A TRUNCATE command checks for the table in the cache only and could
|
||||||
|
be fooled to believe, the table is not open.
|
||||||
|
Pull the emergency brake in this situation. (Bug #8306)
|
||||||
|
*/
|
||||||
|
if (test_if_reopen(filename))
|
||||||
|
{
|
||||||
|
my_printf_error(0, "MyISAM table '%s' is in use "
|
||||||
|
"(most likely by a MERGE table). Try FLUSH TABLES.",
|
||||||
|
MYF(0), name + dirname_length(name));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
if ((file= my_create_with_symlink(linkname_ptr,
|
if ((file= my_create_with_symlink(linkname_ptr,
|
||||||
filename,
|
filename,
|
||||||
0, O_RDWR | O_TRUNC,
|
0, O_RDWR | O_TRUNC,
|
||||||
|
@ -50,7 +50,7 @@ if (pos > end_pos) \
|
|||||||
** In MySQL the server will handle version issues.
|
** In MySQL the server will handle version issues.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
static MI_INFO *test_if_reopen(char *filename)
|
MI_INFO *test_if_reopen(char *filename)
|
||||||
{
|
{
|
||||||
LIST *pos;
|
LIST *pos;
|
||||||
|
|
||||||
|
@ -705,6 +705,7 @@ void mi_copy_status(void* to,void *from);
|
|||||||
my_bool mi_check_status(void* param);
|
my_bool mi_check_status(void* param);
|
||||||
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
|
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
|
||||||
|
|
||||||
|
extern MI_INFO *test_if_reopen(char *filename);
|
||||||
my_bool check_table_is_closed(const char *name, const char *where);
|
my_bool check_table_is_closed(const char *name, const char *where);
|
||||||
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
|
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
|
||||||
int mi_open_keyfile(MYISAM_SHARE *share);
|
int mi_open_keyfile(MYISAM_SHARE *share);
|
||||||
|
@ -555,3 +555,21 @@ select count(*) from t1 where a is null;
|
|||||||
count(*)
|
count(*)
|
||||||
2
|
2
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (c1 int, index(c1));
|
||||||
|
create table t2 (c1 int, index(c1)) engine=merge union=(t1);
|
||||||
|
insert into t1 values (1);
|
||||||
|
flush tables;
|
||||||
|
select * from t2;
|
||||||
|
c1
|
||||||
|
1
|
||||||
|
flush tables;
|
||||||
|
truncate table t1;
|
||||||
|
insert into t1 values (1);
|
||||||
|
flush tables;
|
||||||
|
select * from t2;
|
||||||
|
c1
|
||||||
|
1
|
||||||
|
truncate table t1;
|
||||||
|
ERROR HY000: MyISAM table 't1' is in use (most likely by a MERGE table). Try FLUSH TABLES.
|
||||||
|
insert into t1 values (1);
|
||||||
|
drop table t1,t2;
|
||||||
|
@ -524,3 +524,29 @@ explain select count(*) from t1 where a is null;
|
|||||||
select count(*) from t1 where a is null;
|
select count(*) from t1 where a is null;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #8306: TRUNCATE leads to index corruption
|
||||||
|
#
|
||||||
|
create table t1 (c1 int, index(c1));
|
||||||
|
create table t2 (c1 int, index(c1)) engine=merge union=(t1);
|
||||||
|
insert into t1 values (1);
|
||||||
|
# Close all tables.
|
||||||
|
flush tables;
|
||||||
|
# Open t2 and (implicitly) t1.
|
||||||
|
select * from t2;
|
||||||
|
# Truncate after flush works (unless another threads reopens t2 in between).
|
||||||
|
flush tables;
|
||||||
|
truncate table t1;
|
||||||
|
insert into t1 values (1);
|
||||||
|
# Close all tables.
|
||||||
|
flush tables;
|
||||||
|
# Open t2 and (implicitly) t1.
|
||||||
|
select * from t2;
|
||||||
|
# Truncate t1, wich was not recognized as open without the bugfix.
|
||||||
|
# Now, it should fail with a table-in-use error message.
|
||||||
|
--error 1105
|
||||||
|
truncate table t1;
|
||||||
|
# The insert used to fail on the crashed table.
|
||||||
|
insert into t1 values (1);
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user