From 48e84fb95e6f31d104c542a2f4e8dd79757482fe Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 17:57:29 +0500 Subject: 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 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'myisam') 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) -- cgit v1.2.1