From 96415bb39da6cafaf2059de6d9b58dbc115c7f92 Mon Sep 17 00:00:00 2001 From: Timothy Smith Date: Tue, 13 Jan 2009 15:14:11 +0100 Subject: [PATCH] Applying InnoDB snapshot innodb-5.1-ss3603 Detailed description of changes: r3601 | marko | 2008-12-22 16:05:19 +0200 (Mon, 22 Dec 2008) | 9 lines branches/5.1: Make SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED a true replacement of SET GLOBAL INNODB_LOCKS_UNSAFE_FOR_BINLOG=1. This fixes an error that was introduced in r370, causing semi-consistent read not to not unlock rows in READ UNCOMMITTED mode. (Bug #41671, Issue #146) rb://67 approved by Heikki Tuuri --- mysql-test/r/innodb-semi-consistent.result | 5 +++-- mysql-test/t/innodb-semi-consistent-master.opt | 2 +- mysql-test/t/innodb-semi-consistent.test | 7 +++++-- storage/innobase/handler/ha_innodb.cc | 3 ++- storage/innobase/row/row0mysql.c | 7 ++++--- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/innodb-semi-consistent.result b/mysql-test/r/innodb-semi-consistent.result index 6173048c320..55e3cb5c7b4 100644 --- a/mysql-test/r/innodb-semi-consistent.result +++ b/mysql-test/r/innodb-semi-consistent.result @@ -1,6 +1,6 @@ drop table if exists t1; set binlog_format=mixed; -set session transaction isolation level read committed; +set session transaction isolation level repeatable read; create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1; insert into t1 values (1),(2),(3),(4),(5),(6),(7); set autocommit=0; @@ -8,11 +8,12 @@ select * from t1 where a=3 lock in share mode; a 3 set binlog_format=mixed; -set session transaction isolation level read committed; +set session transaction isolation level repeatable read; set autocommit=0; update t1 set a=10 where a=5; ERROR HY000: Lock wait timeout exceeded; try restarting transaction commit; +set session transaction isolation level read committed; update t1 set a=10 where a=5; select * from t1 where a=2 for update; ERROR HY000: Lock wait timeout exceeded; try restarting transaction diff --git a/mysql-test/t/innodb-semi-consistent-master.opt b/mysql-test/t/innodb-semi-consistent-master.opt index 2746e4e184e..e76299453d3 100644 --- a/mysql-test/t/innodb-semi-consistent-master.opt +++ b/mysql-test/t/innodb-semi-consistent-master.opt @@ -1 +1 @@ ---innodb_locks_unsafe_for_binlog=true --innodb_lock_wait_timeout=2 +--innodb_lock_wait_timeout=2 diff --git a/mysql-test/t/innodb-semi-consistent.test b/mysql-test/t/innodb-semi-consistent.test index a3496625e95..6d3020bb560 100644 --- a/mysql-test/t/innodb-semi-consistent.test +++ b/mysql-test/t/innodb-semi-consistent.test @@ -11,7 +11,7 @@ connect (a,localhost,root,,); connect (b,localhost,root,,); connection a; set binlog_format=mixed; -set session transaction isolation level read committed; +set session transaction isolation level repeatable read; create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1; insert into t1 values (1),(2),(3),(4),(5),(6),(7); set autocommit=0; @@ -19,13 +19,15 @@ set autocommit=0; select * from t1 where a=3 lock in share mode; connection b; set binlog_format=mixed; -set session transaction isolation level read committed; +set session transaction isolation level repeatable read; set autocommit=0; -- error ER_LOCK_WAIT_TIMEOUT update t1 set a=10 where a=5; connection a; commit; connection b; +# perform a semi-consisent read (and unlock non-matching rows) +set session transaction isolation level read committed; update t1 set a=10 where a=5; connection a; -- error ER_LOCK_WAIT_TIMEOUT @@ -33,6 +35,7 @@ select * from t1 where a=2 for update; # this should lock the records (1),(2) select * from t1 where a=2 limit 1 for update; connection b; +# semi-consistent read will skip non-matching locked rows a=1, a=2 update t1 set a=11 where a=6; -- error ER_LOCK_WAIT_TIMEOUT update t1 set a=12 where a=2; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 366bc3966c7..513ce85ad0c 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4129,7 +4129,8 @@ ha_innobase::unlock_row(void) switch (prebuilt->row_read_type) { case ROW_READ_WITH_LOCKS: if (!srv_locks_unsafe_for_binlog - || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED) { + && prebuilt->trx->isolation_level + != TRX_ISO_READ_COMMITTED) { break; } /* fall through */ diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 1713863f1fe..088d944cb91 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1486,12 +1486,13 @@ row_unlock_for_mysql( ut_ad(prebuilt && trx); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); - if (!(srv_locks_unsafe_for_binlog - || trx->isolation_level == TRX_ISO_READ_COMMITTED)) { + if (UNIV_UNLIKELY + (!srv_locks_unsafe_for_binlog + && trx->isolation_level != TRX_ISO_READ_COMMITTED)) { fprintf(stderr, "InnoDB: Error: calling row_unlock_for_mysql though\n" - "InnoDB: srv_locks_unsafe_for_binlog is FALSE and\n" + "InnoDB: innodb_locks_unsafe_for_binlog is FALSE and\n" "InnoDB: this session is not using" " READ COMMITTED isolation level.\n");