MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Sergey Vojtovich Date:March 25 2010 12:08pm
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-25
      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).

    modified:
      mysql-test/r/fulltext.result
      mysql-test/r/myisam.result
      mysql-test/r/variables.result
      mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_32.result
      mysql-test/t/fulltext.test
      sql/mysqld.cc
      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-25 12:08:21 +0000
@@ -631,4 +631,17 @@ 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;
+Warnings:
+Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '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/r/myisam.result'
--- a/mysql-test/r/myisam.result	2010-03-10 12:32:12 +0000
+++ b/mysql-test/r/myisam.result	2010-03-25 12:08:21 +0000
@@ -2313,6 +2313,8 @@ INSERT INTO t1 SELECT a+1280,b FROM t1;
 INSERT INTO t1 SELECT a+2560,b FROM t1;
 INSERT INTO t1 SELECT a+5120,b FROM t1;
 SET myisam_sort_buffer_size=4;
+Warnings:
+Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '4'
 REPAIR TABLE t1;
 Table	Op	Msg_type	Msg_text
 test.t1	repair	error	myisam_sort_buffer_size is too small
@@ -2363,6 +2365,8 @@ CREATE TABLE t1(a CHAR(255), KEY(a));
 SELECT * FROM t1, t1 AS a1;
 a	a
 SET myisam_sort_buffer_size=4;
+Warnings:
+Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '4'
 INSERT INTO t1 VALUES
 ('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
 ('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),

=== modified file 'mysql-test/r/variables.result'
--- a/mysql-test/r/variables.result	2010-01-21 08:10:05 +0000
+++ b/mysql-test/r/variables.result	2010-03-25 12:08:21 +0000
@@ -523,6 +523,8 @@ select @@max_user_connections;
 100
 set global max_write_lock_count=100;
 set myisam_sort_buffer_size=100;
+Warnings:
+Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '100'
 set global net_buffer_length=100;
 Warnings:
 Warning	1292	Truncated incorrect net_buffer_length value: '100'

=== modified file 'mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_32.result'
--- a/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_32.result	2009-03-20 17:11:22 +0000
+++ b/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_32.result	2010-03-25 12:08:21 +0000
@@ -8,11 +8,15 @@ SELECT @start_session_value;
 8388608
 '#--------------------FN_DYNVARS_005_01-------------------------#'
 SET @@global.myisam_sort_buffer_size   = 100;
+Warnings:
+Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '100'
 SET @@global.myisam_sort_buffer_size   = DEFAULT;
 SELECT @@global.myisam_sort_buffer_size  ;
 @@global.myisam_sort_buffer_size
 8388608
 SET @@session.myisam_sort_buffer_size   = 200;
+Warnings:
+Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '200'
 SET @@session.myisam_sort_buffer_size   = DEFAULT;
 SELECT @@session.myisam_sort_buffer_size  ;
 @@session.myisam_sort_buffer_size
@@ -28,9 +32,11 @@ SELECT @@session.myisam_sort_buffer_size
 1
 '#--------------------FN_DYNVARS_005_03-------------------------#'
 SET @@global.myisam_sort_buffer_size   = 4;
+Warnings:
+Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '4'
 SELECT @@global.myisam_sort_buffer_size  ;
 @@global.myisam_sort_buffer_size
-4
+4096
 SET @@global.myisam_sort_buffer_size   = 4294967295;
 SELECT @@global.myisam_sort_buffer_size  ;
 @@global.myisam_sort_buffer_size
@@ -41,9 +47,11 @@ SELECT @@global.myisam_sort_buffer_size 
 655354
 '#--------------------FN_DYNVARS_005_04-------------------------#'
 SET @@session.myisam_sort_buffer_size   = 4;
+Warnings:
+Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '4'
 SELECT @@session.myisam_sort_buffer_size  ;
 @@session.myisam_sort_buffer_size
-4
+4096
 SET @@session.myisam_sort_buffer_size   = 4294967295;
 SELECT @@session.myisam_sort_buffer_size  ;
 @@session.myisam_sort_buffer_size
@@ -58,13 +66,13 @@ Warnings:
 Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '0'
 SELECT @@global.myisam_sort_buffer_size  ;
 @@global.myisam_sort_buffer_size
-4
+4096
 SET @@global.myisam_sort_buffer_size   = -1024;
 Warnings:
 Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '-1024'
 SELECT @@global.myisam_sort_buffer_size  ;
 @@global.myisam_sort_buffer_size
-4
+4096
 SET @@global.myisam_sort_buffer_size   = 429496729533;
 Warnings:
 Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '429496729533'
@@ -101,28 +109,28 @@ Warnings:
 Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '0'
 SELECT @@session.myisam_sort_buffer_size  ;
 @@session.myisam_sort_buffer_size
-4
+4096
 SET @@session.myisam_sort_buffer_size   = -2;
 Warnings:
 Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '-2'
 SELECT @@session.myisam_sort_buffer_size  ;
 @@session.myisam_sort_buffer_size
-4
+4096
 SET @@session.myisam_sort_buffer_size   = 65530.34.;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.' at line 1
 SELECT @@session.myisam_sort_buffer_size  ;
 @@session.myisam_sort_buffer_size
-4
+4096
 SET @@session.myisam_sort_buffer_size   = test;
 ERROR 42000: Incorrect argument type to variable 'myisam_sort_buffer_size'
 SELECT @@session.myisam_sort_buffer_size  ;
 @@session.myisam_sort_buffer_size
-4
+4096
 SET @@session.myisam_sort_buffer_size   = "test";
 ERROR 42000: Incorrect argument type to variable 'myisam_sort_buffer_size'
 SELECT @@session.myisam_sort_buffer_size  ;
 @@session.myisam_sort_buffer_size
-4
+4096
 '#------------------FN_DYNVARS_005_06-----------------------#'
 SELECT @@global.myisam_sort_buffer_size   = VARIABLE_VALUE 
 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES 
@@ -141,20 +149,24 @@ Warnings:
 Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '1'
 SELECT @@global.myisam_sort_buffer_size  ;
 @@global.myisam_sort_buffer_size
-4
+4096
 SET @@global.myisam_sort_buffer_size   = FALSE;
 Warnings:
 Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '0'
 SELECT @@global.myisam_sort_buffer_size  ;
 @@global.myisam_sort_buffer_size
-4
+4096
 '#---------------------FN_DYNVARS_001_09----------------------#'
 SET @@global.myisam_sort_buffer_size   = 10;
+Warnings:
+Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '10'
 SELECT @@myisam_sort_buffer_size   = @@global.myisam_sort_buffer_size  ;
 @@myisam_sort_buffer_size   = @@global.myisam_sort_buffer_size
-0
+1
 '#---------------------FN_DYNVARS_001_10----------------------#'
 SET @@myisam_sort_buffer_size   = 100;
+Warnings:
+Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '100'
 SELECT @@myisam_sort_buffer_size   = @@local.myisam_sort_buffer_size  ;
 @@myisam_sort_buffer_size   = @@local.myisam_sort_buffer_size
 1
@@ -167,7 +179,7 @@ Warnings:
 Warning	1292	Truncated incorrect myisam_sort_buffer_size value: '1'
 SELECT @@myisam_sort_buffer_size  ;
 @@myisam_sort_buffer_size
-4
+4096
 SELECT local.myisam_sort_buffer_size  ;
 ERROR 42S02: Unknown table 'local' in field list
 SELECT session.myisam_sort_buffer_size  ;

=== 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-25 12:08:21 +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 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2010-03-01 13:49:51 +0000
+++ b/sql/mysqld.cc	2010-03-25 12:08:21 +0000
@@ -6858,7 +6858,7 @@ The minimum value for this variable is 4
    "The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
    (uchar**) &global_system_variables.myisam_sort_buff_size,
    (uchar**) &max_system_variables.myisam_sort_buff_size, 0,
-   GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
+   GET_ULONG, REQUIRED_ARG, 8192 * 1024, 4096, ~0L, 0, 1, 0},
   {"myisam_use_mmap", OPT_MYISAM_USE_MMAP,
    "Use memory mapping for reading and writing MyISAM tables.",
    (uchar**) &opt_myisam_use_mmap,

=== 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-25 12:08:21 +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-25 12:08:21 +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-20100325120821-3s0fbhwc3li6l5r4.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (svoj:3404) Bug#51866Sergey Vojtovich25 Mar