From 61ffbc31ae2172d3282288bc8c4520ea493c92ae Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Mar 2005 09:27:09 +0200 Subject: [PATCH 1/5] InnoDB: Fix compilation errors on IA-64 Windows innobase/include/srv0srv.h: Declare srv_auto_extend_increment and srv_max_purge_lag as ulong, because ulint and ulong are of different size on Win64. innobase/srv/srv0srv.c: Declare srv_auto_extend_increment and srv_max_purge_lag as ulong, because ulint and ulong are of different size on Win64. --- innobase/include/srv0srv.h | 4 ++-- innobase/srv/srv0srv.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index aa2fead53c2..30dd3db7bb1 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -50,7 +50,7 @@ extern ulint* srv_data_file_is_raw_partition; extern ibool srv_auto_extend_last_data_file; extern ulint srv_last_file_size_max; -extern ulint srv_auto_extend_increment; +extern ulong srv_auto_extend_increment; extern ibool srv_created_new_raw; @@ -101,7 +101,7 @@ extern ibool srv_use_doublewrite_buf; extern ibool srv_set_thread_priorities; extern int srv_query_thread_priority; -extern ulint srv_max_purge_lag; +extern ulong srv_max_purge_lag; /*-------------------------------------------*/ extern ulint srv_n_rows_inserted; diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 217a97d84a2..5c5d62f777b 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -86,7 +86,7 @@ ulint srv_last_file_size_max = 0; /* if != 0, this tells the max size auto-extending may increase the last data file size */ -ulint srv_auto_extend_increment = 8; /* If the last data file is +ulong srv_auto_extend_increment = 8; /* If the last data file is auto-extended, we add this many pages to it at a time */ ulint* srv_data_file_is_raw_partition = NULL; @@ -849,7 +849,7 @@ srv_general_init(void) /*======================= InnoDB Server FIFO queue =======================*/ /* Maximum allowable purge history length. <=0 means 'infinite'. */ -ulint srv_max_purge_lag = 0; +ulong srv_max_purge_lag = 0; /************************************************************************* Puts an OS thread to wait if there are too many concurrent threads From 22e0b300a47321ec8dfef0bb8bc5f7c0f1449ce1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Mar 2005 16:09:22 +0200 Subject: [PATCH 2/5] InnoDB: Commit inserts to the temporary tables created by CREATE INDEX and DROP INDEX every 10,000 rows, similar to ALTER TABLE. sql/ha_innodb.cc: Commit inserts to the temporary tables created by CREATE INDEX and DROP INDEX every 10,000 rows, similar to ALTER TABLE. sql/ha_innodb.h: Remove duplicate declaration of srv_max_purge_lag. --- sql/ha_innodb.cc | 4 +++- sql/ha_innodb.h | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 4f32bb08e9a..0fbac13be28 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2316,7 +2316,9 @@ ha_innobase::write_row( if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); - if (user_thd->lex->sql_command == SQLCOM_ALTER_TABLE + if ((user_thd->lex->sql_command == SQLCOM_ALTER_TABLE + || user_thd->lex->sql_command == SQLCOM_CREATE_INDEX + || user_thd->lex->sql_command == SQLCOM_DROP_INDEX) && num_write_row >= 10000) { /* ALTER TABLE is COMMITted at every 10000 copied rows. The IX table lock for the original table has to be re-issued. diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index e76a966c6b9..f10785b695d 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -202,7 +202,6 @@ extern "C" { extern ulong srv_max_buf_pool_modified_pct; extern ulong srv_max_purge_lag; extern ulong srv_auto_extend_increment; -extern ulong srv_max_purge_lag; } extern TYPELIB innobase_lock_typelib; From a10fb6971ae10304dac0798e79f5a6824aed0620 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Mar 2005 20:46:23 +0200 Subject: [PATCH 3/5] row0sel.c: row_sel_store_mysql_rec(): Do not try to space-pad BLOB fields. (Bug #8771) innobase/row/row0sel.c: row_sel_store_mysql_rec(): Do not try to space-pad BLOB fields. (Bug #8771) --- innobase/row/row0sel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 2de02081176..7c935128d8a 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2407,10 +2407,11 @@ row_sel_store_mysql_rec( collations will be introduced in 4.1, we hardcode the charset-collation codes here. 5.0 will use a different approach. */ - if (templ->charset == 35 + if (pad_char != '\0' + && (templ->charset == 35 || templ->charset == 90 || (templ->charset >= 128 - && templ->charset <= 144)) { + && templ->charset <= 144))) { /* There are two bytes per char, so the length has to be an even number. */ ut_a(!(templ->mysql_col_len & 1)); From 26f75ffc83e39ee915e8d4973955c950ddabb35b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Mar 2005 10:35:00 +0100 Subject: [PATCH 4/5] 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. --- myisam/mi_create.c | 15 +++++++++++++++ myisam/mi_open.c | 2 +- myisam/myisamdef.h | 1 + mysql-test/r/myisam.result | 18 ++++++++++++++++++ mysql-test/t/myisam.test | 26 ++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 1 deletion(-) diff --git a/myisam/mi_create.c b/myisam/mi_create.c index f99a2c655d2..da3330627a7 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -533,6 +533,21 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, 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, filename, 0, O_RDWR | O_TRUNC, diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 2a327e4bd35..2c85a03c6f4 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -50,7 +50,7 @@ if (pos > end_pos) \ ** 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; diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 736ce3f3869..916932c9eb3 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -705,6 +705,7 @@ void mi_copy_status(void* to,void *from); my_bool mi_check_status(void* param); 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); int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup); int mi_open_keyfile(MYISAM_SHARE *share); diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index d155a14bb60..eaed7c620e3 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -555,3 +555,21 @@ select count(*) from t1 where a is null; count(*) 2 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; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index c8ed7910b76..0babd1f9401 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -524,3 +524,29 @@ explain select count(*) from t1 where a is null; select count(*) from t1 where a is null; 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; + From 199e195d3dd41d42defd5942a3b9da42e6cf1d5c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Mar 2005 11:49:50 +0100 Subject: [PATCH 5/5] Bug#8306 - TRUNCATE leads to index corruption After merge fix. The bugfix results in a different error message in this situation. --- mysql-test/t/symlink.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 25c78129129..7fb7e81b3b1 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -83,7 +83,7 @@ create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, p create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path"; # Should fail becasue the file t9.MYI already exist in 'run' ---error 1,1 +--error 1,1,1105 eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="$MYSQL_TEST_DIR/var/run"; # Should fail becasue the file t9.MYD already exist in 'tmp'