MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Sergey Vojtovich Date:March 17 2010 9:42am
Subject:bzr commit into mysql-5.1-bugteam branch (svoj:3404) Bug#51866
View as plain text  
#At file:///home/svoj/devel/bzr-mysql/mysql-5.1-bugteam-bug51866/ based on revid:mattias.jonsson@stripped

 3404 Sergey Vojtovich	2010-03-17
      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.
     @ mysql-test/r/fulltext.result
        A test case for BUG#51866.
     @ mysql-test/t/fulltext.test
        A test case for BUG#51866.
     @ 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).

    modified:
      mysql-test/r/fulltext.result
      mysql-test/t/fulltext.test
      storage/myisam/mi_check.c
      storage/myisam/sort.c
=== modified file 'mysql-test/r/fulltext.result'
--- a/mysql-test/r/fulltext.result	2010-02-26 13:16:46 +0000
+++ b/mysql-test/r/fulltext.result	2010-03-17 09:42:02 +0000
@@ -631,4 +631,15 @@ CREATE TABLE t1(a CHAR(1),FULLTEXT(a));
 SELECT 1 FROM t1 WHERE MATCH(a) AGAINST ('') AND ROW(a,a) > ROW(1,1);
 1
 DROP TABLE t1;
+#
+# BUG#51866 - crash with repair by sort and fulltext keys
+#
+CREATE TABLE t1(a CHAR(4), FULLTEXT(a));
+INSERT INTO t1 VALUES('aaaa');
+SET myisam_sort_buffer_size=4;
+REPAIR TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
+DROP TABLE t1;
 End of 5.1 tests

=== modified file 'mysql-test/t/fulltext.test'
--- a/mysql-test/t/fulltext.test	2010-02-26 13:16:46 +0000
+++ b/mysql-test/t/fulltext.test	2010-03-17 09:42:02 +0000
@@ -575,5 +575,14 @@ CREATE TABLE t1(a CHAR(1),FULLTEXT(a));
 SELECT 1 FROM t1 WHERE MATCH(a) AGAINST ('') AND ROW(a,a) > ROW(1,1);
 DROP TABLE t1;
 
+--echo #
+--echo # BUG#51866 - crash with repair by sort and fulltext keys
+--echo #
+CREATE TABLE t1(a CHAR(4), FULLTEXT(a));
+INSERT INTO t1 VALUES('aaaa');
+SET myisam_sort_buffer_size=4;
+REPAIR TABLE t1;
+SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
+DROP TABLE t1;
 
 --echo End of 5.1 tests

=== modified file 'storage/myisam/mi_check.c'
--- a/storage/myisam/mi_check.c	2009-10-27 14:30:02 +0000
+++ b/storage/myisam/mi_check.c	2010-03-17 09:42:02 +0000
@@ -2396,10 +2396,8 @@ int mi_repair_by_sort(MI_CHECK *param, r
       /*
         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, r
           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;

=== modified file 'storage/myisam/sort.c'
--- a/storage/myisam/sort.c	2009-10-27 14:27:27 +0000
+++ b/storage/myisam/sort.c	2010-03-17 09:42:02 +0000
@@ -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 
   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 
 	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
     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
           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_p
       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;


Attachment: [text/bzr-bundle] bzr/svoj@sun.com-20100317094202-xl8f0lulw0wm1jy1.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (svoj:3404) Bug#51866Sergey Vojtovich17 Mar
  • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3404) Bug#51866Ingo Strüwing24 Mar
    • Re: bzr commit into mysql-5.1-bugteam branch (svoj:3404) Bug#51866Sergey Vojtovich24 Mar