From 31754c57bd388b57c57c68df0c763af6a3bd7216 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 20:34:20 +0500 Subject: [PATCH 1/2] BUG#22562 - REPAIR TABLE .. USE_FRM causes server crash on Windows and server hangs on Linux If REPAIR TABLE ... USE_FRM is issued for table that is located in different than default database server crash could happen. In reopen_name_locked_table take database name from table_list (user specified or default database) instead of from thd (default database). Affects 4.1 only. mysql-test/r/repair.result: A test case for BUG#22562. mysql-test/t/repair.test: A test case for BUG#22562. sql/sql_base.cc: In reopen_name_locked_table take database name from table_list (user specified or default database) instead of from thd (default database). --- mysql-test/r/repair.result | 7 +++++++ mysql-test/t/repair.test | 10 ++++++++++ sql/sql_base.cc | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result index c069824e9f0..815305013be 100644 --- a/mysql-test/r/repair.result +++ b/mysql-test/r/repair.result @@ -48,3 +48,10 @@ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_par t1 1 a 1 a A 5 NULL NULL YES BTREE SET myisam_repair_threads=@@global.myisam_repair_threads; DROP TABLE t1; +CREATE TABLE t1(a INT); +USE mysql; +REPAIR TABLE test.t1 USE_FRM; +Table Op Msg_type Msg_text +test.t1 repair status OK +USE test; +DROP TABLE t1; diff --git a/mysql-test/t/repair.test b/mysql-test/t/repair.test index f086d5b0c2a..91d03ce3082 100644 --- a/mysql-test/t/repair.test +++ b/mysql-test/t/repair.test @@ -45,4 +45,14 @@ SHOW INDEX FROM t1; SET myisam_repair_threads=@@global.myisam_repair_threads; DROP TABLE t1; +# +# BUG#22562 - REPAIR TABLE .. USE_FRM causes server crash on Windows and +# server hangs on Linux +# +CREATE TABLE t1(a INT); +USE mysql; +REPAIR TABLE test.t1 USE_FRM; +USE test; +DROP TABLE t1; + # End of 4.1 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0a9529d6067..561d75a765e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -821,7 +821,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) if (!(table = table_list->table)) DBUG_RETURN(0); - char* db = thd->db ? thd->db : table_list->db; + char *db= table_list->db; char* table_name = table_list->real_name; char key[MAX_DBKEY_LENGTH]; uint key_length; From 48cf65c037a870d1ee2bb9c3aeade85d2b36a248 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 17:57:29 +0500 Subject: [PATCH 2/2] BUG#23175 - MYISAM crash/repair failed during repair Repair table could crash a server if there is not sufficient memory (myisam_sort_buffer_size) to operate. Affects not only repair, but also all statements that use create index by sort: repair by sort, parallel repair, bulk insert. Return an error if there is not sufficient memory to store at least one key per BUFFPEK. Also fixed memory leak if thr_find_all_keys returns an error. myisam/sort.c: maxbuffer is number of BUFFPEK-s for repair. It is calculated as records / keys. keys is number of keys that can be stored in memory (myisam_sort_buffer_size). There must be sufficient memory to store both BUFFPEK-s and keys. It was checked correctly before this patch. However there is another requirement that wasn't checked: there must be sufficient memory for at least one key per BUFFPEK, otherwise repair by sort/parallel repair cannot operate. Return an error if there is not sufficient memory to store at least one key per BUFFPEK. Also fixed memory leak if thr_find_all_keys returns an error. mysql-test/r/repair.result: A test case for BUG#23175. mysql-test/t/repair.test: A test case for BUG#23175. --- myisam/sort.c | 8 ++++++-- mysql-test/r/repair.result | 28 ++++++++++++++++++++++++++++ mysql-test/t/repair.test | 28 ++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/myisam/sort.c b/myisam/sort.c index 727840709da..154d50d4d39 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -148,7 +148,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, skr=maxbuffer; if (memavl < sizeof(BUFFPEK)*(uint) maxbuffer || (keys=(memavl-sizeof(BUFFPEK)*(uint) maxbuffer)/ - (sort_length+sizeof(char*))) <= 1) + (sort_length+sizeof(char*))) <= 1 || + keys < (uint) maxbuffer) { mi_check_print_error(info->sort_info->param, "sort_buffer_size is to small"); @@ -363,7 +364,8 @@ pthread_handler_decl(thr_find_all_keys,arg) skr=maxbuffer; if (memavl < sizeof(BUFFPEK)*maxbuffer || (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ - (sort_length+sizeof(char*))) <= 1) + (sort_length+sizeof(char*))) <= 1 || + keys < (uint) maxbuffer) { mi_check_print_error(sort_param->sort_info->param, "sort_buffer_size is to small"); @@ -497,6 +499,8 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) if (!sinfo->sort_keys) { got_error=1; + my_free(mi_get_rec_buff_ptr(info, sinfo->rec_buff), + MYF(MY_ALLOW_ZERO_PTR)); continue; } if (!got_error) diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result index c069824e9f0..8b3782ec2a4 100644 --- a/mysql-test/r/repair.result +++ b/mysql-test/r/repair.result @@ -48,3 +48,31 @@ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_par t1 1 a 1 a A 5 NULL NULL YES BTREE SET myisam_repair_threads=@@global.myisam_repair_threads; DROP TABLE t1; +CREATE TABLE t1(a CHAR(255), KEY(a)); +SET myisam_sort_buffer_size=4096; +INSERT INTO t1 VALUES +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'); +SET myisam_repair_threads=2; +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair error sort_buffer_size is to small +test.t1 repair warning Number of rows changed from 0 to 157 +test.t1 repair status OK +SET myisam_repair_threads=@@global.myisam_repair_threads; +SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; +DROP TABLE t1; diff --git a/mysql-test/t/repair.test b/mysql-test/t/repair.test index f086d5b0c2a..b192d5c0a64 100644 --- a/mysql-test/t/repair.test +++ b/mysql-test/t/repair.test @@ -45,4 +45,32 @@ SHOW INDEX FROM t1; SET myisam_repair_threads=@@global.myisam_repair_threads; DROP TABLE t1; +# +# BUG#23175 - MYISAM crash/repair failed during repair +# +CREATE TABLE t1(a CHAR(255), KEY(a)); +SET myisam_sort_buffer_size=4096; +INSERT INTO t1 VALUES +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'), +('0'),('0'),('0'),('0'),('0'),('0'),('0'); +SET myisam_repair_threads=2; +REPAIR TABLE t1; +SET myisam_repair_threads=@@global.myisam_repair_threads; +SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; +DROP TABLE t1; + # End of 4.1 tests