From: Date: March 6 2009 11:17pm Subject: bzr commit into mysql-6.0 branch (davi:2743) Bug#989 WL#4284 List-Archive: http://lists.mysql.com/commits/68564 X-Bug: 989 Message-Id: <20090306221721.497E1EC105@skynet.ctb.virtua.com.br> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============5214256432798327859==" --===============5214256432798327859== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline # At a local mysql-6.0 repository of davi 2743 Davi Arnaut 2009-03-06 Bug#989: If DROP TABLE while there's an active transaction, wrong binlog order WL#4284: Transactional DDL locking Currently the MySQL server does not keep metadata locks on schema objects for the duration of a transaction, thus failing to guarantee the integrity of the schema objects being used during the transaction and to protect then from concurrent DDL operations. This also poses a problem for replication as a DDL operation might be replicated even thought there are active transactions using the object being modified. The solution is to defer the release of metadata locks until a active transaction is either committed or rolled back. This prevents other statements from modifying the table for the entire duration of the transaction. This provides commitment ordering for guaranteeing serializability across multiple transactions. - Incompatible change: If MySQL's metadata locking system encounters a lock conflict, the usual schema is to use the try and back-off technique to avoid deadlocks -- this schema consists in releasing all locks and trying to acquire them all in one go. But in a transactional context this algorithm can't be utilized as its not possible to release locks acquired during the course of the transaction without breaking the transaction commitments. To avoid deadlocks in this case, the ER_LOCK_DEADLOCK will be returned if a lock conflict is encountered during a transaction. Let's consider an example: A transaction has two statements that modify table t1, then table t2, and then commits. The first statement of the transaction will acquire a shared metadata lock on table t1, and it will be kept utill COMMIT to ensure serializability. At the moment when the second statement attempts to acquire a shared metadata lock on t2, a concurrent ALTER or DROP statement might have locked t2 exclusively. The prescription of the current locking protocol is that the acquirer of the shared lock backs off -- gives up all his current locks and retries. This implies that the entire multi-statement transaction has to be rolled back. - Incompatible change: FLUSH commands such as FLUSH PRIVILEGES and FLUSH TABLES WITH READ LOCK won't cause locked tables to be implicitly unlocked anymore. @ mysql-test/extra/binlog_tests/drop_table.test Add test case for Bug#989 @ mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/include/locktrans.inc Add test case for WL#4284 @ mysql-test/include/mix1.inc Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/include/mix2.inc Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/r/flush_block_commit.result Update test case result. @ mysql-test/r/flush_block_commit_notembedded.result Update test case result. @ mysql-test/r/innodb.result Update test case result. @ mysql-test/r/innodb_mysql.result Update test case result. @ mysql-test/r/lock.result Add test case result. @ mysql-test/r/locktrans_innodb.result Add test case result for WL#4284 @ mysql-test/r/locktrans_myisam.result Add test case result for WL#4284 @ mysql-test/r/mix2_myisam.result Update test case result. @ mysql-test/r/partition_innodb_semi_consistent.result Update test case result. @ mysql-test/r/read_only_innodb.result Update test case result. @ mysql-test/suite/binlog/r/binlog_row_drop_tbl.result Add test case result for Bug#989 @ mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result Update test case result. @ mysql-test/suite/binlog/r/binlog_stm_drop_tbl.result Add test case result for Bug#989 @ mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result Update test case result. @ mysql-test/suite/binlog/t/binlog_row_drop_tbl.test Add test case for Bug#989 @ mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test Add test case for Bug#989 @ mysql-test/suite/falcon/r/falcon_bugs2.result Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/suite/falcon/t/disabled.def Disable tests made meaningless by transactional metadata locking. @ mysql-test/suite/falcon/t/falcon_bugs2.test Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/suite/ndb/r/ndb_index_ordered.result Remove result for disabled part of the test case. @ mysql-test/suite/ndb/t/disabled.def Disable tests made meaningless by transactional metadata locking. @ mysql-test/suite/ndb/t/ndb_index_ordered.test Comment out test made meaningless by transactional metadata locking. @ mysql-test/suite/rpl/r/rpl_locktrans_falcon.result Add test case result for WL#4284 @ mysql-test/suite/rpl/r/rpl_locktrans_innodb.result Add test case result for WL#4284 @ mysql-test/suite/rpl/r/rpl_locktrans_myisam.result Add test case result for WL#4284 @ mysql-test/suite/rpl/t/disabled.def Disable tests made meaningless by transactional metadata locking. @ mysql-test/suite/sys_vars/t/autocommit_func.test Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/t/flush_block_commit.test Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/t/flush_block_commit_notembedded.test Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/t/innodb.test Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/t/partition_innodb_semi_consistent.test Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/t/read_only_innodb.test Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ mysql-test/t/xa.test Fix test case to reflect the fact that transactions now hold metadata locks for the duration of a transaction. @ sql/log_event.cc Release metadata locks after issuing a commit. @ sql/mysql_priv.h Rename parameter to match the name used in the definition. @ sql/rpl_injector.cc Release metadata locks on commit and rollback. @ sql/rpl_rli.cc Remove assert made meaningless, metadata locks are released at the end of the transaction. @ sql/set_var.cc Close tables and release locks if autocommit mode is set. @ sql/slave.cc Release metadata locks after a rollback. @ sql/sql_acl.cc Don't implicitly unlock locked tables. Issue a implicit commit at the end and unlock tables. @ sql/sql_base.cc Defer the release of metadata locks when closing tables if not required to. Issue a deadlock error if the locking protocol requires that a transaction re-acquire its locks. Release metadata locks when closing tables for reopen. @ sql/sql_class.cc Release metadata locks if the thread is killed. @ sql/sql_parse.cc Release metadata locks after implicitly committing a active transaction, or after explicit commits or rollbacks. @ sql/sql_servers.cc Don't implicitly unlock locked tables. Issue a implicit commit at the end and unlock tables. @ sql/sql_table.cc Close table and release metadata locks after a admin operation. @ sql/transaction.cc Release metadata locks after the implicitly committed due to a new transaction being started. Also, release metadata locks acquired after a savepoint if the transaction is rolled back to the save point. added: mysql-test/extra/binlog_tests/drop_table.test mysql-test/suite/binlog/r/binlog_row_drop_tbl.result mysql-test/suite/binlog/r/binlog_stm_drop_tbl.result mysql-test/suite/binlog/t/binlog_row_drop_tbl.test mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test modified: mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test mysql-test/include/locktrans.inc mysql-test/include/mix1.inc mysql-test/include/mix2.inc mysql-test/r/flush_block_commit.result mysql-test/r/flush_block_commit_notembedded.result mysql-test/r/innodb.result mysql-test/r/innodb_mysql.result mysql-test/r/lock.result mysql-test/r/locktrans_innodb.result mysql-test/r/locktrans_myisam.result mysql-test/r/mix2_myisam.result mysql-test/r/partition_innodb_semi_consistent.result mysql-test/r/read_only_innodb.result mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result mysql-test/suite/falcon/r/falcon_bugs2.result mysql-test/suite/falcon/t/disabled.def mysql-test/suite/falcon/t/falcon_bugs2.test mysql-test/suite/ndb/r/ndb_index_ordered.result mysql-test/suite/ndb/t/disabled.def mysql-test/suite/ndb/t/ndb_index_ordered.test mysql-test/suite/rpl/r/rpl_locktrans_falcon.result mysql-test/suite/rpl/r/rpl_locktrans_innodb.result mysql-test/suite/rpl/r/rpl_locktrans_myisam.result mysql-test/suite/rpl/t/disabled.def mysql-test/suite/sys_vars/t/autocommit_func.test mysql-test/t/flush_block_commit.test mysql-test/t/flush_block_commit_notembedded.test mysql-test/t/innodb.test mysql-test/t/lock.test mysql-test/t/partition_innodb_semi_consistent.test mysql-test/t/read_only_innodb.test mysql-test/t/xa.test sql/log_event.cc sql/mysql_priv.h sql/rpl_injector.cc sql/rpl_rli.cc sql/set_var.cc sql/slave.cc sql/sql_acl.cc sql/sql_base.cc sql/sql_class.cc sql/sql_parse.cc sql/sql_servers.cc sql/sql_table.cc sql/transaction.cc === added file 'mysql-test/extra/binlog_tests/drop_table.test' --- a/mysql-test/extra/binlog_tests/drop_table.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/extra/binlog_tests/drop_table.test 2009-03-06 22:17:00 +0000 @@ -0,0 +1,34 @@ +# +# Bug#989: If DROP TABLE while there's an active transaction, wrong binlog order +# + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +RESET MASTER; +CREATE TABLE t1 (a INT); +SET AUTOCOMMIT=OFF; +BEGIN; +INSERT INTO t1 VALUES(1); + +connection con2; +--send DROP TABLE t1; + +connection con1; +COMMIT; + +connection con2; +--reap + +connection default; + +--disconnect con1 +--disconnect con2 + +let $VERSION=`select version()`; +source include/show_binlog_events.inc; === modified file 'mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test' --- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test 2008-07-22 14:16:22 +0000 +++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test 2009-03-06 22:17:00 +0000 @@ -204,6 +204,10 @@ select (@after:=unix_timestamp())*0; # a # the bug, the reap would return immediately after the insert into t2. select (@after-@before) >= 2; +connection con3; +commit; + +connection con2; drop table t1,t2; commit; === modified file 'mysql-test/include/locktrans.inc' --- a/mysql-test/include/locktrans.inc 2008-05-23 13:54:03 +0000 +++ b/mysql-test/include/locktrans.inc 2009-03-06 22:17:00 +0000 @@ -1050,6 +1050,19 @@ COMMIT; DROP TRIGGER t1_ai; } +--echo # +--echo # WL#4284: Transactional DDL locking +--echo # + +SET AUTOCOMMIT= 0; +LOCK TABLES t1 WRITE, t2 WRITE; +SAVEPOINT sp1; +INSERT INTO t1 VALUES (1); +SAVEPOINT sp2; +INSERT INTO t2 VALUES (2); +ROLLBACK TO SAVEPOINT sp1; +UNLOCK TABLES; + # --echo ## Cleanup. connection default; === modified file 'mysql-test/include/mix1.inc' --- a/mysql-test/include/mix1.inc 2009-02-02 15:58:48 +0000 +++ b/mysql-test/include/mix1.inc 2009-03-06 22:17:00 +0000 @@ -1331,6 +1331,7 @@ SELECT * FROM t1; connection con2; --reap SELECT * FROM t1; +COMMIT; --echo # Switch to connection con1 connection con1; === modified file 'mysql-test/include/mix2.inc' --- a/mysql-test/include/mix2.inc 2007-06-06 17:57:07 +0000 +++ b/mysql-test/include/mix2.inc 2009-03-06 22:17:00 +0000 @@ -1994,6 +1994,7 @@ commit; connection b; set autocommit = 0; update t1 set b = 5 where a = 2; +commit; connection a; delimiter |; create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end | @@ -2056,6 +2057,7 @@ update t2 set b = b + 5 where a = 1; update t3 set b = b + 5 where a = 1; update t4 set b = b + 5 where a = 1; insert into t5(a) values(20); +commit; connection b; set autocommit = 0; insert into t1(a) values(7); === modified file 'mysql-test/r/flush_block_commit.result' --- a/mysql-test/r/flush_block_commit.result 2006-12-26 16:22:17 +0000 +++ b/mysql-test/r/flush_block_commit.result 2009-03-06 22:17:00 +0000 @@ -2,12 +2,11 @@ drop table if exists t1; create table t1 (a int) engine=innodb; begin; insert into t1 values(1); -flush tables with read lock; -select * from t1; -a +flush tables with read lock;; commit; select * from t1; a +1 unlock tables; begin; select * from t1 for update; @@ -19,13 +18,12 @@ flush tables with read lock; commit; a 1 +commit; unlock tables; commit; begin; insert into t1 values(10); flush tables with read lock; -commit; -unlock tables; flush tables with read lock; unlock tables; begin; @@ -36,4 +34,10 @@ a show create database test; Database Create Database test CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ +commit; +flush tables with read lock; +begin; +insert into t1 values (1);; +unlock tables; +commit; drop table t1; === modified file 'mysql-test/r/flush_block_commit_notembedded.result' --- a/mysql-test/r/flush_block_commit_notembedded.result 2008-02-03 09:00:49 +0000 +++ b/mysql-test/r/flush_block_commit_notembedded.result 2009-03-06 22:17:00 +0000 @@ -1,12 +1,14 @@ create table t1 (a int) engine=innodb; reset master; set autocommit=0; -insert t1 values (1); +select 1; +1 +1 flush tables with read lock; show master status; File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000001 107 -commit; +insert into t1 values (1); show master status; File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000001 107 === modified file 'mysql-test/r/innodb.result' --- a/mysql-test/r/innodb.result 2009-02-13 16:30:54 +0000 +++ b/mysql-test/r/innodb.result 2009-03-06 22:17:00 +0000 @@ -2819,10 +2819,10 @@ t2 CREATE TABLE `t2` ( DROP TABLE t2,t1; create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb; insert into t1(a) values (1),(2),(3); +create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end | commit; set autocommit = 0; update t1 set b = 5 where a = 2; -create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end | set autocommit = 0; insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100), (11),(21),(31),(41),(51),(61),(71),(81),(91),(101), @@ -2870,6 +2870,7 @@ insert into t2(a) values(8); delete from t2 where a = 3; update t4 set b = b + 1 where a = 3; commit; +commit; drop trigger t1t; drop trigger t2t; drop trigger t3t; === modified file 'mysql-test/r/innodb_mysql.result' --- a/mysql-test/r/innodb_mysql.result 2009-02-12 18:27:05 +0000 +++ b/mysql-test/r/innodb_mysql.result 2009-03-06 22:17:00 +0000 @@ -1564,6 +1564,7 @@ a b SELECT * FROM t1; a b 1 init+con1+con2 +COMMIT; # Switch to connection con1 # 3. test for updated key column: TRUNCATE t1; === modified file 'mysql-test/r/lock.result' --- a/mysql-test/r/lock.result 2008-10-21 23:12:53 +0000 +++ b/mysql-test/r/lock.result 2009-03-06 22:17:00 +0000 @@ -235,5 +235,17 @@ unlock tables; drop table t1; drop view v1; # +# WL#4284: Transactional DDL locking +# +# FLUSH PRIVILEGES should not implicitly unlock locked tables. +# +drop table if exists t1; +create table t1 (c1 int); +lock tables t1 read; +flush privileges; +ERROR HY000: Table 'host' was not locked with LOCK TABLES +unlock tables; +drop table t1; +# # End of 6.0 tests. # === modified file 'mysql-test/r/locktrans_innodb.result' --- a/mysql-test/r/locktrans_innodb.result 2008-12-24 10:48:24 +0000 +++ b/mysql-test/r/locktrans_innodb.result 2009-03-06 22:17:00 +0000 @@ -920,6 +920,17 @@ TRUNCATE t1; TRUNCATE t2; COMMIT; DROP TRIGGER t1_ai; +# +# WL#4284: Transactional DDL locking +# +SET AUTOCOMMIT= 0; +LOCK TABLES t1 WRITE, t2 WRITE; +SAVEPOINT sp1; +INSERT INTO t1 VALUES (1); +SAVEPOINT sp2; +INSERT INTO t2 VALUES (2); +ROLLBACK TO SAVEPOINT sp1; +UNLOCK TABLES; ## Cleanup. SET AUTOCOMMIT= 1; UNLOCK TABLES; === modified file 'mysql-test/r/locktrans_myisam.result' --- a/mysql-test/r/locktrans_myisam.result 2008-12-24 10:48:24 +0000 +++ b/mysql-test/r/locktrans_myisam.result 2009-03-06 22:17:00 +0000 @@ -392,6 +392,19 @@ ERROR 0A000: LOCK is not allowed in stor CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW LOCK TABLE t2 IN EXCLUSIVE MODE; ERROR 0A000: LOCK is not allowed in stored procedures +# +# WL#4284: Transactional DDL locking +# +SET AUTOCOMMIT= 0; +LOCK TABLES t1 WRITE, t2 WRITE; +SAVEPOINT sp1; +INSERT INTO t1 VALUES (1); +SAVEPOINT sp2; +INSERT INTO t2 VALUES (2); +ROLLBACK TO SAVEPOINT sp1; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +UNLOCK TABLES; ## Cleanup. SET AUTOCOMMIT= 1; UNLOCK TABLES; === modified file 'mysql-test/r/mix2_myisam.result' --- a/mysql-test/r/mix2_myisam.result 2008-10-20 09:16:47 +0000 +++ b/mysql-test/r/mix2_myisam.result 2009-03-06 22:17:00 +0000 @@ -2063,6 +2063,7 @@ insert into t1(a) values (1),(2),(3); commit; set autocommit = 0; update t1 set b = 5 where a = 2; +commit; create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end | set autocommit = 0; insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100), @@ -2105,6 +2106,7 @@ update t2 set b = b + 5 where a = 1; update t3 set b = b + 5 where a = 1; update t4 set b = b + 5 where a = 1; insert into t5(a) values(20); +commit; set autocommit = 0; insert into t1(a) values(7); insert into t2(a) values(8); === modified file 'mysql-test/r/partition_innodb_semi_consistent.result' --- a/mysql-test/r/partition_innodb_semi_consistent.result 2009-01-13 22:12:16 +0000 +++ b/mysql-test/r/partition_innodb_semi_consistent.result 2009-03-06 22:17:00 +0000 @@ -102,7 +102,7 @@ a b # Switch to connection con1 # 3. test for updated key column: TRUNCATE t1; -TRUNCATE t2; +DELETE FROM t2; INSERT INTO t1 VALUES (1,'init'); BEGIN; UPDATE t1 SET a = 2, b = CONCAT(b, '+con1') WHERE a = 1; === modified file 'mysql-test/r/read_only_innodb.result' --- a/mysql-test/r/read_only_innodb.result 2008-04-08 05:20:58 +0000 +++ b/mysql-test/r/read_only_innodb.result 2009-03-06 22:17:00 +0000 @@ -7,12 +7,10 @@ insert into table_11733 values(11733); set global read_only=1; select @@global.read_only; @@global.read_only -1 +0 select * from table_11733 ; -a -11733 +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction COMMIT; -ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement set global read_only=0; drop table table_11733 ; drop user test@localhost; === added file 'mysql-test/suite/binlog/r/binlog_row_drop_tbl.result' --- a/mysql-test/suite/binlog/r/binlog_row_drop_tbl.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/binlog/r/binlog_row_drop_tbl.result 2009-03-06 22:17:00 +0000 @@ -0,0 +1,16 @@ +DROP TABLE IF EXISTS t1; +RESET MASTER; +CREATE TABLE t1 (a INT); +SET AUTOCOMMIT=OFF; +BEGIN; +INSERT INTO t1 VALUES(1); +DROP TABLE t1;; +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT) +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # use `test`; DROP TABLE t1 === modified file 'mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result' --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result 2009-02-10 14:46:07 +0000 +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result 2009-03-06 22:17:00 +0000 @@ -232,6 +232,7 @@ select (@after:=unix_timestamp())*0; select (@after-@before) >= 2; (@after-@before) >= 2 1 +commit; drop table t1,t2; commit; begin; @@ -272,6 +273,10 @@ master-bin.000001 # Query # # use `test` master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; COMMIT master-bin.000001 # Query # # use `test`; drop table t1,t2 master-bin.000001 # Query # # use `test`; create table t0 (n int) master-bin.000001 # Query # # use `test`; BEGIN === added file 'mysql-test/suite/binlog/r/binlog_stm_drop_tbl.result' --- a/mysql-test/suite/binlog/r/binlog_stm_drop_tbl.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/binlog/r/binlog_stm_drop_tbl.result 2009-03-06 22:17:00 +0000 @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS t1; +RESET MASTER; +CREATE TABLE t1 (a INT); +SET AUTOCOMMIT=OFF; +BEGIN; +INSERT INTO t1 VALUES(1); +DROP TABLE t1;; +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT) +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES(1) +master-bin.000001 # Query # # use `test`; DROP TABLE t1 === modified file 'mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result' --- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2009-02-10 14:46:07 +0000 +++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2009-03-06 22:17:00 +0000 @@ -207,6 +207,7 @@ select (@after:=unix_timestamp())*0; select (@after-@before) >= 2; (@after-@before) >= 2 1 +commit; drop table t1,t2; commit; begin; === added file 'mysql-test/suite/binlog/t/binlog_row_drop_tbl.test' --- a/mysql-test/suite/binlog/t/binlog_row_drop_tbl.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/binlog/t/binlog_row_drop_tbl.test 2009-03-06 22:17:00 +0000 @@ -0,0 +1,5 @@ +# This is a wrapper for drop_table.test so that the same test case can be used +# For both statement and row based bin logs + +-- source include/have_binlog_format_row.inc +-- source extra/binlog_tests/drop_table.test === added file 'mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test' --- a/mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test 2009-03-06 22:17:00 +0000 @@ -0,0 +1,5 @@ +# This is a wrapper for drop_table.test so that the same test case can be used +# For both statement and row based bin logs + +-- source include/have_binlog_format_mixed_or_statement.inc +-- source extra/binlog_tests/drop_table.test === modified file 'mysql-test/suite/falcon/r/falcon_bugs2.result' --- a/mysql-test/suite/falcon/r/falcon_bugs2.result 2007-09-20 15:44:25 +0000 +++ b/mysql-test/suite/falcon/r/falcon_bugs2.result 2009-03-06 22:17:00 +0000 @@ -290,6 +290,7 @@ SET autocommit=0; SELECT * FROM t1; a DROP TABLE t1; +COMMIT; ***************** falcon_bugs2_022 ***************** SET autocommit=0; SET tx_isolation="READ-COMMITTED"; @@ -306,6 +307,8 @@ a SELECT * FROM t1; a 1 +COMMIT; +COMMIT; DROP TABLE t1; ***************** falcon_bugs2_023 ***************** CREATE TABLE t1 (a int); === modified file 'mysql-test/suite/falcon/t/disabled.def' --- a/mysql-test/suite/falcon/t/disabled.def 2009-02-25 13:15:43 +0000 +++ b/mysql-test/suite/falcon/t/disabled.def 2009-03-06 22:17:00 +0000 @@ -11,3 +11,5 @@ ############################################################################## falcon_unicode-big : Bug#43182 2009-02-25 hakank Disabled until licensing details of UnicodeData.txt are cleared +falcon_bug_22972 : WL#4284: Can't drop table used by a pending transaction (there is metadata lock on the table). +falcon_bug_24024 : WL#4284: Can't drop table used by a pending transaction (there is metadata lock on the table). === modified file 'mysql-test/suite/falcon/t/falcon_bugs2.test' --- a/mysql-test/suite/falcon/t/falcon_bugs2.test 2009-01-07 10:41:07 +0000 +++ b/mysql-test/suite/falcon/t/falcon_bugs2.test 2009-03-06 22:17:00 +0000 @@ -512,7 +512,11 @@ SELECT * FROM t1; # Final cleanup connection default; -DROP TABLE t1; +send DROP TABLE t1; +connection con1; +COMMIT; +connection default; +--reap --disconnect con1 # @@ -539,6 +543,10 @@ SELECT * FROM t1; connection con1; SELECT * FROM t1; +COMMIT; + +connection default; +COMMIT; # Final cleanup DROP TABLE t1; === modified file 'mysql-test/suite/ndb/r/ndb_index_ordered.result' --- a/mysql-test/suite/ndb/r/ndb_index_ordered.result 2007-06-27 12:28:02 +0000 +++ b/mysql-test/suite/ndb/r/ndb_index_ordered.result 2009-03-06 22:17:00 +0000 @@ -637,21 +637,6 @@ select count(*)- 4 from t1 use index (v) count(*)- 4 0 drop table t1; -create table t1(a int primary key, b int not null, index(b)); -insert into t1 values (1,1), (2,2); -set autocommit=0; -begin; -select count(*) from t1; -count(*) -2 -ALTER TABLE t1 ADD COLUMN c int; -select a from t1 where b = 2; -a -2 -show tables; -Tables_in_test -t1 -drop table t1; create table t1 (a int, c varchar(10), primary key using hash (a), index(c)) engine=ndb; insert into t1 (a, c) values (1,'aaa'),(3,'bbb'); === modified file 'mysql-test/suite/ndb/t/disabled.def' --- a/mysql-test/suite/ndb/t/disabled.def 2009-02-13 16:18:07 +0000 +++ b/mysql-test/suite/ndb/t/disabled.def 2009-03-06 22:17:00 +0000 @@ -14,3 +14,5 @@ ndb_partition_error2 : Bug#40989 msven # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open #ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events ndb_cache_trans : Bug#42565 ndb_cache_trans failure since SERVER_STATUS_IN_TRANS added to hash key +ndb_alter_table_online : WL#4284: Needs to be reworked, tries to alter table used by a pending transaction. +ndb_alter_table3 : WL#4284: Needs to be reworked, tries to alter table used by a pending transaction. === modified file 'mysql-test/suite/ndb/t/ndb_index_ordered.test' --- a/mysql-test/suite/ndb/t/ndb_index_ordered.test 2007-07-04 20:38:53 +0000 +++ b/mysql-test/suite/ndb/t/ndb_index_ordered.test 2009-03-06 22:17:00 +0000 @@ -333,21 +333,29 @@ select count(*)- 4 from t1 use index (v) drop table t1; +# +# Disabled due to WL#4284 +# +# Needs to be reworked. It's not possible anymore to do a non-fast alter table +# on a table that is being used by a pending transaction (transaction holds a +# metadata lock on the table). +# # bug#7798 -create table t1(a int primary key, b int not null, index(b)); -insert into t1 values (1,1), (2,2); -connect (con1,localhost,root,,test); -connect (con2,localhost,root,,test); -connection con1; -set autocommit=0; -begin; -select count(*) from t1; -connection con2; -ALTER TABLE t1 ADD COLUMN c int; -connection con1; -select a from t1 where b = 2; -show tables; -drop table t1; +# create table t1(a int primary key, b int not null, c int, index(b)); +# insert into t1 values (1,1,1), (2,2,2); +# connect (con1,localhost,root,,test); +# connect (con2,localhost,root,,test); +# connection con1; +# set autocommit=0; +# begin; +# select count(*) from t1; +# connection con2; +# ALTER TABLE t1 ADD COLUMN c int +# connection con1; +# select a from t1 where b = 2; +# show tables; +# drop table t1; +# # mysqld 5.0.13 crash, no bug# create table t1 (a int, c varchar(10), === modified file 'mysql-test/suite/rpl/r/rpl_locktrans_falcon.result' --- a/mysql-test/suite/rpl/r/rpl_locktrans_falcon.result 2008-12-15 12:41:31 +0000 +++ b/mysql-test/suite/rpl/r/rpl_locktrans_falcon.result 2009-03-06 22:17:00 +0000 @@ -394,6 +394,17 @@ ERROR 0A000: LOCK is not allowed in stor CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW LOCK TABLE t2 IN EXCLUSIVE MODE; ERROR 0A000: LOCK is not allowed in stored procedures +# +# WL#4284: Transactional DDL locking +# +SET AUTOCOMMIT= 0; +LOCK TABLES t1 WRITE, t2 WRITE; +SAVEPOINT sp1; +INSERT INTO t1 VALUES (1); +SAVEPOINT sp2; +INSERT INTO t2 VALUES (2); +ROLLBACK TO SAVEPOINT sp1; +UNLOCK TABLES; ## Cleanup. SET AUTOCOMMIT= 1; UNLOCK TABLES; === modified file 'mysql-test/suite/rpl/r/rpl_locktrans_innodb.result' --- a/mysql-test/suite/rpl/r/rpl_locktrans_innodb.result 2009-01-26 16:03:39 +0000 +++ b/mysql-test/suite/rpl/r/rpl_locktrans_innodb.result 2009-03-06 22:17:00 +0000 @@ -926,6 +926,17 @@ TRUNCATE t1; TRUNCATE t2; COMMIT; DROP TRIGGER t1_ai; +# +# WL#4284: Transactional DDL locking +# +SET AUTOCOMMIT= 0; +LOCK TABLES t1 WRITE, t2 WRITE; +SAVEPOINT sp1; +INSERT INTO t1 VALUES (1); +SAVEPOINT sp2; +INSERT INTO t2 VALUES (2); +ROLLBACK TO SAVEPOINT sp1; +UNLOCK TABLES; ## Cleanup. SET AUTOCOMMIT= 1; UNLOCK TABLES; === modified file 'mysql-test/suite/rpl/r/rpl_locktrans_myisam.result' --- a/mysql-test/suite/rpl/r/rpl_locktrans_myisam.result 2008-12-24 10:48:24 +0000 +++ b/mysql-test/suite/rpl/r/rpl_locktrans_myisam.result 2009-03-06 22:17:00 +0000 @@ -439,6 +439,19 @@ ERROR 0A000: LOCK is not allowed in stor CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW LOCK TABLE t2 IN EXCLUSIVE MODE; ERROR 0A000: LOCK is not allowed in stored procedures +# +# WL#4284: Transactional DDL locking +# +SET AUTOCOMMIT= 0; +LOCK TABLES t1 WRITE, t2 WRITE; +SAVEPOINT sp1; +INSERT INTO t1 VALUES (1); +SAVEPOINT sp2; +INSERT INTO t2 VALUES (2); +ROLLBACK TO SAVEPOINT sp1; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +UNLOCK TABLES; ## Cleanup. SET AUTOCOMMIT= 1; UNLOCK TABLES; === modified file 'mysql-test/suite/rpl/t/disabled.def' --- a/mysql-test/suite/rpl/t/disabled.def 2009-02-14 11:23:14 +0000 +++ b/mysql-test/suite/rpl/t/disabled.def 2009-03-06 22:17:00 +0000 @@ -17,3 +17,5 @@ rpl_binlog_corruption : BUG#41793 2 rpl_extraCol_falcon : Bug#40930 2008-11-21 johnemb rpl.rpl_extraCol_falcon fails doing STOP SLAVE (on Windows PB2) rpl_cross_version : Bug#42311 2009-01-23 aelkin rpl_log_pos : Bug#42858 2009-02-14 alik rpl.rpl_log_pos fails, thus was disabled +rpl_failed_optimize : WL#4284: Can't optimize table used by a pending transaction (there is metadata lock on the table). +rpl_read_only : WL#4284: Setting Read only won't succeed until all metadata locks are released. === modified file 'mysql-test/suite/sys_vars/t/autocommit_func.test' --- a/mysql-test/suite/sys_vars/t/autocommit_func.test 2008-12-19 15:12:15 +0000 +++ b/mysql-test/suite/sys_vars/t/autocommit_func.test 2009-03-06 22:17:00 +0000 @@ -153,6 +153,10 @@ SELECT * from t1; CONNECTION test_con2; SELECT * from t1; +--echo ## Commit changes +CONNECTION test_con1; +COMMIT; + --echo ## Dropping table t1 ## DROP table t1; === modified file 'mysql-test/t/flush_block_commit.test' --- a/mysql-test/t/flush_block_commit.test 2006-12-26 16:22:17 +0000 +++ b/mysql-test/t/flush_block_commit.test 2009-03-06 22:17:00 +0000 @@ -21,16 +21,13 @@ create table t1 (a int) engine=innodb; begin; insert into t1 values(1); connection con2; -flush tables with read lock; -select * from t1; +--send flush tables with read lock; connection con1; -send commit; # blocked by con2 -sleep 1; +commit; connection con2; -select * from t1; # verify con1 was blocked and data did not move +--reap +select * from t1; unlock tables; -connection con1; -reap; # No deadlock ? @@ -47,6 +44,7 @@ connection con1; commit; # should not be blocked by con3 connection con2; reap; +commit; connection con3; reap; unlock tables; @@ -60,8 +58,6 @@ connection con1; begin; insert into t1 values(10); flush tables with read lock; -commit; -unlock tables; connection con2; flush tables with read lock; # bug caused hang here unlock tables; @@ -71,6 +67,24 @@ unlock tables; begin; select * from t1; show create database test; +commit; + +# GLR blocks new transactions +connection con1; +flush tables with read lock; +connection con2; +begin; +--send insert into t1 values (1); +connection con1; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for release of readlock" and + info = "insert into t1 values (1)"; +--source include/wait_condition.inc +unlock tables; +connection con2; +--reap +commit; drop table t1; === modified file 'mysql-test/t/flush_block_commit_notembedded.test' --- a/mysql-test/t/flush_block_commit_notembedded.test 2007-06-15 16:56:11 +0000 +++ b/mysql-test/t/flush_block_commit_notembedded.test 2009-03-06 22:17:00 +0000 @@ -17,12 +17,12 @@ connection con1; create table t1 (a int) engine=innodb; reset master; set autocommit=0; -insert t1 values (1); +select 1; connection con2; flush tables with read lock; show master status; connection con1; -send commit; +send insert into t1 values (1); connection con2; sleep 1; show master status; === modified file 'mysql-test/t/innodb.test' --- a/mysql-test/t/innodb.test 2009-01-26 16:32:29 +0000 +++ b/mysql-test/t/innodb.test 2009-03-06 22:17:00 +0000 @@ -1797,16 +1797,15 @@ connect (b,localhost,root,,); connection a; create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb; insert into t1(a) values (1),(2),(3); +delimiter |; +create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end | +delimiter ;| commit; connection b; set autocommit = 0; update t1 set b = 5 where a = 2; connection a; -delimiter |; -create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end | -delimiter ;| set autocommit = 0; -connection a; insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100), (11),(21),(31),(41),(51),(61),(71),(81),(91),(101), (12),(22),(32),(42),(52),(62),(72),(82),(92),(102), @@ -1870,6 +1869,9 @@ insert into t2(a) values(8); delete from t2 where a = 3; update t4 set b = b + 1 where a = 3; commit; +connection a; +commit; +connection b; drop trigger t1t; drop trigger t2t; drop trigger t3t; === modified file 'mysql-test/t/lock.test' --- a/mysql-test/t/lock.test 2008-10-21 23:12:53 +0000 +++ b/mysql-test/t/lock.test 2009-03-06 22:17:00 +0000 @@ -281,5 +281,20 @@ drop table t1; drop view v1; --echo # +--echo # WL#4284: Transactional DDL locking +--echo # +--echo # FLUSH PRIVILEGES should not implicitly unlock locked tables. +--echo # +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (c1 int); +lock tables t1 read; +--error ER_TABLE_NOT_LOCKED +flush privileges; +unlock tables; +drop table t1; + +--echo # --echo # End of 6.0 tests. --echo # === modified file 'mysql-test/t/partition_innodb_semi_consistent.test' --- a/mysql-test/t/partition_innodb_semi_consistent.test 2009-01-13 22:12:16 +0000 +++ b/mysql-test/t/partition_innodb_semi_consistent.test 2009-03-06 22:17:00 +0000 @@ -157,7 +157,7 @@ connection con1; --echo # 3. test for updated key column: TRUNCATE t1; -TRUNCATE t2; +DELETE FROM t2; INSERT INTO t1 VALUES (1,'init'); === modified file 'mysql-test/t/read_only_innodb.test' --- a/mysql-test/t/read_only_innodb.test 2008-04-08 05:20:58 +0000 +++ b/mysql-test/t/read_only_innodb.test 2009-03-06 22:17:00 +0000 @@ -28,15 +28,16 @@ BEGIN; insert into table_11733 values(11733); connection default; -set global read_only=1; +send set global read_only=1; connection con1; select @@global.read_only; +-- error ER_LOCK_DEADLOCK select * from table_11733 ; --- error ER_OPTION_PREVENTS_STATEMENT COMMIT; connection default; +reap; set global read_only=0; drop table table_11733 ; drop user test@localhost; === modified file 'mysql-test/t/xa.test' --- a/mysql-test/t/xa.test 2008-10-23 20:56:03 +0000 +++ b/mysql-test/t/xa.test 2009-03-06 22:17:00 +0000 @@ -72,9 +72,10 @@ xa rollback 'testa','testb'; xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'; select * from t1; -drop table t1; disconnect con1; +connection default; +drop table t1; # # Bug#28323: Server crashed in xid cache operations === modified file 'sql/log_event.cc' --- a/sql/log_event.cc 2009-03-04 13:33:47 +0000 +++ b/sql/log_event.cc 2009-03-06 22:17:00 +0000 @@ -5181,10 +5181,17 @@ void Xid_log_event::print(FILE* file, PR #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) int Xid_log_event::do_apply_event(Relay_log_info const *rli) { + bool res; /* For a slave Xid_log_event is COMMIT */ general_log_print(thd, COM_QUERY, "COMMIT /* implicit, from Xid_log_event */"); - return trans_commit(thd); + if (!(res= trans_commit(thd))) + { + close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); + } + return res; } Log_event::enum_skip_reason === modified file 'sql/mysql_priv.h' --- a/sql/mysql_priv.h 2009-02-23 14:53:18 +0000 +++ b/sql/mysql_priv.h 2009-03-06 22:17:00 +0000 @@ -792,7 +792,7 @@ extern my_decimal decimal_zero; void free_items(Item *item); void cleanup_items(Item *item); class THD; -void close_thread_tables(THD *thd, bool skip_mdl= 0); +void close_thread_tables(THD *thd, bool is_back_off= 0); #ifndef NO_EMBEDDED_ACCESS_CHECKS bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables); === modified file 'sql/rpl_injector.cc' --- a/sql/rpl_injector.cc 2008-12-13 11:02:16 +0000 +++ b/sql/rpl_injector.cc 2009-03-06 22:17:00 +0000 @@ -83,17 +83,25 @@ int injector::transaction::commit() explicitly. */ trans_commit_stmt(m_thd); - trans_commit(m_thd); + if (!trans_commit(m_thd)) + { + close_thread_tables(m_thd); + if (!m_thd->locked_tables_mode) + m_thd->mdl_context.release_all_locks(); + } DBUG_RETURN(0); } int injector::transaction::rollback() { DBUG_ENTER("injector::transaction::rollback()"); - //psergey ha_autocommit_or_rollback(m_thd, 1 /* error to get rollback */); trans_rollback_stmt(m_thd); - //psergey end_trans(m_thd, ROLLBACK); - trans_rollback(m_thd); + if (!trans_rollback(m_thd)) + { + close_thread_tables(m_thd); + if (!m_thd->locked_tables_mode) + m_thd->mdl_context.release_all_locks(); + } DBUG_RETURN(0); } === modified file 'sql/rpl_rli.cc' --- a/sql/rpl_rli.cc 2009-03-04 13:31:31 +0000 +++ b/sql/rpl_rli.cc 2009-03-06 22:17:00 +0000 @@ -1170,6 +1170,8 @@ void Relay_log_info::cleanup_context(THD } m_table_map.clear_tables(); slave_close_thread_tables(thd); + if (error && !thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); clear_flag(IN_STMT); /* Cleanup for the flags that have been set at do_apply_event. @@ -1182,13 +1184,6 @@ void Relay_log_info::cleanup_context(THD void Relay_log_info::clear_tables_to_lock() { - /* - Deallocating elements of table list below will also free memory where - meta-data locks are stored. So we want to be sure that we don't have - any references to this memory left. - */ - DBUG_ASSERT(!current_thd->mdl_context.has_locks()); - while (tables_to_lock) { uchar* to_free= reinterpret_cast(tables_to_lock); @@ -1207,12 +1202,6 @@ void Relay_log_info::clear_tables_to_loc void Relay_log_info::slave_close_thread_tables(THD *thd) { - /* - Since we use same memory chunks for allocation of metadata lock - objects for tables as we use for allocating corresponding elements - of 'tables_to_lock' list, we have to release metadata locks by - closing tables before calling clear_tables_to_lock(). - */ close_thread_tables(thd); clear_tables_to_lock(); } === modified file 'sql/set_var.cc' --- a/sql/set_var.cc 2009-03-04 10:04:58 +0000 +++ b/sql/set_var.cc 2009-03-06 22:17:00 +0000 @@ -3497,9 +3497,15 @@ static bool set_option_autocommit(THD *t need to commit any outstanding transactions. */ if (var->save_result.ulong_value != 0 && - (thd->options & OPTION_NOT_AUTOCOMMIT) && - trans_commit(thd)) - return 1; + (thd->options & OPTION_NOT_AUTOCOMMIT)) + { + if (trans_commit(thd)) + return TRUE; + + close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); + } if (var->save_result.ulong_value != 0) thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag; === modified file 'sql/slave.cc' --- a/sql/slave.cc 2009-02-23 14:53:18 +0000 +++ b/sql/slave.cc 2009-03-06 22:17:00 +0000 @@ -2162,6 +2162,9 @@ static int exec_relay_log_event(THD* thd { exec_res= 0; trans_rollback(thd); + close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); /* chance for concurrent connection to get more locks */ safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE), (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli); === modified file 'sql/sql_acl.cc' --- a/sql/sql_acl.cc 2009-03-04 10:04:58 +0000 +++ b/sql/sql_acl.cc 2009-03-06 22:17:00 +0000 @@ -30,6 +30,7 @@ #include #include "sp_head.h" #include "sp.h" +#include "transaction.h" time_t mysql_db_table_last_check= 0L; @@ -676,9 +677,6 @@ my_bool acl_reload(THD *thd) my_bool return_val= 1; DBUG_ENTER("acl_reload"); - /* Can't have locked tables here. */ - thd->locked_tables_list.unlock_locked_tables(thd); - /* To avoid deadlocks we should obtain table locks before obtaining acl_cache->lock mutex. @@ -732,7 +730,10 @@ my_bool acl_reload(THD *thd) if (old_initialized) pthread_mutex_unlock(&acl_cache->lock); end: + trans_commit_implicit(thd); close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); DBUG_RETURN(return_val); } @@ -3823,7 +3824,10 @@ my_bool grant_reload(THD *thd) free_root(&old_mem,MYF(0)); } rw_unlock(&LOCK_grant); + trans_commit_implicit(thd); close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); /* It is OK failing to load procs_priv table because we may be === modified file 'sql/sql_base.cc' --- a/sql/sql_base.cc 2009-03-04 13:33:47 +0000 +++ b/sql/sql_base.cc 2009-03-06 22:17:00 +0000 @@ -1475,11 +1475,22 @@ void close_thread_tables(THD *thd, if (thd->open_tables) close_open_tables(thd); - thd->mdl_context.release_all_locks(); if (!is_back_off) { thd->mdl_context.remove_all_requests(); } + + /* + Defer the release of metadata locks until the current transaction + is either committed or rolled back. This prevents other statements + from modifying the table for the entire duration of this transaction. + This provides commitment ordering for guaranteeing serializability + across multiple transactions. + */ + if (!thd->in_multi_stmt_transaction() || + (thd->state_flags & Open_tables_state::BACKUPS_AVAIL)) + thd->mdl_context.release_all_locks(); + DBUG_VOID_RETURN; } @@ -3618,6 +3629,7 @@ int open_tables(THD *thd, TABLE_LIST **s /* Also used for indicating that prelocking is need */ TABLE_LIST **query_tables_last_own; bool safe_to_ignore_table; + bool has_locks= thd->mdl_context.has_locks(); DBUG_ENTER("open_tables"); /* @@ -3759,6 +3771,18 @@ int open_tables(THD *thd, TABLE_LIST **s if (action) { /* + We have met a exclusive metadata lock or a old version of table and + we are inside a transaction that already hold locks. We can't follow + the locking protocol in this scenario as it might lead to deadlocks. + */ + if (thd->in_multi_stmt_transaction() && has_locks) + { + my_error(ER_LOCK_DEADLOCK, MYF(0)); + result= -1; + goto err; + } + + /* We have met exclusive metadata lock or old version of table. Now we have to close all tables which are not up to date/release metadata locks. We also have to throw away set of prelocked tables (and thus @@ -4625,6 +4649,8 @@ void close_tables_for_reopen(THD *thd, T for (TABLE_LIST *tmp= *tables; tmp; tmp= tmp->next_global) tmp->table= 0; close_thread_tables(thd, is_back_off); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); } === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2009-03-04 13:33:47 +0000 +++ b/sql/sql_class.cc 2009-03-06 22:17:00 +0000 @@ -946,6 +946,17 @@ void THD::cleanup(void) trans_rollback(this); xid_cache_delete(&transaction.xid_state); } + + /* + Thread could be in the middle of a ongoing transaction + that just got rolled back. Release any metadata locks. + */ + if (!locked_tables_mode) + { + DBUG_ASSERT(open_tables == NULL); + mdl_context.release_all_locks(); + } + locked_tables_list.unlock_locked_tables(this); #if defined(ENABLED_DEBUG_SYNC) === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2009-03-04 13:33:47 +0000 +++ b/sql/sql_parse.cc 2009-03-06 22:17:00 +0000 @@ -133,11 +133,11 @@ static bool some_non_temp_table_to_be_up @param mask Bitmask used for the SQL command match. */ -static bool opt_implicit_commit(THD *thd, uint mask) +static bool stmt_causes_implicit_commit(THD *thd, uint mask) { LEX *lex= thd->lex; - bool res= FALSE, skip= FALSE; - DBUG_ENTER("opt_implicit_commit"); + bool skip= FALSE; + DBUG_ENTER("stmt_causes_implicit_commit"); if (!(sql_command_flags[lex->sql_command] & mask)) DBUG_RETURN(FALSE); @@ -158,15 +158,7 @@ static bool opt_implicit_commit(THD *thd break; } - if (!skip) - { - /* Commit or rollback the statement transaction. */ - thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd); - /* Commit the normal transaction if one is active. */ - res= trans_commit_implicit(thd); - } - - DBUG_RETURN(res); + DBUG_RETURN(!skip); } @@ -1225,6 +1217,9 @@ bool dispatch_command(enum enum_server_c ulong options= (ulong) (uchar) packet[0]; if (trans_commit_implicit(thd)) break; + close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); if (check_global_access(thd,RELOAD_ACL)) break; general_log_print(thd, command, NullS); @@ -1232,6 +1227,9 @@ bool dispatch_command(enum enum_server_c break; if (trans_commit_implicit(thd)) break; + close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); my_ok(thd); break; } @@ -1997,8 +1995,18 @@ mysql_execute_command(THD *thd) not run in it's own transaction it may simply never appear on the slave in case the outside transaction rolls back. */ - if (opt_implicit_commit(thd, CF_IMPLICT_COMMIT_BEGIN)) - goto error; + if (stmt_causes_implicit_commit(thd, CF_IMPLICT_COMMIT_BEGIN)) + { + /* Commit or rollback the statement transaction. */ + thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd); + /* Commit the normal transaction if one is active. */ + if (trans_commit_implicit(thd)) + goto error; + /* Close tables and release metadata locks. */ + close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); + } switch (lex->sql_command) { @@ -3460,6 +3468,7 @@ ddl_blocker_err: if (thd->options & OPTION_TABLE_LOCK) { trans_commit_implicit(thd); + thd->mdl_context.release_all_locks(); thd->options&= ~(OPTION_TABLE_LOCK); } if (thd->global_read_lock) @@ -3515,6 +3524,8 @@ ddl_blocker_err: /* we must end the trasaction first, regardless of anything */ if (trans_commit_implicit(thd)) goto error; + /* release transactional metadata locks. */ + thd->mdl_context.release_all_locks(); alloc_mdl_requests(all_tables, thd->locked_tables_list.locked_tables_root()); @@ -3538,6 +3549,13 @@ ddl_blocker_err: */ trans_rollback_stmt(thd); trans_commit_implicit(thd); + /* + Close tables and release metadata locks otherwise a later call to + close_thread_tables might not release the locks if autocommit is off. + */ + close_thread_tables(thd); + DBUG_ASSERT(!thd->locked_tables_mode); + thd->mdl_context.release_all_locks(); thd->options&= ~(OPTION_TABLE_LOCK); } else @@ -4040,6 +4058,8 @@ ddl_blocker_err: thd->locked_tables_mode == LTM_LOCK_TABLES); if (trans_commit(thd)) goto error; + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); /* Begin transaction with the same isolation level. */ if (lex->tx_chain && trans_begin(thd)) goto error; @@ -4054,6 +4074,8 @@ ddl_blocker_err: thd->locked_tables_mode == LTM_LOCK_TABLES); if (trans_rollback(thd)) goto error; + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); /* Begin transaction with the same isolation level. */ if (lex->tx_chain && trans_begin(thd)) goto error; @@ -4413,6 +4435,12 @@ create_sp_error: if (trans_commit_implicit(thd)) goto error; + + close_thread_tables(thd); + + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); + #ifndef NO_EMBEDDED_ACCESS_CHECKS if (sp_automatic_privileges && !opt_noacl && sp_revoke_privileges(thd, db, name, @@ -4559,11 +4587,15 @@ create_sp_error: case SQLCOM_XA_COMMIT: if (trans_xa_commit(thd)) goto error; + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); my_ok(thd); break; case SQLCOM_XA_ROLLBACK: if (trans_xa_rollback(thd)) goto error; + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); my_ok(thd); break; case SQLCOM_XA_RECOVER: @@ -4703,10 +4735,20 @@ finish: start_waiting_global_read_lock(thd); } - /* If commit fails, we should be able to reset the OK status. */ - thd->stmt_da->can_overwrite_status= TRUE; - opt_implicit_commit(thd, CF_IMPLICIT_COMMIT_END); - thd->stmt_da->can_overwrite_status= FALSE; + if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END)) + { + /* If commit fails, we should be able to reset the OK status. */ + thd->stmt_da->can_overwrite_status= TRUE; + /* Commit or rollback the statement transaction. */ + thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd); + /* Commit the normal transaction if one is active. */ + trans_commit_implicit(thd); + /* Close tables and release metadata locks. */ + close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); + thd->stmt_da->can_overwrite_status= FALSE; + } DBUG_RETURN(res || thd->is_error()); @@ -6680,6 +6722,9 @@ bool reload_acl_and_cache(THD *thd, ulon query_cache.flush(); // RESET QUERY CACHE } #endif /*HAVE_QUERY_CACHE*/ + + DBUG_ASSERT(thd->locked_tables_mode || !thd->mdl_context.has_locks()); + /* Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too (see sql_yacc.yy) === modified file 'sql/sql_servers.cc' --- a/sql/sql_servers.cc 2009-03-02 21:18:26 +0000 +++ b/sql/sql_servers.cc 2009-03-06 22:17:00 +0000 @@ -39,6 +39,7 @@ #include #include "sp_head.h" #include "sp.h" +#include "transaction.h" /* We only use 1 mutex to guard the data structures - THR_LOCK_servers. @@ -223,9 +224,6 @@ bool servers_reload(THD *thd) bool return_val= TRUE; DBUG_ENTER("servers_reload"); - /* Can't have locked tables here */ - thd->locked_tables_list.unlock_locked_tables(thd); - DBUG_PRINT("info", ("locking servers_cache")); rw_wrlock(&THR_LOCK_servers); @@ -251,7 +249,10 @@ bool servers_reload(THD *thd) } end: + trans_commit_implicit(thd); close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); DBUG_PRINT("info", ("unlocking servers_cache")); rw_unlock(&THR_LOCK_servers); DBUG_RETURN(return_val); === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2009-03-04 13:33:47 +0000 +++ b/sql/sql_table.cc 2009-03-06 22:17:00 +0000 @@ -4393,6 +4393,8 @@ static bool mysql_admin_table(THD* thd, trans_commit_stmt(thd); trans_commit(thd); close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); lex->reset_query_tables_list(FALSE); table->table=0; // For query cache if (protocol->write()) @@ -4442,7 +4444,10 @@ static bool mysql_admin_table(THD* thd, { DBUG_PRINT("admin", ("recreating table")); trans_rollback_stmt(thd); + trans_rollback(thd); close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); tmp_disable_binlog(thd); // binlogging is done by caller if wanted result_code= mysql_recreate_table(thd, table); reenable_binlog(thd); @@ -4556,13 +4561,16 @@ send_result_message: We have to end the row, so analyze could return more rows. */ trans_commit_stmt(thd); + trans_commit(thd); + close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); protocol->store(STRING_WITH_LEN("note"), system_charset_info); protocol->store(STRING_WITH_LEN( "Table does not support optimize, doing recreate + analyze instead"), system_charset_info); if (protocol->write()) goto err; - close_thread_tables(thd); DBUG_PRINT("info", ("HA_ADMIN_TRY_ALTER, trying analyze...")); TABLE_LIST *save_next_local= table->next_local, *save_next_global= table->next_global; @@ -4579,7 +4587,10 @@ send_result_message: if (thd->stmt_da->is_ok()) thd->stmt_da->reset_diagnostics_area(); trans_commit_stmt(thd); + trans_commit(thd); close_thread_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); if (!result_code) // recreation went ok { if ((table->table= open_ltable(thd, table, lock_type, 0)) && @@ -4673,6 +4684,7 @@ send_result_message: query_cache_invalidate3(thd, table->table, 0); } } + /* Error path, a admin command failed. */ trans_commit_stmt(thd); trans_commit_implicit(thd); close_thread_tables(thd); === modified file 'sql/transaction.cc' --- a/sql/transaction.cc 2009-01-26 17:19:14 +0000 +++ b/sql/transaction.cc 2009-03-06 22:17:00 +0000 @@ -98,6 +98,10 @@ bool trans_begin(THD *thd, uint flags) thd->locked_tables_list.unlock_locked_tables(thd); + DBUG_ASSERT(!thd->locked_tables_mode); + + thd->mdl_context.release_all_locks(); + if (trans_commit_implicit(thd)) DBUG_RETURN(TRUE); @@ -336,6 +340,13 @@ bool trans_savepoint(THD *thd, LEX_STRIN newsv->prev= thd->transaction.savepoints; thd->transaction.savepoints= newsv; + /* + Remember the last acquired lock before the savepoint was set. + This is used as a marker to only release locks acquired after + the setting of this savepoint. + */ + newsv->mdl_savepoint = thd->mdl_context.mdl_savepoint(); + DBUG_RETURN(FALSE); } @@ -380,6 +391,10 @@ bool trans_rollback_to_savepoint(THD *th thd->transaction.savepoints= sv; + /* Release metadata locks that were acquired during this savepoint unit. */ + if (!res && !thd->locked_tables_mode) + thd->mdl_context.rollback_to_savepoint(sv->mdl_savepoint); + DBUG_RETURN(test(res)); } --===============5214256432798327859== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/davi.arnaut@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: davi.arnaut@stripped # target_branch: file:///home/davi/bzr/work/4284-6.0/ # testament_sha1: ed1e455dbdfa0dffe466557105843a5819b8f0b6 # timestamp: 2009-03-06 19:17:21 -0300 # base_revision_id: alik@stripped # # Begin bundle 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 /mqGEn/4u5IpwoSGMmSd0A== --===============5214256432798327859==--