List:Commits« Previous MessageNext Message »
From:Ramil Kalimullin Date:July 31 2008 4:50am
Subject:bzr commit into mysql-5.1 branch (ramil:2681) Bug#37756
View as plain text  
#At file:///home/ram/mysql/b37756.5.1/

 2681 Ramil Kalimullin	2008-07-31
      Fix for bug #37756: enabling fulltext indexes with 
        myisam_repair_threads > 1 causes crash
      
      Problem: parallel repair (myisam_repair_threads > 1) of a myisam
      table with two or more fulltext keys that use the same parser may
      lead to a server crash. ALTER TABLE ENABLE KEYS is affected as well.
      
      Fix: properly initialize fulltext structures for parallel repair.
      
      Note: 1. there's no deterministic test case.
      2. now we call parser->init() for each each fulltext key
      (not for each fulltext parser used).
modified:
  storage/myisam/ft_parser.c
  storage/myisam/ftdefs.h
  storage/myisam/mi_check.c

per-file messages:
  storage/myisam/ft_parser.c
    Fix for bug #37756: enabling fulltext indexes with 
      myisam_repair_threads > 1 causes crash
    
    In ftparser_call_initializer() we "group" parsers
    and allocate parameters for each unique parser used.
    In case of parallel repairing we may have a bunch
    of parsers that use the only MI_INFO structure.
    Each of these parsers must have its own parameter
    structure in order not to interfere with others.
        
    Moreover, the allocation is done without mutex
    lock so parallel ftparser_call_initializer() calls
    are unsafe.
        
    Now we don't "group" the fulltext parsers.
    Parameter allocation code moved to ftparser_alloc_param()
    function which is called from mi_repair_parallel() as well
    to allocate parameters for each parser used.
  storage/myisam/ftdefs.h
    Fix for bug #37756: enabling fulltext indexes with 
      myisam_repair_threads > 1 causes crash
    
    ftparser_alloc_param(MI_INFO *info) added.
  storage/myisam/mi_check.c
    Fix for bug #37756: enabling fulltext indexes with 
      myisam_repair_threads > 1 causes crash
    
    ftparser_alloc_param(info) called in case of parallel 
    repair to allocate fulltext parser parameters.
=== modified file 'storage/myisam/ft_parser.c'
--- a/storage/myisam/ft_parser.c	2007-11-14 14:32:03 +0000
+++ b/storage/myisam/ft_parser.c	2008-07-31 04:50:44 +0000
@@ -324,59 +324,58 @@ int ft_parse(TREE *wtree, uchar *doc, in
 }
 
 #define MAX_PARAM_NR 2
-MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info,
-                                                uint keynr, uint paramnr)
+
+
+MYSQL_FTPARSER_PARAM* ftparser_alloc_param(MI_INFO *info)
 {
-  uint32 ftparser_nr;
-  struct st_mysql_ftparser *parser;
-  if (! info->ftparser_param)
+  if (!info->ftparser_param)
   {
-    /* info->ftparser_param can not be zero after the initialization,
-       because it always includes built-in fulltext parser. And built-in
-       parser can be called even if the table has no fulltext indexes and
-       no varchar/text fields. */
-    if (! info->s->ftparsers)
+    /* 
+      info->ftparser_param can not be zero after the initialization,
+      because it always includes built-in fulltext parser. And built-in
+      parser can be called even if the table has no fulltext indexes and
+      no varchar/text fields.
+    */
+    if (!info->s->ftparsers)
     {
-      /* It's ok that modification to shared structure is done w/o mutex
-         locks, because all threads would set the same variables to the
-         same values. */
-      uint i, j, keys= info->s->state.header.keys, ftparsers= 1;
+      /*
+        It's ok that modification to shared structure is done w/o mutex
+        locks, because all threads would set the same variables to the
+        same values. 
+      */
+      uint i, keys= info->s->state.header.keys, ftparsers= 1;
       for (i= 0; i < keys; i++)
       {
         MI_KEYDEF *keyinfo= &info->s->keyinfo[i];
+
         if (keyinfo->flag & HA_FULLTEXT)
-        {
-          for (j= 0;; j++)
-          {
-            if (j == i)
-            {
-              keyinfo->ftparser_nr= ftparsers++;
-              break;
-            }
-            if (info->s->keyinfo[j].flag & HA_FULLTEXT &&
-                keyinfo->parser == info->s->keyinfo[j].parser)
-            {
-              keyinfo->ftparser_nr= info->s->keyinfo[j].ftparser_nr;
-              break;
-            }
-          }
-        }
+          keyinfo->ftparser_nr= ftparsers++;
       }
       info->s->ftparsers= ftparsers;
     }
     /*
       We have to allocate two MYSQL_FTPARSER_PARAM structures per plugin
       because in a boolean search a parser is called recursively
-      ftb_find_relevance* calls ftb_check_phrase*
-      (MAX_PARAM_NR=2)
+      ftb_find_relevance* calls ftb_check_phrase * (MAX_PARAM_NR == 2).
     */
     info->ftparser_param= (MYSQL_FTPARSER_PARAM *)
       my_malloc(MAX_PARAM_NR * sizeof(MYSQL_FTPARSER_PARAM) *
                 info->s->ftparsers, MYF(MY_WME|MY_ZEROFILL));
     init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
-    if (! info->ftparser_param)
-      return 0;
   }
+  return info->ftparser_param;
+}
+
+
+MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info,
+                                                uint keynr, uint paramnr)
+{
+  uint32 ftparser_nr;
+  struct st_mysql_ftparser *parser;
+  
+  if (!ftparser_alloc_param(info))
+    return 0;
+
   if (keynr == NO_SUCH_KEY)
   {
     ftparser_nr= 0;

=== modified file 'storage/myisam/ftdefs.h'
--- a/storage/myisam/ftdefs.h	2007-05-10 09:59:39 +0000
+++ b/storage/myisam/ftdefs.h	2008-07-31 04:50:44 +0000
@@ -146,6 +146,7 @@ void ft_boolean_close_search(FT_INFO *);
 float ft_boolean_get_relevance(FT_INFO *);
 my_off_t ft_boolean_get_docid(FT_INFO *);
 void ft_boolean_reinit_search(FT_INFO *);
+MYSQL_FTPARSER_PARAM* ftparser_alloc_param(MI_INFO *info);
 extern MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info,
                                                        uint keynr,
                                                        uint paramnr);

=== modified file 'storage/myisam/mi_check.c'
--- a/storage/myisam/mi_check.c	2008-03-31 07:40:39 +0000
+++ b/storage/myisam/mi_check.c	2008-07-31 04:50:44 +0000
@@ -2893,6 +2893,9 @@ int mi_repair_parallel(MI_CHECK *param, 
   sort_param[0].master= 1;
   sort_param[0].fix_datafile= (my_bool)(! rep_quick);
   sort_param[0].calc_checksum= test(param->testflag & T_CALC_CHECKSUM);
+  
+  if (!ftparser_alloc_param(info))
+    goto err;
 
   sort_info.got_error=0;
   pthread_mutex_lock(&sort_info.mutex);

Thread
bzr commit into mysql-5.1 branch (ramil:2681) Bug#37756Ramil Kalimullin31 Jul
  • Re: bzr commit into mysql-5.1 branch (ramil:2681) Bug#37756Sergei Golubchik18 Aug