List:Commits« Previous MessageNext Message »
From:ingo Date:September 29 2006 3:58pm
Subject:bk commit into 5.1 tree (istruewing:1.2348)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of istruewing. When istruewing 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, 2006-09-29 15:58:15+02:00, istruewing@stripped +1 -0
  Merge chilla.local:/home/mydev/mysql-5.1--team
  into  chilla.local:/home/mydev/mysql-5.1-bug20627
  MERGE: 1.2330.1.8

  sql/sql_insert.cc@stripped, 2006-09-29 15:58:00+02:00, istruewing@stripped +0 -0
    Auto merged
    MERGE: 1.224.1.2

# 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:	istruewing
# Host:	chilla.local
# Root:	/home/mydev/mysql-5.1-bug20627/RESYNC

--- 1.225/sql/sql_insert.cc	2006-09-29 15:58:27 +02:00
+++ 1.226/sql/sql_insert.cc	2006-09-29 15:58:27 +02:00
@@ -572,7 +572,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
 
   free_underlaid_joins(thd, &thd->lex->select_lex);
   joins_freed= TRUE;
-  table->file->ha_release_auto_increment();
 
   /*
     Now all rows are inserted.  Time to update logs and sends response to
@@ -591,6 +590,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   else
 #endif
   {
+    /*
+      Do not do this release if this is a delayed insert, it would steal
+      auto_inc values from the delayed_insert thread as they share TABLE.
+    */
+    table->file->ha_release_auto_increment();
     if (!thd->prelocked_mode && table->file->ha_end_bulk_insert()
&& !error)
     {
       table->file->print_error(my_errno,MYF(0));
@@ -1330,13 +1334,16 @@ public:
   bool query_start_used, ignore, log_query;
   bool stmt_depends_on_first_successful_insert_id_in_prev_stmt;
   ulonglong first_successful_insert_id_in_prev_stmt;
+  ulonglong forced_insert_id;
+  ulong auto_increment_increment;
+  ulong auto_increment_offset;
   timestamp_auto_set_type timestamp_field_type;
   LEX_STRING query;
 
   delayed_row(LEX_STRING const query_arg, enum_duplicates dup_arg,
               bool ignore_arg, bool log_query_arg)
     : record(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg),
-      query(query_arg)
+      forced_insert_id(0), query(query_arg)
     {}
   ~delayed_row()
   {
@@ -1694,6 +1701,7 @@ write_delayed(THD *thd,TABLE *table, enu
 {
   delayed_row *row;
   delayed_insert *di=thd->di;
+  const Discrete_interval *forced_auto_inc;
   DBUG_ENTER("write_delayed");
   DBUG_PRINT("enter", ("query = '%s' length %u", query.str, query.length));
 
@@ -1743,6 +1751,17 @@ write_delayed(THD *thd,TABLE *table, enu
     thd->first_successful_insert_id_in_prev_stmt;
   row->timestamp_field_type=    table->timestamp_field_type;
 
+  /* Copy session variables. */
+  row->auto_increment_increment= thd->variables.auto_increment_increment;
+  row->auto_increment_offset=    thd->variables.auto_increment_offset;
+  /* Copy the next forced auto increment value, if any. */
+  if ((forced_auto_inc= thd->auto_inc_intervals_forced.get_next()))
+  {
+    row->forced_insert_id= forced_auto_inc->minimum();
+    DBUG_PRINT("delayed", ("transmitting auto_inc: %lu",
+                           (ulong) row->forced_insert_id));
+  }
+
   di->rows.push_back(row);
   di->stacked_inserts++;
   di->status=1;
@@ -1994,6 +2013,10 @@ pthread_handler_t handle_delayed_insert(
       MYSQL_LOCK *lock=thd->lock;
       thd->lock=0;
       pthread_mutex_unlock(&di->mutex);
+      /*
+        We need to release next_insert_id before unlocking. This is
+        enforced by handler::ha_external_lock().
+      */
       di->table->file->ha_release_auto_increment();
       mysql_unlock_tables(thd, lock);
       di->group_count=0;
@@ -2114,14 +2137,43 @@ bool delayed_insert::handle_inserts(void
 
     thd.start_time=row->start_time;
     thd.query_start_used=row->query_start_used;
-    /* for the binlog, forget auto_increment ids generated by previous rows */
-//    thd.auto_inc_intervals_in_cur_stmt_for_binlog.empty();
+    /*
+      To get the exact auto_inc interval to store in the binlog we must not
+      use values from the previous interval (of the previous rows).
+    */
+    bool log_query= (row->log_query && row->query.str != NULL);
+    DBUG_PRINT("delayed", ("query: '%s'  length: %u", row->query.str ?
+                           row->query.str : "[NULL]", row->query.length));
+    if (row->query.str)
+    {
+      /*
+        This is the first value of an INSERT statement.
+        It is the right place to clear a forced insert_id.
+        This is usually done after the last value of an INSERT statement,
+        but we won't know this in the insert delayed thread. But before
+        the first value is sufficiently equivalent to after the last
+        value of the previous statement.
+      */
+      table->file->ha_release_auto_increment();
+      thd.auto_inc_intervals_in_cur_stmt_for_binlog.empty();
+    }
     thd.first_successful_insert_id_in_prev_stmt= 
       row->first_successful_insert_id_in_prev_stmt;
     thd.stmt_depends_on_first_successful_insert_id_in_prev_stmt= 
       row->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
     table->timestamp_field_type= row->timestamp_field_type;
 
+    /* Copy the session variables. */
+    thd.variables.auto_increment_increment= row->auto_increment_increment;
+    thd.variables.auto_increment_offset=    row->auto_increment_offset;
+    /* Copy a forced insert_id, if any. */
+    if (row->forced_insert_id)
+    {
+      DBUG_PRINT("delayed", ("received auto_inc: %lu",
+                             (ulong) row->forced_insert_id));
+      thd.force_one_auto_inc_interval(row->forced_insert_id);
+    }
+
     info.ignore= row->ignore;
     info.handle_duplicates= row->dup;
     if (info.ignore ||
@@ -2156,7 +2208,7 @@ bool delayed_insert::handle_inserts(void
       table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
     }
 
-    if (row->log_query && row->query.str != NULL &&
mysql_bin_log.is_open())
+    if (log_query && mysql_bin_log.is_open())
     {
       /*
         If the query has several rows to insert, only the first row will come
@@ -2199,6 +2251,7 @@ bool delayed_insert::handle_inserts(void
 	  /* This should never happen */
 	  table->file->print_error(error,MYF(0));
 	  sql_print_error("%s",thd.net.last_error);
+          DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
 	  goto err;
 	}
 	query_cache_invalidate3(&thd, table, 1);
@@ -2241,6 +2294,7 @@ bool delayed_insert::handle_inserts(void
   {						// This shouldn't happen
     table->file->print_error(error,MYF(0));
     sql_print_error("%s",thd.net.last_error);
+    DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
     goto err;
   }
   query_cache_invalidate3(&thd, table, 1);
@@ -2248,13 +2302,16 @@ bool delayed_insert::handle_inserts(void
   DBUG_RETURN(0);
 
  err:
+  DBUG_EXECUTE("error", max_rows= 0;);
   /* Remove all not used rows */
   while ((row=rows.get()))
   {
     delete row;
     thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
     stacked_inserts--;
+    DBUG_EXECUTE("error", max_rows++;);
   }
+  DBUG_PRINT("error", ("dropped %lu rows after an error", max_rows));
   thread_safe_increment(delayed_insert_errors, &LOCK_delayed_status);
   pthread_mutex_lock(&mutex);
   DBUG_RETURN(1);
Thread
bk commit into 5.1 tree (istruewing:1.2348)ingo29 Sep