MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:<gshchepa Date:October 8 2007 8:07pm
Subject:bk commit into 5.1 tree (gshchepa:1.2587) BUG#31310
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of uchum. When uchum 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-10-09 01:07:15+05:00, gshchepa@stripped +3 -0
  Fixed bug #31310.
  Locked rows of the InnoDB storage was silently skipped in the read-committed
  isolation level.
  
  QUICK_RANGE_SELECT for unique ranges lacks second (blocking) read
  of the record that was read semi-consistently and just skip it.
  
  The handler::read_multi_range_next method has been modified
  to retry previous unique range if the previous read was
  semi-consistent.

  mysql-test/include/mix1.inc@stripped, 2007-10-09 01:03:44+05:00, gshchepa@stripped +125 -0
    Added test case for bug #31310.

  mysql-test/r/innodb_mysql.result@stripped, 2007-10-09 01:03:59+05:00, gshchepa@stripped +80 -0
    Added test case for bug #31310.

  sql/handler.cc@stripped, 2007-10-09 01:03:36+05:00, gshchepa@stripped +5 -3
    Fixed bug #31310.
    The handler::read_multi_range_next method has been modified
    to retry previous unique range if the previous read was
    semi-consistent.

diff -Nrup a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
--- a/mysql-test/include/mix1.inc	2007-09-14 21:03:12 +05:00
+++ b/mysql-test/include/mix1.inc	2007-10-09 01:03:44 +05:00
@@ -29,6 +29,7 @@ eval SET SESSION STORAGE_ENGINE = $engin
 
 --disable_warnings
 drop table if exists t1,t2,t3,t1m,t1i,t2m,t2i,t4;
+drop procedure if exists p1;
 --enable_warnings
 
 
@@ -1146,4 +1147,128 @@ select @b:=f2 from t1;
 select if(@a=@b,"ok","wrong");
 drop table t1;
 
+#
+# Bug #31310: Locked rows silently skipped in read-committed isolation level.
+#
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+SET SESSION AUTOCOMMIT = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+--echo # Switch to connection con1
+connection con1;
+
+eval
+CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256))
+ENGINE = $engine_type;
+INSERT INTO t1 VALUES (1,2);
+
+--#echo 1. test for locking:
+
+BEGIN;
+--enable_info
+UPDATE t1 SET b = 12 WHERE a = 1;
+--disable_info
+SELECT * FROM t1;
+
+--echo # Switch to connection con2
+connection con2;
+
+--enable_info
+--disable_abort_on_error
+--error ER_LOCK_WAIT_TIMEOUT
+UPDATE t1 SET b = 21 WHERE a = 1;
+--disable_info
+
+--echo # Switch to connection con1
+connection con1;
+SELECT * FROM t1;
+ROLLBACK;
+
+--echo # 2. test for serialized update:
+
+CREATE TABLE t2 (a INT);
+
+TRUNCATE t1;
+INSERT INTO t1 VALUES (1,'init');
+
+DELIMITER |;
+CREATE PROCEDURE p1()
+BEGIN
+  UPDATE t1 SET b = CONCAT(b, '+con2')  WHERE a = 1;
+  INSERT INTO t2 VALUES ();
+END|
+DELIMITER ;|
+
+BEGIN;
+--enable_info
+UPDATE t1 SET b = CONCAT(b, '+con1') WHERE a = 1;
+--disable_info
+SELECT * FROM t1;
+
+--echo # Switch to connection con2
+connection con2;
+
+--send CALL p1;
+
+--echo # Switch to connection con1
+connection con1;
+SELECT * FROM t1;
+COMMIT;
+
+let $bug31310 = 1;
+while ($bug31310)
+{
+  let $bug31310= `SELECT 1 - COUNT(*) FROM t2`;
+}
+
+SELECT * FROM t1;
+
+--echo # Switch to connection con2
+connection con2;
+SELECT * FROM t1;
+
+--echo # Switch to connection con1
+connection con1;
+
+--echo # 3. test for updated key column:
+
+TRUNCATE t1;
+TRUNCATE t2;
+
+INSERT INTO t1 VALUES (1,'init');
+
+BEGIN;
+--enable_info
+UPDATE t1 SET a = 2, b = CONCAT(b, '+con1') WHERE a = 1;
+--disable_info
+SELECT * FROM t1;
+
+--echo # Switch to connection con2
+connection con2;
+
+--send CALL p1;
+
+--echo # Switch to connection con1
+connection con1;
+SELECT * FROM t1;
+COMMIT;
+
+let $bug31310 = 1;
+while ($bug31310)
+{
+  let $bug31310= `SELECT 1 - COUNT(*) FROM t2`;
+}
+
+SELECT * FROM t1;
+
+--echo # Switch to connection con2
+connection con2;
+SELECT * FROM t1;
+
+connection default;
+disconnect con1;
+disconnect con2;
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
 --echo End of 5.1 tests
diff -Nrup a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
--- a/mysql-test/r/innodb_mysql.result	2007-09-14 21:03:12 +05:00
+++ b/mysql-test/r/innodb_mysql.result	2007-10-09 01:03:59 +05:00
@@ -1,5 +1,6 @@
 SET SESSION STORAGE_ENGINE = InnoDB;
 drop table if exists t1,t2,t3,t1m,t1i,t2m,t2i,t4;
+drop procedure if exists p1;
 create table t1 (
 c_id int(11) not null default '0',
 org_id int(11) default null,
@@ -1419,4 +1420,83 @@ select if(@a=@b,"ok","wrong");
 if(@a=@b,"ok","wrong")
 ok
 drop table t1;
+SET SESSION AUTOCOMMIT = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+# Switch to connection con1
+CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256))
+ENGINE = InnoDB;
+INSERT INTO t1 VALUES (1,2);
+BEGIN;
+UPDATE t1 SET b = 12 WHERE a = 1;
+affected rows: 1
+info: Rows matched: 1  Changed: 1  Warnings: 0
+SELECT * FROM t1;
+a	b
+1	12
+# Switch to connection con2
+UPDATE t1 SET b = 21 WHERE a = 1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Switch to connection con1
+SELECT * FROM t1;
+a	b
+1	12
+ROLLBACK;
+# 2. test for serialized update:
+CREATE TABLE t2 (a INT);
+TRUNCATE t1;
+INSERT INTO t1 VALUES (1,'init');
+CREATE PROCEDURE p1()
+BEGIN
+UPDATE t1 SET b = CONCAT(b, '+con2')  WHERE a = 1;
+INSERT INTO t2 VALUES ();
+END|
+BEGIN;
+UPDATE t1 SET b = CONCAT(b, '+con1') WHERE a = 1;
+affected rows: 1
+info: Rows matched: 1  Changed: 1  Warnings: 0
+SELECT * FROM t1;
+a	b
+1	init+con1
+# Switch to connection con2
+CALL p1;;
+# Switch to connection con1
+SELECT * FROM t1;
+a	b
+1	init+con1
+COMMIT;
+SELECT * FROM t1;
+a	b
+1	init+con1
+# Switch to connection con2
+SELECT * FROM t1;
+a	b
+1	init+con1+con2
+# Switch to connection con1
+# 3. test for updated key column:
+TRUNCATE t1;
+TRUNCATE t2;
+INSERT INTO t1 VALUES (1,'init');
+BEGIN;
+UPDATE t1 SET a = 2, b = CONCAT(b, '+con1') WHERE a = 1;
+affected rows: 1
+info: Rows matched: 1  Changed: 1  Warnings: 0
+SELECT * FROM t1;
+a	b
+2	init+con1
+# Switch to connection con2
+CALL p1;;
+# Switch to connection con1
+SELECT * FROM t1;
+a	b
+2	init+con1
+COMMIT;
+SELECT * FROM t1;
+a	b
+2	init+con1
+# Switch to connection con2
+SELECT * FROM t1;
+a	b
+2	init+con1
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
 End of 5.1 tests
diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc	2007-08-31 11:57:57 +05:00
+++ b/sql/handler.cc	2007-10-09 01:03:36 +05:00
@@ -3145,6 +3145,8 @@ int handler::read_multi_range_next(KEY_M
     }
     else
     {
+      if (was_semi_consistent_read())
+        goto scan_it_again;
       /*
         We need to set this for the last range only, but checking this
         condition is more expensive than just setting the result code.
@@ -3152,10 +3154,10 @@ int handler::read_multi_range_next(KEY_M
       result= HA_ERR_END_OF_FILE;
     }
 
+    multi_range_curr++;
+scan_it_again:
     /* Try the next range(s) until one matches a record. */
-    for (multi_range_curr++;
-         multi_range_curr < multi_range_end;
-         multi_range_curr++)
+    for (; multi_range_curr < multi_range_end; multi_range_curr++)
     {
       result= read_range_first(multi_range_curr->start_key.keypart_map ?
                                &multi_range_curr->start_key : 0,
Thread
bk commit into 5.1 tree (gshchepa:1.2587) BUG#31310gshchepa8 Oct