From: Date: March 5 2009 10:59am Subject: bzr commit into mysql-6.0 branch (davi:2741) Bug#989 WL#4284 List-Archive: http://lists.mysql.com/commits/68333 X-Bug: 989 Message-Id: <20090305095936.16811EC105@skynet.ctb.virtua.com.br> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============4984668276852997279==" --===============4984668276852997279== 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 2741 Davi Arnaut 2009-03-05 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 Update test case result. @ 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 Delete from MyISAM table to avoid taking a exclusive lock. @ 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/mysql_priv.h Introduce prototype for function which releases metadata locks. @ sql/rpl_rli.cc Remove assert made meaningless, metadata locks are released at the end of the transaction. @ 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 after taking transactional locks. @ sql/sql_parse.cc Add function to implicitly end a active transaction and that closes tables and releases the metadata locks afterwards. Force release of metadata locks when flushing with autocommit off. @ sql/sql_table.cc Remove unnecessary calls to close_thread_tables. @ sql/transaction.cc Release locks once the transaction is committed or rolled back. Same for savepoints. 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/mysql_priv.h sql/rpl_rli.cc sql/sql_base.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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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: Test case is obsolete, should be reworked or removed. +falcon_bug_24024 : WL#4284: Test case is obsolete, should be reworked or removed. === 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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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 Test case needs to be reworked +ndb_alter_table3 : WL#4284 Test case needs to be reworked === 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-05 09:59:19 +0000 @@ -333,21 +333,22 @@ select count(*)- 4 from t1 use index (v) drop table t1; +# Disabled due to WL#4284 # 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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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: Test case is obsolete, should be reworked or removed. + === 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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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-05 09:59:19 +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/mysql_priv.h' --- a/sql/mysql_priv.h 2009-02-23 14:53:18 +0000 +++ b/sql/mysql_priv.h 2009-03-05 09:59:19 +0000 @@ -792,7 +792,8 @@ 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); +void release_metadata_locks(THD *thd); #ifndef NO_EMBEDDED_ACCESS_CHECKS bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables); === 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-05 09:59:19 +0000 @@ -1182,13 +1182,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 +1200,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/sql_base.cc' --- a/sql/sql_base.cc 2009-03-04 13:33:47 +0000 +++ b/sql/sql_base.cc 2009-03-05 09:59:19 +0000 @@ -1475,11 +1475,43 @@ 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; +} + + +/** + Release metadata locks that were acquired during the current transaction. + + @param thd Current thread +*/ + +void release_metadata_locks(THD *thd) +{ + DBUG_ENTER("release_metadata_locks"); + + if (thd->locked_tables_mode) + DBUG_VOID_RETURN; + + DBUG_ASSERT(thd->open_tables == NULL); + + thd->mdl_context.release_all_locks(); + DBUG_VOID_RETURN; } @@ -3618,6 +3650,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 +3792,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 +4670,7 @@ 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); + release_metadata_locks(thd); } === 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-05 09:59:19 +0000 @@ -127,6 +127,27 @@ static bool some_non_temp_table_to_be_up /* + Implicitly end (commit) a active transaction. + + @note Close tables and releases metadata locks. + + @param thd Thread handle. +*/ + +static bool end_active_trans(THD *thd) +{ + bool res; + DBUG_ENTER("opt_implicit_commit"); + if (!(res= trans_commit_implicit(thd))) + { + close_thread_tables(thd); + release_metadata_locks(thd); + } + DBUG_RETURN(res); +} + + +/* Implicitly commit a active transaction if statement requires so. @param thd Thread handle. @@ -163,7 +184,7 @@ static bool opt_implicit_commit(THD *thd /* 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); + res= end_active_trans(thd); } DBUG_RETURN(res); @@ -1223,14 +1244,14 @@ bool dispatch_command(enum enum_server_c bool not_used; status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]); ulong options= (ulong) (uchar) packet[0]; - if (trans_commit_implicit(thd)) + if (end_active_trans(thd)) break; if (check_global_access(thd,RELOAD_ACL)) break; general_log_print(thd, command, NullS); if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, ¬_used)) break; - if (trans_commit_implicit(thd)) + if (end_active_trans(thd)) break; my_ok(thd); break; @@ -3459,7 +3480,7 @@ ddl_blocker_err: thd->locked_tables_list.unlock_locked_tables(thd); if (thd->options & OPTION_TABLE_LOCK) { - trans_commit_implicit(thd); + end_active_trans(thd); thd->options&= ~(OPTION_TABLE_LOCK); } if (thd->global_read_lock) @@ -3513,7 +3534,7 @@ ddl_blocker_err: goto error; thd->locked_tables_list.unlock_locked_tables(thd); /* we must end the trasaction first, regardless of anything */ - if (trans_commit_implicit(thd)) + if (end_active_trans(thd)) goto error; alloc_mdl_requests(all_tables, thd->locked_tables_list.locked_tables_root()); @@ -3537,7 +3558,7 @@ ddl_blocker_err: that it can't lock a table in its list */ trans_rollback_stmt(thd); - trans_commit_implicit(thd); + end_active_trans(thd); thd->options&= ~(OPTION_TABLE_LOCK); } else @@ -4411,7 +4432,7 @@ create_sp_error: lex->sql_command == SQLCOM_DROP_PROCEDURE, 0)) goto error; - if (trans_commit_implicit(thd)) + if (end_active_trans(thd)) goto error; #ifndef NO_EMBEDDED_ACCESS_CHECKS if (sp_automatic_privileges && !opt_noacl && @@ -6680,6 +6701,12 @@ 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. + */ + release_metadata_locks(thd); + /* 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-05 09:59:19 +0000 @@ -4327,7 +4327,6 @@ static bool mysql_admin_table(THD* thd, case 1: // error, message written to net trans_rollback_stmt(thd); trans_rollback(thd); - close_thread_tables(thd); DBUG_PRINT("admin", ("simple error, admin next table")); continue; case -1: // error, message could be written to net @@ -4392,7 +4391,6 @@ static bool mysql_admin_table(THD* thd, protocol->store(buff, length, system_charset_info); trans_commit_stmt(thd); trans_commit(thd); - close_thread_tables(thd); lex->reset_query_tables_list(FALSE); table->table=0; // For query cache if (protocol->write()) @@ -4442,7 +4440,7 @@ static bool mysql_admin_table(THD* thd, { DBUG_PRINT("admin", ("recreating table")); trans_rollback_stmt(thd); - close_thread_tables(thd); + trans_rollback(thd); tmp_disable_binlog(thd); // binlogging is done by caller if wanted result_code= mysql_recreate_table(thd, table); reenable_binlog(thd); @@ -4556,13 +4554,13 @@ send_result_message: We have to end the row, so analyze could return more rows. */ trans_commit_stmt(thd); + trans_commit(thd); 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 +4577,7 @@ send_result_message: if (thd->stmt_da->is_ok()) thd->stmt_da->reset_diagnostics_area(); trans_commit_stmt(thd); - close_thread_tables(thd); + trans_commit(thd); if (!result_code) // recreation went ok { if ((table->table= open_ltable(thd, table, lock_type, 0)) && @@ -4687,7 +4685,6 @@ send_result_message: err: trans_rollback_stmt(thd); trans_rollback(thd); - close_thread_tables(thd); // Shouldn't be needed if (table) table->table=0; DBUG_RETURN(TRUE); === modified file 'sql/transaction.cc' --- a/sql/transaction.cc 2009-01-26 17:19:14 +0000 +++ b/sql/transaction.cc 2009-03-05 09:59:19 +0000 @@ -101,6 +101,8 @@ bool trans_begin(THD *thd, uint flags) if (trans_commit_implicit(thd)) DBUG_RETURN(TRUE); + release_metadata_locks(thd); + thd->options|= OPTION_BEGIN; thd->server_status|= SERVER_STATUS_IN_TRANS; @@ -112,6 +114,36 @@ bool trans_begin(THD *thd, uint flags) /** + Close tables and releases metadata locks that were implicitly or + explicitly acquired during the current transaction. + + @param thd Current thread +*/ + +static void trans_release_locks(THD *thd) +{ + DBUG_ENTER("trans_release_locks"); + + /* + Relies on close_thread_tables to close tables and to release the locks. + */ + close_thread_tables(thd); + + /* + close_thread_tables might have not released the locks if this + is a multi-statement transaction due to autocommit being off. + In this case, release any locks if not under locked tables mode + as the transaction is probably being implicitly committed or + rolled back. + */ + if (!thd->locked_tables_mode) + thd->mdl_context.release_all_locks(); + + DBUG_VOID_RETURN; +} + + +/** Commit the current transaction, making its changes permanent. @param thd Current thread @@ -141,6 +173,7 @@ bool trans_commit(THD *thd) thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); thd->transaction.all.modified_non_trans_table= FALSE; thd->lex->start_transaction_opt= 0; + trans_release_locks(thd); DBUG_RETURN(test(res)); } @@ -207,6 +240,7 @@ bool trans_rollback(THD *thd) thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); thd->transaction.all.modified_non_trans_table= FALSE; thd->lex->start_transaction_opt= 0; + trans_release_locks(thd); DBUG_RETURN(test(res)); } @@ -336,6 +370,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 +421,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)); } @@ -592,6 +637,7 @@ bool trans_xa_commit(THD *thd) thd->server_status&= ~SERVER_STATUS_IN_TRANS; xid_cache_delete(&thd->transaction.xid_state); thd->transaction.xid_state.xa_state= XA_NOTR; + trans_release_locks(thd); DBUG_RETURN(res); } @@ -640,6 +686,7 @@ bool trans_xa_rollback(THD *thd) thd->server_status&= ~SERVER_STATUS_IN_TRANS; xid_cache_delete(&thd->transaction.xid_state); thd->transaction.xid_state.xa_state= XA_NOTR; + trans_release_locks(thd); DBUG_RETURN(res); } --===============4984668276852997279== 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: 7505e925fbc154658c2b89150f81dfede180d71e # timestamp: 2009-03-05 06:59:35 -0300 # base_revision_id: kostja@stripped # # Begin bundle IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWbYCwmoAJZBfgHUwff///3/v /+D////+YDq+96583QjeccA3Tb5eNb1u319eNnw+nh72AeCh7O5rZgtq7d2lLj3AHd954eq+3y94 ZRzu6A7ecPva+b0G2A+3VOh3msnTScOaqcAFo3RnZp0W6coXG5xups0rU6Z00AAswAUrbDQaUKAN 2AAA42aXpnsYKBQAAAEEQyajTEynphR4mnqnogAAAaAA0ADECSQACAkiMAaEjKAAANGgPSAAGg0y BCQpPSehkNMU0yZGgBoAGgAAAAJCQgQE0mQxNE9Jomnkp+qfqaT9JPUaBk9QAyMgyCKRBMIAAATT QJiTQmIp6aIbU8mhGamR5RgkiAgAQCAjTIaEYqfqelNPQhoNH6oZqeoBpnM12KMIQA/+v5/0Xehk Q/wP4FIfxKFg7ElP4rx+tKeV6LAxZGJ2L6p+437rzPe1m/r0ez6vqI7VH41PU05Pg8Ew5iofKzBj xJcOI96e8F+jiSCZJTf86BjGkx+lyoG+/6Ku3pI9HdqtXLtE0kQEREAskYAICGMhBgvk0mLJi9sb R8dCAufSHJWlHmy2Yc7JUthGMzFeVtdywgQbYWxStnfGm7WQkFp8/9mWhKuo8ShKs4F3i+HU9K5N e3GdiLFvbZg9bUqe2Bfq0cc6Opti0/1RcOelK4SXI6kS847FveRRJXMWMLdQr6iwHtutssFszJZK fkUSyaXMoijcIAxpMLv6cjFoK6+Tz89xq4yCrdcr6FnFIO3HTiYG8DTFluTczWOvBbXPBxvlSSbQ DYJ8kRR/S2zs/Ahr/D2ecsZiSOXZEjqe9i80gkR8mUxsQ2I7MoHUzJpGGrsC7S6aZgavyi1xNHG3 xcbbekj82dUJI9mVceWXdzRoayyrhORzw5LcYei+KlnIqGBG4YVbzSCLu6OH1MnApBxa1OJ1UTb3 FyXzJUzfUjGKzmI1EPOKhxdLM3q5L6RvBoK6SizMI3FnVhxMXnHlYzuvK5fm8Q/Jx9p42YcXYGF+ 0fKG2bmKyK93GPfbOGKZfFAkE4gZMgGbdRxogcMClMKv7OxpOcRGgyGKX9Qm/6jDA/3aEvqCoJ95 H3mfrAfwToZKSgf7AU2ihSKEMNttNg22m0Ng22xjYMYNobbbQ22htNsYNgDbY2NjYhsBsSbG0223 fvYvkhC9DE/V5eXrukae2I6V01xWPgJm7kIbblt4huZUbkWdjUU7adEwBQQmlvwgLdSauX6TCVFr ONkBo61pybLImU2ZnUIycFsGCiiI4CwBgtMgnJotsRgtULZW+wy1vMISRM4eC5l4upZGjthMuGsu hd61nNA7GTZp3JmdnpsGcpsKnbRxpCSEWFHJZpwNC3canBozn89qidjEPGlIGMp8psQlMVtdWYIF EPRQwW2bFlX5BIu01F8JHRCxOEVIWlRNlOgHIwXI2FqiK20DqGcjWUHfT6JC1OaQLDBR7/gd/Dw/ q7DT23hj6eyGn0xJR0m14qJAfK9aT1HqPXS33r7EEypVGIBQudezjj4BuIj+fMRXy/Ibvb/VMiek h/aIUvoVGggmvAewwGGZsGGoaBpGrOu7rL66joXRKjipM95yP0kUy4lJFtRTD82mcUE4BU8Uf4qL 81Uw9wVQdkIBHjkce+BtYkzOfr7cG2Kh9I3Zq9JBLyH00yuhCZVriFGAZgPlwiJAddeKzBqRYvCS E4HlCxD5mfN9v7fK3g0cTBYYRhkAbT23gwMyNz2D7rlxZIbP2DPIWUhj1X3aYM5Dx3XT6CNdkX2N rdW61w47RN0Vz89XhyF2bzzFkybnV+cm2lRU+X7ErFwbEsSNgZTGdtC60KwlcMocfvhl4gzR6Pp1 G1HFLZibEloV1wmc1KEVWRS1SKQ83w2jxgyH18jLP0OFQnMbnSQisINZ8jEDHuDrbraYZto4UNPL NWE3bUzsCOKEjaIwxmRmUb27Odmz4nVyKspTNRyIdQe0QPgYHrA9gj6iwN4uVVN5J1QoOEf5mjA7 ieiZmjO4w47yd9JJSFP7hNPjN3CiJb95MRet68Dqv69OxiCRVmEYPvwhdOSmRnFPeixRN95G7HZx MIWQaPPLSy3veF9cxtepNQq4eIhoO5CIh54ePoMTceYrx+DBAfDFPWUmGBoTqZ+qH2Bvl8/p+D/c fD66vCcqNT6sTasqtCtG/B2Oy0e2ltKgK9IaydQbxBDHIth6p3NvzSy4Qapwotx21RulJAd/RZvz /tnGhwTIDxZmBmE4e1ny1NsOHSj7qSjBth8KqnrUi7xMtLp4p3nFwzBhyc3B5rl4+QBZ7lO9OF1s 4b7StOVnyqTaxyONSvd1HHyBIPCVO/2y8GSQhtI9rE2JCG1+KQv02Ym0NnyaRGA2h/mSDwSh9zbP i+o+CgfnUOnRqQ/D7sJpgHvwiI9Xwgj5o+7/DW2QRgeeERR8/7/AOY3efVfez327fwbFRAHLhc/f ncwixle0XCy7URBZl4ytUvDgjIgJhYKj35Pbj/Yk2o8BjvX7ooV/7PafLT8dcd4fiL0rYkGpvTDO ED9aNEI+RPqPuVXz+n6CkpQZ4Qppp4TonTKqqij9H7IbPykZFrHOMn0YdbA0sMOgdQ7iGbDjfBol +IylWP1oaP2FDSRgZFjCATfYGQimP8tgimtwS2vdk7aeY7XJpamloZbnGWN9DpNSn6yCux2XGJwv 6E0JNwZmXOEIMyYNJoKAthMClUW4pxVE8usq5BPqCdhQytrcyoYWpCbYV3tAOCHGCEDxnWwTHGEI TtZhUNCHC4rDQiFuwmZnKyqaZudpaAug0Vt+OVdFv28zJPm5pley99TsxVizvGffbTmCsg6+dqyN mQyYx+okckjg9XGW66/eHdQJIgcbMpoGopGTehjYJtsECZyDkkq7g1f9Eru797TCOal9S5c67LVN ewXqTckd7gwDmYjWmpnamlNRdJ4soq3TecNBAW0KxG1S2Ui56GtVFUVFFRUKUab1jOtKvZ094j1H l9kFBgkcsZaC1PGnBx8QxzwkIusjJwpZRtuDRG4zj/pRV+VKsXyKqlkGlJdTM0dDKstA0ssVQgIr oCtdTW+swo1lbKu8R4eP0Pqnnd+2dtp63F2AkDbGB7GhYYBZl39GsErtArsAprOQtiCIyO7zYGB7 OWhmwzYizDDEspEZHdw3fC+4FuTVqYib4kaV7kG7oNcQVhYaWGC3G+CpoSuNIAhhQAAo7jM4Ghya EZgtExNFDLaywtBMo08Bwy8yxweC9T3wMUbgxJ1FF5sJkyBnSAHEt0EFMeWhNqzAEoCnIFETJlqV SAqEk7VIphWGEyhCgZGVKisKyqUWB0jY+KlWaZZFKg9JUWBwhIcpIeMZVFHAoL5kJstiFC5AKs8k K7JIarJMJxCbVag80SLPtm5c0srYL0krMESyHgWxh2/gmr4FmMpMESE8UhYKDyJUeUu+dXl4tCaZ kkkmbouUEdGjkmCoISJkyBV5lCThGXJKSWIXKMofx+Qonl4LGxk3KnBg2IETk8cky5QsWsNkkVIn BMiUMDjwOJExi5j7/zPMGQoXPBl8MjkEU1snjL+SHIwF9+CORWBtEtgdTBzgu0kLQ5yTErFUVTRs hnHXnksyxN2mlSVm9EgjSvXfvA6r+Lf2tCb5GvBcVxA+ZmcBU+A27T8olgg1VygbipIFsoihtROo qg46Y7Bpxm/u0Sgj1xJGio9DmtJPPAjKcuSImTCoKSyxOjhQJp8hXHFRjQ0f5jAewhNuC6cwJ8Nb jE0n4lKK243JZB4WsTFDXBcDxOdF0yhKvE8UHkXzvHEh3LbxadoOlZ1r52fbi9NQzi9MKVBzJGDB szTTu1cXqpTFikUCRA1KlYjppiwKO2aajogDHbiRL16Ki3HG12tb6bXFwBI2M8Em4URQuJRa2cUY PmaH8mDQ2MyGtcOs9Ve7PfBMUi9mSjMb31c9WTxxrWjsgiuJmBQWsivXwKYoPiZe6hU4GjbKwVJF osQVF4LVLoNh50NUcPGHB6AKkh5W3lAIW6cXY3JpSLk7Bo7ouPr0RPIqdmGphmzDgQkeOqG/cmGF FlVRMuCYJqayPXBweRuPlvuDdLd5p5dy4PwHaL+wTogpGM4iSN4dDqIbjiqKNjqOoqGZYUKBEzN4 MH3ZCEcupmmWFTiF5YYyaPJek5PtM5iZJFCwaSQLBUeSOj0fpmI4GRv1nTjLkjey0VGi26GLvPjQ OUaxviVo9ZXTZmahLIKdbtHMPj8RM2xX7ligqqC+SPyiOctw3K5GBlkWIRGMDIVUuzDStNLdKm9i KSl9oV07TsHQenkfJXKJgzvWF7HAkYigX3DuRSkyRBV8PXa2SCd5AMWUS9t40DLljXq3vrayEyiu 9iQtTKbF1m+XrVlBn8DEmFlnTnJ//zi5k967Q1NKnfetU7cYZS9MNYbELBCRrFQWtFcbWzLcuzwH Uk6/glUfHtlhI9Mz4j0HtX4K1zLtvs6iJh+I6afW2DtTkNdqJwqD3sMbFbt57lF2Ut0PNrjQoZ6C nxJNFLMuFk+pxORsbsMjU0IGJU0MZtyQc96JghzjJM0VKDjfenFZDM55FWE7ldzUneki6hAYoZMG SZJIismKCSPkekywdBN3oqdtpajmMRLi4wNDI6ipsSIWnQIHA2NRsNp8AwYspaWEzKZTwch+DSYT 73Y7n4ebodzW52vDS5mkNWO9ofFyPdsfRvdQ1FZcYWOjfhfo9HzC1yPR4urWlzwrp4cN74U1EpxE FGWdNBKuRrrJdCmYs6q6tHOOjU3VxLqC/TUwYndjsDRA3y4GUyZ18sVcrXgvk+SUapyBCvog8U5O mwLJwESRATlMfkgrK9B1maictDhA8npSKzPfcqqhGLmZXT9SIyKGrE4kkFjBcYjZhzSc7aOK2Z57 Sp6x4mKrzsPLiEh79xrzF7Do3IDFxis80E5nthz9lCguiahhRUqDOTk60h1zjslSjpTdXEEQE3va I0hhmuaK8GDAfasFhCRZmLOY6qWHy73HzLh5HJ2o4Rc35GMRiN5Q1AliWzeDI9+xDvcqrsJpeHhZ LwcoM4JjsjivXzebmDosTqOAHPPGCZ5EBxMgQL3qaDwu5QLRbjUkWkTU1KDFhoDHSJkZkSYxA4kC ZQZMlGl8DYPm8qGQ732cbwGY+bzdml6PJxOZWM3TIIBAKRvjQLopdF4VjgGgEzvkTkFD9VCyZMCS OyYUaxh7FkEkDRFxjuw7QDWoorWVGZTrCETjSeXwDFZzF+Z1PvxvxyZxrZ2VU0twYndwc8Hl7DY8 yAozoKqDz87DwMlwSNH0HG0nYL0Wk0I7vhWU7QnIIRMmbe04KfMcWMFzRXfB6cXXMIOFQJxba0Ba yczrA/OvxYAmL5VInq9yrjrjjwmCK4Zy5JyFYisfSRIY5IzQ1vh2pRFEg16OgMOi8zclcHAXQqqV m3NwhzMFFlCZJi0YmRH3ps1seakcRnrJUhho7kYEGY3A7Pqon5PuX1UyWJO6tFtD0EORQyLG4mXC Z47ihhhdcxK7cjmciUenfmcj1c8jc0Igxxw2qGjtcbSZrXQxkikSSPBdDEzo+IKzBjR1MTIoQarc CR18WaHTpY8FI1GJS6zkeCuLBjeSOBE1NwY6kChU9OiCZkLCZBhN7eaik1GRwoeQ+zqfB9aWpuyU O56ljoej7vq4vZ3ORqfJMjsezgbBxuV2M3B9HS6XzaWmya65YhhsunLbxXczQm5A7URPDvaMHmd5 JQIx5FPHNlTtmHpGKjNuR3d3MAq4RrcMtvai0MW3kvGXxaI51XpK4ymJjBODxCRwl86kA+JQnBbo vVMy84b70mm3pez9xOuRYhkWTzMESlBOVytsrjbdXJFy+q+7uQsGHGVoqNw44OD7xRPYVm2bN4V5 m0ODJV9EDwidwd4DZkfMgTs2MzVsin66GhUvmm7qWxLx91jjh6Tbkr/JapxclFY4Wb8YbtsYEnyC W5HMiWGJqobo3HPjMyuaQ45xuLpHIsPPgvl1bhO3qONhPRuQW+ToqHCiUKkbDmq2zgn5lkBCRM2W ZAw63NSHCRyNCZoYl61MGZxZUMg6KQYkTvQcTcWDkjvXDEiPkTWJUmuioaGZNakTdv0WRQwdaFDs XIuJDmiYcdd7WX33m4M9xoa+zzaXs7BMPu3CKSexucjWFDiaH1cLse1Q4+TzcjQ8nA8/JuOBq5zc zY+bc6Ha3OO70dflBrnnVcfTAwCVsHytQSK6bQmSZzWtYk2nSVp1rZ07vpPfAEFlyrjkcXg4UhM4 XkZNoCYxOjlCZ3CEiuNLYWJhO4JxMaEq55+M4o0Op5m0yRLht5rgc59UtcHhaKwdMf6iCYvMlFOz 8FeUSXVpwWBTGHjyZ6yXcdweT6azX24y7s1UiOm50hiJFxgYdwO4WhbnaZ6810qz0W1sfWLDGTgH GjoyaPgLZZmTJHP25Cpom7Eqyi+h2McEHXeHkWtWvzgeRyOKkPpbQQokwJEtBYj4UvUeBxo5HkJk VixYz9NypyXMkC56yxWu5udGx7So1T1Ezc+CqVPI2OSBUODbbQqlS2kzlpedWse7xcb32umTmdrx b3022DrZN5e7TmbG8muC9SoaLt7etzp290M5zdHUXyi0oQfc5WhDBqF8VMaVnxxCZVKNp27jktgw qUgRQ2Ta3ZIWDIukrp6kiDZ+JnBEO1XrUiWumpt2HAy2LwKZGzBhsI3fTB7B2DJQiRWDB9Bbr5Z2 zPD+ofho6N0EzcQcBMygzY6we7AzFPj8WkZLnQ47MeWYHYuDQ/kVDyJH1XtVyZThuRip0WL4pR2Y LfnrA/7MDqWatnlWUiJY7NDiNIU0VgObssAgDAkIhEBCxLDdNO9TUudUZO4Ib8SXILyjJIARnmbl 0IrOHppowYZGzMimoJmQ3mg2vE3mwrNhMqNrVm7PL3cnBc8FDgebmBxscEBjk29nzVVyaPMwXMHq uMRQWBM2ebqDeyd7ke/PE82je4m58H0NzN6ZXq3abdvZ6bm8LYI1cDk6X7QPZIhSOy9d6YiO2buJ 7BtzNGbqKus0XwoGOAJKZ0xZNJd7SBAFJkhoJyc8oe8moogMkMwuCMiRyfSlK5sK6YWR45J2NRUN naMzHcsbzy8vYaXGumCChsaxgIe862N0M+RyUeNyfYcmCZ5rgoV06JnRixsPI87nbPdOrh9oM7rs odRNjYqYMjjBsOKjh4+8CCJhUcMcDyU5FLjiDZG6Oi4QLlyJI8lA6MmvEDY3NyZuYgbkTQTNG5Uk ZIG5wVKECpwRKFpjYKaN96mC44kYDRFHwWzdDiNurodYO7NrZ46o4pxiSKyREAq4erxmMk75WbvW jyzztasBYQkWCli6iu0r40dzmNHURkPQJLo8rimeRDg4rKrqtcag2iS0mk5aoISN4EDcsVIFCKBy VDginqQMDypOU6RKKEn3JDEZwhNpFzvvBVbmkvQq2lYsqRG2GYSBaKnkclpHFHuc+w3DWHjjRAks MxAEz3OuQpA3sOPvSsZIEih81UgVvQm+x8RoQmSLB5XMhNhxE2JkzY3PmrGDkwUHGQ69ohIcZLmj RUcckS5Y+0eVOBxQJE6tAgaiNEiVChE612LP1kSyBCYj9/n9f6zBJVYS235maDt35OyyEde+WiRD MIQGDRgduMXWkIqjGUKyGsS4hmDCAGYYjUDGagjCRRLi5zbiE7ZPSzd0JEEkRgkYMLO1BjK1pYzG YbNaEiZFXAyJu0JoMzArAt/d8h+IsPIQPAObU2cnpvxdmWabuWpsrv0VBV4fjWKLklXjfttPSzTh Fa0nyd282q8rfqT1xDcfrWhQua1FuF/MWURfmEyBwo/dt5fWMsuk98n6/RAly0D9PFTceluWq8zF e/9H9R5Zyw0kjra4UZfl4ioX6eoj13vvZGhsaYmwGDbTWZI02xjBtjGNNd0Iw+wiYwiNkhFEoJFB EYhjBsGhIGm27/bpsuvw/WJBffBVnVntbQq/3FmhWzP0n41/qlo6/HMJfOfcELDEjBzrL86JTEJD 7IS/Nbux/+lAB5/u/waUpQnQIfeDPw2vQYhYgCIFgIYUYgYSCI/iNNND/si/+QLaB8f80VxNsrV5 AqQODWIZv8Xb/tGtI/BmrAvxIKUKCTQEEHj/R8fiiy9JazMwkCwDcfZLruQRMQ5CCiU34oC3938Q V4mBhXqQJxwvAmvsF2q/l9VzUzUQxlzB8QNETUFx/iFBQZBQISRKcvP/h6CmcGp25zHd//VNqH/H 81DVtXgi6jVoHBaO4ZbjXsQKqiCUZnQKSFLNkFqMfA9MOzmQFBQkkgimAIUEjYAZB+p4v/wQuHTB CpgIkDgtUtELtZvhaKMMDgTK5w1A2BMeBqUw4ETCJu3VzJkygQ0LCNJimJhbwDV0ElZ18gpVb33h /KNUFQCG4QlCTRKkWgwJMHTS3vNNUsA0AGhCbYG7DUmSAzwQQtwBwAtlSP++gMiGlRqgDCD//osQ IgqsIPBwf7ZSWf5Ho2yMoLr5jumX6QPcv2ny/NH4AfWQHzPqCPqC+lT6iGYQ6+Yai0WqaabbGP8n XgvmjcFiyPvKQC2G2qEIaQDbRwEf8LJaJg22NEBYEYSSOOqxKaY2OFJLkWA3re29sLMYv1PcOKDh ACwuBmoHKaoW8RuRgYGsDPNA+qUUNxCSSqiJ/k06CJIQbsgFMrw4FyQAJjCeTKC/nQTJaQM8ESFg WzAVC7j9sEvp3pa/5fqDw+9EnZD0Qk5zGQFKWn2+322qUR2H9R6Bj8T8Rw8/OUtgxj2gkWCR+I8E j9BuXJHgXn2Kkz87jM7CR1qqsCp8fpcbG41Mi4c8i05CAuNC4Dx0bjEjIx2uYjbnZg2I+i5M77wj gFpaan20Jm8JEjp4h/wl1HYlsZnA3Dmx09i6qLQ6G4qMdZU6HEqORHLDcshdaYQfBvXBASEcOrGG IylB5wu8Kl/ZnEtAAmnj+oCY1WKN4IbDxSekgOO2RoiHUYNpoMBQcwuNTtL3FprMIUm50OZFOAqe xldrzdqazjB7n/XzZnVpfhtL293PZ8HaLrxqmV9vIKggzvV8GjWSP8RuHPkdihBAEUGaKT8KSSKU hvqsLXk0zE+n+UBzSgL2FBaKTfS94gjgVHZ3dtr/7bPC5oEU2Gim7eCp4GAgy4E0sCa8FzX6z0uc 1rCQQkAkQpzUkgQQlfWpCqIPWFZB9AQw1yUgkWQOFRIJbBao7sja9g9ENYqmN9+bzyBqAz/gZwVP RsqfJh+Xo83Q2mhj91xb0I1/dQi6TubD4NoepyPQtYN/0tPA+p8lhYUnye5cFQ/MXxIMZmZcWhsO ZnLcbGJQUDM220ChIqdFTzGNyJAYyYOih7F5C4NyIZJDzQYF45EiWjl5eTOVyEiYVChU+EzZvax8 YWSghhRMTMY4HDhhmN6E678Pgt5aMWjHI1HL74kTivBNM6jI4m8zMA2EdpcZHwVDmRKlpA8wcsHc QE94XFxUWGAkTPY/GRW8Hk73kPu2GItQYWPeJpPv75I43dSfuHLSRxtu4MOpd3s+zjfs9MTyyAnF mqlUCN4Jll6e78n12NQ9WuetwPs6tPBxOpxg2ej0aW7vjDxm99ZjfEEE+DzwEVUu1NgGuLFEn2xz JoehWyYYZc5pQoiRshig5SEInrJHmdZyPYZDnX43FShMsOQYB7A9o95nQ6EzZaECw9R5LcRGMgOJ 3rAqTO+3HBoybcHa0blx5+RMeg0d+gkPMm+7jY8L3BwBTgZNBG0rIM5pNhQai54pmhWNxnIvNhhN BWnu73iZTaXE+Jt20mk2mIwEjQa264c0bp6KRnLRrDYrGjJhuvtl11OhaMZFxmcgc3q9ZbzJ+D08 nK4XKFTzPFiS9W40EQk5JIRggUChgVu+6GI7RiE+DBe2PNsMT0RVkeT8wJeAUKJG5L7QHcZTSgwK STovG8iEGsQJMSsMzQFLJz7H18/NhxONcr6t2Im+lJS3gyEgHwZEoIRIHUQIhIlgZ9ni73uHifR3 4i6vneTLiHcJGNoCSzYK4GeqqcyJBeqSuQUUukVV4S16WWftz0ELwTQughGqAPXmNQ8jzMyZM8jo VNx6zpdlQkeJiaDjkzRMYgMH4Kh7txWUzNSA43KnoJmR59qyWJJYnJYktiZuMjsVi5WjoJDWHNCQ x7vdIksxhBma5sgRG7ihIxN4xzOZmZ2ETrORI4HnzIFxlBUtEwKWkDDgMY3mspBD3U0nwa0UhRKD mA3NhnNZMGgEiBINWkpO1ZwOh1HAxy4GJcaL9gKBzLQcvOIeSkG3Peh16hFRWZDKHc4G4PQHa8ik Jscz5OOOQOQmphM5BvLTobToWnMtcj4Op9yYcQU2vz1YQ7MGcxOx7d3ycTShShV3zBNj0fMzlzx7 CKbH2anW31c85I0SjHL3BOTa9zrm1uZ2l4hhjS53Jz2736K+1XKwkZ9mXTlh13kfel0rCpWQ+nB4 HzmJQGLxhGSQi5v4Ubs88wazzUmjKbeyKKphoVVIxE8W99wQ0ritqoa3WZEiy89saWKEcCa6DbTH MyamXT2z663bjguiOGwrBZbizYNNNlhDJIYCkYUSGhIWIjvaRefQ8ik9inxENrY31eUz7j8o+RIw P8Jkj2oGKn0Ina7XfR0G5VBk0dHBI9czY7Oy5pfXgaxrwb+9u7/Ztm337rfMr2dWG6GNdtJvnJ5T i3Y0ttuhkPiyDAsLTmUXI5FJGZvV6uCwqUDzXQmalxJjsLjBUByhkSxHPPz9KsLyqc1Oox2HNShu KE9w5YYHO30diQjailhTmKoETo8ygTegpUKlAyhZsmiCsBRrs3dnae49iWMEQHq7vlUfYdDsOpFk sUCHgVG0wGwwGINhBzPllzIgtOBmMBoOHrCy8lQdS2hAXncEij7O5Wc80pDHAxvkumu8mLd59bzS VLsY2Db4nabbAPvcBjXqkTs7AOwaFnjitwcTvKOdpZkuhe3AKGdhdTQHaYSgZo8z9BKHcwlbbm3s 0obiOpm6Dqc9d8QEAu8bMVGMr4teLAO1Mgdfm2Y0hIranjEUe06+XSw2m2viD/acM9eCGmx7wiQi j7cqpXZEMlUyOhkTAgrzkZCjIUTOxTs5u+YlWvz8Si4guPgvIhwCe6GtkXuNzv1uKkLRj9Rfaubt 1KFMMNwyJnx5UUBjNNBG0ywyBm0a0U3lQ/kkAiE6pCkIgUmAogrg8jkoggkGRSd6pqomuriBfFSv EJEEPp5nFOJY5EVIPvLjf8ONzYXUJ/eZlZEc4lDEEnn8/GCDh96SBdx95I9w5UofE5FsaeIx8TmU PiOWFD1LEc+8tMjxKC4LQmfP50KHcqqZkZDGpQxMTRY3NfBexb7wOj2FDZPWh4ZLkz5ekcTVCpsS NTQvOJuJkfaNQxLVQsGLip6RGy9Dsj0r3nD2KDuniswqdDiXF5gQCJiSMjibjoWmx8w4hqLjANxq OkzaYysFMzfDyepMxBgJ+tZ2BTMVUp3cLiY9R0Ob3fJv6sGH8lE6dVE8VE7AkYFyDyXeu9fRjuEX WlMi18opIKRu2aD3OM+j3KBz8nzTBvexIQMbDkKZVvm6HotA/lBkeDqbnZelRjd7jdDwaHc9n68j Hwh1O7TITAQrDCD0RjXmN5pRmFB2F78l8DE1WCwFxW2aqvcFLifZscWb3zNRlAHUZHK8XK5/o+jn YtoeQmaEGM+VCYC6zYQb8Iim5zO1JGRhwycTySo8H6NyXVDt9XA1Mxm3f2zDSNVxaZcQkiWV/ptd jkexvHo7TFsk5Gh6OoqaejNm9UvYOQfqCc1PBgHyb2S4HZITi+bJwt5Uc3q0hiBMMAKUumYY5FIh B6mVyNTJxt7WIm5hFPtC+O2/YWvcqiEggwkn/wYHC6Hu8W14sYHTdjIgYDuQ+DjfJvc0ntZkYcbw fHEySltDW7lIOgcXDnDLhXih9pmmB7VNncI7ZSXg9gwUPq4G9sa3iZ3u2Glyu9yVfIIt051jDhGV CKmFODzorc74jS1PErdDXd60h5ZwvJBY7xxtBM5OMuq0tK9L4cT9DqkKgGvSaXCSeDiwl+M6h7v+ xLdDrVTk4DY+HTHQ3l5UGFRNhCgBl8SNxb3st6txMh1mV+27yfmi80EsRNC6hu/me4Be4D3YKCSG gInz6YS7yiU21NfAZoDHfFN5DjSlLo4ZoOnQBLcLiC/lYc2iONClKmqEVx5ttHkxobzIl86/Ne3P cHiuaXRoQNgNoE21UgSIFd33P1Jnv7vE0tB4IbDzxkiCUmTEQkREEyif630iFeKjBjfYQbecwzOC PiHRCjLcSAMKLqgJHmkB1KcJkEwJSWwl5aShLyoWp+fB/kJWCz+Hm2lFiiS8jM6WH6PNpeaEOZ1v 0eLW4HyseLBJ0rwd17zbxyvF9sBxbd1mgteDofj4dAeLS5RwuEnQ/LteT4VOJ0hrYdPUSIX8mXNp a2Wex6IqcGTXmd25vTKQKUWOh3u11N7uZJgDtkGcsrU9EybxrZGr6uhzjqcXuKmNcMEQENNR9znc O5xvqhgdT0D4g2Ol8XqHjDne7d56FGIQYgLHG4nyPFpFe7leDgHQ63S5w8nk3uEe0IdwgYJaMSid AYEUODTbTTHqqIEfY+KnX5lzAD3Jo0XFY3g0PJ0ob2pwpMcWRhWYkATYklBU+GnA9rCnSqaRNDBJ +6ZW35dSiQBBEpY5iyUQ+SIkIgwSGHD3AI5CHwFYAvUyYjyT3KMbj3sBjdgimi40aWoN7S0Jmezo Qwod7l/C+rE1uUE6h4qgUitAO5M8HXRS3/9h05j4EgvQCH3JiSjQe4QMswnu1XxoCKpUBNnIngVk QglJ/I7oZ9PJlpeTp5NW6t6O1q2ij+UZYEJlgIWTA3uISkfUtQZnDsMvc9Q2tSHk9mvjAbohS17w YWbDrSKXqNj7Vh2hKmdZfEeWSIIpalrGARZAEGGl8G72b9C7DzmqXl4jIE47elFT6m49XKXht5oJ ikWIkxNtDJ1eD5r8xofFrcJB1fYkimRMOiCNkgyqJ4/fnrE0CQJpWfF2OtkbXY5mkwhY5A0OQQbj WEgPbLFzKUmWNZDOc6ur74Rtco/Vk9soi46ByXMNxlSnUCk39cGwvGUrBzesyjI4W/CQT7uR863b HUn+lTYo4nwMyIQdgKAI3dS9LBBzW99gwY+1iQxhQwBjXbKpvwKZDaMCUqQp7QkKC45M4UJMLneD LOPs7W1sbi1rRS+IlJBghJOhkL4NjiNyEjHeACuswWqPhNGtzEWKoyAaG1UKBUgD95pexqdc5MpY nBgUtLT2nMdKLkKjWYpnq17SBcBCLaECYvZ0FCQEBdc9no4mTS426suAWStrY0TBflpVX9dqq/e5 T80+GSeGoJCaX1gYeDlejqHPlB0AQwAjlA+CdB7w7qY2NjYmuwYRDGhIwpcVBQzGiTvnIYgAfucn i0O9tGl+5933LG4w4HycvJtQ1PMIxqY4RxwBBOUw863E/D0+RpbnBU67kwywDjdLRDraQnCIBgEq QW5aD1d17YqenOk0PEO7hV/iQomF7EjloTWBqdjlEU3m+IjEpm2ukDfUzk0lCFCKuz9pkfxoIgUd DhLoSIESCEJuckKSIgRhFL5AyRiCCBaJNCU2mumFMjUC1qwJf8hiDAGMhzMIv4XEhwtT8Ye75tZa mCBl+ZJZxNiGBZcdrVgxipgwExI5WP2MD5G1KB/a6Q03YL/Qc7Aku9BBjYoHglxRQJMYqE2Dmanm S+ovRNOW2A0VXDj3CveLB96sbMFTQhnMyWx8mXV+fwcgcjwtfomG7XPhrJzpp0KgmMIH0b5u5yOJ udzqyN2HFi40frEUp2Wou3c1P1ZqJ+H5/kindJ+k5SlEoiSib/8VNbhBTq63k5P8qiQGY4DwaHaZ 8DSezS4HwRazqYi2AxVP2fvagLm3UbKXo5S9ubbwN7g+kWpB9N3BgmPq9W1DS6JkeLlafF653xeT Ub2t2t7c6bQqd/QbeLicjS+uN4mf7Pk0jy4ub02OOWfZa4dLJtfwfohtdjaApUyZAhPQ5htfYPz0 jqNLpdW14OJe5Ds2trJy4u9muyIYVhgIICNkkJJCMDOXg9n8ylCAlBAQQJ2EJuN+9jQ5mg34m7q4 ZO52OnBRBEGwZCp1c7kPSDAUbgrBE/tWEStyFvJGML6tONpHErMqDORMnOJzg2PnoeTqZpmfjRJl KgaMVIe1bhW4TY7+747wuAyNI45p+6BKRzqJEKpIL2/+n7LUKcE6yYlArCn7ZCHLyPnPUomuGcJv eBvI1oebNkydMzml1JyTJ/39p0p7Pk7ejcllcXpc/JShzGTlH+8rBUykD1GjG5i7bpeEHmh5H9wV eKrYPZ1EhwBSgcQ5R4/jEvJlKTKVLKbOeBvfncG4N6ydY2ekymEPq0kiKoE9mmgNZD1Y6vw1aXW0 rZZG+RFD4Gi53DyW22f5dr7eNWdmBaozAP+JQVl5gvYbGdVriGmUsqC6MF5oIwqp3KSxayc4k+m5 ceULA9zAp1AhHGxqMejBaFZtXjOUIPQzTCrPD25EVXK2CJ6E5XzNYQ9iQygtvEL2hkAURL78z941 glIAGocaKTUehLhIhg2GZCR0oraz8nYuRBNDCOoICGK6YBQrEY1maL9+ojp23bbufRzFzZW2qcSD TBycZmcYDaCmIFJb/RwOIjwxBirz3kID9GkKC5RJOJ+Hg/iOpFOLqzPJhoOxhellZPoetYNyrRh5 u6AvcIR2v0SRxySSSSRJJJJJJJJJJJJJJJJJJJJJJJJKSSSSSSSSSSSSSSSSJFC5dmBc0kK4nill IpSKpVQIOv8/eHpH7kxJHqd/64brRBaggBdrxkinAjLL+yRjnIzlKNoWoWrULmFSlDRmQKACaIH5 KC07Pxl56nGWQ9PNXnH2PyNNXzPD3BJiMU8JtEjXzPwKWVSQM4W9iDLLuF55Wds9cURQsbtRG5iG PTAqEYlnStvyNkJjbbTS1wDBweYQNrqL2JqJpiYvW16UK+WeeSR8rOyacblyllaD8wqG1kmTCEQq RxEC6kkI5Wl9z7OB+DwfnPwDGzGZoj6b3k3ufTAMEER9JG0nmN+eAVJygghNKiR7zapiSQltFEkK dCoktAIbF3q/5kSiBiIgICGA0ghsxtBjwK/DWCaX7N2+6QsPFyoHzRmmhKANVc/kMTiIghhMbGMG Ns6BcLisG7NuIMsi2yOSQEK/YgQ9OaIUVAh9y0ozc44hkKJSG05anj3fBzJoNCiSC33hQ/q5lCII j9Igm/izJKv6QDOAKywkh0Yc4xMyDmlBhPE0FRo+S7fVoTBCD3kLIVpBlJRiLS0qUmLxXUlT8v4u MbUs7uAGZ9x6TPZwudQsjhAWjGqgzAaKbBUho65x9nyGwDSn8C+SD9ZJ/CBFxpBXxfCbFhByZ3Li QfAa7OagxjD3kN5pnNFLTO1pR5Ol4Ps/k7H0cBeRB+BrLML1KTQ2P24jTe0PV7MmpyvQ7uAT7ns7 qTS/ch/NaxzP8lwPobNUhMDmM6FhhQD1eZfHJ5u1vA+s81gg1hCh6OVP3zUFyNS2ePUjuRMg/Boa 7kN3JzuvejaMJj4+X7yGIs/UuMNyDEGG2EVJQBwGx3Nz2MjqZSdHo/JyfEOvj6xF+4oSro+QcdjZ ZfrHE0vpU8XS8RyOJ8Xfl3REpDGOZMCbjzn8DQzSoD1c5KeG10VM+7yWne8kxP5od28VSZqcIg42 va0PNraXS+JhcL3atG5zOx4jYmdwtGF8Hm5LB1+LcFxxdD1Nbim68O1yuraIYJSh9HG8W92Ot8Wt vdjGxnmbv3uVqxAHx/p18jljany3FTicXYdYim1/G5sdhQzTOw8nzL3x7Uplyvg0NZD6PRxPVwOk 6OdMX7nvrcga3L1ejZyMpS3nmw1mLwEjBIHcyNLlZOXQ8b8iGjOhvdri0O23IrhEyH32vWfg6mot Nmq3UbzxeLDrejhfJ835/ba8G+18XZq3PCl0NQZmwPV2Ovi+vNoere1KA5Xo3Nbldw+Trd521Zzc 41jndEThjRGooaCceQVbnPlKsegMON4vu3dPJw6Gkx5Dlm/0O1ImWHU2uF86mmx4OUJmtzSbDU5X G8Gox3iug6vBubNBkZvFwHSZgamt56tljYgDgbndiepmdEdHkbWWLKainHN5stjzxUNPRtxT3mbE 5TZ5vDe0NGdrcrvbePeQKb2XJuZtB4MOQuobhyZXW0uh5ljNk6r3YybXTsa3C4zeDY3Dsd7ubWH0 /V8P+8/6QzaJf8i7kinChIWwFhNQ --===============4984668276852997279==--