List:Commits« Previous MessageNext Message »
From:antony Date:May 25 2006 10:03pm
Subject:bk commit into 4.1 tree (acurtis:1.2488) BUG#20051
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of antony. When antony does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2488 06/05/25 15:03:42 acurtis@stripped +8 -0
  Bug#20051
    "Parallel OPTIMIZE TABLE deadlocks and ignores myisam_repair_threads value"
    REPAIR/OPTIMIZE should respect myisam_max_threads variable
    REPAIR/OPTIMIZE deadlock fix

  sql/ha_myisam.cc
    1.163 06/05/25 15:03:40 acurtis@stripped +5 -4
    Bug#20051
      MyISAM REPAIR/OPTIMIZE should respect myisam_max_threads variable

  mysys/mf_iocache.c
    1.49 06/05/25 15:03:40 acurtis@stripped +3 -1
    Bug#20051
      init_io_cache_share():
      Assert that num_threads more than 0
      initialize count to 0 so code in lock_io_cache() executes.

  mysql-test/t/repair.test
    1.15 06/05/25 15:03:40 acurtis@stripped +29 -0
    Bug#20051
      Test for bug

  mysql-test/r/repair.result
    1.17 06/05/25 15:03:40 acurtis@stripped +44 -0
    Bug#20051
      Test for bug

  myisam/sort.c
    1.46 06/05/25 15:03:40 acurtis@stripped +0 -1
    Bug#20051
      we call remove_io_thread elsewhere

  myisam/myisamchk.c
    1.131 06/05/25 15:03:40 acurtis@stripped +1 -1
    64 threads should be plenty for parallel repair

  myisam/mi_check.c
    1.158 06/05/25 15:03:39 acurtis@stripped +20 -3
    Bug#20051
      mi_repair_parallel should respect max_threads
      mi_repair_parallel deadlock fix

  include/myisam.h
    1.67 06/05/25 15:03:39 acurtis@stripped +1 -1
    mi_repair_parallel() needs arg for max_threads

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	acurtis
# Host:	localhost.(none)
# Root:	/home/antony/work2/p1-bug20051.2

--- 1.66/include/myisam.h	2005-10-22 15:46:04 -07:00
+++ 1.67/include/myisam.h	2006-05-25 15:03:39 -07:00
@@ -407,7 +407,7 @@ int mi_sort_index(MI_CHECK *param, regis
 int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
 		      const char * name, int rep_quick);
 int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
-		      const char * name, int rep_quick);
+		      const char * name, int rep_quick, int max_threads);
 int change_to_newfile(const char * filename, const char * old_ext,
 		      const char * new_ext, uint raid_chunks,
 		      myf myflags);

--- 1.157/myisam/mi_check.c	2006-04-29 10:38:37 -07:00
+++ 1.158/myisam/mi_check.c	2006-05-25 15:03:39 -07:00
@@ -2358,7 +2358,7 @@ err:
 */
 
 int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
-			const char * name, int rep_quick)
+			const char * name, int rep_quick, int max_threads)
 {
 #ifndef THREAD
   return mi_repair_by_sort(param, info, name, rep_quick);
@@ -2590,12 +2590,15 @@ int mi_repair_parallel(MI_CHECK *param, 
   pthread_cond_init(&sort_info.cond, 0);
   pthread_mutex_lock(&sort_info.mutex);
 
-  init_io_cache_share(&param->read_cache, &io_share, i);
+  init_io_cache_share(&param->read_cache, &io_share, max_threads);
   (void) pthread_attr_init(&thr_attr);
   (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
 
   for (i=0 ; i < sort_info.total_keys ; i++)
   {
+    while (sort_info.threads_running >= max_threads)
+      pthread_cond_wait(&sort_info.cond, &sort_info.mutex);
+
     sort_param[i].read_cache=param->read_cache;
     /*
       two approaches: the same amount of memory for each thread
@@ -2614,7 +2617,6 @@ int mi_repair_parallel(MI_CHECK *param, 
 		       (void *) (sort_param+i)))
     {
       mi_check_print_error(param,"Cannot start a repair thread");
-      remove_io_thread(&param->read_cache);
       sort_info.got_error=1;
     }
     else
@@ -2622,9 +2624,24 @@ int mi_repair_parallel(MI_CHECK *param, 
   }
   (void) pthread_attr_destroy(&thr_attr);
 
+  /* if we have fewer running threads than expected,
+     make sure that the iocache is notified */
+  if (sort_info.threads_running < max_threads)
+  {
+    int count= max_threads - sort_info.threads_running;
+    while (count--)
+      remove_io_thread(&param->read_cache);
+  }
+
   /* waiting for all threads to finish */
   while (sort_info.threads_running)
+  {
+    int count= sort_info.threads_running;
     pthread_cond_wait(&sort_info.cond, &sort_info.mutex);
+    count-= sort_info.threads_running;
+    while (count--)
+      remove_io_thread(&param->read_cache);
+  }
   pthread_mutex_unlock(&sort_info.mutex);
 
   if ((got_error= thr_write_keys(sort_param)))

--- 1.130/myisam/myisamchk.c	2005-12-04 05:32:54 -08:00
+++ 1.131/myisam/myisamchk.c	2006-05-25 15:03:40 -07:00
@@ -1020,7 +1020,7 @@ static int myisamchk(MI_CHECK *param, my
           if (param->testflag & T_REP_BY_SORT)
             error=mi_repair_by_sort(param,info,filename,rep_quick);
           else
-            error=mi_repair_parallel(param,info,filename,rep_quick);
+            error=mi_repair_parallel(param,info,filename,rep_quick,64);
 	  state_updated=1;
 	}
 	else if (param->testflag & T_REP_ANY)

--- 1.45/myisam/sort.c	2005-10-20 19:29:11 -07:00
+++ 1.46/myisam/sort.c	2006-05-25 15:03:40 -07:00
@@ -444,7 +444,6 @@ err:
   close_cached_file(&info->tempfile_for_exceptions);
 
 ok:
-  remove_io_thread(&info->read_cache);
   pthread_mutex_lock(&info->sort_info->mutex);
   info->sort_info->threads_running--;
   pthread_cond_signal(&info->sort_info->cond);

--- 1.48/mysys/mf_iocache.c	2006-02-16 10:45:54 -08:00
+++ 1.49/mysys/mf_iocache.c	2006-05-25 15:03:40 -07:00
@@ -505,9 +505,11 @@ int _my_b_read(register IO_CACHE *info, 
 void init_io_cache_share(IO_CACHE *info, IO_CACHE_SHARE *s, uint num_threads)
 {
   DBUG_ASSERT(info->type == READ_CACHE);
+  DBUG_ASSERT(num_threads > 0);
   pthread_mutex_init(&s->mutex, MY_MUTEX_INIT_FAST);
   pthread_cond_init (&s->cond, 0);
-  s->total=s->count=num_threads-1;
+  s->total=num_threads-1;
+  s->count=0;
   s->active=0;
   info->share=s;
   info->read_function=_my_b_read_r;

--- 1.162/sql/ha_myisam.cc	2005-10-20 19:29:11 -07:00
+++ 1.163/sql/ha_myisam.cc	2006-05-25 15:03:40 -07:00
@@ -609,14 +609,15 @@ int ha_myisam::repair(THD *thd, MI_CHECK
       local_testflag|= T_STATISTICS;
       param.testflag|= T_STATISTICS;		// We get this for free
       statistics_done=1;
-      if (current_thd->variables.myisam_repair_threads>1)
+      if (thd->variables.myisam_repair_threads>1)
       {
         char buf[40];
-        /* TODO: respect myisam_repair_threads variable */
-        my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
+        uint threads= min(thd->variables.myisam_repair_threads, 
+                          my_count_bits(key_map));
+        my_snprintf(buf, 40, "Repair with %d threads", threads);
         thd->proc_info=buf;
         error = mi_repair_parallel(&param, file, fixed_name,
-            param.testflag & T_QUICK);
+            param.testflag & T_QUICK, threads);
         thd->proc_info="Repair done"; // to reset proc_info, as
                                       // it was pointing to local buffer
       }

--- 1.16/mysql-test/r/repair.result	2006-05-12 09:16:28 -07:00
+++ 1.17/mysql-test/r/repair.result	2006-05-25 15:03:40 -07:00
@@ -37,3 +37,47 @@ Table	Op	Msg_type	Msg_text
 test.t1	repair	warning	Number of rows changed from 0 to 1
 test.t1	repair	status	OK
 drop table t1;
+SET @@myisam_repair_threads=2;
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note	1051	Unknown table 't1'
+CREATE TABLE t1 (
+`_id` int(11) NOT NULL default '0',
+`name` text,
+PRIMARY KEY  (`_id`),
+UNIQUE KEY `sequence_name_index` (`name`(50))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 (`_id`, `name`) VALUES (1,'sample1'),
+(2,'sample2'), (3,'sample3'), (4,'sample4'), (5,'sample5'),
+(6,'sample6'), (7,'sample7'), (8,'sample8'), (9,'sample9');
+SHOW VARIABLES LIKE 'myisam_repair_threads';
+Variable_name	Value
+myisam_repair_threads	2
+SELECT _id FROM t1;
+_id
+1
+2
+3
+4
+5
+6
+7
+8
+9
+DELETE FROM t1 WHERE _id < 8;
+OPTIMIZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+CHECK TABLE t1 EXTENDED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	error	Found key at page 2048 that points to record outside datafile
+test.t1	check	error	Corrupt
+REPAIR TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+SELECT _id FROM t1;
+_id
+8
+9
+DROP TABLE t1;
+SET @@myisam_repair_threads=1;

--- 1.14/mysql-test/t/repair.test	2006-05-12 09:16:47 -07:00
+++ 1.15/mysql-test/t/repair.test	2006-05-25 15:03:40 -07:00
@@ -34,4 +34,33 @@ repair table t1;
 repair table t1 use_frm;
 drop table t1;
 
+#
+# Bug#20051 - multithreaded OPTIMIZE/REPAIR deadlocks
+#
+
+SET @@myisam_repair_threads=2;
+
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+  `_id` int(11) NOT NULL default '0',
+  `name` text,
+  PRIMARY KEY  (`_id`),
+  UNIQUE KEY `sequence_name_index` (`name`(50))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+INSERT INTO t1 (`_id`, `name`) VALUES (1,'sample1'),
+(2,'sample2'), (3,'sample3'), (4,'sample4'), (5,'sample5'),
+(6,'sample6'), (7,'sample7'), (8,'sample8'), (9,'sample9');
+
+SHOW VARIABLES LIKE 'myisam_repair_threads';
+SELECT _id FROM t1;
+DELETE FROM t1 WHERE _id < 8;
+OPTIMIZE TABLE t1;
+CHECK TABLE t1 EXTENDED;
+# when bug#8283 is fixed, remove the following line
+REPAIR TABLE t1;
+SELECT _id FROM t1;
+DROP TABLE t1;
+SET @@myisam_repair_threads=1;
+
 # End of 4.1 tests
Thread
bk commit into 4.1 tree (acurtis:1.2488) BUG#20051antony26 May