List:Commits« Previous MessageNext Message »
From:holyfoot Date:April 24 2007 1:42pm
Subject:bk commit into 5.1 tree (holyfoot:1.2567) BUG#27405
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of hf. When hf 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@stripped, 2007-04-24 18:42:46+05:00, holyfoot@stripped +1 -0
  bug #27405 (Partitioning InnoDB auto_increment bug)
  InnoDB engine changes internal auto_increment counter only after
  ha_innodb::write_row, so two threads can't simultaneously
  operate between ha_innodb::update_autoincrement and
  ha_innodb::write_row.
  So concurrent execution of ha_partition::write_row prevented

  sql/ha_partition.cc@stripped, 2007-04-24 18:42:43+05:00, holyfoot@stripped +21 -2
    use table_share->mutex to avoid concurrent write_row for AUTO_INCREMENTed table

# 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:	holyfoot
# Host:	hfmain.(none)
# Root:	/home/hf/work/27405/my51-27405

--- 1.88/sql/ha_partition.cc	2007-04-24 18:42:50 +05:00
+++ 1.89/sql/ha_partition.cc	2007-04-24 18:42:50 +05:00
@@ -2647,6 +2647,7 @@ int ha_partition::write_row(byte * buf)
   uint32 part_id;
   int error;
   longlong func_value;
+  bool autoincrement_lock= false;
 #ifdef NOT_NEEDED
   byte *rec0= m_rec0;
 #endif
@@ -2662,7 +2663,21 @@ int ha_partition::write_row(byte * buf)
     or a new row, then update the auto_increment value in the record.
   */
   if (table->next_number_field && buf == table->record[0])
+  {
+    /*
+      Some engines (InnoDB for example) can change autoincrement
+      counter only after 'table->write_row' operation.
+      So if another thread gets inside the ha_partition::write_row
+      before it is complete, it gets same auto_increment value,
+      which means DUP_KEY error (bug #27405)
+      Here we separate the access using table_share->mutex, and
+      use autoincrement_lock variable to avoid unnecessary locks.
+      Probably not an ideal solution.
+    */
+    autoincrement_lock= true;
+    pthread_mutex_lock(&table_share->mutex);
     update_auto_increment();
+  }
 
   my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
 #ifdef NOT_NEEDED
@@ -2683,11 +2698,15 @@ int ha_partition::write_row(byte * buf)
   if (unlikely(error))
   {
     m_part_info->err_value= func_value;
-    DBUG_RETURN(error);
+    goto exit;
   }
   m_last_part= part_id;
   DBUG_PRINT("info", ("Insert in partition %d", part_id));
-  DBUG_RETURN(m_file[part_id]->write_row(buf));
+  error= m_file[part_id]->write_row(buf);
+exit:
+  if (autoincrement_lock)
+    pthread_mutex_unlock(&table_share->mutex);
+  DBUG_RETURN(error);
 }
 
 
Thread
bk commit into 5.1 tree (holyfoot:1.2567) BUG#27405holyfoot24 Apr