List:Internals« Previous MessageNext Message »
From:Heikki Tuuri Date:May 17 2005 6:43pm
Subject:bk commit into 5.0 tree (heikki:1.1841) BUG#10359
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of heikki. When heikki 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.1841 05/05/17 21:43:15 heikki@stripped +2 -0
  ha_innodb.h, ha_innodb.cc:
    Fix bug #10359 : the critical AUTO-INC bug in InnoDB; since reading of the auto-inc counter in an INSERT was not protected by the AUTO-INC table lock of InnoDB, two inserted rows could get the same value for the auto-inc counter, leading to a duplicate key error

  sql/ha_innodb.h
    1.95 05/05/17 21:41:13 heikki@stripped +0 -1
    Fix bug #10359 : the critical AUTO-INC bug in InnoDB; since reading of the auto-inc counter in an INSERT was not protected by the AUTO-INC table lock of InnoDB, two inserted rows could get the same value for the auto-inc counter, leading to a duplicate key error

  sql/ha_innodb.cc
    1.208 05/05/17 21:41:10 heikki@stripped +34 -21
    Fix bug #10359 : the critical AUTO-INC bug in InnoDB; since reading of the auto-inc counter in an INSERT was not protected by the AUTO-INC table lock of InnoDB, two inserted rows could get the same value for the auto-inc counter, leading to a duplicate key error

# 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:	heikki
# Host:	hundin.mysql.fi
# Root:	/home/heikki/mysql-5.0

--- 1.207/sql/ha_innodb.cc	Fri May  6 16:33:58 2005
+++ 1.208/sql/ha_innodb.cc	Tue May 17 21:41:10 2005
@@ -3170,12 +3170,28 @@
 			prebuilt->sql_stat_start = TRUE;
 		}
 
-		/*
-                  We must use the handler code to update the auto-increment
-                  value to be sure that increment it correctly.
-                */
+		/* We have to use the transactional lock mechanism on the
+		auto-inc counter of the table to ensure that replication and
+		roll-forward of the binlog exactly imitates also the given
+		auto-inc values. The lock is released at each SQL statement's
+		end. This lock also prevents a race where two threads would
+		call ::get_auto_increment() simultaneously. */
+
+		error = row_lock_table_autoinc_for_mysql(prebuilt);
+
+		if (error != DB_SUCCESS) {
+			/* Deadlock or lock wait timeout */
+
+			error = convert_error_code_to_mysql(error, user_thd);
+
+			goto func_exit;
+		}
+
+		/* We must use the handler code to update the auto-increment
+                value to be sure that we increment it correctly. */
+
     		update_auto_increment();
-                auto_inc_used= 1;
+                auto_inc_used = 1;
 
 	}
 
@@ -3198,24 +3214,15 @@
           	auto_inc = table->next_number_field->val_int();
 
           	if (auto_inc != 0) {
-			/* This call will calculate the max of the current
-			value and the value supplied by the user and
-			update the counter accordingly */
-
-			/* We have to use the transactional lock mechanism
-			on the auto-inc counter of the table to ensure
-			that replication and roll-forward of the binlog
-			exactly imitates also the given auto-inc values.
-			The lock is released at each SQL statement's
-			end. */
-
-            		error = row_lock_table_autoinc_for_mysql(prebuilt);
+			/* This call will update the counter according to the
+			value that was inserted in the table */
 
             		if (error != DB_SUCCESS) {
               			error = convert_error_code_to_mysql(error,
 								user_thd);
               			goto func_exit;
             		}
+
             		dict_table_autoinc_update(prebuilt->table, auto_inc);
           	}
         }
@@ -5795,7 +5802,6 @@
 	    	read_view_close_for_mysql(trx);
 	}
 
-	auto_inc_counter_for_this_stat = 0;
 	prebuilt->sql_stat_start = TRUE;
 	prebuilt->hint_need_to_fetch_extra_cols = 0;
 	prebuilt->read_just_key = 0;
@@ -5985,7 +5991,7 @@
 
 	trx->n_mysql_tables_in_use--;
 	prebuilt->mysql_has_locked = FALSE;
-	auto_inc_counter_for_this_stat = 0;
+
 	if (trx->n_lock_table_exp) {
 		row_unlock_tables_for_mysql(trx);
 	}
@@ -6505,7 +6511,7 @@
 /***********************************************************************
 This function initializes the auto-inc counter if it has not been
 initialized yet. This function does not change the value of the auto-inc
-counter if it already has been initialized. In paramete ret returns
+counter if it already has been initialized. In parameter ret returns
 the value of the auto-inc counter. */
 
 int
@@ -6624,7 +6630,14 @@
 	error = innobase_read_and_init_auto_inc(&nr);
 
 	if (error) {
-
+		/* This should never happen in the current (5.0.6) code, since
+		we call this function only after the counter has been
+		initialized. */
+	
+		ut_print_timestamp(stderr);
+		fprintf(stderr,
+		"  InnoDB: Error: error %lu in ::get_auto_increment()\n",
+						(ulong)error);
           	return(~(ulonglong) 0);
 	}
 

--- 1.94/sql/ha_innodb.h	Mon May  9 12:26:46 2005
+++ 1.95/sql/ha_innodb.h	Tue May 17 21:41:13 2005
@@ -70,7 +70,6 @@
 					ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
 					or undefined */
 	uint		num_write_row;	/* number of write_row() calls */
-	longlong	auto_inc_counter_for_this_stat;
 	ulong max_supported_row_length(const byte *buf);
 
 	uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
Thread
bk commit into 5.0 tree (heikki:1.1841) BUG#10359Heikki Tuuri17 May