Commit 258d9a96 authored by unknown's avatar unknown
Browse files

Merge heikki@bk-internal.mysql.com:/home/bk/mysql-5.0

into hundin.mysql.fi:/home/heikki/mysql-5.0

parents 14ade135 f9469777
Loading
Loading
Loading
Loading
+51 −22
Original line number Diff line number Diff line
@@ -1496,8 +1496,8 @@ innobase_start_trx_and_assign_read_view(
/*********************************************************************
Commits a transaction in an InnoDB database or marks an SQL statement
ended. */

static int
static
int
innobase_commit(
/*============*/
			/* out: 0 */
@@ -5991,6 +5991,7 @@ ha_innobase::external_lock(
			reads. */

			prebuilt->select_lock_type = LOCK_S;
			prebuilt->stored_select_lock_type = LOCK_S;
		}

		/* Starting from 4.1.9, no InnoDB table lock is taken in LOCK
@@ -6030,7 +6031,6 @@ ha_innobase::external_lock(
	trx->n_mysql_tables_in_use--;
	prebuilt->mysql_has_locked = FALSE;


	/* If the MySQL lock count drops to zero we know that the current SQL
	statement has ended */

@@ -6563,12 +6563,14 @@ the value of the auto-inc counter. */
int
ha_innobase::innobase_read_and_init_auto_inc(
/*=========================================*/
				/* out: 0 or error code: deadlock or
				lock wait timeout */
				/* out: 0 or error code: deadlock or lock wait
				timeout */
	longlong*	ret)	/* out: auto-inc value */
{
  	row_prebuilt_t* prebuilt	= (row_prebuilt_t*) innobase_prebuilt;
    	longlong        auto_inc;
	ulint		old_select_lock_type;
	ibool		trx_was_not_started	= FALSE;
  	int     	error;

  	ut_a(prebuilt);
@@ -6576,6 +6578,10 @@ ha_innobase::innobase_read_and_init_auto_inc(
                (trx_t*) current_thd->ha_data[innobase_hton.slot]);
	ut_a(prebuilt->table);
	
	if (prebuilt->trx->conc_state == TRX_NOT_STARTED) {
		trx_was_not_started = TRUE;
	}

	/* In case MySQL calls this in the middle of a SELECT query, release
	possible adaptive hash latch to avoid deadlocks of threads */

@@ -6587,7 +6593,9 @@ ha_innobase::innobase_read_and_init_auto_inc(
		/* Already initialized */
		*ret = auto_inc;
	
		return(0);
		error = 0;

		goto func_exit_early;
	}

	error = row_lock_table_autoinc_for_mysql(prebuilt);
@@ -6595,7 +6603,7 @@ ha_innobase::innobase_read_and_init_auto_inc(
	if (error != DB_SUCCESS) {
		error = convert_error_code_to_mysql(error, user_thd);

		goto func_exit;
		goto func_exit_early;
	}	

	/* Check again if someone has initialized the counter meanwhile */
@@ -6604,30 +6612,37 @@ ha_innobase::innobase_read_and_init_auto_inc(
	if (auto_inc != 0) {
		*ret = auto_inc;
	
		return(0);
		error = 0;

		goto func_exit_early;
	}

  	(void) extra(HA_EXTRA_KEYREAD);
  	index_init(table->s->next_number_index);

	/* We use an exclusive lock when we read the max key value from the
  	auto-increment column index. This is because then build_template will
  	advise InnoDB to fetch all columns. In SHOW TABLE STATUS the query
  	id of the auto-increment column is not changed, and previously InnoDB
  	did not fetch it, causing SHOW TABLE STATUS to show wrong values
  	for the autoinc column. */

  	prebuilt->select_lock_type = LOCK_X;
	/* Starting from 5.0.9, we use a consistent read to read the auto-inc
	column maximum value. This eliminates the spurious deadlocks caused
	by the row X-lock that we previously used. Note the following flaw
	in our algorithm: if some other user meanwhile UPDATEs the auto-inc
	column, our consistent read will not return the largest value. We
	accept this flaw, since the deadlocks were a bigger trouble. */

  	/* Play safe and also give in another way the hint to fetch
  	all columns in the key: */
  	/* Fetch all the columns in the key */
  	
	prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;

	prebuilt->trx->mysql_n_tables_locked += 1;
	old_select_lock_type = prebuilt->select_lock_type;
  	prebuilt->select_lock_type = LOCK_NONE;

	/* Eliminate an InnoDB error print that happens when we try to SELECT
	from a table when no table has been locked in ::external_lock(). */
	prebuilt->trx->n_mysql_tables_in_use++;

	error = index_last(table->record[1]);

	prebuilt->trx->n_mysql_tables_in_use--;
  	prebuilt->select_lock_type = old_select_lock_type;

  	if (error) {
		if (error == HA_ERR_END_OF_FILE) {
			/* The table was empty, initialize to 1 */
@@ -6635,7 +6650,10 @@ ha_innobase::innobase_read_and_init_auto_inc(

			error = 0;
		} else {
			/* Deadlock or a lock wait timeout */
			/* This should not happen in a consistent read */
			fprintf(stderr,
"InnoDB: Error: consistent read of auto-inc column returned %lu\n",
								(ulong)error);
  			auto_inc = -1;

  			goto func_exit;
@@ -6655,6 +6673,17 @@ ha_innobase::innobase_read_and_init_auto_inc(

	*ret = auto_inc;

func_exit_early:
	/* Since MySQL does not seem to call autocommit after SHOW TABLE
	STATUS (even if we would register the trx here), we must commit our
	transaction here if it was started here. This is to eliminate a
	dangling transaction. */

	if (trx_was_not_started) {

		innobase_commit_low(prebuilt->trx);
	}

 	return(error);
}