List:Commits« Previous MessageNext Message »
From:marko.makela Date:October 4 2010 10:08am
Subject:bzr push into mysql-5.1-innodb branch (marko.makela:3619 to 3621) Bug#56716
View as plain text  
 3621 Marko Mäkelä	2010-10-04
      Bug#56716 InnoDB locks a record gap without locking the table
      
      row_search_for_mysql(): Acquire an intention lock on the table
      before locking the first record gap.

    added:
      mysql-test/suite/innodb_plugin/r/innodb_bug56716.result
      mysql-test/suite/innodb_plugin/t/innodb_bug56716.test
    modified:
      storage/innodb_plugin/ChangeLog
      storage/innodb_plugin/row/row0sel.c
 3620 Marko Mäkelä	2010-10-04
      Bug#56716 InnoDB locks a record gap without locking the table
      
      row_search_for_mysql(): Acquire an intention lock on the table
      before locking the first record gap.

    added:
      mysql-test/suite/innodb/r/innodb_bug56716.result
      mysql-test/suite/innodb/t/innodb_bug56716.test
    modified:
      storage/innobase/row/row0sel.c
 3619 Vasil Dimov	2010-10-04 [merge]
      Merge mysql-5.1-bugteam -> mysql-5.1-innodb

    modified:
      mysql-test/r/ps_2myisam.result
      mysql-test/r/ps_3innodb.result
      mysql-test/r/ps_4heap.result
      mysql-test/r/ps_5merge.result
      sql/item_func.cc
=== added file 'mysql-test/suite/innodb/r/innodb_bug56716.result'
--- a/mysql-test/suite/innodb/r/innodb_bug56716.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_bug56716.result	revid:marko.makela@strippeds7
@@ -0,0 +1,4 @@
+CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB;
+SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE;
+a	b	c
+DROP TABLE bug56716;

=== added file 'mysql-test/suite/innodb/t/innodb_bug56716.test'
--- a/mysql-test/suite/innodb/t/innodb_bug56716.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_bug56716.test	revid:marko.makela@stripped
@@ -0,0 +1,10 @@
+#
+# Bug #56716 InnoDB locks a record gap without locking the table
+#
+-- source include/have_innodb.inc
+
+CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB;
+
+SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE;
+
+DROP TABLE bug56716;

=== added file 'mysql-test/suite/innodb_plugin/r/innodb_bug56716.result'
--- a/mysql-test/suite/innodb_plugin/r/innodb_bug56716.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb_plugin/r/innodb_bug56716.result	revid:marko.makela@strippedfis7
@@ -0,0 +1,4 @@
+CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB;
+SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE;
+a	b	c
+DROP TABLE bug56716;

=== added file 'mysql-test/suite/innodb_plugin/t/innodb_bug56716.test'
--- a/mysql-test/suite/innodb_plugin/t/innodb_bug56716.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56716.test	revid:marko.makela@stripped40dra6o08a1bfis7
@@ -0,0 +1,10 @@
+#
+# Bug #56716 InnoDB locks a record gap without locking the table
+#
+-- source include/have_innodb_plugin.inc
+
+CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB;
+
+SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE;
+
+DROP TABLE bug56716;

=== modified file 'storage/innobase/row/row0sel.c'
--- a/storage/innobase/row/row0sel.c	revid:vasil.dimov@strippedelbovdwafra5
+++ b/storage/innobase/row/row0sel.c	revid:marko.makela@stripped
@@ -3599,6 +3599,42 @@ shortcut_fails_too_big_rec:
 
 	clust_index = dict_table_get_first_index(index->table);
 
+	/* Do some start-of-statement preparations */
+
+	if (!prebuilt->sql_stat_start) {
+		/* No need to set an intention lock or assign a read view */
+
+		if (trx->read_view == NULL
+		    && prebuilt->select_lock_type == LOCK_NONE) {
+
+			fputs("InnoDB: Error: MySQL is trying to"
+			      " perform a consistent read\n"
+			      "InnoDB: but the read view is not assigned!\n",
+			      stderr);
+			trx_print(stderr, trx, 600);
+			fputc('\n', stderr);
+			ut_error;
+		}
+	} else if (prebuilt->select_lock_type == LOCK_NONE) {
+		/* This is a consistent read */
+		/* Assign a read view for the query */
+
+		trx_assign_read_view(trx);
+		prebuilt->sql_stat_start = FALSE;
+	} else {
+		err = lock_table(0, index->table,
+				 prebuilt->select_lock_type == LOCK_S
+				 ? LOCK_IS : LOCK_IX, thr);
+
+		if (err != DB_SUCCESS) {
+
+			goto lock_wait_or_error;
+		}
+		prebuilt->sql_stat_start = FALSE;
+	}
+
+	/* Open or restore index cursor position */
+
 	if (UNIV_LIKELY(direction != 0)) {
 		ibool	need_to_process = sel_restore_position_for_mysql(
 			&same_user_rec, BTR_SEARCH_LEAF,
@@ -3674,42 +3710,6 @@ shortcut_fails_too_big_rec:
 		}
 	}
 
-	if (!prebuilt->sql_stat_start) {
-		/* No need to set an intention lock or assign a read view */
-
-		if (trx->read_view == NULL
-		    && prebuilt->select_lock_type == LOCK_NONE) {
-
-			fputs("InnoDB: Error: MySQL is trying to"
-			      " perform a consistent read\n"
-			      "InnoDB: but the read view is not assigned!\n",
-			      stderr);
-			trx_print(stderr, trx, 600);
-			fputc('\n', stderr);
-			ut_a(0);
-		}
-	} else if (prebuilt->select_lock_type == LOCK_NONE) {
-		/* This is a consistent read */
-		/* Assign a read view for the query */
-
-		trx_assign_read_view(trx);
-		prebuilt->sql_stat_start = FALSE;
-	} else {
-		ulint	lock_mode;
-		if (prebuilt->select_lock_type == LOCK_S) {
-			lock_mode = LOCK_IS;
-		} else {
-			lock_mode = LOCK_IX;
-		}
-		err = lock_table(0, index->table, lock_mode, thr);
-
-		if (err != DB_SUCCESS) {
-
-			goto lock_wait_or_error;
-		}
-		prebuilt->sql_stat_start = FALSE;
-	}
-
 rec_loop:
 	/*-------------------------------------------------------------*/
 	/* PHASE 4: Look for matching records in a loop */

=== modified file 'storage/innodb_plugin/ChangeLog'
--- a/storage/innodb_plugin/ChangeLog	revid:vasil.dimov@strippedom-20101004094958-ji3oelbovdwafra5
+++ b/storage/innodb_plugin/ChangeLog	revid:marko.makela@stripped641-40dra6o08a1bfis7
@@ -1,3 +1,8 @@
+2010-09-27	The InnoDB Team
+
+	* row/row0sel.c, innodb_bug56716.result, innodb_bug56716.test:
+	Fix Bug #56716 InnoDB locks a record gap without locking the table
+
 2010-09-06	The InnoDB Team
 	* dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result
 	Fix Bug #53756 	ALTER TABLE ADD PRIMARY KEY affects crash recovery

=== modified file 'storage/innodb_plugin/row/row0sel.c'
--- a/storage/innodb_plugin/row/row0sel.c	revid:vasil.dimov@strippedelbovdwafra5
+++ b/storage/innodb_plugin/row/row0sel.c	revid:marko.makela@strippeds7
@@ -3719,6 +3719,42 @@ release_search_latch_if_needed:
 
 	clust_index = dict_table_get_first_index(index->table);
 
+	/* Do some start-of-statement preparations */
+
+	if (!prebuilt->sql_stat_start) {
+		/* No need to set an intention lock or assign a read view */
+
+		if (trx->read_view == NULL
+		    && prebuilt->select_lock_type == LOCK_NONE) {
+
+			fputs("InnoDB: Error: MySQL is trying to"
+			      " perform a consistent read\n"
+			      "InnoDB: but the read view is not assigned!\n",
+			      stderr);
+			trx_print(stderr, trx, 600);
+			fputc('\n', stderr);
+			ut_error;
+		}
+	} else if (prebuilt->select_lock_type == LOCK_NONE) {
+		/* This is a consistent read */
+		/* Assign a read view for the query */
+
+		trx_assign_read_view(trx);
+		prebuilt->sql_stat_start = FALSE;
+	} else {
+		err = lock_table(0, index->table,
+				 prebuilt->select_lock_type == LOCK_S
+				 ? LOCK_IS : LOCK_IX, thr);
+
+		if (err != DB_SUCCESS) {
+
+			goto lock_wait_or_error;
+		}
+		prebuilt->sql_stat_start = FALSE;
+	}
+
+	/* Open or restore index cursor position */
+
 	if (UNIV_LIKELY(direction != 0)) {
 		ibool	need_to_process = sel_restore_position_for_mysql(
 			&same_user_rec, BTR_SEARCH_LEAF,
@@ -3794,42 +3830,6 @@ release_search_latch_if_needed:
 		}
 	}
 
-	if (!prebuilt->sql_stat_start) {
-		/* No need to set an intention lock or assign a read view */
-
-		if (trx->read_view == NULL
-		    && prebuilt->select_lock_type == LOCK_NONE) {
-
-			fputs("InnoDB: Error: MySQL is trying to"
-			      " perform a consistent read\n"
-			      "InnoDB: but the read view is not assigned!\n",
-			      stderr);
-			trx_print(stderr, trx, 600);
-			fputc('\n', stderr);
-			ut_a(0);
-		}
-	} else if (prebuilt->select_lock_type == LOCK_NONE) {
-		/* This is a consistent read */
-		/* Assign a read view for the query */
-
-		trx_assign_read_view(trx);
-		prebuilt->sql_stat_start = FALSE;
-	} else {
-		ulint	lock_mode;
-		if (prebuilt->select_lock_type == LOCK_S) {
-			lock_mode = LOCK_IS;
-		} else {
-			lock_mode = LOCK_IX;
-		}
-		err = lock_table(0, index->table, lock_mode, thr);
-
-		if (err != DB_SUCCESS) {
-
-			goto lock_wait_or_error;
-		}
-		prebuilt->sql_stat_start = FALSE;
-	}
-
 rec_loop:
 	/*-------------------------------------------------------------*/
 	/* PHASE 4: Look for matching records in a loop */

Attachment: [text/bzr-bundle] bzr/marko.makela@oracle.com-20101004100641-40dra6o08a1bfis7.bundle
Thread
bzr push into mysql-5.1-innodb branch (marko.makela:3619 to 3621) Bug#56716marko.makela4 Oct