summaryrefslogtreecommitdiff
path: root/storage/myisam
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@sun.com>2010-03-25 16:08:21 +0400
committerSergey Vojtovich <svoj@sun.com>2010-03-25 16:08:21 +0400
commit412798658a5ede71651ed9112791d055a42edef7 (patch)
tree8a9f456988aff49c5dd5d915427810c19bad01c7 /storage/myisam
parent7297ec560ee8ab09c796de81b482f73b8f83eb4a (diff)
downloadmariadb-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.c9
-rw-r--r--storage/myisam/sort.c26
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;