diff options
author | Sergey Vojtovich <svoj@sun.com> | 2010-03-25 16:08:21 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@sun.com> | 2010-03-25 16:08:21 +0400 |
commit | 412798658a5ede71651ed9112791d055a42edef7 (patch) | |
tree | 8a9f456988aff49c5dd5d915427810c19bad01c7 /storage/myisam | |
parent | 7297ec560ee8ab09c796de81b482f73b8f83eb4a (diff) | |
download | mariadb-git-412798658a5ede71651ed9112791d055a42edef7.tar.gz |
BUG#51866 - crash with repair by sort and fulltext keys
Repairing MyISAM table with fulltext indexes and low
myisam_sort_buffer_size may crash the server.
Estimation of number of index entries was done incorrectly,
causing further assertion failure or server crash.
Docs note: min value for myisam_sort_buffer_size has been
changed from 4 to 4096.
mysql-test/r/fulltext.result:
A test case for BUG#51866.
mysql-test/r/myisam.result:
Min value for myisam_sort_buffer_size is 4096.
mysql-test/r/variables.result:
Min value for myisam_sort_buffer_size is 4096.
mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_32.result:
Min value for myisam_sort_buffer_size is 4096.
mysql-test/t/fulltext.test:
A test case for BUG#51866.
sql/mysqld.cc:
Min value for myisam_sort_buffer_size is 4096.
storage/myisam/mi_check.c:
When estimating number of index entries for external
fulltext parser, take into account that key_length may
be bigger than myisam_sort_buffer_size. Reuse logic
from _create_index_by_sort(): force MIN_SORT_BUFFER to
be min value for myisam_sort_buffer_size.
Another problem is that ftkey_nr has no other meaning
than serial number of fulltext index starting with 1.
We can't say if this key using built-in or external
parser basing on it's value. In other words we always
entered if-branch for external parser. At this point,
the only way to check if we use default parser is to
compare keyinfo::parser with &ft_default_parser.
storage/myisam/sort.c:
Get rid of MIN_SORT_MEMORY, use MIN_SORT_BUFFER instead
(defined in myisamdef.h, has the same value and purpose).
Diffstat (limited to 'storage/myisam')
-rw-r--r-- | storage/myisam/mi_check.c | 9 | ||||
-rw-r--r-- | storage/myisam/sort.c | 26 |
2 files changed, 16 insertions, 19 deletions
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index c10cfdd0c9b..8e3864d1c44 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -2396,10 +2396,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, /* fulltext indexes may have much more entries than the number of rows in the table. We estimate the number here. - - Note, built-in parser is always nr. 0 - see ftparser_call_initializer() */ - if (sort_param.keyinfo->ftkey_nr == 0) + if (sort_param.keyinfo->parser == &ft_default_parser) { /* for built-in parser the number of generated index entries @@ -2416,8 +2414,9 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, so, we'll use all the sort memory and start from ~10 buffpeks. (see _create_index_by_sort) */ - sort_info.max_records= - 10*param->sort_buffer_length/sort_param.key_length; + sort_info.max_records= 10 * + max(param->sort_buffer_length, MIN_SORT_BUFFER) / + sort_param.key_length; } sort_param.key_read=sort_ft_key_read; diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index b450d27de66..0333898092f 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -28,13 +28,11 @@ /* static variables */ -#undef MIN_SORT_MEMORY #undef MYF_RW #undef DISK_BUFFER_SIZE #define MERGEBUFF 15 #define MERGEBUFF2 31 -#define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD) #define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL) #define DISK_BUFFER_SIZE (IO_SIZE*16) @@ -131,12 +129,12 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, sort_keys= (uchar **) NULL; error= 1; maxbuffer=1; - memavl=max(sortbuff_size,MIN_SORT_MEMORY); + memavl= max(sortbuff_size, MIN_SORT_BUFFER); records= info->sort_info->max_records; sort_length= info->key_length; LINT_INIT(keys); - while (memavl >= MIN_SORT_MEMORY) + while (memavl >= MIN_SORT_BUFFER) { if ((records < UINT_MAX32) && ((my_off_t) (records + 1) * @@ -171,10 +169,10 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, break; } old_memavl=memavl; - if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY) - memavl=MIN_SORT_MEMORY; + if ((memavl= memavl/4*3) < MIN_SORT_BUFFER && old_memavl > MIN_SORT_BUFFER) + memavl= MIN_SORT_BUFFER; } - if (memavl < MIN_SORT_MEMORY) + if (memavl < MIN_SORT_BUFFER) { mi_check_print_error(info->sort_info->param,"MyISAM sort buffer too small"); /* purecov: tested */ goto err; /* purecov: tested */ @@ -348,12 +346,12 @@ pthread_handler_t thr_find_all_keys(void *arg) bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); sort_keys= (uchar **) NULL; - memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY); + memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER); idx= (uint)sort_param->sort_info->max_records; sort_length= sort_param->key_length; maxbuffer= 1; - while (memavl >= MIN_SORT_MEMORY) + while (memavl >= MIN_SORT_BUFFER) { if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= (my_off_t) memavl) @@ -391,11 +389,11 @@ pthread_handler_t thr_find_all_keys(void *arg) break; } old_memavl= memavl; - if ((memavl= memavl/4*3) < MIN_SORT_MEMORY && - old_memavl > MIN_SORT_MEMORY) - memavl= MIN_SORT_MEMORY; + if ((memavl= memavl / 4 * 3) < MIN_SORT_BUFFER && + old_memavl > MIN_SORT_BUFFER) + memavl= MIN_SORT_BUFFER; } - if (memavl < MIN_SORT_MEMORY) + if (memavl < MIN_SORT_BUFFER) { mi_check_print_error(sort_param->sort_info->param, "MyISAM sort buffer too small"); @@ -569,7 +567,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) if (!mergebuf) { length=param->sort_buffer_length; - while (length >= MIN_SORT_MEMORY) + while (length >= MIN_SORT_BUFFER) { if ((mergebuf= my_malloc(length, MYF(0)))) break; |