From: Date: March 6 2009 8:27pm Subject: bzr commit into mysql-6.0 branch (davi:2742) Bug#989 WL#4284 List-Archive: http://lists.mysql.com/commits/68553 X-Bug: 989 Message-Id: <20090306192755.A698FEC105@skynet.ctb.virtua.com.br> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0060308215497529352==" --===============0060308215497529352== 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 2742 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. @ 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/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 result for Bug#989 @ mysql-test/suite/binlog/t/binlog_stm_drop_tbl.test Add test case result for Bug#989 @ mysql-test/suite/falcon/r/falcon_bugs2.result Update test case result. @ 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_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_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/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/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_base.cc sql/sql_class.cc sql/sql_parse.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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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/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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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; === 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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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/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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +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 19:27:34 +0000 @@ -3501,6 +3501,10 @@ static bool set_option_autocommit(THD *t trans_commit(thd)) return 1; + 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; else === modified file 'sql/slave.cc' --- a/sql/slave.cc 2009-02-23 14:53:18 +0000 +++ b/sql/slave.cc 2009-03-06 19:27:34 +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_base.cc' --- a/sql/sql_base.cc 2009-03-04 13:33:47 +0000 +++ b/sql/sql_base.cc 2009-03-06 19:27:34 +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 19:27:34 +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 19:27:34 +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,13 @@ bool reload_acl_and_cache(THD *thd, ulon query_cache.flush(); // RESET QUERY CACHE } #endif /*HAVE_QUERY_CACHE*/ + + /* + Release any metadata locks acquired during the above reloads. + */ + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); + /* Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too (see sql_yacc.yy) === 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 19:27:34 +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 19:27:34 +0000 @@ -98,6 +98,9 @@ bool trans_begin(THD *thd, uint flags) thd->locked_tables_list.unlock_locked_tables(thd); + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); + if (trans_commit_implicit(thd)) DBUG_RETURN(TRUE); @@ -336,6 +339,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 +390,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)); } --===============0060308215497529352== 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: 22e0d27938c73f9b90dd1b070404e7ca7ffd27ea # timestamp: 2009-03-06 16:27:55 -0300 # base_revision_id: davi.arnaut@stripped\ # l5jo9ahoorsrxtdx # # Begin bundle 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 ThQkLzoJY4A= --===============0060308215497529352==--