List:Commits« Previous MessageNext Message »
From:Bjorn Munch Date:April 5 2011 1:04pm
Subject:bzr commit into mysql-5.5-mtr branch (bjorn.munch:3192)
View as plain text  
#At file:///home/bm136801/my/mtr-55/ based on revid:bjorn.munch@stripped

 3192 Bjorn Munch	2011-04-05 [merge]
      merge from 5.5 main

    removed:
      storage/innobase/include/thr0loc.h
      storage/innobase/include/thr0loc.ic
      storage/innobase/thr/
      storage/innobase/thr/thr0loc.c
    added:
      mysql-test/suite/innodb/r/innodb_bug60196.result
      mysql-test/suite/innodb/t/innodb_bug60196-master.opt
      mysql-test/suite/innodb/t/innodb_bug60196.test
    renamed:
      mysql-test/r/partition_not_embedded.result => mysql-test/r/partition_myisam.result
      mysql-test/t/partition_not_embedded.test => mysql-test/t/partition_myisam.test
    modified:
      mysql-test/r/func_group.result
      mysql-test/r/partition_error.result
      mysql-test/r/partition_symlink.result
      mysql-test/t/func_group.test
      mysql-test/t/partition_error.test
      mysql-test/t/partition_symlink.test
      plugin/auth/auth_socket.c
      sql/item.cc
      storage/innobase/CMakeLists.txt
      storage/innobase/btr/btr0cur.c
      storage/innobase/btr/btr0sea.c
      storage/innobase/buf/buf0buf.c
      storage/innobase/buf/buf0lru.c
      storage/innobase/buf/buf0rea.c
      storage/innobase/dict/dict0load.c
      storage/innobase/fil/fil0fil.c
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/handler/i_s.cc
      storage/innobase/handler/i_s.h
      storage/innobase/ibuf/ibuf0ibuf.c
      storage/innobase/include/btr0pcur.h
      storage/innobase/include/btr0pcur.ic
      storage/innobase/include/buf0buf.h
      storage/innobase/include/buf0rea.h
      storage/innobase/include/ha_prototypes.h
      storage/innobase/include/ibuf0ibuf.h
      storage/innobase/include/ibuf0ibuf.ic
      storage/innobase/include/mtr0mtr.h
      storage/innobase/include/mtr0mtr.ic
      storage/innobase/include/page0page.h
      storage/innobase/include/rem0rec.h
      storage/innobase/include/rem0rec.ic
      storage/innobase/include/srv0srv.h
      storage/innobase/include/sync0arr.h
      storage/innobase/include/sync0sync.h
      storage/innobase/mem/mem0dbg.c
      storage/innobase/mtr/mtr0mtr.c
      storage/innobase/page/page0page.c
      storage/innobase/page/page0zip.c
      storage/innobase/srv/srv0srv.c
      storage/innobase/srv/srv0start.c
      storage/innobase/sync/sync0arr.c
      storage/innobase/sync/sync0rw.c
      storage/innobase/sync/sync0sync.c
      storage/innobase/trx/trx0i_s.c
      storage/innobase/trx/trx0trx.c
      storage/innobase/ut/ut0dbg.c
      mysql-test/r/partition_myisam.result
      mysql-test/t/partition_myisam.test
=== modified file 'mysql-test/r/func_group.result'
--- a/mysql-test/r/func_group.result	2011-02-02 09:18:44 +0000
+++ b/mysql-test/r/func_group.result	2011-04-02 19:41:10 +0000
@@ -1737,6 +1737,15 @@ SELECT MIN(GET_LOCK('aaaaaaaaaaaaaaaaa',
 SELECT MIN(GET_LOCK('aaaaaaaaaaaaaaaaa',0) / '0b1111111111111111111111111111111111111111111111111111111111111111111111111' ^ (RAND()));
 SELECT RELEASE_LOCK('aaaaaaaaaaaaaaaaa');
 #
+# Bug #11766094 - 59132: MIN() AND MAX() REMOVE UNSIGNEDNESS 
+#
+CREATE TABLE t1 (a BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (18446668621106209655);
+SELECT MAX(LENGTH(a)), LENGTH(MAX(a)), MIN(a), MAX(a), CONCAT(MIN(a)), CONCAT(MAX(a)) FROM t1;
+MAX(LENGTH(a))	LENGTH(MAX(a))	MIN(a)	MAX(a)	CONCAT(MIN(a))	CONCAT(MAX(a))
+20	20	18446668621106209655	18446668621106209655	18446668621106209655	18446668621106209655
+DROP TABLE t1;
+#
 End of 5.1 tests
 #
 # Bug#52123 Assertion failed: aggregator == aggr->Aggrtype(),

=== modified file 'mysql-test/r/partition_error.result'
--- a/mysql-test/r/partition_error.result	2011-03-08 17:39:25 +0000
+++ b/mysql-test/r/partition_error.result	2011-03-31 12:38:54 +0000
@@ -710,95 +710,8 @@ DROP TABLE t1;
 CREATE TABLE t1 (c TIMESTAMP)
 PARTITION BY HASH (c) PARTITIONS 4;
 ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning
+# Moved to partition_myisam, since it was MyISAM specific
 # Added test with existing TIMESTAMP partitioning (when it was allowed).
-CREATE TABLE t1 (a TIMESTAMP)
-PARTITION BY HASH (UNIX_TIMESTAMP(a));
-INSERT INTO t1 VALUES ('2000-01-02 03:04:05');
-SELECT * FROM t1;
-a
-2000-01-02 03:04:05
-FLUSH TABLES;
-# replacing t1.frm with TO_DAYS(a) which was allowed earlier.
-# Disable warnings, since the result would differ when running with
-# --ps-protocol (only for the 'SELECT * FROM t1' statement).
-SELECT * FROM t1;
-a
-2000-01-02 03:04:05
-SHOW CREATE TABLE t1;
-Table	Create Table
-t1	CREATE TABLE `t1` (
-  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY HASH (TO_DAYS(a)) */
-INSERT INTO t1 VALUES ('2001-02-03 04:05:06');
-SELECT * FROM t1;
-a
-2000-01-02 03:04:05
-2001-02-03 04:05:06
-ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
-Warnings:
-Warning	1486	Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
-ALTER TABLE t1
-PARTITION BY RANGE (TO_DAYS(a))
-(PARTITION p0 VALUES LESS THAN (10000),
-PARTITION p1 VALUES LESS THAN (MAXVALUE));
-ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
-SHOW CREATE TABLE t1;
-Table	Create Table
-t1	CREATE TABLE `t1` (
-  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY HASH (TO_DAYS(a))
-PARTITIONS 3 */
-CREATE TABLE t2 LIKE t1;
-SHOW CREATE TABLE t2;
-Table	Create Table
-t2	CREATE TABLE `t2` (
-  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY HASH (TO_DAYS(a))
-PARTITIONS 3 */
-Warnings:
-Warning	1486	Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
-DROP TABLE t2;
-CREATE TABLE t2 SELECT * FROM t1;
-DROP TABLE t2;
-ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a));
-SHOW CREATE TABLE t1;
-Table	Create Table
-t1	CREATE TABLE `t1` (
-  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY HASH (UNIX_TIMESTAMP(a)) */
-ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
-SHOW CREATE TABLE t1;
-Table	Create Table
-t1	CREATE TABLE `t1` (
-  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY HASH (UNIX_TIMESTAMP(a))
-PARTITIONS 3 */
-SELECT * FROM t1;
-a
-2000-01-02 03:04:05
-2001-02-03 04:05:06
-DROP TABLE t1;
-#
-# Bug#49161: Out of memory; restart server and try again (needed 2 bytes)
-#
-CREATE TABLE t1 (a INT) PARTITION BY HASH (a);
-FLUSH TABLES;
-CHECK TABLE t1;
-Table	Op	Msg_type	Msg_text
-test.t1	check	Error	Failed to read from the .par file
-test.t1	check	Error	Incorrect information in file: './test/t1.frm'
-test.t1	check	error	Corrupt
-SELECT * FROM t1;
-ERROR HY000: Failed to read from the .par file
-# Note that it is currently impossible to drop a partitioned table
-# without the .par file
-DROP TABLE t1;
-ERROR 42S02: Unknown table 't1'
 #
 # Bug#49477: Assertion `0' failed in ha_partition.cc:5530
 # with temporary table and partitions
@@ -831,10 +744,10 @@ Table	Create Table
 t1	CREATE TABLE `t1` (
   `id` int(11) DEFAULT NULL,
   `purchased` date DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
+) ENGINE=<curr_engine> DEFAULT CHARSET=latin1
 /*!50100 PARTITION BY RANGE (YEAR(purchased))
 SUBPARTITION BY HASH (TO_DAYS(purchased))
-(PARTITION p0 VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
+(PARTITION p0 VALUES LESS THAN MAXVALUE ENGINE = <curr_engine>) */
 DROP TABLE t1;
 CREATE TABLE t1 (id INT, purchased DATE)
 PARTITION BY RANGE(YEAR(purchased))
@@ -852,12 +765,12 @@ Table	Create Table
 t1	CREATE TABLE `t1` (
   `id` int(11) DEFAULT NULL,
   `purchased` date DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
+) ENGINE=<curr_engine> DEFAULT CHARSET=latin1
 /*!50100 PARTITION BY RANGE (YEAR(purchased))
 SUBPARTITION BY HASH (TO_DAYS(purchased))
 (PARTITION p0 VALUES LESS THAN MAXVALUE
- (SUBPARTITION sp0 ENGINE = MyISAM,
-  SUBPARTITION sp1 ENGINE = MyISAM)) */
+ (SUBPARTITION sp0 ENGINE = <curr_engine>,
+  SUBPARTITION sp1 ENGINE = <curr_engine>)) */
 DROP TABLE t1;
 CREATE TABLE t1 (id INT, purchased DATE)
 PARTITION BY RANGE(YEAR(purchased))
@@ -872,53 +785,11 @@ Table	Create Table
 t1	CREATE TABLE `t1` (
   `id` int(11) DEFAULT NULL,
   `purchased` date DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
+) ENGINE=<curr_engine> DEFAULT CHARSET=latin1
 /*!50100 PARTITION BY RANGE (YEAR(purchased))
-(PARTITION p0 VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
+(PARTITION p0 VALUES LESS THAN MAXVALUE ENGINE = <curr_engine>) */
 DROP TABLE t1;
 SET @@sql_mode= @org_mode;
-#
-# Bug#50392: insert_id is not reset for partitioned tables
-#            auto_increment on duplicate entry
-CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY);
-SET INSERT_ID= 13;
-INSERT INTO t1 VALUES (NULL);
-SET INSERT_ID= 12;
-INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
-ERROR 23000: Duplicate entry '13' for key 'PRIMARY'
-SHOW CREATE TABLE t1;
-Table	Create Table
-t1	CREATE TABLE `t1` (
-  `a` int(11) NOT NULL AUTO_INCREMENT,
-  PRIMARY KEY (`a`)
-) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=latin1
-INSERT INTO t1 VALUES (NULL);
-SELECT * FROM t1;
-a
-12
-13
-14
-DROP TABLE t1;
-CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) PARTITION BY KEY(a);
-SET INSERT_ID= 13;
-INSERT INTO t1 VALUES (NULL);
-SET INSERT_ID= 12;
-INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
-ERROR 23000: Duplicate entry '13' for key 'PRIMARY'
-SHOW CREATE TABLE t1;
-Table	Create Table
-t1	CREATE TABLE `t1` (
-  `a` int(11) NOT NULL AUTO_INCREMENT,
-  PRIMARY KEY (`a`)
-) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY KEY (a) */
-INSERT INTO t1 VALUES (NULL);
-SELECT * FROM t1;
-a
-12
-13
-14
-DROP TABLE t1;
 CREATE TABLE t1 (a INTEGER NOT NULL, PRIMARY KEY (a));
 INSERT INTO t1 VALUES (1),(1);
 ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
@@ -928,19 +799,6 @@ PARTITION BY KEY (a) PARTITIONS 2;
 INSERT INTO t1 VALUES (1),(1);
 ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
 DROP TABLE t1;
-CREATE TABLE t1 (a INT)
-PARTITION BY HASH (a)
-( PARTITION p0 ENGINE=MyISAM,
-PARTITION p1);
-ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
-CREATE TABLE t1 (a INT)
-PARTITION BY LIST (a)
-SUBPARTITION BY HASH (a)
-( PARTITION p0 VALUES IN (0)
-( SUBPARTITION s0, SUBPARTITION s1 ENGINE=MyISAM, SUBPARTITION s2),
-PARTITION p1 VALUES IN (1)
-( SUBPARTITION s3 ENGINE=MyISAM, SUBPARTITION s4, SUBPARTITION s5 ENGINE=MyISAM));
-ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
 CREATE TABLE t1 (
 a int
 )

=== renamed file 'mysql-test/r/partition_not_embedded.result' => 'mysql-test/r/partition_myisam.result'
--- a/mysql-test/r/partition_not_embedded.result	2009-07-27 11:20:43 +0000
+++ b/mysql-test/r/partition_myisam.result	2011-03-31 12:38:54 +0000
@@ -1,6 +1,166 @@
 DROP TABLE IF EXISTS t1, t2;
+#
+# Bug#50036: Inconsistent errors when using TIMESTAMP
+#            columns/expressions
+# Added test with existing TIMESTAMP partitioning (when it was allowed).
+CREATE TABLE t1 (a TIMESTAMP)
+ENGINE = MyISAM
+PARTITION BY HASH (UNIX_TIMESTAMP(a));
+INSERT INTO t1 VALUES ('2000-01-02 03:04:05');
+SELECT * FROM t1;
+a
+2000-01-02 03:04:05
+FLUSH TABLES;
+# replacing t1.frm with TO_DAYS(a) which was allowed earlier.
+# Disable warnings, since the result would differ when running with
+# --ps-protocol (only for the 'SELECT * FROM t1' statement).
+SELECT * FROM t1;
+a
+2000-01-02 03:04:05
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=<curr_engine> DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (TO_DAYS(a)) */
+INSERT INTO t1 VALUES ('2001-02-03 04:05:06');
+SELECT * FROM t1;
+a
+2000-01-02 03:04:05
+2001-02-03 04:05:06
+ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+Warnings:
+Warning	1486	Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+ALTER TABLE t1
+PARTITION BY RANGE (TO_DAYS(a))
+(PARTITION p0 VALUES LESS THAN (10000),
+PARTITION p1 VALUES LESS THAN (MAXVALUE));
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (TO_DAYS(a))
+PARTITIONS 3 */
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (TO_DAYS(a))
+PARTITIONS 3 */
+Warnings:
+Warning	1486	Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+DROP TABLE t2;
+CREATE TABLE t2 SELECT * FROM t1;
+DROP TABLE t2;
+ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a));
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (UNIX_TIMESTAMP(a)) */
+ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (UNIX_TIMESTAMP(a))
+PARTITIONS 3 */
+SELECT * FROM t1;
+a
+2000-01-02 03:04:05
+2001-02-03 04:05:06
+DROP TABLE t1;
+#
+# Bug#31931: Mix of handlers error message
+#
+CREATE TABLE t1 (a INT)
+PARTITION BY HASH (a)
+( PARTITION p0 ENGINE=MyISAM,
+PARTITION p1);
+ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
+CREATE TABLE t1 (a INT)
+PARTITION BY LIST (a)
+SUBPARTITION BY HASH (a)
+( PARTITION p0 VALUES IN (0)
+( SUBPARTITION s0, SUBPARTITION s1 ENGINE=MyISAM, SUBPARTITION s2),
+PARTITION p1 VALUES IN (1)
+( SUBPARTITION s3 ENGINE=MyISAM, SUBPARTITION s4, SUBPARTITION s5 ENGINE=MyISAM));
+ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
+#
+# Bug#49161: Out of memory; restart server and try again (needed 2 bytes)
+#
+CREATE TABLE t1 (a INT)
+ENGINE = MyISAM
+PARTITION BY HASH (a);
+FLUSH TABLES;
+CHECK TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	check	Error	Failed to read from the .par file
+test.t1	check	Error	Incorrect information in file: './test/t1.frm'
+test.t1	check	error	Corrupt
+SELECT * FROM t1;
+ERROR HY000: Failed to read from the .par file
+# Note that it is currently impossible to drop a partitioned table
+# without the .par file
+DROP TABLE t1;
+ERROR 42S02: Unknown table 't1'
+#
+# Bug#50392: insert_id is not reset for partitioned tables
+#            auto_increment on duplicate entry
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY)
+ENGINE = MyISAM;
+SET INSERT_ID= 13;
+INSERT INTO t1 VALUES (NULL);
+SET INSERT_ID= 12;
+# For transactional engines, 12 will not be inserted, since the failing
+# statement is rolled back.
+INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
+ERROR 23000: Duplicate entry '13' for key 'PRIMARY'
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL AUTO_INCREMENT,
+  PRIMARY KEY (`a`)
+) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (NULL);
+# NOTE: 12 exists only in non transactional engines!
+SELECT * FROM t1;
+a
+12
+13
+14
+DROP TABLE t1;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY)
+ENGINE = MyISAM
+PARTITION BY KEY(a);
+SET INSERT_ID= 13;
+INSERT INTO t1 VALUES (NULL);
+SET INSERT_ID= 12;
+INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
+ERROR 23000: Duplicate entry '13' for key 'PRIMARY'
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL AUTO_INCREMENT,
+  PRIMARY KEY (`a`)
+) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY KEY (a) */
+INSERT INTO t1 VALUES (NULL);
+SELECT * FROM t1;
+a
+12
+13
+14
+DROP TABLE t1;
 # Bug#30102 test
 CREATE TABLE t1 (a INT)
+ENGINE = MyISAM
 PARTITION BY RANGE (a)
 (PARTITION p0 VALUES LESS THAN (6),
 PARTITION `p1....................` VALUES LESS THAN (9),

=== modified file 'mysql-test/r/partition_symlink.result'
--- a/mysql-test/r/partition_symlink.result	2009-10-21 11:59:11 +0000
+++ b/mysql-test/r/partition_symlink.result	2011-03-31 12:38:54 +0000
@@ -6,11 +6,12 @@ DROP DATABASE IF EXISTS mysqltest2;
 CREATE USER mysqltest_1@localhost;
 CREATE DATABASE mysqltest2;
 USE mysqltest2;
-CREATE TABLE t1 (a INT);
+CREATE TABLE t1 (a INT) ENGINE = MyISAM;
 INSERT INTO t1 VALUES (0);
 # user mysqltest_1:
 USE test;
 CREATE TABLE t1 (a INT)
+ENGINE = MyISAM
 PARTITION BY LIST (a) (
 PARTITION p0 VALUES IN (0)
 DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp'
@@ -47,6 +48,7 @@ DROP DATABASE mysqltest2;
 CREATE DATABASE mysqltest2;
 USE mysqltest2;
 CREATE TABLE t1 (a INT)
+ENGINE = MyISAM
 PARTITION BY LIST (a) (
 PARTITION p0 VALUES IN (0)
 DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp'
@@ -58,6 +60,7 @@ DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp'
 # user mysqltest_1:
 USE test;
 CREATE TABLE t1 (a INT)
+ENGINE = MyISAM
 PARTITION BY LIST (a) (
 PARTITION p0 VALUES IN (0)
 DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp'
@@ -68,6 +71,7 @@ DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp'
    );
 Got one of the listed errors
 CREATE TABLE t1 (a INT)
+ENGINE = MyISAM
 PARTITION BY LIST (a) (
 PARTITION p0 VALUES IN (0)
 DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp'
@@ -82,6 +86,7 @@ DROP DATABASE mysqltest2;
 USE test;
 DROP USER mysqltest_1@localhost;
 create table t2 (i int )
+ENGINE = MyISAM
 partition by range (i)
 (
 partition p01 values less than (1000)
@@ -94,6 +99,7 @@ select @@sql_mode;
 @@sql_mode
 NO_DIR_IN_CREATE
 create table t1 (i int )
+ENGINE = MyISAM
 partition by range (i)
 (
 partition p01 values less than (1000)
@@ -113,10 +119,12 @@ t2	CREATE TABLE `t2` (
 DROP TABLE t1, t2;
 set @@sql_mode=@org_mode;
 create table t1 (a int)
+ENGINE = MyISAM
 partition by key (a)
 (partition p0 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data');
 Got one of the listed errors
 create table t1 (a int)
+ENGINE = MyISAM
 partition by key (a)
 (partition p0,
 partition p1 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data');

=== added file 'mysql-test/suite/innodb/r/innodb_bug60196.result'
--- a/mysql-test/suite/innodb/r/innodb_bug60196.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_bug60196.result	2011-03-09 17:15:55 +0000
@@ -0,0 +1,73 @@
+CREATE TABLE Bug_60196_FK1 (Primary_Key INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE Bug_60196_FK2 (Primary_Key INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE Bug_60196 (
+FK1_Key INT NOT NULL,
+FK2_Key INT NOT NULL,
+PRIMARY KEY (FK2_Key, FK1_Key),
+KEY FK1_Key (FK1_Key),
+KEY FK2_Key (FK2_Key),
+CONSTRAINT FK_FK1 FOREIGN KEY (FK1_Key)
+REFERENCES Bug_60196_FK1 (Primary_Key)
+ON DELETE CASCADE
+ON UPDATE CASCADE,
+CONSTRAINT FK_FK2 FOREIGN KEY (FK2_Key)
+REFERENCES Bug_60196_FK2 (Primary_Key)
+ON DELETE CASCADE
+ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT INTO Bug_60196_FK1 VALUES (1), (2), (3), (4), (5);
+INSERT INTO Bug_60196_FK2 VALUES (1), (2), (3), (4), (5);
+INSERT INTO Bug_60196 VALUES (1, 1);
+INSERT INTO Bug_60196 VALUES (1, 2);
+INSERT INTO Bug_60196 VALUES (1, 3);
+INSERT INTO Bug_60196 VALUES (1, 99);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`bug_60196`, CONSTRAINT `FK_FK2` FOREIGN KEY (`FK2_Key`) REFERENCES `Bug_60196_FK2` (`Primary_Key`) ON DELETE CASCADE ON UPDATE CASCADE)
+INSERT INTO Bug_60196 VALUES (99, 1);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`bug_60196`, CONSTRAINT `FK_FK1` FOREIGN KEY (`FK1_Key`) REFERENCES `Bug_60196_FK1` (`Primary_Key`) ON DELETE CASCADE ON UPDATE CASCADE)
+SELECT * FROM bug_60196_FK1;
+Primary_Key
+1
+2
+3
+4
+5
+SELECT * FROM bug_60196_FK2;
+Primary_Key
+1
+2
+3
+4
+5
+SELECT * FROM bug_60196;
+FK1_Key	FK2_Key
+1	1
+1	2
+1	3
+# Stop server
+# Restart server.
+#
+# Try to insert more to the example table with foreign keys.
+# Bug60196 causes the foreign key file not to be found after
+# the resstart above.
+#
+SELECT * FROM Bug_60196;
+FK1_Key	FK2_Key
+1	1
+1	2
+1	3
+INSERT INTO Bug_60196 VALUES (2, 1);
+INSERT INTO Bug_60196 VALUES (2, 2);
+INSERT INTO Bug_60196 VALUES (2, 3);
+SELECT * FROM Bug_60196;
+FK1_Key	FK2_Key
+1	1
+1	2
+1	3
+2	1
+2	2
+2	3
+
+# Clean up.
+DROP TABLE Bug_60196;
+DROP TABLE Bug_60196_FK1;
+DROP TABLE Bug_60196_FK2;

=== added file 'mysql-test/suite/innodb/t/innodb_bug60196-master.opt'
--- a/mysql-test/suite/innodb/t/innodb_bug60196-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_bug60196-master.opt	2011-03-07 15:42:07 +0000
@@ -0,0 +1 @@
+--lower-case-table-names=2

=== added file 'mysql-test/suite/innodb/t/innodb_bug60196.test'
--- a/mysql-test/suite/innodb/t/innodb_bug60196.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_bug60196.test	2011-03-09 17:15:55 +0000
@@ -0,0 +1,87 @@
+# Bug#60196 - Setting lowercase_table_names to 2 on Windows causing
+# Foreign Key problems after an engine is restarted.
+
+# This test case needs InnoDB, a lowercase file system,
+# lower-case-table-names=2, and cannot use the embedded server
+# because it restarts the server.
+--source include/not_embedded.inc
+--source include/have_lowercase2.inc
+--source include/have_case_insensitive_file_system.inc
+--source include/have_innodb.inc
+
+#
+# Create test data.
+#
+CREATE TABLE Bug_60196_FK1 (Primary_Key INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE Bug_60196_FK2 (Primary_Key INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE Bug_60196 (
+  FK1_Key INT NOT NULL,
+  FK2_Key INT NOT NULL,
+  PRIMARY KEY (FK2_Key, FK1_Key),
+  KEY FK1_Key (FK1_Key),
+  KEY FK2_Key (FK2_Key),
+  CONSTRAINT FK_FK1 FOREIGN KEY (FK1_Key)
+    REFERENCES Bug_60196_FK1 (Primary_Key)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE,
+  CONSTRAINT FK_FK2 FOREIGN KEY (FK2_Key)
+    REFERENCES Bug_60196_FK2 (Primary_Key)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT INTO Bug_60196_FK1 VALUES (1), (2), (3), (4), (5);
+INSERT INTO Bug_60196_FK2 VALUES (1), (2), (3), (4), (5);
+INSERT INTO Bug_60196 VALUES (1, 1);
+INSERT INTO Bug_60196 VALUES (1, 2);
+INSERT INTO Bug_60196 VALUES (1, 3);
+--error ER_NO_REFERENCED_ROW_2
+INSERT INTO Bug_60196 VALUES (1, 99);
+--error ER_NO_REFERENCED_ROW_2
+INSERT INTO Bug_60196 VALUES (99, 1);
+
+SELECT * FROM bug_60196_FK1;
+SELECT * FROM bug_60196_FK2;
+SELECT * FROM bug_60196;
+
+--echo # Stop server
+
+# Write file to make mysql-test-run.pl wait for the server to stop
+-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+# Send a shutdown request to the server
+-- shutdown_server 10
+
+# Call script that will poll the server waiting for it to disapear
+-- source include/wait_until_disconnected.inc
+
+--echo # Restart server.
+
+# Write file to make mysql-test-run.pl start up the server again
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+# Turn on reconnect
+--enable_reconnect
+
+# Call script that will poll the server waiting for it to be back online again
+--source include/wait_until_connected_again.inc
+
+# Turn off reconnect again
+--disable_reconnect
+
+--echo #
+--echo # Try to insert more to the example table with foreign keys.
+--echo # Bug60196 causes the foreign key file not to be found after
+--echo # the resstart above.
+--echo #
+SELECT * FROM Bug_60196;
+INSERT INTO Bug_60196 VALUES (2, 1);
+INSERT INTO Bug_60196 VALUES (2, 2);
+INSERT INTO Bug_60196 VALUES (2, 3);
+SELECT * FROM Bug_60196;
+
+--echo
+--echo # Clean up.
+DROP TABLE Bug_60196;
+DROP TABLE Bug_60196_FK1;
+DROP TABLE Bug_60196_FK2;
+

=== modified file 'mysql-test/t/func_group.test'
--- a/mysql-test/t/func_group.test	2011-02-02 09:18:44 +0000
+++ b/mysql-test/t/func_group.test	2011-04-02 19:41:10 +0000
@@ -1117,6 +1117,16 @@ SELECT RELEASE_LOCK('aaaaaaaaaaaaaaaaa')
 
 --enable_result_log
 
+
+--echo #
+--echo # Bug #11766094 - 59132: MIN() AND MAX() REMOVE UNSIGNEDNESS 
+--echo #
+
+CREATE TABLE t1 (a BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (18446668621106209655);
+SELECT MAX(LENGTH(a)), LENGTH(MAX(a)), MIN(a), MAX(a), CONCAT(MIN(a)), CONCAT(MAX(a)) FROM t1;
+DROP TABLE t1;
+
 --echo #
 --echo End of 5.1 tests
 

=== modified file 'mysql-test/t/partition_error.test'
--- a/mysql-test/t/partition_error.test	2011-03-08 17:39:25 +0000
+++ b/mysql-test/t/partition_error.test	2011-03-31 12:38:54 +0000
@@ -741,65 +741,9 @@ DROP TABLE t1;
 CREATE TABLE t1 (c TIMESTAMP)
 PARTITION BY HASH (c) PARTITIONS 4;
 
+--echo # Moved to partition_myisam, since it was MyISAM specific
 --echo # Added test with existing TIMESTAMP partitioning (when it was allowed).
 
-CREATE TABLE t1 (a TIMESTAMP)
-PARTITION BY HASH (UNIX_TIMESTAMP(a));
-INSERT INTO t1 VALUES ('2000-01-02 03:04:05');
---sorted_result
-SELECT * FROM t1;
-FLUSH TABLES;
---echo # replacing t1.frm with TO_DAYS(a) which was allowed earlier.
---remove_file $MYSQLD_DATADIR/test/t1.frm
---copy_file std_data/parts/t1TIMESTAMP.frm $MYSQLD_DATADIR/test/t1.frm
---echo # Disable warnings, since the result would differ when running with
---echo # --ps-protocol (only for the 'SELECT * FROM t1' statement).
---disable_warnings
---sorted_result
-SELECT * FROM t1;
---enable_warnings
-SHOW CREATE TABLE t1;
-INSERT INTO t1 VALUES ('2001-02-03 04:05:06');
---sorted_result
-SELECT * FROM t1;
-ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
---error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
-ALTER TABLE t1
-PARTITION BY RANGE (TO_DAYS(a))
-(PARTITION p0 VALUES LESS THAN (10000),
- PARTITION p1 VALUES LESS THAN (MAXVALUE));
-SHOW CREATE TABLE t1;
-CREATE TABLE t2 LIKE t1;
-SHOW CREATE TABLE t2;
-DROP TABLE t2;
-CREATE TABLE t2 SELECT * FROM t1;
-DROP TABLE t2;
-ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a));
-SHOW CREATE TABLE t1;
-ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
-SHOW CREATE TABLE t1;
---sorted_result
-SELECT * FROM t1;
-DROP TABLE t1;
-
---echo #
---echo # Bug#49161: Out of memory; restart server and try again (needed 2 bytes)
---echo #
-CREATE TABLE t1 (a INT) PARTITION BY HASH (a);
-FLUSH TABLES;
---remove_file $MYSQLD_DATADIR/test/t1.par
---replace_result $MYSQLD_DATADIR ./
-CHECK TABLE t1;
---error ER_FAILED_READ_FROM_PAR_FILE
-SELECT * FROM t1;
---echo # Note that it is currently impossible to drop a partitioned table
---echo # without the .par file
---error ER_BAD_TABLE_ERROR
-DROP TABLE t1;
---remove_file $MYSQLD_DATADIR/test/t1.frm
---remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYI
---remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYD
-
 --echo #
 --echo # Bug#49477: Assertion `0' failed in ha_partition.cc:5530
 --echo # with temporary table and partitions
@@ -820,6 +764,7 @@ SUBPARTITION BY HASH(TO_DAYS(purchased))
 (PARTITION p0 VALUES LESS THAN MAXVALUE
   DATA DIRECTORY = '/tmp/not-existing' 
   INDEX DIRECTORY = '/tmp/not-existing');
+--replace_result MyISAM <curr_engine> InnoDB <curr_engine>
 SHOW CREATE TABLE t1;
 DROP TABLE t1;
 CREATE TABLE t1 (id INT, purchased DATE)
@@ -830,6 +775,7 @@ SUBPARTITION BY HASH(TO_DAYS(purchased))
    DATA DIRECTORY = '/tmp/not-existing' 
    INDEX DIRECTORY = '/tmp/not-existing',
   SUBPARTITION sp1));
+--replace_result MyISAM <curr_engine> InnoDB <curr_engine>
 SHOW CREATE TABLE t1;
 DROP TABLE t1;
 CREATE TABLE t1 (id INT, purchased DATE)
@@ -837,34 +783,11 @@ PARTITION BY RANGE(YEAR(purchased))
 (PARTITION p0 VALUES LESS THAN MAXVALUE
   DATA DIRECTORY = '/tmp/not-existing' 
   INDEX DIRECTORY = '/tmp/not-existing');
+--replace_result MyISAM <curr_engine> InnoDB <curr_engine>
 SHOW CREATE TABLE t1;
 DROP TABLE t1;
 SET @@sql_mode= @org_mode;
 
---echo #
---echo # Bug#50392: insert_id is not reset for partitioned tables
---echo #            auto_increment on duplicate entry
-CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY);
-SET INSERT_ID= 13;
-INSERT INTO t1 VALUES (NULL);
-SET INSERT_ID= 12;
---error ER_DUP_ENTRY
-INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
-SHOW CREATE TABLE t1;
-INSERT INTO t1 VALUES (NULL);
-SELECT * FROM t1;
-DROP TABLE t1;
-CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) PARTITION BY KEY(a);
-SET INSERT_ID= 13;
-INSERT INTO t1 VALUES (NULL);
-SET INSERT_ID= 12;
---error ER_DUP_ENTRY
-INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
-SHOW CREATE TABLE t1;
-INSERT INTO t1 VALUES (NULL);
-SELECT * FROM t1;
-DROP TABLE t1;
-
 #
 # Bug#38719: Partitioning returns a different error code for a
 # duplicate key error
@@ -879,24 +802,6 @@ INSERT INTO t1 VALUES (1),(1);
 DROP TABLE t1;
 
 #
-# Bug#31931: Mix of handlers error message
-#
---error ER_MIX_HANDLER_ERROR
-CREATE TABLE t1 (a INT)
-PARTITION BY HASH (a)
-( PARTITION p0 ENGINE=MyISAM,
-  PARTITION p1);
---error ER_MIX_HANDLER_ERROR
-CREATE TABLE t1 (a INT)
-PARTITION BY LIST (a)
-SUBPARTITION BY HASH (a)
-( PARTITION p0 VALUES IN (0)
-( SUBPARTITION s0, SUBPARTITION s1 ENGINE=MyISAM, SUBPARTITION s2),
-  PARTITION p1 VALUES IN (1)
-( SUBPARTITION s3 ENGINE=MyISAM, SUBPARTITION s4, SUBPARTITION s5 ENGINE=MyISAM));
-
-
-#
 # Bug 29368:
 # Incorrect error, 1467, for syntax error when creating partition
 --error ER_PARTITION_REQUIRES_VALUES_ERROR
@@ -912,7 +817,7 @@ PARTITION BY RANGE (a)
 #
 # Partition by key stand-alone error
 #
---error 1064
+--error ER_PARSE_ERROR
 partition by list (a)
 partitions 3
 (partition x1 values in (1,2,9,4) tablespace ts1,
@@ -949,7 +854,7 @@ partitions 3
 #
 # Partition by key, partition function not allowed
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -964,7 +869,7 @@ partitions 3
 #
 # Partition by key, no partition name
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -995,7 +900,7 @@ select load_file('$MYSQLD_DATADIR/test/t
 #
 # Partition by hash, invalid field in function
 #
---error 1054
+--error ER_BAD_FIELD_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1025,7 +930,7 @@ partitions 3
 #
 # Partition by key specified 3 partitions but only defined 2 => error
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1038,7 +943,7 @@ partitions 3
 #
 # Partition by hash, random function
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1051,7 +956,7 @@ partitions 2
 #
 # Partition by range, random function
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1064,7 +969,7 @@ partitions 2
 #
 # Partition by list, random function
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1200,7 +1105,7 @@ select load_file('$MYSQLD_DATADIR/test/t
 #
 # Subpartition by hash, no partitions defined, wrong subpartition function
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1227,7 +1132,7 @@ select load_file('$MYSQLD_DATADIR/test/t
 #
 # Subpartition by hash, no partitions defined, wrong subpartition function
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1268,7 +1173,7 @@ subpartition by hash (3+4);
 #
 # Subpartition by hash, no partitions defined, wrong subpartition function
 #
---error 1054
+--error ER_BAD_FIELD_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1294,7 +1199,7 @@ select load_file('$MYSQLD_DATADIR/test/t
 #
 # Partition by range, invalid field in function
 #
---error 1054
+--error ER_BAD_FIELD_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1448,7 +1353,7 @@ partitions 2
 #
 # Subpartition by hash, wrong number of subpartitions
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1468,7 +1373,7 @@ subpartitions 3
 #
 # Subpartition by hash, wrong number of subpartitions
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1488,7 +1393,7 @@ subpartition by hash (a+b)
 #
 # Subpartition by list => error
 #
---error 1064 
+--error ER_PARSE_ERROR 
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1507,7 +1412,7 @@ subpartition by list (a+b)
 #
 # Subpartition by list => error
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1551,7 +1456,7 @@ partitions 2
 #
 # Partition by list, invalid field in function
 #
---error 1054
+--error ER_BAD_FIELD_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1635,7 +1540,7 @@ partitions 2
 #
 # Partition by list, missing parenthesis
 #
---error 1064
+--error ER_PARSE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -1649,7 +1554,7 @@ partitions 2
 #
 # Bug #13439: Crash when LESS THAN (non-literal)
 #
---error 1054
+--error ER_BAD_FIELD_ERROR
 CREATE TABLE t1 (a int)
 PARTITION BY RANGE (a)
 (PARTITION p0 VALUES LESS THAN (x1));
@@ -1676,13 +1581,13 @@ partition by range (ascii(v))
 (partition p0 values less than (10));
 #drop table t1;
 
--- error 1064
+-- error ER_PARSE_ERROR
 create table t1 (a int)
 partition by hash (rand(a));
--- error 1064
+-- error ER_PARSE_ERROR
 create table t1 (a int)
 partition by hash(CURTIME() + a);
--- error 1064
+-- error ER_PARSE_ERROR
 create table t1 (a int)
 partition by hash (NOW()+a);
 -- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED

=== renamed file 'mysql-test/t/partition_not_embedded.test' => 'mysql-test/t/partition_myisam.test'
--- a/mysql-test/t/partition_not_embedded.test	2009-07-27 11:20:43 +0000
+++ b/mysql-test/t/partition_myisam.test	2011-03-31 12:38:54 +0000
@@ -1,15 +1,135 @@
 -- source include/have_partition.inc
--- source include/not_embedded.inc
+
 --disable_warnings
 DROP TABLE IF EXISTS t1, t2;
 --enable_warnings
+
+# These tests is only useful when running on MyISAM,
+# due to DATA/INDEX directory, non transactional behavior, tests with MyISAM
+# files etc.
+
 let $MYSQLD_DATADIR= `SELECT @@datadir`;
 
+
+--echo #
+--echo # Bug#50036: Inconsistent errors when using TIMESTAMP
+--echo #            columns/expressions
+
+--echo # Added test with existing TIMESTAMP partitioning (when it was allowed).
+CREATE TABLE t1 (a TIMESTAMP)
+ENGINE = MyISAM
+PARTITION BY HASH (UNIX_TIMESTAMP(a));
+INSERT INTO t1 VALUES ('2000-01-02 03:04:05');
+--sorted_result
+SELECT * FROM t1;
+FLUSH TABLES;
+--echo # replacing t1.frm with TO_DAYS(a) which was allowed earlier.
+--remove_file $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/parts/t1TIMESTAMP.frm $MYSQLD_DATADIR/test/t1.frm
+--echo # Disable warnings, since the result would differ when running with
+--echo # --ps-protocol (only for the 'SELECT * FROM t1' statement).
+--disable_warnings
+--sorted_result
+SELECT * FROM t1;
+--enable_warnings
+--replace_result MyISAM <curr_engine> InnoDB <curr_engine>
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES ('2001-02-03 04:05:06');
+--sorted_result
+SELECT * FROM t1;
+ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE t1
+PARTITION BY RANGE (TO_DAYS(a))
+(PARTITION p0 VALUES LESS THAN (10000),
+ PARTITION p1 VALUES LESS THAN (MAXVALUE));
+SHOW CREATE TABLE t1;
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+CREATE TABLE t2 SELECT * FROM t1;
+DROP TABLE t2;
+ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a));
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+SHOW CREATE TABLE t1;
+--sorted_result
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Bug#31931: Mix of handlers error message
+--echo #
+--error ER_MIX_HANDLER_ERROR
+CREATE TABLE t1 (a INT)
+PARTITION BY HASH (a)
+( PARTITION p0 ENGINE=MyISAM,
+  PARTITION p1);
+--error ER_MIX_HANDLER_ERROR
+CREATE TABLE t1 (a INT)
+PARTITION BY LIST (a)
+SUBPARTITION BY HASH (a)
+( PARTITION p0 VALUES IN (0)
+( SUBPARTITION s0, SUBPARTITION s1 ENGINE=MyISAM, SUBPARTITION s2),
+  PARTITION p1 VALUES IN (1)
+( SUBPARTITION s3 ENGINE=MyISAM, SUBPARTITION s4, SUBPARTITION s5 ENGINE=MyISAM));
+
+--echo #
+--echo # Bug#49161: Out of memory; restart server and try again (needed 2 bytes)
+--echo #
+CREATE TABLE t1 (a INT)
+ENGINE = MyISAM
+PARTITION BY HASH (a);
+FLUSH TABLES;
+--remove_file $MYSQLD_DATADIR/test/t1.par
+--replace_result $MYSQLD_DATADIR ./
+CHECK TABLE t1;
+--error ER_FAILED_READ_FROM_PAR_FILE
+SELECT * FROM t1;
+--echo # Note that it is currently impossible to drop a partitioned table
+--echo # without the .par file
+--error ER_BAD_TABLE_ERROR
+DROP TABLE t1;
+--remove_file $MYSQLD_DATADIR/test/t1.frm
+--remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYI
+--remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYD
+
+--echo #
+--echo # Bug#50392: insert_id is not reset for partitioned tables
+--echo #            auto_increment on duplicate entry
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY)
+ENGINE = MyISAM;
+SET INSERT_ID= 13;
+INSERT INTO t1 VALUES (NULL);
+SET INSERT_ID= 12;
+--echo # For transactional engines, 12 will not be inserted, since the failing
+--echo # statement is rolled back.
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (NULL);
+--echo # NOTE: 12 exists only in non transactional engines!
+SELECT * FROM t1;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY)
+ENGINE = MyISAM
+PARTITION BY KEY(a);
+SET INSERT_ID= 13;
+INSERT INTO t1 VALUES (NULL);
+SET INSERT_ID= 12;
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (NULL);
+SELECT * FROM t1;
+DROP TABLE t1;
 #
 # Bug#30102: rename table does corrupt tables with partition files on failure
 #
 --echo # Bug#30102 test
 CREATE TABLE t1 (a INT)
+ENGINE = MyISAM
 PARTITION BY RANGE (a)
 (PARTITION p0 VALUES LESS THAN (6),
  PARTITION `p1....................` VALUES LESS THAN (9),

=== modified file 'mysql-test/t/partition_symlink.test'
--- a/mysql-test/t/partition_symlink.test	2008-09-06 00:51:17 +0000
+++ b/mysql-test/t/partition_symlink.test	2011-03-31 12:38:54 +0000
@@ -1,5 +1,6 @@
 # Test that must have symlink. eg. using DATA/INDEX DIR
 # (DATA/INDEX DIR requires symlinks)
+# This test is only useful for MyISAM, since no other engine supports DATA DIR
 -- source include/have_partition.inc
 -- source include/have_symlink.inc
 # remove the not_windows line after fixing bug#33687
@@ -33,13 +34,14 @@ DROP DATABASE IF EXISTS mysqltest2;
   CREATE USER mysqltest_1@localhost;
   CREATE DATABASE mysqltest2;
   USE mysqltest2;
-  CREATE TABLE t1 (a INT);
+  CREATE TABLE t1 (a INT) ENGINE = MyISAM;
   INSERT INTO t1 VALUES (0);
 connect(con1,localhost,mysqltest_1,,);
 -- echo # user mysqltest_1:
   USE test;
   -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
   eval CREATE TABLE t1 (a INT)
+   ENGINE = MyISAM
    PARTITION BY LIST (a) (
     PARTITION p0 VALUES IN (0)
      DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp'
@@ -82,6 +84,7 @@ connection default;
   USE mysqltest2;
   -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
   eval CREATE TABLE t1 (a INT)
+   ENGINE = MyISAM
    PARTITION BY LIST (a) (
     PARTITION p0 VALUES IN (0)
      DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp'
@@ -96,6 +99,7 @@ connection con1;
   -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
   -- error 1,1
   eval CREATE TABLE t1 (a INT)
+   ENGINE = MyISAM
    PARTITION BY LIST (a) (
     PARTITION p0 VALUES IN (0)
      DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp'
@@ -107,6 +111,7 @@ connection con1;
   -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
   -- error 1,1
   eval CREATE TABLE t1 (a INT)
+   ENGINE = MyISAM
    PARTITION BY LIST (a) (
     PARTITION p0 VALUES IN (0)
      DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp'
@@ -128,6 +133,7 @@ connection default;
 
 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR 
 eval create table t2 (i int )
+ENGINE = MyISAM
 partition by range (i)
 (
     partition p01 values less than (1000)
@@ -139,6 +145,7 @@ set @org_mode=@@sql_mode;
 set @@sql_mode='NO_DIR_IN_CREATE';
 select @@sql_mode;
 create table t1 (i int )
+ENGINE = MyISAM
 partition by range (i)
 (
     partition p01 values less than (1000)
@@ -157,6 +164,7 @@ set @@sql_mode=@org_mode;
 # Added ER_WRONG_TABLE_NAME and reported bug#39045
 -- error ER_WRONG_ARGUMENTS, ER_WRONG_TABLE_NAME
 create table t1 (a int)
+ENGINE = MyISAM
 partition by key (a)
 (partition p0 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data');
 
@@ -167,6 +175,7 @@ partition by key (a)
 # Added ER_WRONG_TABLE_NAME and reported bug#39045
 --error ER_WRONG_ARGUMENTS, ER_WRONG_TABLE_NAME
 create table t1 (a int)
+ENGINE = MyISAM
 partition by key (a)
 (partition p0,
  partition p1 DATA DIRECTORY 'part-data' INDEX DIRECTORY 'part-data');

=== modified file 'plugin/auth/auth_socket.c'
--- a/plugin/auth/auth_socket.c	2011-01-11 14:53:14 +0000
+++ b/plugin/auth/auth_socket.c	2011-04-05 12:25:19 +0000
@@ -17,7 +17,7 @@
 /**
   @file
 
-  socket_peercred authentication plugin.
+  auth_socket authentication plugin.
 
   Authentication is successful if the connection is done via a unix socket and
   the owner of the client process matches the user name that was used when

=== modified file 'sql/item.cc'
--- a/sql/item.cc	2011-03-30 07:25:49 +0000
+++ b/sql/item.cc	2011-04-02 19:41:10 +0000
@@ -7472,7 +7472,7 @@ String *Item_cache_int::val_str(String *
   DBUG_ASSERT(fixed == 1);
   if (!has_value())
     return NULL;
-  str->set(value, default_charset());
+  str->set_int(value, unsigned_flag, default_charset());
   return str;
 }
 

=== modified file 'storage/innobase/CMakeLists.txt'
--- a/storage/innobase/CMakeLists.txt	2011-02-22 05:04:08 +0000
+++ b/storage/innobase/CMakeLists.txt	2011-03-24 12:00:14 +0000
@@ -241,7 +241,6 @@ SET(INNOBASE_SOURCES	btr/btr0btr.c btr/b
 			row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c
 			srv/srv0srv.c srv/srv0start.c
 			sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c
-			thr/thr0loc.c
 			trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
 			trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
 			usr/usr0sess.c

=== modified file 'storage/innobase/btr/btr0cur.c'
--- a/storage/innobase/btr/btr0cur.c	2011-02-08 11:39:24 +0000
+++ b/storage/innobase/btr/btr0cur.c	2011-03-24 12:00:14 +0000
@@ -402,7 +402,7 @@ btr_cur_search_to_nth_level(
 
 	ut_ad(level == 0 || mode == PAGE_CUR_LE);
 	ut_ad(dict_index_check_search_tuple(index, tuple));
-	ut_ad(!dict_index_is_ibuf(index) || ibuf_inside());
+	ut_ad(!dict_index_is_ibuf(index) || ibuf_inside(mtr));
 	ut_ad(dtuple_check_typed(tuple));
 
 #ifdef UNIV_DEBUG
@@ -4904,27 +4904,45 @@ btr_copy_blob_prefix(
 
 /*******************************************************************//**
 Copies the prefix of a compressed BLOB.  The clustered index record
-that points to this BLOB must be protected by a lock or a page latch. */
+that points to this BLOB must be protected by a lock or a page latch.
+@return	number of bytes written to buf */
 static
-void
+ulint
 btr_copy_zblob_prefix(
 /*==================*/
-	z_stream*	d_stream,/*!< in/out: the decompressing stream */
+	byte*		buf,	/*!< out: the externally stored part of
+				the field, or a prefix of it */
+	ulint		len,	/*!< in: length of buf, in bytes */
 	ulint		zip_size,/*!< in: compressed BLOB page size */
 	ulint		space_id,/*!< in: space id of the BLOB pages */
 	ulint		page_no,/*!< in: page number of the first BLOB page */
 	ulint		offset)	/*!< in: offset on the first BLOB page */
 {
-	ulint	page_type = FIL_PAGE_TYPE_ZBLOB;
+	ulint		page_type = FIL_PAGE_TYPE_ZBLOB;
+	mem_heap_t*	heap;
+	int		err;
+	z_stream	d_stream;
+
+	d_stream.next_out = buf;
+	d_stream.avail_out = len;
+	d_stream.next_in = Z_NULL;
+	d_stream.avail_in = 0;
+
+	/* Zlib inflate needs 32 kilobytes for the default
+	window size, plus a few kilobytes for small objects. */
+	heap = mem_heap_create(40000);
+	page_zip_set_alloc(&d_stream, heap);
 
 	ut_ad(ut_is_2pow(zip_size));
 	ut_ad(zip_size >= PAGE_ZIP_MIN_SIZE);
 	ut_ad(zip_size <= UNIV_PAGE_SIZE);
 	ut_ad(space_id);
 
+	err = inflateInit(&d_stream);
+	ut_a(err == Z_OK);
+
 	for (;;) {
 		buf_page_t*	bpage;
-		int		err;
 		ulint		next_page_no;
 
 		/* There is no latch on bpage directly.  Instead,
@@ -4940,7 +4958,7 @@ btr_copy_zblob_prefix(
 				" compressed BLOB"
 				" page %lu space %lu\n",
 				(ulong) page_no, (ulong) space_id);
-			return;
+			goto func_exit;
 		}
 
 		if (UNIV_UNLIKELY
@@ -4966,13 +4984,13 @@ btr_copy_zblob_prefix(
 			offset += 4;
 		}
 
-		d_stream->next_in = bpage->zip.data + offset;
-		d_stream->avail_in = zip_size - offset;
+		d_stream.next_in = bpage->zip.data + offset;
+		d_stream.avail_in = zip_size - offset;
 
-		err = inflate(d_stream, Z_NO_FLUSH);
+		err = inflate(&d_stream, Z_NO_FLUSH);
 		switch (err) {
 		case Z_OK:
-			if (!d_stream->avail_out) {
+			if (!d_stream.avail_out) {
 				goto end_of_blob;
 			}
 			break;
@@ -4989,13 +5007,13 @@ inflate_error:
 				" compressed BLOB"
 				" page %lu space %lu returned %d (%s)\n",
 				(ulong) page_no, (ulong) space_id,
-				err, d_stream->msg);
+				err, d_stream.msg);
 		case Z_BUF_ERROR:
 			goto end_of_blob;
 		}
 
 		if (next_page_no == FIL_NULL) {
-			if (!d_stream->avail_in) {
+			if (!d_stream.avail_in) {
 				ut_print_timestamp(stderr);
 				fprintf(stderr,
 					"  InnoDB: unexpected end of"
@@ -5004,7 +5022,7 @@ inflate_error:
 					(ulong) page_no,
 					(ulong) space_id);
 			} else {
-				err = inflate(d_stream, Z_FINISH);
+				err = inflate(&d_stream, Z_FINISH);
 				switch (err) {
 				case Z_STREAM_END:
 				case Z_BUF_ERROR:
@@ -5016,7 +5034,7 @@ inflate_error:
 
 end_of_blob:
 			buf_page_release_zip(bpage);
-			return;
+			goto func_exit;
 		}
 
 		buf_page_release_zip(bpage);
@@ -5028,6 +5046,12 @@ end_of_blob:
 		offset = FIL_PAGE_NEXT;
 		page_type = FIL_PAGE_TYPE_ZBLOB2;
 	}
+
+func_exit:
+	inflateEnd(&d_stream);
+	mem_heap_free(heap);
+	UNIV_MEM_ASSERT_RW(buf, d_stream.total_out);
+	return(d_stream.total_out);
 }
 
 /*******************************************************************//**
@@ -5053,28 +5077,8 @@ btr_copy_externally_stored_field_prefix_
 	}
 
 	if (UNIV_UNLIKELY(zip_size)) {
-		int		err;
-		z_stream	d_stream;
-		mem_heap_t*	heap;
-
-		/* Zlib inflate needs 32 kilobytes for the default
-		window size, plus a few kilobytes for small objects. */
-		heap = mem_heap_create(40000);
-		page_zip_set_alloc(&d_stream, heap);
-
-		err = inflateInit(&d_stream);
-		ut_a(err == Z_OK);
-
-		d_stream.next_out = buf;
-		d_stream.avail_out = len;
-		d_stream.avail_in = 0;
-
-		btr_copy_zblob_prefix(&d_stream, zip_size,
-				      space_id, page_no, offset);
-		inflateEnd(&d_stream);
-		mem_heap_free(heap);
-		UNIV_MEM_ASSERT_RW(buf, d_stream.total_out);
-		return(d_stream.total_out);
+		return(btr_copy_zblob_prefix(buf, len, zip_size,
+					     space_id, page_no, offset));
 	} else {
 		return(btr_copy_blob_prefix(buf, len, space_id,
 					    page_no, offset));

=== modified file 'storage/innobase/btr/btr0sea.c'
--- a/storage/innobase/btr/btr0sea.c	2011-01-25 08:51:13 +0000
+++ b/storage/innobase/btr/btr0sea.c	2011-02-28 13:39:07 +0000
@@ -1213,8 +1213,8 @@ btr_search_drop_page_hash_when_freed(
 	having to fear a deadlock. */
 
 	block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH, NULL,
-				BUF_GET_IF_IN_POOL, __FILE__, __LINE__,
-				&mtr);
+				 BUF_PEEK_IF_IN_POOL, __FILE__, __LINE__,
+				 &mtr);
 	/* Because the buffer pool mutex was released by
 	buf_page_peek_if_search_hashed(), it is possible that the
 	block was removed from the buffer pool by another thread

=== modified file 'storage/innobase/buf/buf0buf.c'
--- a/storage/innobase/buf/buf0buf.c	2011-02-02 13:58:01 +0000
+++ b/storage/innobase/buf/buf0buf.c	2011-03-24 12:00:14 +0000
@@ -1233,7 +1233,7 @@ buf_pool_init_instance(
 
 		buf_pool->page_hash = hash_create(2 * buf_pool->curr_size);
 		buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size);
-		
+
 		buf_pool->last_printout_time = ut_time();
 	}
 	/* 2. Initialize flushing fields
@@ -1365,11 +1365,11 @@ buf_pool_drop_hash_index_instance(
 			/* block->is_hashed cannot be modified
 			when we have an x-latch on btr_search_latch;
 			see the comment in buf0buf.h */
-			
+
 			if (!block->is_hashed) {
 				continue;
 			}
-			
+
 			/* To follow the latching order, we
 			have to release btr_search_latch
 			before acquiring block->latch. */
@@ -1378,14 +1378,14 @@ buf_pool_drop_hash_index_instance(
 			we must rescan all blocks, because
 			some may become hashed again. */
 			*released_search_latch = TRUE;
-			
+
 			rw_lock_x_lock(&block->lock);
-			
+
 			/* This should be guaranteed by the
 			callers, which will be holding
 			btr_search_enabled_mutex. */
 			ut_ad(!btr_search_enabled);
-			
+
 			/* Because we did not buffer-fix the
 			block by calling buf_block_get_gen(),
 			it is possible that the block has been
@@ -1395,7 +1395,7 @@ buf_pool_drop_hash_index_instance(
 			block is mapped to.  All we want to do
 			is to drop any hash entries referring
 			to the page. */
-			
+
 			/* It is possible that
 			block->page.state != BUF_FILE_PAGE.
 			Even that does not matter, because
@@ -1403,18 +1403,18 @@ buf_pool_drop_hash_index_instance(
 			check block->is_hashed before doing
 			anything.  block->is_hashed can only
 			be set on uncompressed file pages. */
-			
+
 			btr_search_drop_page_hash_index(block);
-			
+
 			rw_lock_x_unlock(&block->lock);
-			
+
 			rw_lock_x_lock(&btr_search_latch);
-			
+
 			ut_ad(!btr_search_enabled);
 		}
 	}
 }
- 
+
 /********************************************************************//**
 Drops the adaptive hash index.  To prevent a livelock, this function
 is only to be called while holding btr_search_latch and while
@@ -1990,30 +1990,30 @@ buf_pool_resize(void)
 	ulint	min_change_size = 1048576 * srv_buf_pool_instances;
 
 	buf_pool_mutex_enter_all();
-  
+
   	if (srv_buf_pool_old_size == srv_buf_pool_size) {
-  
+
 		buf_pool_mutex_exit_all();
 
   		return;
 
   	} else if (srv_buf_pool_curr_size + min_change_size
 		   > srv_buf_pool_size) {
-  
+
 		change_size = (srv_buf_pool_curr_size - srv_buf_pool_size)
 			    / UNIV_PAGE_SIZE;
 
 		buf_pool_mutex_exit_all();
-  
+
   		/* Disable adaptive hash indexes and empty the index
   		in order to free up memory in the buffer pool chunks. */
 		buf_pool_shrink(change_size);
 
 	} else if (srv_buf_pool_curr_size + min_change_size
 		   < srv_buf_pool_size) {
- 
+
   		/* Enlarge the buffer pool by at least one megabyte */
-  
+
 		change_size = srv_buf_pool_size - srv_buf_pool_curr_size;
 
 		buf_pool_mutex_exit_all();
@@ -2026,10 +2026,10 @@ buf_pool_resize(void)
 
 		return;
 	}
-  
+
   	buf_pool_page_hash_rebuild();
 }
- 
+
 /****************************************************************//**
 Remove the sentinel block for the watch before replacing it with a real block.
 buf_page_watch_clear() or buf_page_watch_occurred() will notice that
@@ -2316,9 +2316,6 @@ buf_page_get_zip(
 	unsigned	access_time;
 	buf_pool_t*	buf_pool = buf_pool_get(space, offset);
 
-#ifndef UNIV_LOG_DEBUG
-	ut_ad(!ibuf_inside());
-#endif
 	buf_pool->stat.n_page_gets++;
 
 	for (;;) {
@@ -2533,16 +2530,19 @@ buf_block_align_instance(
 	/* TODO: protect buf_pool->chunks with a mutex (it will
 	currently remain constant after buf_pool_init()) */
 	for (chunk = buf_pool->chunks, i = buf_pool->n_chunks; i--; chunk++) {
-		lint	offs = ptr - chunk->blocks->frame;
+		ulint	offs;
 
-		if (UNIV_UNLIKELY(offs < 0)) {
+		if (UNIV_UNLIKELY(ptr < chunk->blocks->frame)) {
 
 			continue;
 		}
+		/* else */
+
+		offs = ptr - chunk->blocks->frame;
 
 		offs >>= UNIV_PAGE_SIZE_SHIFT;
 
-		if (UNIV_LIKELY((ulint) offs < chunk->size)) {
+		if (UNIV_LIKELY(offs < chunk->size)) {
 			buf_block_t*	block = &chunk->blocks[offs];
 
 			/* The function buf_chunk_init() invokes
@@ -2719,7 +2719,7 @@ buf_page_get_gen(
 	ulint		rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
 	buf_block_t*	guess,	/*!< in: guessed block or NULL */
 	ulint		mode,	/*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
-				BUF_GET_NO_LATCH, or
+				BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or
 				BUF_GET_IF_IN_POOL_OR_WATCH */
 	const char*	file,	/*!< in: file name */
 	ulint		line,	/*!< in: line where called */
@@ -2738,16 +2738,26 @@ buf_page_get_gen(
 	ut_ad((rw_latch == RW_S_LATCH)
 	      || (rw_latch == RW_X_LATCH)
 	      || (rw_latch == RW_NO_LATCH));
-	ut_ad((mode != BUF_GET_NO_LATCH) || (rw_latch == RW_NO_LATCH));
-	ut_ad(mode == BUF_GET
-	      || mode == BUF_GET_IF_IN_POOL
-	      || mode == BUF_GET_NO_LATCH
-	      || mode == BUF_GET_IF_IN_POOL_OR_WATCH);
+#ifdef UNIV_DEBUG
+	switch (mode) {
+	case BUF_GET_NO_LATCH:
+		ut_ad(rw_latch == RW_NO_LATCH);
+		break;
+	case BUF_GET:
+	case BUF_GET_IF_IN_POOL:
+	case BUF_PEEK_IF_IN_POOL:
+	case BUF_GET_IF_IN_POOL_OR_WATCH:
+		break;
+	default:
+		ut_error;
+	}
+#endif /* UNIV_DEBUG */
 	ut_ad(zip_size == fil_space_get_zip_size(space));
 	ut_ad(ut_is_2pow(zip_size));
 #ifndef UNIV_LOG_DEBUG
-	ut_ad(!ibuf_inside() || ibuf_page_low(space, zip_size, offset,
-					      FALSE, file, line, NULL));
+	ut_ad(!ibuf_inside(mtr)
+	      || ibuf_page_low(space, zip_size, offset,
+			       FALSE, file, line, NULL));
 #endif
 	buf_pool->stat.n_page_gets++;
 	fold = buf_page_address_fold(space, offset);
@@ -2802,6 +2812,7 @@ loop2:
 		buf_pool_mutex_exit(buf_pool);
 
 		if (mode == BUF_GET_IF_IN_POOL
+		    || mode == BUF_PEEK_IF_IN_POOL
 		    || mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
 
 			return(NULL);
@@ -2842,7 +2853,8 @@ got_block:
 
 	must_read = buf_block_get_io_fix(block) == BUF_IO_READ;
 
-	if (must_read && mode == BUF_GET_IF_IN_POOL) {
+	if (must_read && (mode == BUF_GET_IF_IN_POOL
+			  || mode == BUF_PEEK_IF_IN_POOL)) {
 
 		/* The page is being read to buffer pool,
 		but we cannot wait around for the read to
@@ -2876,7 +2888,7 @@ wait_until_unfixed:
 			Try again later. */
 			buf_pool_mutex_exit(buf_pool);
 			os_thread_sleep(WAIT_FOR_READ);
-  
+
 			goto loop;
 		}
 
@@ -2965,6 +2977,7 @@ wait_until_unfixed:
 		mutex_exit(&buf_pool->zip_mutex);
 		buf_pool->n_pend_unzip++;
 
+		bpage->state = BUF_BLOCK_ZIP_FREE;
 		buf_buddy_free(buf_pool, bpage, sizeof *bpage);
 
 		buf_pool_mutex_exit(buf_pool);
@@ -3058,7 +3071,9 @@ wait_until_unfixed:
 
 	buf_pool_mutex_exit(buf_pool);
 
-	buf_page_set_accessed_make_young(&block->page, access_time);
+	if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
+		buf_page_set_accessed_make_young(&block->page, access_time);
+	}
 
 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
 	ut_a(!block->page.file_page_was_freed);
@@ -3111,11 +3126,12 @@ wait_until_unfixed:
 
 	mtr_memo_push(mtr, block, fix_type);
 
-	if (!access_time) {
+	if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL) && !access_time) {
 		/* In the case of a first access, try to apply linear
 		read-ahead */
 
-		buf_read_ahead_linear(space, zip_size, offset);
+		buf_read_ahead_linear(space, zip_size, offset,
+				      ibuf_inside(mtr));
 	}
 
 #ifdef UNIV_IBUF_COUNT_DEBUG
@@ -3172,7 +3188,7 @@ buf_page_optimistic_get(
 	access_time = buf_page_is_accessed(&block->page);
 	buf_page_set_accessed_make_young(&block->page, access_time);
 
-	ut_ad(!ibuf_inside()
+	ut_ad(!ibuf_inside(mtr)
 	      || ibuf_page(buf_block_get_space(block),
 			   buf_block_get_zip_size(block),
 			   buf_block_get_page_no(block), NULL));
@@ -3228,7 +3244,8 @@ buf_page_optimistic_get(
 
 		buf_read_ahead_linear(buf_block_get_space(block),
 				      buf_block_get_zip_size(block),
-				      buf_block_get_page_no(block));
+				      buf_block_get_page_no(block),
+				      ibuf_inside(mtr));
 	}
 
 #ifdef UNIV_IBUF_COUNT_DEBUG
@@ -3304,7 +3321,7 @@ buf_page_get_known_nowait(
 		buf_pool_mutex_exit(buf_pool);
 	}
 
-	ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
+	ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
 
 	if (rw_latch == RW_S_LATCH) {
 		success = rw_lock_s_lock_nowait(&(block->lock),
@@ -3569,14 +3586,13 @@ buf_page_init_for_read(
 		/* It is a read-ahead within an ibuf routine */
 
 		ut_ad(!ibuf_bitmap_page(zip_size, offset));
-		ut_ad(ibuf_inside());
 
-		mtr_start(&mtr);
+		ibuf_mtr_start(&mtr);
 
 		if (!recv_no_ibuf_operations
 		    && !ibuf_page(space, zip_size, offset, &mtr)) {
 
-			mtr_commit(&mtr);
+			ibuf_mtr_commit(&mtr);
 
 			return(NULL);
 		}
@@ -3700,6 +3716,7 @@ err_exit:
 
 				/* The block was added by some other thread. */
 				watch_page = NULL;
+				bpage->state = BUF_BLOCK_ZIP_FREE;
 				buf_buddy_free(buf_pool, bpage, sizeof *bpage);
 				buf_buddy_free(buf_pool, data, zip_size);
 
@@ -3760,7 +3777,7 @@ func_exit:
 
 	if (mode == BUF_READ_IBUF_PAGES_ONLY) {
 
-		mtr_commit(&mtr);
+		ibuf_mtr_commit(&mtr);
 	}
 
 	ut_ad(!bpage || buf_page_in_file(bpage));
@@ -4788,7 +4805,7 @@ buf_get_modified_ratio_pct(void)
 	buf_get_total_list_len(&lru_len, &free_len, &flush_list_len);
 
 	ratio = (100 * flush_list_len) / (1 + lru_len + free_len);
-  
+
 	/* 1 + is there to avoid division by zero */
 
 	return(ratio);
@@ -5171,7 +5188,7 @@ buf_all_freed(void)
 
 	return(TRUE);
 }
-  
+
 /*********************************************************************//**
 Checks that there currently are no pending i/o-operations for the buffer
 pool.

=== modified file 'storage/innobase/buf/buf0lru.c'
--- a/storage/innobase/buf/buf0lru.c	2011-01-25 08:51:13 +0000
+++ b/storage/innobase/buf/buf0lru.c	2011-02-28 13:39:07 +0000
@@ -247,74 +247,78 @@ buf_LRU_drop_page_hash_for_tablespace(
 		sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE);
 
 	buf_pool_mutex_enter(buf_pool);
+	num_entries = 0;
 
 scan_again:
-	num_entries = 0;
 	bpage = UT_LIST_GET_LAST(buf_pool->LRU);
 
 	while (bpage != NULL) {
-		mutex_t*	block_mutex = buf_page_get_mutex(bpage);
 		buf_page_t*	prev_bpage;
+		ibool		is_fixed;
 
-		mutex_enter(block_mutex);
 		prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
 
 		ut_a(buf_page_in_file(bpage));
 
 		if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
 		    || bpage->space != id
-		    || bpage->buf_fix_count > 0
 		    || bpage->io_fix != BUF_IO_NONE) {
-			/* We leave the fixed pages as is in this scan.
-			To be dealt with later in the final scan. */
-			mutex_exit(block_mutex);
-			goto next_page;
+			/* Compressed pages are never hashed.
+			Skip blocks of other tablespaces.
+			Skip I/O-fixed blocks (to be dealt with later). */
+next_page:
+			bpage = prev_bpage;
+			continue;
 		}
 
-		if (((buf_block_t*) bpage)->is_hashed) {
+		mutex_enter(&((buf_block_t*) bpage)->mutex);
+		is_fixed = bpage->buf_fix_count > 0
+			|| !((buf_block_t*) bpage)->is_hashed;
+		mutex_exit(&((buf_block_t*) bpage)->mutex);
 
-			/* Store the offset(i.e.: page_no) in the array
-			so that we can drop hash index in a batch
-			later. */
-			page_arr[num_entries] = bpage->offset;
-			mutex_exit(block_mutex);
-			ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
-			++num_entries;
+		if (is_fixed) {
+			goto next_page;
+		}
 
-			if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
-				goto next_page;
-			}
+		/* Store the page number so that we can drop the hash
+		index in a batch later. */
+		page_arr[num_entries] = bpage->offset;
+		ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
+		++num_entries;
 
-			/* Array full. We release the buf_pool->mutex to
-			obey the latching order. */
-			buf_pool_mutex_exit(buf_pool);
+		if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
+			goto next_page;
+		}
 
-			buf_LRU_drop_page_hash_batch(
-				id, zip_size, page_arr, num_entries);
+		/* Array full. We release the buf_pool->mutex to obey
+		the latching order. */
+		buf_pool_mutex_exit(buf_pool);
 
-			num_entries = 0;
+		buf_LRU_drop_page_hash_batch(
+			id, zip_size, page_arr, num_entries);
 
-			buf_pool_mutex_enter(buf_pool);
-		} else {
-			mutex_exit(block_mutex);
-		}
+		num_entries = 0;
 
-next_page:
-		/* Note that we may have released the buf_pool mutex
-		above after reading the prev_bpage during processing
-		of a page_hash_batch (i.e.: when the array was full).
-		This means that prev_bpage can change in LRU list.
-		This is OK because this function is a 'best effort'
-		to drop as many search hash entries as possible and
-		it does not guarantee that ALL such entries will be
-		dropped. */
-		bpage = prev_bpage;
+		buf_pool_mutex_enter(buf_pool);
+
+		/* Note that we released the buf_pool mutex above
+		after reading the prev_bpage during processing of a
+		page_hash_batch (i.e.: when the array was full).
+		Because prev_bpage could belong to a compressed-only
+		block, it may have been relocated, and thus the
+		pointer cannot be trusted. Because bpage is of type
+		buf_block_t, it is safe to dereference.
+
+		bpage can change in the LRU list. This is OK because
+		this function is a 'best effort' to drop as many
+		search hash entries as possible and it does not
+		guarantee that ALL such entries will be dropped. */
 
 		/* If, however, bpage has been removed from LRU list
 		to the free list then we should restart the scan.
 		bpage->state is protected by buf_pool mutex. */
-		if (bpage && !buf_page_in_file(bpage)) {
-			ut_a(num_entries == 0);
+		if (bpage
+		    && buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
 			goto scan_again;
 		}
 	}
@@ -1889,6 +1893,7 @@ buf_LRU_block_remove_hashed_page(
 			buf_pool, bpage->zip.data,
 			page_zip_get_size(&bpage->zip));
 
+		bpage->state = BUF_BLOCK_ZIP_FREE;
 		buf_buddy_free(buf_pool, bpage, sizeof(*bpage));
 		buf_pool_mutex_exit_allow(buf_pool);
 

=== modified file 'storage/innobase/buf/buf0rea.c'
--- a/storage/innobase/buf/buf0rea.c	2011-02-10 12:07:58 +0000
+++ b/storage/innobase/buf/buf0rea.c	2011-03-24 12:00:14 +0000
@@ -236,10 +236,10 @@ UNIV_INTERN
 ulint
 buf_read_ahead_linear(
 /*==================*/
-	ulint	space,	/*!< in: space id */
-	ulint	zip_size,/*!< in: compressed page size in bytes, or 0 */
-	ulint	offset)	/*!< in: page number of a page; NOTE: the current thread
-			must want access to this page (see NOTE 3 above) */
+	ulint	space,		/*!< in: space id */
+	ulint	zip_size,	/*!< in: compressed page size in bytes, or 0 */
+	ulint	offset,		/*!< in: page number; see NOTE 3 above */
+	ibool	inside_ibuf)	/*!< in: TRUE if we are inside ibuf routine */
 {
 	buf_pool_t*	buf_pool = buf_pool_get(space, offset);
 	ib_int64_t	tablespace_version;
@@ -429,11 +429,9 @@ buf_read_ahead_linear(
 
 	/* If we got this far, read-ahead can be sensible: do it */
 
-	if (ibuf_inside()) {
-		ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
-	} else {
-		ibuf_mode = BUF_READ_ANY_PAGE;
-	}
+	ibuf_mode = inside_ibuf
+		? BUF_READ_IBUF_PAGES_ONLY | OS_AIO_SIMULATED_WAKE_LATER
+		: BUF_READ_ANY_PAGE | OS_AIO_SIMULATED_WAKE_LATER;
 
 	count = 0;
 
@@ -450,7 +448,7 @@ buf_read_ahead_linear(
 		if (!ibuf_bitmap_page(zip_size, i)) {
 			count += buf_read_page_low(
 				&err, FALSE,
-				ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
+				ibuf_mode,
 				space, zip_size, FALSE, tablespace_version, i);
 			if (err == DB_TABLESPACE_DELETED) {
 				ut_print_timestamp(stderr);
@@ -520,7 +518,6 @@ buf_read_ibuf_merge_pages(
 {
 	ulint	i;
 
-	ut_ad(!ibuf_inside());
 #ifdef UNIV_IBUF_DEBUG
 	ut_a(n_stored < UNIV_PAGE_SIZE);
 #endif

=== modified file 'storage/innobase/dict/dict0load.c'
--- a/storage/innobase/dict/dict0load.c	2011-02-10 08:58:23 +0000
+++ b/storage/innobase/dict/dict0load.c	2011-03-07 15:42:07 +0000
@@ -2258,10 +2258,12 @@ loop:
 	/* Since table names in SYS_FOREIGN are stored in a case-insensitive
 	order, we have to check that the table name matches also in a binary
 	string comparison. On Unix, MySQL allows table names that only differ
-	in character case. */
-
-	if (0 != ut_memcmp(field, table_name, len)) {
+	in character case.  If lower_case_table_names=2 then what is stored
+	may not be the same case, but the previous comparison showed that they
+	match with no-case.  */
 
+	if ((srv_lower_case_table_names != 2)
+	    && (0 != ut_memcmp(field, table_name, len))) {
 		goto next_rec;
 	}
 

=== modified file 'storage/innobase/fil/fil0fil.c'
--- a/storage/innobase/fil/fil0fil.c	2010-12-01 08:43:33 +0000
+++ b/storage/innobase/fil/fil0fil.c	2011-03-24 12:00:14 +0000
@@ -4342,8 +4342,6 @@ fil_io(
 	ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
 	      || !ibuf_bitmap_page(zip_size, block_offset)
 	      || sync || is_log);
-	ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE)
-	      || ibuf_page(space_id, zip_size, block_offset, NULL));
 # endif /* UNIV_LOG_DEBUG */
 	if (sync) {
 		mode = OS_AIO_SYNC;

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	2011-03-16 14:11:20 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2011-04-04 06:12:11 +0000
@@ -51,6 +51,7 @@ Place, Suite 330, Boston, MA 02111-1307
 #include <mysql/plugin.h>
 #include <mysql/innodb_priv.h>
 #include <mysql/psi/psi.h>
+#include <my_sys.h>
 
 /** @file ha_innodb.cc */
 
@@ -81,7 +82,6 @@ extern "C" {
 #include "fil0fil.h"
 #include "trx0xa.h"
 #include "row0merge.h"
-#include "thr0loc.h"
 #include "dict0boot.h"
 #include "ha_prototypes.h"
 #include "ut0mem.h"
@@ -279,7 +279,6 @@ static PSI_mutex_info all_innodb_mutexes
 	{&sync_thread_mutex_key, "sync_thread_mutex", 0},
 #  endif /* UNIV_SYNC_DEBUG */
 	{&trx_doublewrite_mutex_key, "trx_doublewrite_mutex", 0},
-	{&thr_local_mutex_key, "thr_local_mutex", 0},
 	{&trx_undo_mutex_key, "trx_undo_mutex", 0}
 };
 # endif /* UNIV_PFS_MUTEX */
@@ -1147,6 +1146,20 @@ innobase_strcasecmp(
 }
 
 /******************************************************************//**
+Strip dir name from a full path name and return only the file name
+@return file name or "null" if no file name */
+extern "C" UNIV_INTERN
+const char*
+innobase_basename(
+/*==============*/
+	const char*	path_name)	/*!< in: full path name */
+{
+	const char*	name = base_name(path_name);
+
+	return((name) ? name : "null");
+}
+
+/******************************************************************//**
 Makes all characters in a NUL-terminated UTF-8 string lower case. */
 extern "C" UNIV_INTERN
 void
@@ -3028,7 +3041,6 @@ innobase_close_connection(
 
 	innobase_rollback_trx(trx);
 
-	thr_local_free(trx->mysql_thread_id);
 	trx_free_for_mysql(trx);
 
 	DBUG_RETURN(0);
@@ -9263,7 +9275,8 @@ innodb_mutex_show_status(
 			if (mutex->count_using > 0) {
 				buf1len= my_snprintf(buf1, sizeof(buf1),
 					"%s:%s",
-					mutex->cmutex_name, mutex->cfile_name);
+					mutex->cmutex_name,
+					innobase_basename(mutex->cfile_name));
 				buf2len= my_snprintf(buf2, sizeof(buf2),
 					"count=%lu, spin_waits=%lu,"
 					" spin_rounds=%lu, "
@@ -9293,7 +9306,8 @@ innodb_mutex_show_status(
 		}
 #else /* UNIV_DEBUG */
 		buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s:%lu",
-				     mutex->cfile_name, (ulong) mutex->cline);
+				     innobase_basename(mutex->cfile_name),
+				     (ulong) mutex->cline);
 		buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
 				     (ulong) mutex->count_os_wait);
 
@@ -9309,7 +9323,8 @@ innodb_mutex_show_status(
 	if (block_mutex) {
 		buf1len = (uint) my_snprintf(buf1, sizeof buf1,
 					     "combined %s:%lu",
-					     block_mutex->cfile_name,
+					     innobase_basename(
+						block_mutex->cfile_name),
 					     (ulong) block_mutex->cline);
 		buf2len = (uint) my_snprintf(buf2, sizeof buf2,
 					     "os_waits=%lu",
@@ -9340,7 +9355,8 @@ innodb_mutex_show_status(
 		}
 
 		buf1len = my_snprintf(buf1, sizeof buf1, "%s:%lu",
-				     lock->cfile_name, (ulong) lock->cline);
+				     innobase_basename(lock->cfile_name),
+				     (ulong) lock->cline);
 		buf2len = my_snprintf(buf2, sizeof buf2, "os_waits=%lu",
 				      (ulong) lock->count_os_wait);
 
@@ -9355,7 +9371,8 @@ innodb_mutex_show_status(
 	if (block_lock) {
 		buf1len = (uint) my_snprintf(buf1, sizeof buf1,
 					     "combined %s:%lu",
-					     block_lock->cfile_name,
+					     innobase_basename(
+						block_lock->cfile_name),
 					     (ulong) block_lock->cline);
 		buf2len = (uint) my_snprintf(buf2, sizeof buf2,
 					     "os_waits=%lu",
@@ -11359,7 +11376,7 @@ mysql_declare_plugin(innobase)
   MYSQL_STORAGE_ENGINE_PLUGIN,
   &innobase_storage_engine,
   innobase_hton_name,
-  "Innobase Oy",
+  plugin_author,
   "Supports transactions, row-level locking, and foreign keys",
   PLUGIN_LICENSE_GPL,
   innobase_init, /* Plugin Init */

=== modified file 'storage/innobase/handler/i_s.cc'
--- a/storage/innobase/handler/i_s.cc	2011-01-10 13:17:00 +0000
+++ b/storage/innobase/handler/i_s.cc	2011-03-02 09:00:48 +0000
@@ -47,8 +47,6 @@ extern "C" {
 #include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
 }
 
-static const char plugin_author[] = "Innobase Oy";
-
 #define OK(expr)		\
 	if ((expr) != 0) {	\
 		DBUG_RETURN(1);	\
@@ -1059,7 +1057,7 @@ UNIV_INTERN struct st_mysql_plugin	i_s_i
 
 	/* plugin author (for SHOW PLUGINS) */
 	/* const char* */
-	STRUCT_FLD(author, "Innobase Oy"),
+	STRUCT_FLD(author, plugin_author),
 
 	/* general descriptive text (for SHOW PLUGINS) */
 	/* const char* */

=== modified file 'storage/innobase/handler/i_s.h'
--- a/storage/innobase/handler/i_s.h	2010-09-17 02:24:32 +0000
+++ b/storage/innobase/handler/i_s.h	2011-02-28 09:07:22 +0000
@@ -26,6 +26,8 @@ Created July 18, 2007 Vasil Dimov
 #ifndef i_s_h
 #define i_s_h
 
+const char plugin_author[] = "Oracle Corporation";
+
 extern struct st_mysql_plugin	i_s_innodb_trx;
 extern struct st_mysql_plugin	i_s_innodb_locks;
 extern struct st_mysql_plugin	i_s_innodb_lock_waits;

=== modified file 'storage/innobase/ibuf/ibuf0ibuf.c'
--- a/storage/innobase/ibuf/ibuf0ibuf.c	2011-02-02 13:58:01 +0000
+++ b/storage/innobase/ibuf/ibuf0ibuf.c	2011-03-24 12:00:14 +0000
@@ -44,7 +44,6 @@ Created 7/19/1997 Heikki Tuuri
 #include "fsp0fsp.h"
 #include "trx0sys.h"
 #include "fil0fil.h"
-#include "thr0loc.h"
 #include "rem0rec.h"
 #include "btr0cur.h"
 #include "btr0pcur.h"
@@ -324,52 +323,43 @@ still physically like the index page eve
 dropped! So, there seems to be no problem. */
 
 /******************************************************************//**
-Sets the flag in the current OS thread local storage denoting that it is
+Sets the flag in the current mini-transaction record indicating we're
 inside an insert buffer routine. */
 UNIV_INLINE
 void
-ibuf_enter(void)
-/*============*/
+ibuf_enter(
+/*=======*/
+	mtr_t*	mtr)	/*!< in/out: mini-transaction */
 {
-	ibool*	ptr;
-
-	ptr = thr_local_get_in_ibuf_field();
-
-	ut_ad(*ptr == FALSE);
-
-	*ptr = TRUE;
+	ut_ad(!mtr->inside_ibuf);
+	mtr->inside_ibuf = TRUE;
 }
 
 /******************************************************************//**
-Sets the flag in the current OS thread local storage denoting that it is
+Sets the flag in the current mini-transaction record indicating we're
 exiting an insert buffer routine. */
 UNIV_INLINE
 void
-ibuf_exit(void)
-/*===========*/
+ibuf_exit(
+/*======*/
+	mtr_t*	mtr)	/*!< in/out: mini-transaction */
 {
-	ibool*	ptr;
-
-	ptr = thr_local_get_in_ibuf_field();
-
-	ut_ad(*ptr == TRUE);
-
-	*ptr = FALSE;
+	ut_ad(mtr->inside_ibuf);
+	mtr->inside_ibuf = FALSE;
 }
 
-/******************************************************************//**
-Returns TRUE if the current OS thread is performing an insert buffer
-routine.
-
-For instance, a read-ahead of non-ibuf pages is forbidden by threads
-that are executing an insert buffer routine.
-@return TRUE if inside an insert buffer routine */
-UNIV_INTERN
-ibool
-ibuf_inside(void)
-/*=============*/
+/**************************************************************//**
+Commits an insert buffer mini-transaction and sets the persistent
+cursor latch mode to BTR_NO_LATCHES, that is, detaches the cursor. */
+UNIV_INLINE
+void
+ibuf_btr_pcur_commit_specify_mtr(
+/*=============================*/
+	btr_pcur_t*	pcur,	/*!< in/out: persistent cursor */
+	mtr_t*		mtr)	/*!< in/out: mini-transaction */
 {
-	return(*thr_local_get_in_ibuf_field());
+	ut_d(ibuf_exit(mtr));
+	btr_pcur_commit_specify_mtr(pcur, mtr);
 }
 
 /******************************************************************//**
@@ -379,11 +369,11 @@ static
 page_t*
 ibuf_header_page_get(
 /*=================*/
-	mtr_t*	mtr)	/*!< in: mtr */
+	mtr_t*	mtr)	/*!< in/out: mini-transaction */
 {
 	buf_block_t*	block;
 
-	ut_ad(!ibuf_inside());
+	ut_ad(!ibuf_inside(mtr));
 
 	block = buf_page_get(
 		IBUF_SPACE_ID, 0, FSP_IBUF_HEADER_PAGE_NO, RW_X_LATCH, mtr);
@@ -404,7 +394,7 @@ ibuf_tree_root_get(
 	buf_block_t*	block;
 	page_t*		root;
 
-	ut_ad(ibuf_inside());
+	ut_ad(ibuf_inside(mtr));
 	ut_ad(mutex_own(&ibuf_mutex));
 
 	mtr_x_lock(dict_index_get_lock(ibuf->index), mtr);
@@ -547,7 +537,7 @@ ibuf_init_at_db_start(void)
 
 	fseg_n_reserved_pages(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
 			      &n_used, &mtr);
-	ibuf_enter();
+	ibuf_enter(&mtr);
 
 	ut_ad(n_used >= 2);
 
@@ -568,9 +558,7 @@ ibuf_init_at_db_start(void)
 	mutex_exit(&ibuf_mutex);
 
 	ibuf->empty = (page_get_n_recs(root) == 0);
-	mtr_commit(&mtr);
-
-	ibuf_exit();
+	ibuf_mtr_commit(&mtr);
 
 	heap = mem_heap_create(450);
 
@@ -1230,19 +1218,30 @@ ibuf_page_low(
 	return(ret);
 }
 
+#ifdef UNIV_DEBUG
+# define ibuf_rec_get_page_no(mtr,rec) ibuf_rec_get_page_no_func(mtr,rec)
+#else /* UNIV_DEBUG */
+# define ibuf_rec_get_page_no(mtr,rec) ibuf_rec_get_page_no_func(rec)
+#endif /* UNIV_DEBUG */
+
 /********************************************************************//**
 Returns the page number field of an ibuf record.
 @return	page number */
 static
 ulint
-ibuf_rec_get_page_no(
-/*=================*/
+ibuf_rec_get_page_no_func(
+/*======================*/
+#ifdef UNIV_DEBUG
+	mtr_t*		mtr,	/*!< in: mini-transaction owning rec */
+#endif /* UNIV_DEBUG */
 	const rec_t*	rec)	/*!< in: ibuf record */
 {
 	const byte*	field;
 	ulint		len;
 
-	ut_ad(ibuf_inside());
+	ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
+	      || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
+	ut_ad(ibuf_inside(mtr));
 	ut_ad(rec_get_n_fields_old(rec) > 2);
 
 	field = rec_get_nth_field_old(rec, 1, &len);
@@ -1264,20 +1263,31 @@ ibuf_rec_get_page_no(
 	return(mach_read_from_4(field));
 }
 
+#ifdef UNIV_DEBUG
+# define ibuf_rec_get_space(mtr,rec) ibuf_rec_get_space_func(mtr,rec)
+#else /* UNIV_DEBUG */
+# define ibuf_rec_get_space(mtr,rec) ibuf_rec_get_space_func(rec)
+#endif /* UNIV_DEBUG */
+
 /********************************************************************//**
 Returns the space id field of an ibuf record. For < 4.1.x format records
 returns 0.
 @return	space id */
 static
 ulint
-ibuf_rec_get_space(
-/*===============*/
+ibuf_rec_get_space_func(
+/*====================*/
+#ifdef UNIV_DEBUG
+	mtr_t*		mtr,	/*!< in: mini-transaction owning rec */
+#endif /* UNIV_DEBUG */
 	const rec_t*	rec)	/*!< in: ibuf record */
 {
 	const byte*	field;
 	ulint		len;
 
-	ut_ad(ibuf_inside());
+	ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
+	      || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
+	ut_ad(ibuf_inside(mtr));
 	ut_ad(rec_get_n_fields_old(rec) > 2);
 
 	field = rec_get_nth_field_old(rec, 1, &len);
@@ -1298,12 +1308,22 @@ ibuf_rec_get_space(
 	return(0);
 }
 
+#ifdef UNIV_DEBUG
+# define ibuf_rec_get_info(mtr,rec,op,comp,info_len,counter)	\
+	ibuf_rec_get_info_func(mtr,rec,op,comp,info_len,counter)
+#else /* UNIV_DEBUG */
+# define ibuf_rec_get_info(mtr,rec,op,comp,info_len,counter)	\
+	ibuf_rec_get_info_func(rec,op,comp,info_len,counter)
+#endif
 /****************************************************************//**
 Get various information about an ibuf record in >= 4.1.x format. */
 static
 void
-ibuf_rec_get_info(
-/*==============*/
+ibuf_rec_get_info_func(
+/*===================*/
+#ifdef UNIV_DEBUG
+	mtr_t*		mtr,	/*!< in: mini-transaction owning rec */
+#endif /* UNIV_DEBUG */
 	const rec_t*	rec,		/*!< in: ibuf record */
 	ibuf_op_t*	op,		/*!< out: operation type, or NULL */
 	ibool*		comp,		/*!< out: compact flag, or NULL */
@@ -1322,7 +1342,9 @@ ibuf_rec_get_info(
 	ulint		info_len_local;
 	ulint		counter_local;
 
-	ut_ad(ibuf_inside());
+	ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
+	      || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
+	ut_ad(ibuf_inside(mtr));
 	fields = rec_get_n_fields_old(rec);
 	ut_a(fields > 4);
 
@@ -1371,18 +1393,29 @@ ibuf_rec_get_info(
 	}
 }
 
+#ifdef UNIV_DEBUG
+# define ibuf_rec_get_op_type(mtr,rec) ibuf_rec_get_op_type_func(mtr,rec)
+#else /* UNIV_DEBUG */
+# define ibuf_rec_get_op_type(mtr,rec) ibuf_rec_get_op_type_func(rec)
+#endif
+
 /****************************************************************//**
 Returns the operation type field of an ibuf record.
 @return	operation type */
 static
 ibuf_op_t
-ibuf_rec_get_op_type(
-/*=================*/
+ibuf_rec_get_op_type_func(
+/*======================*/
+#ifdef UNIV_DEBUG
+	mtr_t*		mtr,	/*!< in: mini-transaction owning rec */
+#endif /* UNIV_DEBUG */
 	const rec_t*	rec)	/*!< in: ibuf record */
 {
 	ulint		len;
 
-	ut_ad(ibuf_inside());
+	ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
+	      || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
+	ut_ad(ibuf_inside(mtr));
 	ut_ad(rec_get_n_fields_old(rec) > 2);
 
 	(void) rec_get_nth_field_old(rec, 1, &len);
@@ -1394,7 +1427,7 @@ ibuf_rec_get_op_type(
 	} else {
 		ibuf_op_t	op;
 
-		ibuf_rec_get_info(rec, &op, NULL, NULL, NULL);
+		ibuf_rec_get_info(mtr, rec, &op, NULL, NULL, NULL);
 
 		return(op);
 	}
@@ -1593,6 +1626,14 @@ ibuf_build_entry_pre_4_1_x(
 	return(tuple);
 }
 
+#ifdef UNIV_DEBUG
+# define ibuf_build_entry_from_ibuf_rec(mtr,ibuf_rec,heap,pindex)	\
+	ibuf_build_entry_from_ibuf_rec_func(mtr,ibuf_rec,heap,pindex)
+#else /* UNIV_DEBUG */
+# define ibuf_build_entry_from_ibuf_rec(mtr,ibuf_rec,heap,pindex)	\
+	ibuf_build_entry_from_ibuf_rec_func(ibuf_rec,heap,pindex)
+#endif
+
 /*********************************************************************//**
 Builds the entry used to
 
@@ -1611,8 +1652,11 @@ hold a latch to the ibuf_rec page as lon
 @return own: entry to insert to a non-clustered index */
 static
 dtuple_t*
-ibuf_build_entry_from_ibuf_rec(
-/*===========================*/
+ibuf_build_entry_from_ibuf_rec_func(
+/*================================*/
+#ifdef UNIV_DEBUG
+	mtr_t*		mtr,	/*!< in: mini-transaction owning rec */
+#endif /* UNIV_DEBUG */
 	const rec_t*	ibuf_rec,	/*!< in: record in an insert buffer */
 	mem_heap_t*	heap,		/*!< in: heap where built */
 	dict_index_t**	pindex)		/*!< out, own: dummy index that
@@ -1629,6 +1673,10 @@ ibuf_build_entry_from_ibuf_rec(
 	ulint		comp;
 	dict_index_t*	index;
 
+	ut_ad(mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_X_FIX)
+	      || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX));
+	ut_ad(ibuf_inside(mtr));
+
 	data = rec_get_nth_field_old(ibuf_rec, 1, &len);
 
 	if (len > 1) {
@@ -1649,7 +1697,7 @@ ibuf_build_entry_from_ibuf_rec(
 
 	types = rec_get_nth_field_old(ibuf_rec, 3, &len);
 
-	ibuf_rec_get_info(ibuf_rec, NULL, &comp, &info_len, NULL);
+	ibuf_rec_get_info(mtr, ibuf_rec, NULL, &comp, &info_len, NULL);
 
 	index = ibuf_dummy_index_create(n_fields, comp);
 
@@ -1736,6 +1784,12 @@ ibuf_rec_get_size(
 	return(size);
 }
 
+#ifdef UNIV_DEBUG
+# define ibuf_rec_get_volume(mtr,rec) ibuf_rec_get_volume_func(mtr,rec)
+#else /* UNIV_DEBUG */
+# define ibuf_rec_get_volume(mtr,rec) ibuf_rec_get_volume_func(rec)
+#endif
+
 /********************************************************************//**
 Returns the space taken by a stored non-clustered index entry if converted to
 an index record.
@@ -1743,8 +1797,11 @@ an index record.
 taken in the page directory */
 static
 ulint
-ibuf_rec_get_volume(
-/*================*/
+ibuf_rec_get_volume_func(
+/*=====================*/
+#ifdef UNIV_DEBUG
+	mtr_t*		mtr,	/*!< in: mini-transaction owning rec */
+#endif /* UNIV_DEBUG */
 	const rec_t*	ibuf_rec)/*!< in: ibuf record */
 {
 	ulint		len;
@@ -1755,7 +1812,9 @@ ibuf_rec_get_volume(
 	ibool		pre_4_1;
 	ulint		comp;
 
-	ut_ad(ibuf_inside());
+	ut_ad(mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_X_FIX)
+	      || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX));
+	ut_ad(ibuf_inside(mtr));
 	ut_ad(rec_get_n_fields_old(ibuf_rec) > 2);
 
 	data = rec_get_nth_field_old(ibuf_rec, 1, &len);
@@ -1783,7 +1842,7 @@ ibuf_rec_get_volume(
 
 		types = rec_get_nth_field_old(ibuf_rec, 3, &len);
 
-		ibuf_rec_get_info(ibuf_rec, &op, &comp, &info_len, NULL);
+		ibuf_rec_get_info(mtr, ibuf_rec, &op, &comp, &info_len, NULL);
 
 		if (op == IBUF_OP_DELETE_MARK || op == IBUF_OP_DELETE) {
 			/* Delete-marking a record doesn't take any
@@ -1800,7 +1859,7 @@ ibuf_rec_get_volume(
 			mem_heap_t*	heap = mem_heap_create(500);
 
 			entry = ibuf_build_entry_from_ibuf_rec(
-				ibuf_rec, heap, &dummy_index);
+				mtr, ibuf_rec, heap, &dummy_index);
 
 			volume = rec_get_converted_size(dummy_index, entry, 0);
 
@@ -2158,21 +2217,15 @@ ibuf_add_free_page(void)
 		mtr_commit(&mtr);
 
 		return(FALSE);
-	}
-
-	{
-		buf_block_t*	block;
-
-		block = buf_page_get(
+	} else {
+		buf_block_t*	block = buf_page_get(
 			IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
-
 		buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
 
-
 		page = buf_block_get_frame(block);
 	}
 
-	ibuf_enter();
+	ibuf_enter(&mtr);
 
 	mutex_enter(&ibuf_mutex);
 
@@ -2200,9 +2253,7 @@ ibuf_add_free_page(void)
 	ibuf_bitmap_page_set_bits(
 		bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, TRUE, &mtr);
 
-	mtr_commit(&mtr);
-
-	ibuf_exit();
+	ibuf_mtr_commit(&mtr);
 
 	return(TRUE);
 }
@@ -2234,7 +2285,7 @@ ibuf_remove_free_page(void)
 	header_page = ibuf_header_page_get(&mtr);
 
 	/* Prevent pessimistic inserts to insert buffer trees for a while */
-	ibuf_enter();
+	ibuf_enter(&mtr);
 	mutex_enter(&ibuf_pessimistic_insert_mutex);
 	mutex_enter(&ibuf_mutex);
 
@@ -2243,14 +2294,12 @@ ibuf_remove_free_page(void)
 		mutex_exit(&ibuf_mutex);
 		mutex_exit(&ibuf_pessimistic_insert_mutex);
 
-		ibuf_exit();
-
-		mtr_commit(&mtr);
+		ibuf_mtr_commit(&mtr);
 
 		return;
 	}
 
-	mtr_start(&mtr2);
+	ibuf_mtr_start(&mtr2);
 
 	root = ibuf_tree_root_get(&mtr2);
 
@@ -2263,9 +2312,8 @@ ibuf_remove_free_page(void)
 	because in fseg_free_page we access level 1 pages, and the root
 	is a level 2 page. */
 
-	mtr_commit(&mtr2);
-
-	ibuf_exit();
+	ibuf_mtr_commit(&mtr2);
+	ibuf_exit(&mtr);
 
 	/* Since pessimistic inserts were prevented, we know that the
 	page is still in the free list. NOTE that also deletes may take
@@ -2280,7 +2328,7 @@ ibuf_remove_free_page(void)
 	buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no);
 #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
 
-	ibuf_enter();
+	ibuf_enter(&mtr);
 
 	mutex_enter(&ibuf_mutex);
 
@@ -2325,9 +2373,7 @@ ibuf_remove_free_page(void)
 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
 	buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no);
 #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
-	mtr_commit(&mtr);
-
-	ibuf_exit();
+	ibuf_mtr_commit(&mtr);
 }
 
 /***********************************************************************//**
@@ -2349,8 +2395,6 @@ ibuf_free_excess_pages(void)
 	ut_ad(rw_lock_get_x_lock_count(
 		fil_space_get_latch(IBUF_SPACE_ID, NULL)) == 1);
 
-	ut_ad(!ibuf_inside());
-
 	/* NOTE: We require that the thread did not own the latch before,
 	because then we know that we can obey the correct latching order
 	for ibuf latches */
@@ -2381,20 +2425,30 @@ ibuf_free_excess_pages(void)
 	}
 }
 
+#ifdef UNIV_DEBUG
+# define ibuf_get_merge_page_nos(contract,rec,mtr,ids,vers,pages,n_stored) \
+	ibuf_get_merge_page_nos_func(contract,rec,mtr,ids,vers,pages,n_stored)
+#else /* UNIV_DEBUG */
+# define ibuf_get_merge_page_nos(contract,rec,mtr,ids,vers,pages,n_stored) \
+	ibuf_get_merge_page_nos_func(contract,rec,ids,vers,pages,n_stored)
+#endif /* UNIV_DEBUG */
+
 /*********************************************************************//**
 Reads page numbers from a leaf in an ibuf tree.
 @return a lower limit for the combined volume of records which will be
 merged */
 static
 ulint
-ibuf_get_merge_page_nos(
-/*====================*/
+ibuf_get_merge_page_nos_func(
+/*=========================*/
 	ibool		contract,/*!< in: TRUE if this function is called to
 				contract the tree, FALSE if this is called
 				when a single page becomes full and we look
 				if it pays to read also nearby pages */
-	rec_t*		rec,	/*!< in: record from which we read up and down
-				in the chain of records */
+	const rec_t*	rec,	/*!< in: insert buffer record */
+#ifdef UNIV_DEBUG
+	mtr_t*		mtr,	/*!< in: mini-transaction holding rec */
+#endif /* UNIV_DEBUG */
 	ulint*		space_ids,/*!< in/out: space id's of the pages */
 	ib_int64_t*	space_versions,/*!< in/out: tablespace version
 				timestamps; used to prevent reading in old
@@ -2417,18 +2471,22 @@ ibuf_get_merge_page_nos(
 	ulint	limit;
 	ulint	n_pages;
 
+	ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
+	      || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
+	ut_ad(ibuf_inside(mtr));
+
 	*n_stored = 0;
 
 	limit = ut_min(IBUF_MAX_N_PAGES_MERGED, buf_pool_get_curr_size() / 4);
 
 	if (page_rec_is_supremum(rec)) {
 
-		rec = page_rec_get_prev(rec);
+		rec = page_rec_get_prev_const(rec);
 	}
 
 	if (page_rec_is_infimum(rec)) {
 
-		rec = page_rec_get_next(rec);
+		rec = page_rec_get_next_const(rec);
 	}
 
 	if (page_rec_is_supremum(rec)) {
@@ -2436,8 +2494,8 @@ ibuf_get_merge_page_nos(
 		return(0);
 	}
 
-	first_page_no = ibuf_rec_get_page_no(rec);
-	first_space_id = ibuf_rec_get_space(rec);
+	first_page_no = ibuf_rec_get_page_no(mtr, rec);
+	first_space_id = ibuf_rec_get_space(mtr, rec);
 	n_pages = 0;
 	prev_page_no = 0;
 	prev_space_id = 0;
@@ -2448,8 +2506,8 @@ ibuf_get_merge_page_nos(
 
 	while (!page_rec_is_infimum(rec) && UNIV_LIKELY(n_pages < limit)) {
 
-		rec_page_no = ibuf_rec_get_page_no(rec);
-		rec_space_id = ibuf_rec_get_space(rec);
+		rec_page_no = ibuf_rec_get_page_no(mtr, rec);
+		rec_space_id = ibuf_rec_get_space(mtr, rec);
 
 		if (rec_space_id != first_space_id
 		    || (rec_page_no / IBUF_MERGE_AREA)
@@ -2466,10 +2524,10 @@ ibuf_get_merge_page_nos(
 		prev_page_no = rec_page_no;
 		prev_space_id = rec_space_id;
 
-		rec = page_rec_get_prev(rec);
+		rec = page_rec_get_prev_const(rec);
 	}
 
-	rec = page_rec_get_next(rec);
+	rec = page_rec_get_next_const(rec);
 
 	/* At the loop start there is no prev page; we mark this with a pair
 	of space id, page no (0, 0) for which there can never be entries in
@@ -2487,8 +2545,8 @@ ibuf_get_merge_page_nos(
 			rec_page_no = 1;
 			rec_space_id = 0;
 		} else {
-			rec_page_no = ibuf_rec_get_page_no(rec);
-			rec_space_id = ibuf_rec_get_space(rec);
+			rec_page_no = ibuf_rec_get_page_no(mtr, rec);
+			rec_space_id = ibuf_rec_get_space(mtr, rec);
 			ut_ad(rec_page_no > IBUF_TREE_ROOT_PAGE_NO);
 		}
 
@@ -2499,9 +2557,9 @@ ibuf_get_merge_page_nos(
 		     || rec_page_no != prev_page_no)
 		    && (prev_space_id != 0 || prev_page_no != 0)) {
 
-			if ((prev_page_no == first_page_no
-			     && prev_space_id == first_space_id)
-			    || contract
+			if (contract
+			    || (prev_page_no == first_page_no
+				&& prev_space_id == first_space_id)
 			    || (volume_for_page
 				> ((IBUF_MERGE_THRESHOLD - 1)
 				   * 4 * UNIV_PAGE_SIZE
@@ -2534,14 +2592,14 @@ ibuf_get_merge_page_nos(
 			break;
 		}
 
-		rec_volume = ibuf_rec_get_volume(rec);
+		rec_volume = ibuf_rec_get_volume(mtr, rec);
 
 		volume_for_page += rec_volume;
 
 		prev_page_no = rec_page_no;
 		prev_space_id = rec_space_id;
 
-		rec = page_rec_get_next(rec);
+		rec = page_rec_get_next_const(rec);
 	}
 
 #ifdef UNIV_IBUF_DEBUG
@@ -2576,7 +2634,6 @@ ibuf_contract_ext(
 	mtr_t		mtr;
 
 	*n_pages = 0;
-	ut_ad(!ibuf_inside());
 
 	/* We perform a dirty read of ibuf->empty, without latching
 	the insert buffer root page. We trust this dirty read except
@@ -2588,9 +2645,7 @@ ibuf_contract_ext(
 		return(0);
 	}
 
-	mtr_start(&mtr);
-
-	ibuf_enter();
+	ibuf_mtr_start(&mtr);
 
 	/* Open a cursor to a randomly chosen leaf of the tree, at a random
 	position within the leaf */
@@ -2609,24 +2664,21 @@ ibuf_contract_ext(
 		ut_ad(page_get_page_no(btr_pcur_get_page(&pcur))
 		      == FSP_IBUF_TREE_ROOT_PAGE_NO);
 
-		ibuf_exit();
-
-		mtr_commit(&mtr);
+		ibuf_mtr_commit(&mtr);
 		btr_pcur_close(&pcur);
 
 		return(0);
 	}
 
-	sum_sizes = ibuf_get_merge_page_nos(TRUE, btr_pcur_get_rec(&pcur),
+	sum_sizes = ibuf_get_merge_page_nos(TRUE,
+					    btr_pcur_get_rec(&pcur), &mtr,
 					    space_ids, space_versions,
 					    page_nos, n_pages);
 #if 0 /* defined UNIV_IBUF_DEBUG */
 	fprintf(stderr, "Ibuf contract sync %lu pages %lu volume %lu\n",
 		sync, *n_pages, sum_sizes);
 #endif
-	ibuf_exit();
-
-	mtr_commit(&mtr);
+	ibuf_mtr_commit(&mtr);
 	btr_pcur_close(&pcur);
 
 	buf_read_ibuf_merge_pages(sync, space_ids, space_versions, page_nos,
@@ -2766,6 +2818,13 @@ ibuf_get_volume_buffered_hash(
 	return(TRUE);
 }
 
+#ifdef UNIV_DEBUG
+# define ibuf_get_volume_buffered_count(mtr,rec,hash,size,n_recs)	\
+	ibuf_get_volume_buffered_count_func(mtr,rec,hash,size,n_recs)
+#else /* UNIV_DEBUG */
+# define ibuf_get_volume_buffered_count(mtr,rec,hash,size,n_recs)	\
+	ibuf_get_volume_buffered_count_func(rec,hash,size,n_recs)
+#endif
 /*********************************************************************//**
 Update the estimate of the number of records on a page, and
 get the space taken by merging the buffered record to the index page.
@@ -2773,8 +2832,11 @@ get the space taken by merging the buffe
 taken in the page directory */
 static
 ulint
-ibuf_get_volume_buffered_count(
-/*===========================*/
+ibuf_get_volume_buffered_count_func(
+/*================================*/
+#ifdef UNIV_DEBUG
+	mtr_t*		mtr,	/*!< in: mini-transaction owning rec */
+#endif /* UNIV_DEBUG */
 	const rec_t*	rec,	/*!< in: insert buffer record */
 	ulint*		hash,	/*!< in/out: hash array */
 	ulint		size,	/*!< in: number of elements in hash array */
@@ -2784,9 +2846,13 @@ ibuf_get_volume_buffered_count(
 	ulint		len;
 	ibuf_op_t	ibuf_op;
 	const byte*	types;
-	ulint		n_fields	= rec_get_n_fields_old(rec);
+	ulint		n_fields;
 
-	ut_ad(ibuf_inside());
+	ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
+	      || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
+	ut_ad(ibuf_inside(mtr));
+
+	n_fields = rec_get_n_fields_old(rec);
 	ut_ad(n_fields > 4);
 	n_fields -= 4;
 
@@ -2871,7 +2937,7 @@ get_volume_comp:
 		mem_heap_t*	heap = mem_heap_create(500);
 
 		entry = ibuf_build_entry_from_ibuf_rec(
-			rec, heap, &dummy_index);
+			mtr, rec, heap, &dummy_index);
 
 		volume = rec_get_converted_size(dummy_index, entry, 0);
 
@@ -2892,7 +2958,7 @@ static
 ulint
 ibuf_get_volume_buffered(
 /*=====================*/
-	btr_pcur_t*	pcur,	/*!< in: pcur positioned at a place in an
+	const btr_pcur_t*pcur,	/*!< in: pcur positioned at a place in an
 				insert buffer tree where we would insert an
 				entry for the index page whose number is
 				page_no, latch mode has to be BTR_MODIFY_PREV
@@ -2902,16 +2968,17 @@ ibuf_get_volume_buffered(
 	lint*		n_recs,	/*!< in/out: minimum number of records on the
 				page after the buffered changes have been
 				applied, or NULL to disable the counting */
-	mtr_t*		mtr)	/*!< in: mtr */
+	mtr_t*		mtr)	/*!< in: mini-transaction of pcur */
 {
-	ulint	volume;
-	rec_t*	rec;
-	page_t*	page;
-	ulint	prev_page_no;
-	page_t*	prev_page;
-	ulint	next_page_no;
-	page_t*	next_page;
-	ulint	hash_bitmap[128 / sizeof(ulint)]; /* bitmap of buffered recs */
+	ulint		volume;
+	const rec_t*	rec;
+	const page_t*	page;
+	ulint		prev_page_no;
+	const page_t*	prev_page;
+	ulint		next_page_no;
+	const page_t*	next_page;
+	/* bitmap of buffered recs */
+	ulint		hash_bitmap[128 / sizeof(ulint)];
 
 	ut_a(trx_sys_multiple_tablespace_format);
 
@@ -2932,26 +2999,22 @@ ibuf_get_volume_buffered(
 	ut_ad(page_validate(page, ibuf->index));
 
 	if (page_rec_is_supremum(rec)) {
-		rec = page_rec_get_prev(rec);
+		rec = page_rec_get_prev_const(rec);
 	}
 
-	for (;;) {
-		if (page_rec_is_infimum(rec)) {
-
-			break;
-		}
+	for (; !page_rec_is_infimum(rec);
+	     rec = page_rec_get_prev_const(rec)) {
+		ut_ad(page_align(rec) == page);
 
-		if (page_no != ibuf_rec_get_page_no(rec)
-		    || space != ibuf_rec_get_space(rec)) {
+		if (page_no != ibuf_rec_get_page_no(mtr, rec)
+		    || space != ibuf_rec_get_space(mtr, rec)) {
 
 			goto count_later;
 		}
 
 		volume += ibuf_get_volume_buffered_count(
-			rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
-
-		rec = page_rec_get_prev(rec);
-		ut_ad(page_align(rec) == page);
+			mtr, rec,
+			hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
 	}
 
 	/* Look at the previous page */
@@ -2967,7 +3030,8 @@ ibuf_get_volume_buffered(
 		buf_block_t*	block;
 
 		block = buf_page_get(
-			IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH, mtr);
+			IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH,
+			mtr);
 
 		buf_block_dbg_add_level(block, SYNC_TREE_NODE);
 
@@ -2977,14 +3041,15 @@ ibuf_get_volume_buffered(
 	}
 
 #ifdef UNIV_BTR_DEBUG
-	ut_a(btr_page_get_next(prev_page, mtr)
-	     == page_get_page_no(page));
+	ut_a(btr_page_get_next(prev_page, mtr) == page_get_page_no(page));
 #endif /* UNIV_BTR_DEBUG */
 
 	rec = page_get_supremum_rec(prev_page);
-	rec = page_rec_get_prev(rec);
+	rec = page_rec_get_prev_const(rec);
+
+	for (;; rec = page_rec_get_prev_const(rec)) {
+		ut_ad(page_align(rec) == prev_page);
 
-	for (;;) {
 		if (page_rec_is_infimum(rec)) {
 
 			/* We cannot go to yet a previous page, because we
@@ -2994,42 +3059,35 @@ ibuf_get_volume_buffered(
 			return(UNIV_PAGE_SIZE);
 		}
 
-		if (page_no != ibuf_rec_get_page_no(rec)
-		    || space != ibuf_rec_get_space(rec)) {
+		if (page_no != ibuf_rec_get_page_no(mtr, rec)
+		    || space != ibuf_rec_get_space(mtr, rec)) {
 
 			goto count_later;
 		}
 
 		volume += ibuf_get_volume_buffered_count(
-			rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
-
-		rec = page_rec_get_prev(rec);
-		ut_ad(page_align(rec) == prev_page);
+			mtr, rec,
+			hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
 	}
 
 count_later:
 	rec = btr_pcur_get_rec(pcur);
 
 	if (!page_rec_is_supremum(rec)) {
-		rec = page_rec_get_next(rec);
+		rec = page_rec_get_next_const(rec);
 	}
 
-	for (;;) {
-		if (page_rec_is_supremum(rec)) {
-
-			break;
-		}
-
-		if (page_no != ibuf_rec_get_page_no(rec)
-		    || space != ibuf_rec_get_space(rec)) {
+	for (; !page_rec_is_supremum(rec);
+	     rec = page_rec_get_next_const(rec)) {
+		if (page_no != ibuf_rec_get_page_no(mtr, rec)
+		    || space != ibuf_rec_get_space(mtr, rec)) {
 
 			return(volume);
 		}
 
 		volume += ibuf_get_volume_buffered_count(
-			rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
-
-		rec = page_rec_get_next(rec);
+			mtr, rec,
+			hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
 	}
 
 	/* Look at the next page */
@@ -3045,7 +3103,8 @@ count_later:
 		buf_block_t*	block;
 
 		block = buf_page_get(
-			IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH, mtr);
+			IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH,
+			mtr);
 
 		buf_block_dbg_add_level(block, SYNC_TREE_NODE);
 
@@ -3059,9 +3118,11 @@ count_later:
 #endif /* UNIV_BTR_DEBUG */
 
 	rec = page_get_infimum_rec(next_page);
-	rec = page_rec_get_next(rec);
+	rec = page_rec_get_next_const(rec);
+
+	for (;; rec = page_rec_get_next_const(rec)) {
+		ut_ad(page_align(rec) == next_page);
 
-	for (;;) {
 		if (page_rec_is_supremum(rec)) {
 
 			/* We give up */
@@ -3069,17 +3130,15 @@ count_later:
 			return(UNIV_PAGE_SIZE);
 		}
 
-		if (page_no != ibuf_rec_get_page_no(rec)
-		    || space != ibuf_rec_get_space(rec)) {
+		if (page_no != ibuf_rec_get_page_no(mtr, rec)
+		    || space != ibuf_rec_get_space(mtr, rec)) {
 
 			return(volume);
 		}
 
 		volume += ibuf_get_volume_buffered_count(
-			rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
-
-		rec = page_rec_get_next(rec);
-		ut_ad(page_align(rec) == next_page);
+			mtr, rec,
+			hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
 	}
 }
 
@@ -3100,9 +3159,7 @@ ibuf_update_max_tablespace_id(void)
 
 	ut_a(!dict_table_is_comp(ibuf->index->table));
 
-	ibuf_enter();
-
-	mtr_start(&mtr);
+	ibuf_mtr_start(&mtr);
 
 	btr_pcur_open_at_index_side(
 		FALSE, ibuf->index, BTR_SEARCH_LEAF, &pcur, TRUE, &mtr);
@@ -3125,14 +3182,20 @@ ibuf_update_max_tablespace_id(void)
 		max_space_id = mach_read_from_4(field);
 	}
 
-	mtr_commit(&mtr);
-	ibuf_exit();
+	ibuf_mtr_commit(&mtr);
 
 	/* printf("Maximum space id in insert buffer %lu\n", max_space_id); */
 
 	fil_set_max_space_id_if_bigger(max_space_id);
 }
 
+#ifdef UNIV_DEBUG
+# define ibuf_get_entry_counter_low(mtr,rec,space,page_no)	\
+	ibuf_get_entry_counter_low_func(mtr,rec,space,page_no)
+#else /* UNIV_DEBUG */
+# define ibuf_get_entry_counter_low(mtr,rec,space,page_no)	\
+	ibuf_get_entry_counter_low_func(rec,space,page_no)
+#endif
 /****************************************************************//**
 Helper function for ibuf_set_entry_counter. Checks if rec is for (space,
 page_no), and if so, reads counter value from it and returns that + 1.
@@ -3140,8 +3203,11 @@ Otherwise, returns 0.
 @return	new counter value, or 0 */
 static
 ulint
-ibuf_get_entry_counter_low(
-/*=======================*/
+ibuf_get_entry_counter_low_func(
+/*============================*/
+#ifdef UNIV_DEBUG
+	mtr_t*		mtr,		/*!< in: mini-transaction of rec */
+#endif /* UNIV_DEBUG */
 	const rec_t*	rec,		/*!< in: insert buffer record */
 	ulint		space,		/*!< in: space id */
 	ulint		page_no)	/*!< in: page number */
@@ -3150,7 +3216,9 @@ ibuf_get_entry_counter_low(
 	const byte*	field;
 	ulint		len;
 
-	ut_ad(ibuf_inside());
+	ut_ad(ibuf_inside(mtr));
+	ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
+	      || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
 	ut_ad(rec_get_n_fields_old(rec) > 2);
 
 	field = rec_get_nth_field_old(rec, 1, &len);
@@ -3222,12 +3290,15 @@ ibuf_set_entry_counter(
 	ulint		counter = 0;
 
 	/* pcur points to either a user rec or to a page's infimum record. */
+	ut_ad(ibuf_inside(mtr));
+	ut_ad(mtr_memo_contains(mtr, btr_pcur_get_block(pcur),
+				MTR_MEMO_PAGE_X_FIX));
 	ut_ad(page_validate(btr_pcur_get_page(pcur), ibuf->index));
 
 	if (btr_pcur_is_on_user_rec(pcur)) {
 
 		counter = ibuf_get_entry_counter_low(
-			btr_pcur_get_rec(pcur), space, page_no);
+			mtr, btr_pcur_get_rec(pcur), space, page_no);
 
 		if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
 			/* The record lacks a counter field.
@@ -3283,7 +3354,7 @@ ibuf_set_entry_counter(
 			ut_ad(page_rec_is_user_rec(rec));
 
 			counter = ibuf_get_entry_counter_low(
-				rec, space, page_no);
+				mtr, rec, space, page_no);
 
 			if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
 				/* The record lacks a counter field.
@@ -3435,7 +3506,6 @@ ibuf_insert_low(
 
 	if (mode == BTR_MODIFY_TREE) {
 		for (;;) {
-			ibuf_enter();
 			mutex_enter(&ibuf_pessimistic_insert_mutex);
 			mutex_enter(&ibuf_mutex);
 
@@ -3446,7 +3516,6 @@ ibuf_insert_low(
 
 			mutex_exit(&ibuf_mutex);
 			mutex_exit(&ibuf_pessimistic_insert_mutex);
-			ibuf_exit();
 
 			if (UNIV_UNLIKELY(!ibuf_add_free_page())) {
 
@@ -3454,11 +3523,9 @@ ibuf_insert_low(
 				return(DB_STRONG_FAIL);
 			}
 		}
-	} else {
-		ibuf_enter();
 	}
 
-	mtr_start(&mtr);
+	ibuf_mtr_start(&mtr);
 
 	btr_pcur_open(ibuf->index, ibuf_entry, PAGE_CUR_LE, mode, &pcur, &mtr);
 	ut_ad(page_validate(btr_pcur_get_page(&pcur), ibuf->index));
@@ -3513,7 +3580,7 @@ fail_exit:
 #ifdef UNIV_IBUF_COUNT_DEBUG
 	ut_a((buffered == 0) || ibuf_count_get(space, page_no));
 #endif
-	mtr_start(&bitmap_mtr);
+	ibuf_mtr_start(&bitmap_mtr);
 
 	bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
 					       zip_size, &bitmap_mtr);
@@ -3534,15 +3601,15 @@ fail_exit:
 		if (buffered + entry_size + page_dir_calc_reserved_space(1)
 		    > ibuf_index_page_calc_free_from_bits(zip_size, bits)) {
 			/* Release the bitmap page latch early. */
-			mtr_commit(&bitmap_mtr);
+			ibuf_mtr_commit(&bitmap_mtr);
 
 			/* It may not fit */
 			do_merge = TRUE;
 
-			ibuf_get_merge_page_nos(
-				FALSE, btr_pcur_get_rec(&pcur),
-				space_ids, space_versions,
-				page_nos, &n_stored);
+			ibuf_get_merge_page_nos(FALSE,
+						btr_pcur_get_rec(&pcur), &mtr,
+						space_ids, space_versions,
+						page_nos, &n_stored);
 
 			goto fail_exit;
 		}
@@ -3555,7 +3622,7 @@ fail_exit:
 	    && !ibuf_set_entry_counter(ibuf_entry, space, page_no, &pcur,
 				       mode == BTR_MODIFY_PREV, &mtr)) {
 bitmap_fail:
-		mtr_commit(&bitmap_mtr);
+		ibuf_mtr_commit(&bitmap_mtr);
 
 		goto fail_exit;
 	}
@@ -3573,7 +3640,7 @@ bitmap_fail:
 					  &bitmap_mtr);
 	}
 
-	mtr_commit(&bitmap_mtr);
+	ibuf_mtr_commit(&bitmap_mtr);
 
 	cursor = btr_pcur_get_btr_cur(&pcur);
 
@@ -3638,9 +3705,8 @@ func_exit:
 	}
 #endif
 
-	mtr_commit(&mtr);
+	ibuf_mtr_commit(&mtr);
 	btr_pcur_close(&pcur);
-	ibuf_exit();
 
 	mem_heap_free(heap);
 
@@ -3898,7 +3964,7 @@ ibuf_insert_to_index_page(
 	page_t*		page		= buf_block_get_frame(block);
 	rec_t*		rec;
 
-	ut_ad(ibuf_inside());
+	ut_ad(ibuf_inside(mtr));
 	ut_ad(dtuple_check_typed(entry));
 	ut_ad(!buf_block_align(page)->is_hashed);
 
@@ -4045,7 +4111,7 @@ ibuf_set_del_mark(
 	page_cur_t	page_cur;
 	ulint		low_match;
 
-	ut_ad(ibuf_inside());
+	ut_ad(ibuf_inside(mtr));
 	ut_ad(dtuple_check_typed(entry));
 
 	low_match = page_cur_search(
@@ -4102,7 +4168,7 @@ ibuf_delete(
 	page_cur_t	page_cur;
 	ulint		low_match;
 
-	ut_ad(ibuf_inside());
+	ut_ad(ibuf_inside(mtr));
 	ut_ad(dtuple_check_typed(entry));
 
 	low_match = page_cur_search(
@@ -4190,7 +4256,7 @@ ibuf_restore_pos(
 		/* The tablespace has been dropped.  It is possible
 		that another thread has deleted the insert buffer
 		entry.  Do not complain. */
-		btr_pcur_commit_specify_mtr(pcur, mtr);
+		ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
 	} else {
 		fprintf(stderr,
 			"InnoDB: ERROR: Submit the output to"
@@ -4208,7 +4274,7 @@ ibuf_restore_pos(
 			      page_rec_get_next(btr_pcur_get_rec(pcur)));
 		fflush(stderr);
 
-		btr_pcur_commit_specify_mtr(pcur, mtr);
+		ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
 
 		fputs("InnoDB: Validating insert buffer tree:\n", stderr);
 		if (!btr_validate_index(ibuf->index, NULL)) {
@@ -4232,8 +4298,8 @@ ibool
 ibuf_delete_rec(
 /*============*/
 	ulint		space,	/*!< in: space id */
-	ulint		page_no,/*!< in: index page number where the record
-				should belong */
+	ulint		page_no,/*!< in: index page number that the record
+				should belong to */
 	btr_pcur_t*	pcur,	/*!< in: pcur positioned on the record to
 				delete, having latch mode BTR_MODIFY_LEAF */
 	const dtuple_t*	search_tuple,
@@ -4244,10 +4310,10 @@ ibuf_delete_rec(
 	page_t*		root;
 	ulint		err;
 
-	ut_ad(ibuf_inside());
+	ut_ad(ibuf_inside(mtr));
 	ut_ad(page_rec_is_user_rec(btr_pcur_get_rec(pcur)));
-	ut_ad(ibuf_rec_get_page_no(btr_pcur_get_rec(pcur)) == page_no);
-	ut_ad(ibuf_rec_get_space(btr_pcur_get_rec(pcur)) == space);
+	ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
+	ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
 
 	success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr);
 
@@ -4280,22 +4346,22 @@ ibuf_delete_rec(
 	}
 
 	ut_ad(page_rec_is_user_rec(btr_pcur_get_rec(pcur)));
-	ut_ad(ibuf_rec_get_page_no(btr_pcur_get_rec(pcur)) == page_no);
-	ut_ad(ibuf_rec_get_space(btr_pcur_get_rec(pcur)) == space);
+	ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
+	ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
 
 	/* We have to resort to a pessimistic delete from ibuf */
 	btr_pcur_store_position(pcur, mtr);
+	ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
 
-	btr_pcur_commit_specify_mtr(pcur, mtr);
-
+	ibuf_mtr_start(mtr);
 	mutex_enter(&ibuf_mutex);
 
-	mtr_start(mtr);
-
 	if (!ibuf_restore_pos(space, page_no, search_tuple,
 			      BTR_MODIFY_TREE, pcur, mtr)) {
 
 		mutex_exit(&ibuf_mutex);
+		ut_ad(!ibuf_inside(mtr));
+		ut_ad(mtr->state == MTR_COMMITTED);
 		goto func_exit;
 	}
 
@@ -4312,9 +4378,11 @@ ibuf_delete_rec(
 	mutex_exit(&ibuf_mutex);
 
 	ibuf->empty = (page_get_n_recs(root) == 0);
-	btr_pcur_commit_specify_mtr(pcur, mtr);
+	ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
 
 func_exit:
+	ut_ad(!ibuf_inside(mtr));
+	ut_ad(mtr->state == MTR_COMMITTED);
 	btr_pcur_close(pcur);
 
 	return(TRUE);
@@ -4406,18 +4474,20 @@ ibuf_merge_or_delete_for_page(
 			update_ibuf_bitmap = FALSE;
 		} else {
 			page_t*	bitmap_page;
+			ulint	bitmap_bits;
 
-			mtr_start(&mtr);
+			ibuf_mtr_start(&mtr);
 
 			bitmap_page = ibuf_bitmap_get_map_page(
 				space, page_no, zip_size, &mtr);
+			bitmap_bits = ibuf_bitmap_page_get_bits(
+				bitmap_page, page_no, zip_size,
+				IBUF_BITMAP_BUFFERED, &mtr);
 
-			if (!ibuf_bitmap_page_get_bits(bitmap_page, page_no,
-						       zip_size,
-						       IBUF_BITMAP_BUFFERED,
-						       &mtr)) {
+			ibuf_mtr_commit(&mtr);
+
+			if (!bitmap_bits) {
 				/* No inserts buffered for this page */
-				mtr_commit(&mtr);
 
 				if (!tablespace_being_deleted) {
 					fil_decr_pending_ibuf_merges(space);
@@ -4425,7 +4495,6 @@ ibuf_merge_or_delete_for_page(
 
 				return;
 			}
-			mtr_commit(&mtr);
 		}
 	} else if (block
 		   && (ibuf_fixed_addr_page(space, zip_size, page_no)
@@ -4434,11 +4503,9 @@ ibuf_merge_or_delete_for_page(
 		return;
 	}
 
-	ibuf_enter();
-
 	heap = mem_heap_create(512);
 
-	if (!trx_sys_multiple_tablespace_format) {
+	if (UNIV_UNLIKELY(!trx_sys_multiple_tablespace_format)) {
 		ut_a(trx_doublewrite_must_reset_space_ids);
 		search_tuple = ibuf_search_tuple_build(space, page_no, heap);
 	} else {
@@ -4465,7 +4532,7 @@ ibuf_merge_or_delete_for_page(
 
 			ut_print_timestamp(stderr);
 
-			mtr_start(&mtr);
+			ibuf_mtr_start(&mtr);
 
 			fputs("  InnoDB: Dump of the ibuf bitmap page:\n",
 			      stderr);
@@ -4473,8 +4540,7 @@ ibuf_merge_or_delete_for_page(
 			bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
 							       zip_size, &mtr);
 			buf_page_print(bitmap_page, 0);
-
-			mtr_commit(&mtr);
+			ibuf_mtr_commit(&mtr);
 
 			fputs("\nInnoDB: Dump of the page:\n", stderr);
 
@@ -4505,7 +4571,7 @@ ibuf_merge_or_delete_for_page(
 	memset(dops, 0, sizeof(dops));
 
 loop:
-	mtr_start(&mtr);
+	ibuf_mtr_start(&mtr);
 
 	if (block) {
 		ibool success;
@@ -4539,8 +4605,8 @@ loop:
 		rec = btr_pcur_get_rec(&pcur);
 
 		/* Check if the entry is for this index page */
-		if (ibuf_rec_get_page_no(rec) != page_no
-		    || ibuf_rec_get_space(rec) != space) {
+		if (ibuf_rec_get_page_no(&mtr, rec) != page_no
+		    || ibuf_rec_get_space(&mtr, rec) != space) {
 
 			if (block) {
 				page_header_reset_last_insert(
@@ -4563,7 +4629,7 @@ loop:
 			dtuple_t*	entry;
 			trx_id_t	max_trx_id;
 			dict_index_t*	dummy_index;
-			ibuf_op_t	op = ibuf_rec_get_op_type(rec);
+			ibuf_op_t	op = ibuf_rec_get_op_type(&mtr, rec);
 
 			max_trx_id = page_get_max_trx_id(page_align(rec));
 			page_update_max_trx_id(block, page_zip, max_trx_id,
@@ -4572,7 +4638,7 @@ loop:
 			ut_ad(page_validate(page_align(rec), ibuf->index));
 
 			entry = ibuf_build_entry_from_ibuf_rec(
-				rec, heap, &dummy_index);
+				&mtr, rec, heap, &dummy_index);
 
 			ut_ad(page_validate(block->frame, dummy_index));
 
@@ -4605,13 +4671,14 @@ loop:
 				Store and restore the cursor position. */
 				ut_ad(rec == btr_pcur_get_rec(&pcur));
 				ut_ad(page_rec_is_user_rec(rec));
-				ut_ad(ibuf_rec_get_page_no(rec) == page_no);
-				ut_ad(ibuf_rec_get_space(rec) == space);
+				ut_ad(ibuf_rec_get_page_no(&mtr, rec)
+				      == page_no);
+				ut_ad(ibuf_rec_get_space(&mtr, rec) == space);
 
 				btr_pcur_store_position(&pcur, &mtr);
-				btr_pcur_commit_specify_mtr(&pcur, &mtr);
+				ibuf_btr_pcur_commit_specify_mtr(&pcur, &mtr);
 
-				mtr_start(&mtr);
+				ibuf_mtr_start(&mtr);
 
 				success = buf_page_get_known_nowait(
 					RW_X_LATCH, block,
@@ -4626,7 +4693,8 @@ loop:
 						      BTR_MODIFY_LEAF,
 						      &pcur, &mtr)) {
 
-					mtr_commit(&mtr);
+					ut_ad(!ibuf_inside(&mtr));
+					ut_ad(mtr.state == MTR_COMMITTED);
 					mops[op]++;
 					ibuf_dummy_index_free(dummy_index);
 					goto loop;
@@ -4641,7 +4709,7 @@ loop:
 
 			ibuf_dummy_index_free(dummy_index);
 		} else {
-			dops[ibuf_rec_get_op_type(rec)]++;
+			dops[ibuf_rec_get_op_type(&mtr, rec)]++;
 		}
 
 		/* Delete the record from ibuf */
@@ -4652,7 +4720,7 @@ loop:
 
 			goto loop;
 		} else if (btr_pcur_is_after_last_on_page(&pcur)) {
-			mtr_commit(&mtr);
+			ibuf_mtr_commit(&mtr);
 			btr_pcur_close(&pcur);
 
 			goto loop;
@@ -4686,7 +4754,7 @@ reset_bit:
 		}
 	}
 
-	mtr_commit(&mtr);
+	ibuf_mtr_commit(&mtr);
 	btr_pcur_close(&pcur);
 	mem_heap_free(heap);
 
@@ -4710,8 +4778,6 @@ reset_bit:
 		fil_decr_pending_ibuf_merges(space);
 	}
 
-	ibuf_exit();
-
 #ifdef UNIV_IBUF_COUNT_DEBUG
 	ut_a(ibuf_count_get(space, page_no) == 0);
 #endif
@@ -4731,9 +4797,8 @@ ibuf_delete_for_discarded_space(
 	mem_heap_t*	heap;
 	btr_pcur_t	pcur;
 	dtuple_t*	search_tuple;
-	rec_t*		ibuf_rec;
+	const rec_t*	ibuf_rec;
 	ulint		page_no;
-	ibool		closed;
 	mtr_t		mtr;
 
 	/* Counts for discarded operations. */
@@ -4748,9 +4813,7 @@ ibuf_delete_for_discarded_space(
 
 	memset(dops, 0, sizeof(dops));
 loop:
-	ibuf_enter();
-
-	mtr_start(&mtr);
+	ibuf_mtr_start(&mtr);
 
 	/* Position pcur in the insert buffer at the first entry for the
 	space */
@@ -4770,39 +4833,34 @@ loop:
 		ibuf_rec = btr_pcur_get_rec(&pcur);
 
 		/* Check if the entry is for this space */
-		if (ibuf_rec_get_space(ibuf_rec) != space) {
+		if (ibuf_rec_get_space(&mtr, ibuf_rec) != space) {
 
 			goto leave_loop;
 		}
 
-		page_no = ibuf_rec_get_page_no(ibuf_rec);
+		page_no = ibuf_rec_get_page_no(&mtr, ibuf_rec);
 
-		dops[ibuf_rec_get_op_type(ibuf_rec)]++;
+		dops[ibuf_rec_get_op_type(&mtr, ibuf_rec)]++;
 
 		/* Delete the record from ibuf */
-		closed = ibuf_delete_rec(space, page_no, &pcur, search_tuple,
-					 &mtr);
-		if (closed) {
+		if (ibuf_delete_rec(space, page_no, &pcur, search_tuple,
+				    &mtr)) {
 			/* Deletion was pessimistic and mtr was committed:
 			we start from the beginning again */
 
-			ibuf_exit();
-
 			goto loop;
 		}
 
 		if (btr_pcur_is_after_last_on_page(&pcur)) {
-			mtr_commit(&mtr);
+			ibuf_mtr_commit(&mtr);
 			btr_pcur_close(&pcur);
 
-			ibuf_exit();
-
 			goto loop;
 		}
 	}
 
 leave_loop:
-	mtr_commit(&mtr);
+	ibuf_mtr_commit(&mtr);
 	btr_pcur_close(&pcur);
 
 #ifdef HAVE_ATOMIC_BUILTINS
@@ -4814,8 +4872,6 @@ leave_loop:
 	mutex_exit(&ibuf_mutex);
 #endif /* HAVE_ATOMIC_BUILTINS */
 
-	ibuf_exit();
-
 	mem_heap_free(heap);
 }
 
@@ -4831,18 +4887,15 @@ ibuf_is_empty(void)
 	const page_t*	root;
 	mtr_t		mtr;
 
-	ibuf_enter();
-	mtr_start(&mtr);
+	ibuf_mtr_start(&mtr);
 
 	mutex_enter(&ibuf_mutex);
 	root = ibuf_tree_root_get(&mtr);
 	mutex_exit(&ibuf_mutex);
 
 	is_empty = (page_get_n_recs(root) == 0);
-	mtr_commit(&mtr);
-	ibuf_exit();
-
 	ut_a(is_empty == ibuf->empty);
+	ibuf_mtr_commit(&mtr);
 
 	return(is_empty);
 }

=== modified file 'storage/innobase/include/btr0pcur.h'
--- a/storage/innobase/include/btr0pcur.h	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/include/btr0pcur.h	2011-03-21 07:56:38 +0000
@@ -150,7 +150,7 @@ UNIV_INLINE
 ulint
 btr_pcur_get_up_match(
 /*==================*/
-	btr_pcur_t*	cursor); /*!< in: memory buffer for persistent cursor */
+	const btr_pcur_t*	cursor); /*!< in: persistent cursor */
 /**************************************************************//**
 Gets the low_match value for a pcur after a search.
 @return number of matched fields at the cursor or to the right if
@@ -159,7 +159,7 @@ UNIV_INLINE
 ulint
 btr_pcur_get_low_match(
 /*===================*/
-	btr_pcur_t*	cursor); /*!< in: memory buffer for persistent cursor */
+	const btr_pcur_t*	cursor); /*!< in: persistent cursor */
 /**************************************************************//**
 If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first
 user record satisfying the search condition, in the case PAGE_CUR_L or
@@ -264,22 +264,6 @@ ulint
 btr_pcur_get_rel_pos(
 /*=================*/
 	const btr_pcur_t*	cursor);/*!< in: persistent cursor */
-/*********************************************************//**
-Sets the mtr field for a pcur. */
-UNIV_INLINE
-void
-btr_pcur_set_mtr(
-/*=============*/
-	btr_pcur_t*	cursor,	/*!< in: persistent cursor */
-	mtr_t*		mtr);	/*!< in, own: mtr */
-/*********************************************************//**
-Gets the mtr field for a pcur.
-@return	mtr */
-UNIV_INLINE
-mtr_t*
-btr_pcur_get_mtr(
-/*=============*/
-	btr_pcur_t*	cursor);	/*!< in: persistent cursor */
 /**************************************************************//**
 Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES,
 that is, the cursor becomes detached. If there have been modifications
@@ -387,10 +371,6 @@ page_cur_t*
 btr_pcur_get_page_cur(
 /*==================*/
 	const btr_pcur_t*	cursor);	/*!< in: persistent cursor */
-#else /* UNIV_DEBUG */
-# define btr_pcur_get_btr_cur(cursor) (&(cursor)->btr_cur)
-# define btr_pcur_get_page_cur(cursor) (&(cursor)->btr_cur.page_cur)
-#endif /* UNIV_DEBUG */
 /*********************************************************//**
 Returns the page of a persistent cursor.
 @return	pointer to the page */
@@ -398,7 +378,7 @@ UNIV_INLINE
 page_t*
 btr_pcur_get_page(
 /*==============*/
-	btr_pcur_t*	cursor);/*!< in: persistent cursor */
+	const btr_pcur_t*	cursor);/*!< in: persistent cursor */
 /*********************************************************//**
 Returns the buffer block of a persistent cursor.
 @return	pointer to the block */
@@ -406,7 +386,7 @@ UNIV_INLINE
 buf_block_t*
 btr_pcur_get_block(
 /*===============*/
-	btr_pcur_t*	cursor);/*!< in: persistent cursor */
+	const btr_pcur_t*	cursor);/*!< in: persistent cursor */
 /*********************************************************//**
 Returns the record of a persistent cursor.
 @return	pointer to the record */
@@ -414,7 +394,14 @@ UNIV_INLINE
 rec_t*
 btr_pcur_get_rec(
 /*=============*/
-	btr_pcur_t*	cursor);/*!< in: persistent cursor */
+	const btr_pcur_t*	cursor);/*!< in: persistent cursor */
+#else /* UNIV_DEBUG */
+# define btr_pcur_get_btr_cur(cursor) (&(cursor)->btr_cur)
+# define btr_pcur_get_page_cur(cursor) (&(cursor)->btr_cur.page_cur)
+# define btr_pcur_get_page(cursor) ((cursor)->btr_cur.page_cur.block->frame)
+# define btr_pcur_get_block(cursor) ((cursor)->btr_cur.page_cur.block)
+# define btr_pcur_get_rec(cursor) ((cursor)->btr_cur.page_cur.rec)
+#endif /* UNIV_DEBUG */
 /*********************************************************//**
 Checks if the persistent cursor is on a user record. */
 UNIV_INLINE
@@ -517,9 +504,6 @@ struct btr_pcur_struct{
 	/* NOTE that the following fields may possess dynamically allocated
 	memory which should be freed if not needed anymore! */
 
-	mtr_t*		mtr;		/*!< NULL, or this field may contain
-					a mini-transaction which holds the
-					latch on the cursor page */
 	byte*		old_rec_buf;	/*!< NULL, or a dynamically allocated
 					buffer for old_rec */
 	ulint		buf_size;	/*!< old_rec_buf size if old_rec_buf

=== modified file 'storage/innobase/include/btr0pcur.ic'
--- a/storage/innobase/include/btr0pcur.ic	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/include/btr0pcur.ic	2011-03-21 07:56:38 +0000
@@ -42,34 +42,6 @@ btr_pcur_get_rel_pos(
 	return(cursor->rel_pos);
 }
 
-/*********************************************************//**
-Sets the mtr field for a pcur. */
-UNIV_INLINE
-void
-btr_pcur_set_mtr(
-/*=============*/
-	btr_pcur_t*	cursor,	/*!< in: persistent cursor */
-	mtr_t*		mtr)	/*!< in, own: mtr */
-{
-	ut_ad(cursor);
-
-	cursor->mtr = mtr;
-}
-
-/*********************************************************//**
-Gets the mtr field for a pcur.
-@return	mtr */
-UNIV_INLINE
-mtr_t*
-btr_pcur_get_mtr(
-/*=============*/
-	btr_pcur_t*	cursor)	/*!< in: persistent cursor */
-{
-	ut_ad(cursor);
-
-	return(cursor->mtr);
-}
-
 #ifdef UNIV_DEBUG
 /*********************************************************//**
 Returns the btr cursor component of a persistent cursor.
@@ -95,7 +67,7 @@ btr_pcur_get_page_cur(
 {
 	return(btr_cur_get_page_cur(btr_pcur_get_btr_cur(cursor)));
 }
-#endif /* UNIV_DEBUG */
+
 /*********************************************************//**
 Returns the page of a persistent cursor.
 @return	pointer to the page */
@@ -103,7 +75,7 @@ UNIV_INLINE
 page_t*
 btr_pcur_get_page(
 /*==============*/
-	btr_pcur_t*	cursor)	/*!< in: persistent cursor */
+	const btr_pcur_t*	cursor)	/*!< in: persistent cursor */
 {
 	ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
@@ -117,7 +89,7 @@ UNIV_INLINE
 buf_block_t*
 btr_pcur_get_block(
 /*===============*/
-	btr_pcur_t*	cursor)	/*!< in: persistent cursor */
+	const btr_pcur_t*	cursor)	/*!< in: persistent cursor */
 {
 	ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 
@@ -131,13 +103,14 @@ UNIV_INLINE
 rec_t*
 btr_pcur_get_rec(
 /*=============*/
-	btr_pcur_t*	cursor)	/*!< in: persistent cursor */
+	const btr_pcur_t*	cursor)	/*!< in: persistent cursor */
 {
 	ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 	ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
 	return(btr_cur_get_rec(btr_pcur_get_btr_cur(cursor)));
 }
+#endif /* UNIV_DEBUG */
 
 /**************************************************************//**
 Gets the up_match value for a pcur after a search.
@@ -147,9 +120,9 @@ UNIV_INLINE
 ulint
 btr_pcur_get_up_match(
 /*==================*/
-	btr_pcur_t*	cursor) /*!< in: memory buffer for persistent cursor */
+	const btr_pcur_t*	cursor) /*!< in: persistent cursor */
 {
-	btr_cur_t*	btr_cursor;
+	const btr_cur_t*	btr_cursor;
 
 	ut_ad((cursor->pos_state == BTR_PCUR_WAS_POSITIONED)
 	      || (cursor->pos_state == BTR_PCUR_IS_POSITIONED));
@@ -169,9 +142,9 @@ UNIV_INLINE
 ulint
 btr_pcur_get_low_match(
 /*===================*/
-	btr_pcur_t*	cursor) /*!< in: memory buffer for persistent cursor */
+	const btr_pcur_t*	cursor) /*!< in: persistent cursor */
 {
-	btr_cur_t*	btr_cursor;
+	const btr_cur_t*	btr_cursor;
 
 	ut_ad((cursor->pos_state == BTR_PCUR_WAS_POSITIONED)
 	      || (cursor->pos_state == BTR_PCUR_IS_POSITIONED));

=== modified file 'storage/innobase/include/buf0buf.h'
--- a/storage/innobase/include/buf0buf.h	2011-02-02 13:58:01 +0000
+++ b/storage/innobase/include/buf0buf.h	2011-02-28 13:39:07 +0000
@@ -41,6 +41,8 @@ Created 11/5/1995 Heikki Tuuri
 /* @{ */
 #define BUF_GET			10	/*!< get always */
 #define	BUF_GET_IF_IN_POOL	11	/*!< get if in pool */
+#define BUF_PEEK_IF_IN_POOL	12	/*!< get if in pool, do not make
+					the block young in the LRU list */
 #define BUF_GET_NO_LATCH	14	/*!< get and bufferfix, but
 					set no latch; we have
 					separated this case, because
@@ -396,7 +398,7 @@ buf_page_get_gen(
 	ulint		rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
 	buf_block_t*	guess,	/*!< in: guessed block or NULL */
 	ulint		mode,	/*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
-				BUF_GET_NO_LATCH or
+				BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH or
 				BUF_GET_IF_IN_POOL_OR_WATCH */
 	const char*	file,	/*!< in: file name */
 	ulint		line,	/*!< in: line where called */

=== modified file 'storage/innobase/include/buf0rea.h'
--- a/storage/innobase/include/buf0rea.h	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/include/buf0rea.h	2011-03-24 12:00:14 +0000
@@ -70,10 +70,10 @@ UNIV_INTERN
 ulint
 buf_read_ahead_linear(
 /*==================*/
-	ulint	space,	/*!< in: space id */
-	ulint	zip_size,/*!< in: compressed page size in bytes, or 0 */
-	ulint	offset);/*!< in: page number of a page; NOTE: the current thread
-			must want access to this page (see NOTE 3 above) */
+	ulint	space,		/*!< in: space id */
+	ulint	zip_size,	/*!< in: compressed page size in bytes, or 0 */
+	ulint	offset,		/*!< in: page number; see NOTE 3 above */
+	ibool	inside_ibuf);	/*!< in: TRUE if we are inside ibuf routine */
 /********************************************************************//**
 Issues read requests for pages which the ibuf module wants to read in, in
 order to contract the insert buffer tree. Technically, this function is like

=== modified file 'storage/innobase/include/ha_prototypes.h'
--- a/storage/innobase/include/ha_prototypes.h	2010-08-17 08:19:24 +0000
+++ b/storage/innobase/include/ha_prototypes.h	2011-02-25 08:33:13 +0000
@@ -174,6 +174,15 @@ innobase_strcasecmp(
 	const char*	b);	/*!< in: second string to compare */
 
 /******************************************************************//**
+Strip dir name from a full path name and return only its file name.
+@return file name or "null" if no file name */
+UNIV_INTERN
+const char*
+innobase_basename(
+/*==============*/
+	const char*	path_name);	/*!< in: full path name */
+
+/******************************************************************//**
 Returns true if the thread is executing a SELECT statement.
 @return	true if thd is executing SELECT */
 

=== modified file 'storage/innobase/include/ibuf0ibuf.h'
--- a/storage/innobase/include/ibuf0ibuf.h	2010-12-01 13:09:02 +0000
+++ b/storage/innobase/include/ibuf0ibuf.h	2011-03-24 12:00:14 +0000
@@ -104,6 +104,22 @@ UNIV_INTERN
 void
 ibuf_update_max_tablespace_id(void);
 /*===============================*/
+/***************************************************************//**
+Starts an insert buffer mini-transaction. */
+UNIV_INLINE
+void
+ibuf_mtr_start(
+/*===========*/
+	mtr_t*	mtr)	/*!< out: mini-transaction */
+	__attribute__((nonnull));
+/***************************************************************//**
+Commits an insert buffer mini-transaction. */
+UNIV_INLINE
+void
+ibuf_mtr_commit(
+/*============*/
+	mtr_t*	mtr)	/*!< in/out: mini-transaction */
+	__attribute__((nonnull));
 /*********************************************************************//**
 Initializes an ibuf bitmap page. */
 UNIV_INTERN
@@ -224,10 +240,12 @@ routine.
 For instance, a read-ahead of non-ibuf pages is forbidden by threads
 that are executing an insert buffer routine.
 @return TRUE if inside an insert buffer routine */
-UNIV_INTERN
+UNIV_INLINE
 ibool
-ibuf_inside(void);
-/*=============*/
+ibuf_inside(
+/*========*/
+	const mtr_t*	mtr)	/*!< in: mini-transaction */
+	__attribute__((nonnull, pure));
 /***********************************************************************//**
 Checks if a page address is an ibuf bitmap page (level 3 page) address.
 @return	TRUE if a bitmap page */

=== modified file 'storage/innobase/include/ibuf0ibuf.ic'
--- a/storage/innobase/include/ibuf0ibuf.ic	2010-08-10 10:22:48 +0000
+++ b/storage/innobase/include/ibuf0ibuf.ic	2011-03-24 12:00:14 +0000
@@ -37,6 +37,30 @@ buffer inserts to this page.  If there i
 corresponding bits are set in the ibuf bitmap. */
 #define IBUF_PAGE_SIZE_PER_FREE_SPACE	32
 
+/***************************************************************//**
+Starts an insert buffer mini-transaction. */
+UNIV_INLINE
+void
+ibuf_mtr_start(
+/*===========*/
+	mtr_t*	mtr)	/*!< out: mini-transaction */
+{
+	mtr_start(mtr);
+	mtr->inside_ibuf = TRUE;
+}
+/***************************************************************//**
+Commits an insert buffer mini-transaction. */
+UNIV_INLINE
+void
+ibuf_mtr_commit(
+/*============*/
+	mtr_t*	mtr)	/*!< in/out: mini-transaction */
+{
+	ut_ad(mtr->inside_ibuf);
+	ut_d(mtr->inside_ibuf = FALSE);
+	mtr_commit(mtr);
+}
+
 /** Insert buffer struct */
 struct ibuf_struct{
 	ulint		size;		/*!< current size of the ibuf index
@@ -120,6 +144,22 @@ ibuf_should_try(
 	return(FALSE);
 }
 
+/******************************************************************//**
+Returns TRUE if the current OS thread is performing an insert buffer
+routine.
+
+For instance, a read-ahead of non-ibuf pages is forbidden by threads
+that are executing an insert buffer routine.
+@return TRUE if inside an insert buffer routine */
+UNIV_INLINE
+ibool
+ibuf_inside(
+/*========*/
+	const mtr_t*	mtr)	/*!< in: mini-transaction */
+{
+	return(mtr->inside_ibuf);
+}
+
 /***********************************************************************//**
 Checks if a page address is an ibuf bitmap page address.
 @return	TRUE if a bitmap page */

=== modified file 'storage/innobase/include/mtr0mtr.h'
--- a/storage/innobase/include/mtr0mtr.h	2010-07-21 14:22:29 +0000
+++ b/storage/innobase/include/mtr0mtr.h	2011-03-24 12:00:14 +0000
@@ -190,21 +190,21 @@ functions).  The page number parameter w
 /* @} */
 
 /***************************************************************//**
-Starts a mini-transaction and creates a mini-transaction handle
-and buffer in the memory buffer given by the caller.
-@return	mtr buffer which also acts as the mtr handle */
+Starts a mini-transaction. */
 UNIV_INLINE
-mtr_t*
+void
 mtr_start(
 /*======*/
-	mtr_t*	mtr);	/*!< in: memory buffer for the mtr buffer */
+	mtr_t*	mtr)	/*!< out: mini-transaction */
+	__attribute__((nonnull));
 /***************************************************************//**
 Commits a mini-transaction. */
 UNIV_INTERN
 void
 mtr_commit(
 /*=======*/
-	mtr_t*	mtr);	/*!< in: mini-transaction */
+	mtr_t*	mtr)	/*!< in/out: mini-transaction */
+	__attribute__((nonnull));
 /**********************************************************//**
 Sets and returns a savepoint in mtr.
 @return	savepoint */
@@ -378,6 +378,8 @@ struct mtr_struct{
 #endif
 	dyn_array_t	memo;	/*!< memo stack for locks etc. */
 	dyn_array_t	log;	/*!< mini-transaction log */
+	ibool		inside_ibuf;
+				/*!< TRUE if inside ibuf changes */
 	ibool		modifications;
 				/* TRUE if the mtr made modifications to
 				buffer pool pages */

=== modified file 'storage/innobase/include/mtr0mtr.ic'
--- a/storage/innobase/include/mtr0mtr.ic	2010-12-01 08:43:33 +0000
+++ b/storage/innobase/include/mtr0mtr.ic	2011-03-24 12:00:14 +0000
@@ -30,26 +30,23 @@ Created 11/26/1995 Heikki Tuuri
 #include "mach0data.h"
 
 /***************************************************************//**
-Starts a mini-transaction and creates a mini-transaction handle
-and a buffer in the memory buffer given by the caller.
-@return	mtr buffer which also acts as the mtr handle */
+Starts a mini-transaction. */
 UNIV_INLINE
-mtr_t*
+void
 mtr_start(
 /*======*/
-	mtr_t*	mtr)	/*!< in: memory buffer for the mtr buffer */
+	mtr_t*	mtr)	/*!< out: mini-transaction */
 {
 	dyn_array_create(&(mtr->memo));
 	dyn_array_create(&(mtr->log));
 
 	mtr->log_mode = MTR_LOG_ALL;
 	mtr->modifications = FALSE;
+	mtr->inside_ibuf = FALSE;
 	mtr->n_log_recs = 0;
 
 	ut_d(mtr->state = MTR_ACTIVE);
 	ut_d(mtr->magic_n = MTR_MAGIC_N);
-
-	return(mtr);
 }
 
 /***************************************************//**

=== modified file 'storage/innobase/include/page0page.h'
--- a/storage/innobase/include/page0page.h	2010-07-21 14:22:29 +0000
+++ b/storage/innobase/include/page0page.h	2011-03-21 07:56:38 +0000
@@ -952,7 +952,7 @@ UNIV_INTERN
 ibool
 page_rec_validate(
 /*==============*/
-	rec_t*		rec,	/*!< in: physical record */
+	const rec_t*	rec,	/*!< in: physical record */
 	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
 /***************************************************************//**
 Checks that the first directory slot points to the infimum record and
@@ -972,7 +972,7 @@ UNIV_INTERN
 ibool
 page_simple_validate_old(
 /*=====================*/
-	page_t*	page);	/*!< in: old-style index page */
+	const page_t*	page);	/*!< in: index page in ROW_FORMAT=REDUNDANT */
 /***************************************************************//**
 This function checks the consistency of an index page when we do not
 know the index. This is also resilient so that this should never crash
@@ -982,7 +982,7 @@ UNIV_INTERN
 ibool
 page_simple_validate_new(
 /*=====================*/
-	page_t*	block);	/*!< in: new-style index page */
+	const page_t*	page);	/*!< in: index page in ROW_FORMAT!=REDUNDANT */
 /***************************************************************//**
 This function checks the consistency of an index page.
 @return	TRUE if ok */
@@ -990,7 +990,7 @@ UNIV_INTERN
 ibool
 page_validate(
 /*==========*/
-	page_t*		page,	/*!< in: index page */
+	const page_t*	page,	/*!< in: index page */
 	dict_index_t*	index);	/*!< in: data dictionary index containing
 				the page record type definition */
 /***************************************************************//**

=== modified file 'storage/innobase/include/rem0rec.h'
--- a/storage/innobase/include/rem0rec.h	2010-10-19 06:35:14 +0000
+++ b/storage/innobase/include/rem0rec.h	2011-03-21 07:56:38 +0000
@@ -600,6 +600,7 @@ ulint
 rec_offs_size(
 /*==========*/
 	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
+#ifdef UNIV_DEBUG
 /**********************************************************//**
 Returns a pointer to the start of the record.
 @return	pointer to start */
@@ -607,7 +608,7 @@ UNIV_INLINE
 byte*
 rec_get_start(
 /*==========*/
-	rec_t*		rec,	/*!< in: pointer to record */
+	const rec_t*	rec,	/*!< in: pointer to record */
 	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
 /**********************************************************//**
 Returns a pointer to the end of the record.
@@ -616,8 +617,12 @@ UNIV_INLINE
 byte*
 rec_get_end(
 /*========*/
-	rec_t*		rec,	/*!< in: pointer to record */
+	const rec_t*	rec,	/*!< in: pointer to record */
 	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
+#else /* UNIV_DEBUG */
+# define rec_get_start(rec, offsets) ((rec) - rec_offs_extra_size(offsets))
+# define rec_get_end(rec, offsets) ((rec) + rec_offs_data_size(offsets))
+#endif /* UNIV_DEBUG */
 /***************************************************************//**
 Copies a physical record to a buffer.
 @return	pointer to the origin of the copy */

=== modified file 'storage/innobase/include/rem0rec.ic'
--- a/storage/innobase/include/rem0rec.ic	2010-07-21 14:22:29 +0000
+++ b/storage/innobase/include/rem0rec.ic	2011-03-21 07:56:38 +0000
@@ -1462,6 +1462,7 @@ rec_offs_size(
 	return(rec_offs_data_size(offsets) + rec_offs_extra_size(offsets));
 }
 
+#ifdef UNIV_DEBUG
 /**********************************************************//**
 Returns a pointer to the end of the record.
 @return	pointer to end */
@@ -1469,11 +1470,11 @@ UNIV_INLINE
 byte*
 rec_get_end(
 /*========*/
-	rec_t*		rec,	/*!< in: pointer to record */
+	const rec_t*	rec,	/*!< in: pointer to record */
 	const ulint*	offsets)/*!< in: array returned by rec_get_offsets() */
 {
 	ut_ad(rec_offs_validate(rec, NULL, offsets));
-	return(rec + rec_offs_data_size(offsets));
+	return((rec_t*) rec + rec_offs_data_size(offsets));
 }
 
 /**********************************************************//**
@@ -1483,12 +1484,13 @@ UNIV_INLINE
 byte*
 rec_get_start(
 /*==========*/
-	rec_t*		rec,	/*!< in: pointer to record */
+	const rec_t*	rec,	/*!< in: pointer to record */
 	const ulint*	offsets)/*!< in: array returned by rec_get_offsets() */
 {
 	ut_ad(rec_offs_validate(rec, NULL, offsets));
-	return(rec - rec_offs_extra_size(offsets));
+	return((rec_t*) rec - rec_offs_extra_size(offsets));
 }
+#endif /* UNIV_DEBUG */
 
 /***************************************************************//**
 Copies a physical record to a buffer.

=== modified file 'storage/innobase/include/srv0srv.h'
--- a/storage/innobase/include/srv0srv.h	2011-02-22 05:04:08 +0000
+++ b/storage/innobase/include/srv0srv.h	2011-03-22 11:39:16 +0000
@@ -442,16 +442,8 @@ typedef enum srv_stats_method_name_enum
 #ifndef UNIV_HOTBACKUP
 /** Types of threads existing in the system. */
 enum srv_thread_type {
-	SRV_COM = 1,	/**< threads serving communication and queries */
-	SRV_CONSOLE,	/**< thread serving console */
-	SRV_WORKER,	/**< threads serving parallelized queries and
+	SRV_WORKER = 0,	/**< threads serving parallelized queries and
 			queries released from lock wait */
-#if 0
-	/* Utility threads */
-	SRV_BUFFER,	/**< thread flushing dirty buffer blocks */
-	SRV_RECOVERY,	/**< threads finishing a recovery */
-	SRV_INSERT,	/**< thread flushing the insert buffer to disk */
-#endif
 	SRV_MASTER	/**< the master thread, (whose type number must
 			be biggest) */
 };
@@ -490,13 +482,6 @@ ulint
 srv_get_n_threads(void);
 /*===================*/
 /*********************************************************************//**
-Returns the calling thread type.
-@return	SRV_COM, ... */
-
-enum srv_thread_type
-srv_get_thread_type(void);
-/*=====================*/
-/*********************************************************************//**
 Check whether thread type has reserved a slot.
 @return	slot number or UNDEFINED if not found*/
 UNIV_INTERN

=== modified file 'storage/innobase/include/sync0arr.h'
--- a/storage/innobase/include/sync0arr.h	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/include/sync0arr.h	2011-03-30 11:52:26 +0000
@@ -115,8 +115,11 @@ Prints warnings of long semaphore waits
 @return	TRUE if fatal semaphore wait threshold was exceeded */
 UNIV_INTERN
 ibool
-sync_array_print_long_waits(void);
-/*=============================*/
+sync_array_print_long_waits(
+/*========================*/
+	os_thread_id_t*	waiter,	/*!< out: longest waiting thread */
+	const void**	sema)	/*!< out: longest-waited-for semaphore */
+	__attribute__((nonnull));
 /********************************************************************//**
 Validates the integrity of the wait array. Checks
 that the number of reserved cells equals the count variable. */

=== modified file 'storage/innobase/include/sync0sync.h'
--- a/storage/innobase/include/sync0sync.h	2011-02-22 05:04:08 +0000
+++ b/storage/innobase/include/sync0sync.h	2011-03-24 12:00:14 +0000
@@ -110,7 +110,6 @@ extern mysql_pfs_key_t	syn_arr_mutex_key
 extern mysql_pfs_key_t	sync_thread_mutex_key;
 # endif /* UNIV_SYNC_DEBUG */
 extern mysql_pfs_key_t	trx_doublewrite_mutex_key;
-extern mysql_pfs_key_t	thr_local_mutex_key;
 extern mysql_pfs_key_t	trx_undo_mutex_key;
 #endif /* UNIV_PFS_MUTEX */
 

=== removed file 'storage/innobase/include/thr0loc.h'
--- a/storage/innobase/include/thr0loc.h	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/include/thr0loc.h	1970-01-01 00:00:00 +0000
@@ -1,90 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/thr0loc.h
-The thread local storage
-
-Created 10/5/1995 Heikki Tuuri
-*******************************************************/
-
-/* This module implements storage private to each thread,
-a capability useful in some situations like storing the
-OS handle to the current thread, or its priority. */
-
-#ifndef thr0loc_h
-#define thr0loc_h
-
-#include "univ.i"
-#include "os0thread.h"
-
-/****************************************************************//**
-Initializes the thread local storage module. */
-UNIV_INTERN
-void
-thr_local_init(void);
-/*================*/
- /****************************************************************//**
-Close the thread local storage module. */
-UNIV_INTERN
-void
-thr_local_close(void);
-/*=================*/
-/*******************************************************************//**
-Creates a local storage struct for the calling new thread. */
-UNIV_INTERN
-void
-thr_local_create(void);
-/*==================*/
-/*******************************************************************//**
-Frees the local storage struct for the specified thread. */
-UNIV_INTERN
-void
-thr_local_free(
-/*===========*/
-	os_thread_id_t	id);	/*!< in: thread id */
-/*******************************************************************//**
-Gets the slot number in the thread table of a thread.
-@return	slot number */
-UNIV_INTERN
-ulint
-thr_local_get_slot_no(
-/*==================*/
-	os_thread_id_t	id);	/*!< in: thread id of the thread */
-/*******************************************************************//**
-Sets in the local storage the slot number in the thread table of a thread. */
-UNIV_INTERN
-void
-thr_local_set_slot_no(
-/*==================*/
-	os_thread_id_t	id,	/*!< in: thread id of the thread */
-	ulint		slot_no);/*!< in: slot number */
-/*******************************************************************//**
-Returns pointer to the 'in_ibuf' field within the current thread local
-storage.
-@return	pointer to the in_ibuf field */
-UNIV_INTERN
-ibool*
-thr_local_get_in_ibuf_field(void);
-/*=============================*/
-
-#ifndef UNIV_NONINL
-#include "thr0loc.ic"
-#endif
-
-#endif

=== removed file 'storage/innobase/include/thr0loc.ic'
--- a/storage/innobase/include/thr0loc.ic	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/include/thr0loc.ic	1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/thr0loc.ic
-Thread local storage
-
-Created 10/4/1995 Heikki Tuuri
-*******************************************************/

=== modified file 'storage/innobase/mem/mem0dbg.c'
--- a/storage/innobase/mem/mem0dbg.c	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/mem/mem0dbg.c	2011-02-25 11:21:02 +0000
@@ -24,6 +24,8 @@ but is included in mem0mem.* !
 Created 6/9/1994 Heikki Tuuri
 *************************************************************************/
 
+#include "ha_prototypes.h"
+
 #ifdef UNIV_MEM_DEBUG
 # ifndef UNIV_HOTBACKUP
 /* The mutex which protects in the debug version the hash table
@@ -400,7 +402,7 @@ mem_hash_remove(
 		fprintf(stderr,
 			"Memory heap or buffer freed in %s line %lu"
 			" did not exist.\n",
-			file_name, (ulong) line);
+			innobase_basename(file_name), (ulong) line);
 		ut_error;
 	}
 
@@ -419,8 +421,9 @@ mem_hash_remove(
 			"in %s line %lu and tried to free in %s line %lu.\n"
 			"Hex dump of 400 bytes around memory heap"
 			" first block start:\n",
-			node->nth_heap, node->file_name, (ulong) node->line,
-			file_name, (ulong) line);
+			node->nth_heap,
+			innobase_basename(node->file_name), (ulong) node->line,
+			innobase_basename(file_name), (ulong) line);
 		ut_print_buf(stderr, (byte*)node->heap - 200, 400);
 		fputs("\nDump of the mem heap:\n", stderr);
 		mem_heap_validate_or_print(node->heap, NULL, TRUE, &error,
@@ -763,7 +766,8 @@ mem_validate_no_assert(void)
 					"Inconsistency in memory heap"
 					" or buffer created\n"
 					"in %s line %lu.\n",
-					node->file_name, node->line);
+					innobase_basename(node->file_name),
+					node->line);
 
 				mutex_exit(&mem_hash_mutex);
 
@@ -989,7 +993,8 @@ mem_print_info_low(
 		fprintf(outfile,
 			"%lu: file %s line %lu of size %lu phys.size %lu"
 			" with %lu blocks, type %lu\n",
-			node->nth_heap, node->file_name, node->line,
+			node->nth_heap,
+			innobase_basename(node->file_name), node->line,
 			allocated_mem, ph_size, n_blocks,
 			(node->heap)->type);
 next_heap:

=== modified file 'storage/innobase/mtr/mtr0mtr.c'
--- a/storage/innobase/mtr/mtr0mtr.c	2010-07-22 04:46:12 +0000
+++ b/storage/innobase/mtr/mtr0mtr.c	2011-03-24 12:00:14 +0000
@@ -251,6 +251,7 @@ mtr_commit(
 	ut_ad(mtr);
 	ut_ad(mtr->magic_n == MTR_MAGIC_N);
 	ut_ad(mtr->state == MTR_ACTIVE);
+	ut_ad(!mtr->inside_ibuf);
 	ut_d(mtr->state = MTR_COMMITTING);
 
 #ifndef UNIV_HOTBACKUP

=== modified file 'storage/innobase/page/page0page.c'
--- a/storage/innobase/page/page0page.c	2011-02-08 11:39:24 +0000
+++ b/storage/innobase/page/page0page.c	2011-03-21 07:56:38 +0000
@@ -166,11 +166,11 @@ static
 ibool
 page_dir_slot_check(
 /*================*/
-	page_dir_slot_t*	slot)	/*!< in: slot */
+	const page_dir_slot_t*	slot)	/*!< in: slot */
 {
-	page_t*	page;
-	ulint	n_slots;
-	ulint	n_owned;
+	const page_t*	page;
+	ulint		n_slots;
+	ulint		n_owned;
 
 	ut_a(slot);
 
@@ -1803,12 +1803,12 @@ UNIV_INTERN
 ibool
 page_rec_validate(
 /*==============*/
-	rec_t*		rec,	/*!< in: physical record */
+	const rec_t*	rec,	/*!< in: physical record */
 	const ulint*	offsets)/*!< in: array returned by rec_get_offsets() */
 {
-	ulint	n_owned;
-	ulint	heap_no;
-	page_t*	page;
+	ulint		n_owned;
+	ulint		heap_no;
+	const page_t*	page;
 
 	page = page_align(rec);
 	ut_a(!page_is_comp(page) == !rec_offs_comp(offsets));
@@ -1889,16 +1889,16 @@ UNIV_INTERN
 ibool
 page_simple_validate_old(
 /*=====================*/
-	page_t*	page)	/*!< in: old-style index page */
+	const page_t*	page)	/*!< in: index page in ROW_FORMAT=REDUNDANT */
 {
-	page_dir_slot_t* slot;
-	ulint		slot_no;
-	ulint		n_slots;
-	rec_t*		rec;
-	byte*		rec_heap_top;
-	ulint		count;
-	ulint		own_count;
-	ibool		ret	= FALSE;
+	const page_dir_slot_t*	slot;
+	ulint			slot_no;
+	ulint			n_slots;
+	const rec_t*		rec;
+	const byte*		rec_heap_top;
+	ulint			count;
+	ulint			own_count;
+	ibool			ret	= FALSE;
 
 	ut_a(!page_is_comp(page));
 
@@ -2011,7 +2011,7 @@ page_simple_validate_old(
 			goto func_exit;
 		}
 
-		rec = page_rec_get_next(rec);
+		rec = page_rec_get_next_const(rec);
 		own_count++;
 	}
 
@@ -2072,7 +2072,7 @@ page_simple_validate_old(
 			goto func_exit;
 		}
 
-		rec = page_rec_get_next(rec);
+		rec = page_rec_get_next_const(rec);
 	}
 
 	if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) {
@@ -2099,16 +2099,16 @@ UNIV_INTERN
 ibool
 page_simple_validate_new(
 /*=====================*/
-	page_t*	page)	/*!< in: new-style index page */
+	const page_t*	page)	/*!< in: index page in ROW_FORMAT!=REDUNDANT */
 {
-	page_dir_slot_t* slot;
-	ulint		slot_no;
-	ulint		n_slots;
-	rec_t*		rec;
-	byte*		rec_heap_top;
-	ulint		count;
-	ulint		own_count;
-	ibool		ret	= FALSE;
+	const page_dir_slot_t*	slot;
+	ulint			slot_no;
+	ulint			n_slots;
+	const rec_t*		rec;
+	const byte*		rec_heap_top;
+	ulint			count;
+	ulint			own_count;
+	ibool			ret	= FALSE;
 
 	ut_a(page_is_comp(page));
 
@@ -2221,7 +2221,7 @@ page_simple_validate_new(
 			goto func_exit;
 		}
 
-		rec = page_rec_get_next(rec);
+		rec = page_rec_get_next_const(rec);
 		own_count++;
 	}
 
@@ -2283,7 +2283,7 @@ page_simple_validate_new(
 			goto func_exit;
 		}
 
-		rec = page_rec_get_next(rec);
+		rec = page_rec_get_next_const(rec);
 	}
 
 	if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) {
@@ -2308,26 +2308,26 @@ UNIV_INTERN
 ibool
 page_validate(
 /*==========*/
-	page_t*		page,	/*!< in: index page */
+	const page_t*	page,	/*!< in: index page */
 	dict_index_t*	index)	/*!< in: data dictionary index containing
 				the page record type definition */
 {
-	page_dir_slot_t*slot;
-	mem_heap_t*	heap;
-	byte*		buf;
-	ulint		count;
-	ulint		own_count;
-	ulint		rec_own_count;
-	ulint		slot_no;
-	ulint		data_size;
-	rec_t*		rec;
-	rec_t*		old_rec		= NULL;
-	ulint		offs;
-	ulint		n_slots;
-	ibool		ret		= FALSE;
-	ulint		i;
-	ulint*		offsets		= NULL;
-	ulint*		old_offsets	= NULL;
+	const page_dir_slot_t*	slot;
+	mem_heap_t*		heap;
+	byte*			buf;
+	ulint			count;
+	ulint			own_count;
+	ulint			rec_own_count;
+	ulint			slot_no;
+	ulint			data_size;
+	const rec_t*		rec;
+	const rec_t*		old_rec		= NULL;
+	ulint			offs;
+	ulint			n_slots;
+	ibool			ret		= FALSE;
+	ulint			i;
+	ulint*			offsets		= NULL;
+	ulint*			old_offsets	= NULL;
 
 	if (UNIV_UNLIKELY((ibool) !!page_is_comp(page)
 			  != dict_table_is_comp(index->table))) {
@@ -2482,7 +2482,7 @@ page_validate(
 		count++;
 		own_count++;
 		old_rec = rec;
-		rec = page_rec_get_next(rec);
+		rec = page_rec_get_next_const(rec);
 
 		/* set old_offsets to offsets; recycle offsets */
 		{
@@ -2556,7 +2556,7 @@ n_owned_zero:
 			buf[offs + i] = 1;
 		}
 
-		rec = page_rec_get_next(rec);
+		rec = page_rec_get_next_const(rec);
 	}
 
 	if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) {

=== modified file 'storage/innobase/page/page0zip.c'
--- a/storage/innobase/page/page0zip.c	2011-02-08 11:39:24 +0000
+++ b/storage/innobase/page/page0zip.c	2011-03-15 10:26:53 +0000
@@ -653,13 +653,13 @@ page_zip_dir_encode(
 Allocate memory for zlib. */
 static
 void*
-page_zip_malloc(
+page_zip_zalloc(
 /*============*/
 	void*	opaque,	/*!< in/out: memory heap */
 	uInt	items,	/*!< in: number of items to allocate */
 	uInt	size)	/*!< in: size of an item in bytes */
 {
-	return(mem_heap_alloc(opaque, items * size));
+	return(mem_heap_zalloc(opaque, items * size));
 }
 
 /**********************************************************************//**
@@ -684,7 +684,7 @@ page_zip_set_alloc(
 {
 	z_stream*	strm = stream;
 
-	strm->zalloc = page_zip_malloc;
+	strm->zalloc = page_zip_zalloc;
 	strm->zfree = page_zip_free;
 	strm->opaque = heap;
 }
@@ -2912,19 +2912,18 @@ zlib_error:
 
 	page_zip_set_alloc(&d_stream, heap);
 
-	if (UNIV_UNLIKELY(inflateInit2(&d_stream, UNIV_PAGE_SIZE_SHIFT)
-			  != Z_OK)) {
-		ut_error;
-	}
-
 	d_stream.next_in = page_zip->data + PAGE_DATA;
 	/* Subtract the space reserved for
 	the page header and the end marker of the modification log. */
 	d_stream.avail_in = page_zip_get_size(page_zip) - (PAGE_DATA + 1);
-
 	d_stream.next_out = page + PAGE_ZIP_START;
 	d_stream.avail_out = UNIV_PAGE_SIZE - PAGE_ZIP_START;
 
+	if (UNIV_UNLIKELY(inflateInit2(&d_stream, UNIV_PAGE_SIZE_SHIFT)
+			  != Z_OK)) {
+		ut_error;
+	}
+
 	/* Decode the zlib header and the index information. */
 	if (UNIV_UNLIKELY(inflate(&d_stream, Z_BLOCK) != Z_OK)) {
 

=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c	2011-02-22 05:04:08 +0000
+++ b/storage/innobase/srv/srv0srv.c	2011-03-30 11:52:26 +0000
@@ -66,7 +66,6 @@ Created 10/8/1995 Heikki Tuuri
 #include "mem0mem.h"
 #include "mem0pool.h"
 #include "sync0sync.h"
-#include "thr0loc.h"
 #include "que0que.h"
 #include "log0recv.h"
 #include "pars0pars.h"
@@ -690,7 +689,7 @@ Unix.*/
 struct srv_slot_struct{
 	os_thread_id_t	id;		/*!< thread id */
 	os_thread_t	handle;		/*!< thread handle */
-	unsigned	type:3;		/*!< thread type: user, utility etc. */
+	unsigned	type:1;		/*!< thread type: user, utility etc. */
 	unsigned	in_use:1;	/*!< TRUE if this slot is in use */
 	unsigned	suspended:1;	/*!< TRUE if the thread is waiting
 					for the event of this slot */
@@ -797,6 +796,7 @@ srv_table_get_nth_slot(
 /*===================*/
 	ulint	index)		/*!< in: index of the slot */
 {
+	ut_ad(mutex_own(&kernel_mutex));
 	ut_a(index < OS_THREAD_MAX_N);
 
 	return(srv_sys->threads + index);
@@ -815,7 +815,7 @@ srv_get_n_threads(void)
 
 	mutex_enter(&kernel_mutex);
 
-	for (i = SRV_COM; i < SRV_MASTER + 1; i++) {
+	for (i = 0; i < SRV_MASTER + 1; i++) {
 
 		n_threads += srv_n_threads[i];
 	}
@@ -825,13 +825,46 @@ srv_get_n_threads(void)
 	return(n_threads);
 }
 
+#ifdef UNIV_DEBUG
 /*********************************************************************//**
-Reserves a slot in the thread table for the current thread. Also creates the
-thread local storage struct for the current thread. NOTE! The server mutex
-has to be reserved by the caller!
-@return	reserved slot index */
+Validates the type of a thread table slot.
+@return TRUE if ok */
 static
-ulint
+ibool
+srv_thread_type_validate(
+/*=====================*/
+	enum srv_thread_type	type)	/*!< in: thread type */
+{
+	switch (type) {
+	case SRV_WORKER:
+	case SRV_MASTER:
+		return(TRUE);
+	}
+	ut_error;
+	return(FALSE);
+}
+#endif /* UNIV_DEBUG */
+
+/*********************************************************************//**
+Gets the type of a thread table slot.
+@return thread type */
+static
+enum srv_thread_type
+srv_slot_get_type(
+/*==============*/
+	const srv_slot_t*	slot)	/*!< in: thread slot */
+{
+	enum srv_thread_type	type	= (enum srv_thread_type) slot->type;
+	ut_ad(srv_thread_type_validate(type));
+	return(type);
+}
+
+/*********************************************************************//**
+Reserves a slot in the thread table for the current thread.
+NOTE! The server mutex has to be reserved by the caller!
+@return	reserved slot */
+static
+srv_slot_t*
 srv_table_reserve_slot(
 /*===================*/
 	enum srv_thread_type	type)	/*!< in: type of the thread */
@@ -839,8 +872,7 @@ srv_table_reserve_slot(
 	srv_slot_t*	slot;
 	ulint		i;
 
-	ut_a(type > 0);
-	ut_a(type <= SRV_MASTER);
+	ut_ad(srv_thread_type_validate(type));
 	ut_ad(mutex_own(&kernel_mutex));
 
 	i = 0;
@@ -851,53 +883,40 @@ srv_table_reserve_slot(
 		slot = srv_table_get_nth_slot(i);
 	}
 
-	ut_a(slot->in_use == FALSE);
-
 	slot->in_use = TRUE;
 	slot->suspended = FALSE;
 	slot->type = type;
+	ut_ad(srv_slot_get_type(slot) == type);
 	slot->id = os_thread_get_curr_id();
 	slot->handle = os_thread_get_curr();
 
-	thr_local_create();
-
-	thr_local_set_slot_no(os_thread_get_curr_id(), i);
-
-	return(i);
+	return(slot);
 }
 
 /*********************************************************************//**
 Suspends the calling thread to wait for the event in its thread slot.
-NOTE! The server mutex has to be reserved by the caller!
-@return	event for the calling thread to wait */
+NOTE! The server mutex has to be reserved by the caller! */
 static
-os_event_t
-srv_suspend_thread(void)
-/*====================*/
+void
+srv_suspend_thread(
+/*===============*/
+	srv_slot_t*	slot)	/*!< in/out: thread slot */
 {
-	srv_slot_t*		slot;
-	os_event_t		event;
-	ulint			slot_no;
 	enum srv_thread_type	type;
 
 	ut_ad(mutex_own(&kernel_mutex));
-
-	slot_no = thr_local_get_slot_no(os_thread_get_curr_id());
+	ut_ad(slot->in_use);
+	ut_ad(!slot->suspended);
+	ut_ad(slot->id == os_thread_get_curr_id());
 
 	if (srv_print_thread_releases) {
 		fprintf(stderr,
 			"Suspending thread %lu to slot %lu\n",
-			(ulong) os_thread_get_curr_id(), (ulong) slot_no);
+			(ulong) os_thread_get_curr_id(),
+			(ulong) (slot - srv_sys->threads));
 	}
 
-	slot = srv_table_get_nth_slot(slot_no);
-
-	type = slot->type;
-
-	ut_ad(type >= SRV_WORKER);
-	ut_ad(type <= SRV_MASTER);
-
-	event = slot->event;
+	type = srv_slot_get_type(slot);
 
 	slot->suspended = TRUE;
 
@@ -905,9 +924,7 @@ srv_suspend_thread(void)
 
 	srv_n_threads_active[type]--;
 
-	os_event_reset(event);
-
-	return(event);
+	os_event_reset(slot->event);
 }
 
 /*********************************************************************//**
@@ -926,8 +943,7 @@ srv_release_threads(
 	ulint		i;
 	ulint		count	= 0;
 
-	ut_ad(type >= SRV_WORKER);
-	ut_ad(type <= SRV_MASTER);
+	ut_ad(srv_thread_type_validate(type));
 	ut_ad(n > 0);
 	ut_ad(mutex_own(&kernel_mutex));
 
@@ -935,7 +951,8 @@ srv_release_threads(
 
 		slot = srv_table_get_nth_slot(i);
 
-		if (slot->in_use && slot->type == type && slot->suspended) {
+		if (slot->in_use && slot->suspended
+		    && srv_slot_get_type(slot) == type) {
 
 			slot->suspended = FALSE;
 
@@ -963,34 +980,6 @@ srv_release_threads(
 }
 
 /*********************************************************************//**
-Returns the calling thread type.
-@return	SRV_COM, ... */
-UNIV_INTERN
-enum srv_thread_type
-srv_get_thread_type(void)
-/*=====================*/
-{
-	ulint			slot_no;
-	srv_slot_t*		slot;
-	enum srv_thread_type	type;
-
-	mutex_enter(&kernel_mutex);
-
-	slot_no = thr_local_get_slot_no(os_thread_get_curr_id());
-
-	slot = srv_table_get_nth_slot(slot_no);
-
-	type = slot->type;
-
-	ut_ad(type >= SRV_WORKER);
-	ut_ad(type <= SRV_MASTER);
-
-	mutex_exit(&kernel_mutex);
-
-	return(type);
-}
-
-/*********************************************************************//**
 Check whether thread type has reserved a slot. Return the first slot that
 is found. This works because we currently have only 1 thread of each type.
 @return	slot number or ULINT_UNDEFINED if not found*/
@@ -1003,6 +992,7 @@ srv_thread_has_reserved_slot(
 	ulint			i;
 	ulint			slot_no = ULINT_UNDEFINED;
 
+	ut_ad(srv_thread_type_validate(type));
 	mutex_enter(&kernel_mutex);
 
 	for (i = 0; i < OS_THREAD_MAX_N; i++) {
@@ -1040,22 +1030,18 @@ srv_init(void)
 	mutex_create(srv_innodb_monitor_mutex_key,
 		     &srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
 
-	srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
+	srv_sys->threads = mem_zalloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
 
 	for (i = 0; i < OS_THREAD_MAX_N; i++) {
-		slot = srv_table_get_nth_slot(i);
-		slot->in_use = FALSE;
-		slot->type=0;	/* Avoid purify errors */
+		slot = srv_sys->threads + i;
 		slot->event = os_event_create(NULL);
 		ut_a(slot->event);
 	}
 
-	srv_mysql_table = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
+	srv_mysql_table = mem_zalloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
 
 	for (i = 0; i < OS_THREAD_MAX_N; i++) {
 		slot = srv_mysql_table + i;
-		slot->in_use = FALSE;
-		slot->type = 0;
 		slot->event = os_event_create(NULL);
 		ut_a(slot->event);
 	}
@@ -1142,7 +1128,6 @@ srv_general_init(void)
 	os_sync_init();
 	sync_init();
 	mem_init(srv_mem_pool_size);
-	thr_local_init();
 }
 
 /*======================= InnoDB Server FIFO queue =======================*/
@@ -1501,7 +1486,7 @@ srv_table_reserve_slot_for_mysql(void)
 	while (slot->in_use) {
 		i++;
 
-		if (i >= OS_THREAD_MAX_N) {
+		if (UNIV_UNLIKELY(i >= OS_THREAD_MAX_N)) {
 
 			ut_print_timestamp(stderr);
 
@@ -2382,6 +2367,12 @@ srv_error_monitor_thread(
 	ib_uint64_t	old_lsn;
 	ib_uint64_t	new_lsn;
 	ib_int64_t	sig_count;
+	/* longest waiting thread for a semaphore */
+	os_thread_id_t	waiter		= os_thread_get_curr_id();
+	os_thread_id_t	old_waiter	= waiter;
+	/* the semaphore that is being waited for */
+	const void*	sema		= NULL;
+	const void*	old_sema	= NULL;
 
 	old_lsn = srv_start_lsn;
 
@@ -2435,7 +2426,8 @@ loop:
 
 	sync_arr_wake_threads_if_sema_free();
 
-	if (sync_array_print_long_waits()) {
+	if (sync_array_print_long_waits(&waiter, &sema)
+	    && sema == old_sema && os_thread_eq(waiter, old_waiter)) {
 		fatal_cnt++;
 		if (fatal_cnt > 10) {
 
@@ -2450,6 +2442,8 @@ loop:
 		}
 	} else {
 		fatal_cnt = 0;
+		old_waiter = waiter;
+		old_sema = sema;
 	}
 
 	/* Flush stderr so that a database user gets the output
@@ -2489,7 +2483,7 @@ srv_is_any_background_thread_active(void
 
 	mutex_enter(&kernel_mutex);
 
-	for (i = SRV_COM; i <= SRV_MASTER; ++i) {
+	for (i = 0; i <= SRV_MASTER; ++i) {
 		if (srv_n_threads_active[i] != 0) {
 			ret = TRUE;
 			break;
@@ -2643,7 +2637,7 @@ srv_master_thread(
 			os_thread_create */
 {
 	buf_pool_stat_t buf_stat;
-	os_event_t	event;
+	srv_slot_t*	slot;
 	ulint		old_activity_count;
 	ulint		n_pages_purged	= 0;
 	ulint		n_bytes_merged;
@@ -2671,7 +2665,7 @@ srv_master_thread(
 
 	mutex_enter(&kernel_mutex);
 
-	srv_table_reserve_slot(SRV_MASTER);
+	slot = srv_table_reserve_slot(SRV_MASTER);
 
 	srv_n_threads_active[SRV_MASTER]++;
 
@@ -3060,7 +3054,7 @@ suspend_thread:
 		goto loop;
 	}
 
-	event = srv_suspend_thread();
+	srv_suspend_thread(slot);
 
 	mutex_exit(&kernel_mutex);
 
@@ -3070,7 +3064,7 @@ suspend_thread:
 	manual also mentions this string in several places. */
 	srv_main_thread_op_info = "waiting for server activity";
 
-	os_event_wait(event);
+	os_event_wait(slot->event);
 
 	if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
 		/* This is only extra safety, the thread should exit
@@ -3084,8 +3078,6 @@ suspend_thread:
 	main thread goes back to loop. */
 
 	goto loop;
-
-	OS_THREAD_DUMMY_RETURN;	/* Not reached, avoid compiler warning */
 }
 
 /*********************************************************************//**
@@ -3100,7 +3092,6 @@ srv_purge_thread(
 {
 	srv_slot_t*	slot;
 	ulint		retries = 0;
-	ulint		slot_no = ULINT_UNDEFINED;
 	ulint		n_total_purged = ULINT_UNDEFINED;
 
 	ut_a(srv_n_purge_threads == 1);
@@ -3116,9 +3107,7 @@ srv_purge_thread(
 
 	mutex_enter(&kernel_mutex);
 
-	slot_no = srv_table_reserve_slot(SRV_WORKER);
-
-	slot = srv_table_get_nth_slot(slot_no);
+	slot = srv_table_reserve_slot(SRV_WORKER);
 
 	++srv_n_threads_active[SRV_WORKER];
 
@@ -3137,15 +3126,13 @@ srv_purge_thread(
 		    || (n_total_purged == 0
 			&& retries >= TRX_SYS_N_RSEGS)) {
 
-			os_event_t	event;
-
 			mutex_enter(&kernel_mutex);
 
-			event = srv_suspend_thread();
+			srv_suspend_thread(slot);
 
 			mutex_exit(&kernel_mutex);
 
-			os_event_wait(event);
+			os_event_wait(slot->event);
 
 			retries = 0;
 		}
@@ -3179,16 +3166,11 @@ srv_purge_thread(
 
 	mutex_enter(&kernel_mutex);
 
-	ut_ad(srv_table_get_nth_slot(slot_no) == slot);
-
 	/* Decrement the active count. */
-	srv_suspend_thread();
+	srv_suspend_thread(slot);
 
 	slot->in_use = FALSE;
 
-	/* Free the thread local memory. */
-	thr_local_free(os_thread_get_curr_id());
-
 	mutex_exit(&kernel_mutex);
 
 #ifdef UNIV_DEBUG_THREAD_CREATION

=== modified file 'storage/innobase/srv/srv0start.c'
--- a/storage/innobase/srv/srv0start.c	2011-02-08 11:39:24 +0000
+++ b/storage/innobase/srv/srv0start.c	2011-03-24 12:00:14 +0000
@@ -85,7 +85,6 @@ Created 2/16/1996 Heikki Tuuri
 # include "row0row.h"
 # include "row0mysql.h"
 # include "btr0pcur.h"
-# include "thr0loc.h"
 # include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
 # include "zlib.h" /* for ZLIB_VERSION */
 
@@ -2210,7 +2209,6 @@ innobase_shutdown_for_mysql(void)
 	ibuf_close();
 	log_shutdown();
 	lock_sys_close();
-	thr_local_close();
 	trx_sys_file_format_close();
 	trx_sys_close();
 

=== modified file 'storage/innobase/sync/sync0arr.c'
--- a/storage/innobase/sync/sync0arr.c	2011-01-18 10:30:33 +0000
+++ b/storage/innobase/sync/sync0arr.c	2011-03-30 11:52:26 +0000
@@ -40,6 +40,7 @@ Created 9/5/1995 Heikki Tuuri
 #include "os0sync.h"
 #include "os0file.h"
 #include "srv0srv.h"
+#include "ha_prototypes.h"
 
 /*
 			WAIT ARRAY
@@ -478,8 +479,8 @@ sync_array_cell_print(
 	fprintf(file,
 		"--Thread %lu has waited at %s line %lu"
 		" for %.2f seconds the semaphore:\n",
-		(ulong) os_thread_pf(cell->thread), cell->file,
-		(ulong) cell->line,
+		(ulong) os_thread_pf(cell->thread),
+		innobase_basename(cell->file), (ulong) cell->line,
 		difftime(time(NULL), cell->reservation_time));
 
 	if (type == SYNC_MUTEX) {
@@ -493,7 +494,8 @@ sync_array_cell_print(
 			"Last time reserved in file %s line %lu, "
 #endif /* UNIV_SYNC_DEBUG */
 			"waiters flag %lu\n",
-			(void*) mutex, mutex->cfile_name, (ulong) mutex->cline,
+			(void*) mutex, innobase_basename(mutex->cfile_name),
+			(ulong) mutex->cline,
 			(ulong) mutex->lock_word,
 #ifdef UNIV_SYNC_DEBUG
 			mutex->file_name, (ulong) mutex->line,
@@ -512,7 +514,7 @@ sync_array_cell_print(
 
 		fprintf(file,
 			" RW-latch at %p created in file %s line %lu\n",
-			(void*) rwlock, rwlock->cfile_name,
+			(void*) rwlock, innobase_basename(rwlock->cfile_name),
 			(ulong) rwlock->cline);
 		writer = rw_lock_get_writer(rwlock);
 		if (writer != RW_LOCK_NOT_LOCKED) {
@@ -533,7 +535,7 @@ sync_array_cell_print(
 			(ulong) rw_lock_get_reader_count(rwlock),
 			(ulong) rwlock->waiters,
 			rwlock->lock_word,
-			rwlock->last_s_file_name,
+			innobase_basename(rwlock->last_s_file_name),
 			(ulong) rwlock->last_s_line,
 			rwlock->last_x_file_name,
 			(ulong) rwlock->last_x_line);
@@ -913,8 +915,10 @@ Prints warnings of long semaphore waits
 @return	TRUE if fatal semaphore wait threshold was exceeded */
 UNIV_INTERN
 ibool
-sync_array_print_long_waits(void)
-/*=============================*/
+sync_array_print_long_waits(
+/*========================*/
+	os_thread_id_t*	waiter,	/*!< out: longest waiting thread */
+	const void**	sema)	/*!< out: longest-waited-for semaphore */
 {
 	sync_cell_t*	cell;
 	ibool		old_val;
@@ -922,6 +926,7 @@ sync_array_print_long_waits(void)
 	ulint		i;
 	ulint		fatal_timeout = srv_fatal_semaphore_wait_threshold;
 	ibool		fatal = FALSE;
+	double		longest_diff = 0;
 
 #ifdef UNIV_DEBUG_VALGRIND
 	/* Increase the timeouts if running under valgrind because it executes
@@ -937,22 +942,36 @@ sync_array_print_long_waits(void)
 
 	for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
 
+		double	diff;
+		void*	wait_object;
+
 		cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
 
-		if (cell->wait_object != NULL && cell->waiting
-		    && difftime(time(NULL), cell->reservation_time)
-		    > SYNC_ARRAY_TIMEOUT) {
+		wait_object = cell->wait_object;
+
+		if (wait_object == NULL || !cell->waiting) {
+
+			continue;
+		}
+
+		diff = difftime(time(NULL), cell->reservation_time);
+
+		if (diff > SYNC_ARRAY_TIMEOUT) {
 			fputs("InnoDB: Warning: a long semaphore wait:\n",
 			      stderr);
 			sync_array_cell_print(stderr, cell);
 			noticed = TRUE;
 		}
 
-		if (cell->wait_object != NULL && cell->waiting
-		    && difftime(time(NULL), cell->reservation_time)
-		    > fatal_timeout) {
+		if (diff > fatal_timeout) {
 			fatal = TRUE;
 		}
+
+		if (diff > longest_diff) {
+			longest_diff = diff;
+			*sema = wait_object;
+			*waiter = cell->thread;
+		}
 	}
 
 	if (noticed) {

=== modified file 'storage/innobase/sync/sync0rw.c'
--- a/storage/innobase/sync/sync0rw.c	2011-02-15 09:29:56 +0000
+++ b/storage/innobase/sync/sync0rw.c	2011-02-25 11:21:02 +0000
@@ -39,6 +39,7 @@ Created 9/11/1995 Heikki Tuuri
 #include "mem0mem.h"
 #include "srv0srv.h"
 #include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
+#include "ha_prototypes.h"
 
 /*
 	IMPLEMENTATION OF THE RW_LOCK
@@ -407,7 +408,8 @@ lock_loop:
 			" cfile %s cline %lu rnds %lu\n",
 			(ulong) os_thread_pf(os_thread_get_curr_id()),
 			(void*) lock,
-			lock->cfile_name, (ulong) lock->cline, (ulong) i);
+			innobase_basename(lock->cfile_name),
+			(ulong) lock->cline, (ulong) i);
 	}
 
 	/* We try once again to obtain the lock */
@@ -442,7 +444,8 @@ lock_loop:
 				"Thread %lu OS wait rw-s-lock at %p"
 				" cfile %s cline %lu\n",
 				os_thread_pf(os_thread_get_curr_id()),
-				(void*) lock, lock->cfile_name,
+				(void*) lock,
+				innobase_basename(lock->cfile_name),
 				(ulong) lock->cline);
 		}
 
@@ -664,7 +667,8 @@ lock_loop:
 			"Thread %lu spin wait rw-x-lock at %p"
 			" cfile %s cline %lu rnds %lu\n",
 			os_thread_pf(os_thread_get_curr_id()), (void*) lock,
-			lock->cfile_name, (ulong) lock->cline, (ulong) i);
+			innobase_basename(lock->cfile_name),
+			(ulong) lock->cline, (ulong) i);
 	}
 
 	sync_array_reserve_cell(sync_primary_wait_array,
@@ -687,7 +691,8 @@ lock_loop:
 			"Thread %lu OS wait for rw-x-lock at %p"
 			" cfile %s cline %lu\n",
 			os_thread_pf(os_thread_get_curr_id()), (void*) lock,
-			lock->cfile_name, (ulong) lock->cline);
+			innobase_basename(lock->cfile_name),
+			(ulong) lock->cline);
 	}
 
 	/* these stats may not be accurate */

=== modified file 'storage/innobase/sync/sync0sync.c'
--- a/storage/innobase/sync/sync0sync.c	2011-02-22 05:04:08 +0000
+++ b/storage/innobase/sync/sync0sync.c	2011-02-25 11:21:02 +0000
@@ -43,6 +43,7 @@ Created 9/5/1995 Heikki Tuuri
 #ifdef UNIV_SYNC_DEBUG
 # include "srv0start.h" /* srv_is_being_started */
 #endif /* UNIV_SYNC_DEBUG */
+#include "ha_prototypes.h"
 
 /*
 	REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
@@ -543,7 +544,8 @@ spin_loop:
 		"Thread %lu spin wait mutex at %p"
 		" cfile %s cline %lu rnds %lu\n",
 		(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
-		mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
+		innobase_basename(mutex->cfile_name),
+		(ulong) mutex->cline, (ulong) i);
 #endif
 
 	mutex_spin_round_count += i;
@@ -620,7 +622,8 @@ spin_loop:
 	fprintf(stderr,
 		"Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n",
 		(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
-		mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
+		innobase_basename(mutex->cfile_name),
+		(ulong) mutex->cline, (ulong) i);
 #endif
 
 	mutex_os_wait_count++;
@@ -869,7 +872,8 @@ sync_print_warning(
 	if (mutex->magic_n == MUTEX_MAGIC_N) {
 		fprintf(stderr,
 			"Mutex created at %s %lu\n",
-			mutex->cfile_name, (ulong) mutex->cline);
+			innobase_basename(mutex->cfile_name),
+			(ulong) mutex->cline);
 
 		if (mutex_get_lock_word(mutex) != 0) {
 			ulint		line;

=== removed directory 'storage/innobase/thr'
=== removed file 'storage/innobase/thr/thr0loc.c'
--- a/storage/innobase/thr/thr0loc.c	2010-11-11 13:13:52 +0000
+++ b/storage/innobase/thr/thr0loc.c	1970-01-01 00:00:00 +0000
@@ -1,307 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file thr/thr0loc.c
-The thread local storage
-
-Created 10/5/1995 Heikki Tuuri
-*******************************************************/
-
-#include "thr0loc.h"
-#ifdef UNIV_NONINL
-#include "thr0loc.ic"
-#endif
-
-#include "sync0sync.h"
-#include "hash0hash.h"
-#include "mem0mem.h"
-#include "srv0srv.h"
-
-/*
-	IMPLEMENTATION OF THREAD LOCAL STORAGE
-	======================================
-
-The threads sometimes need private data which depends on the thread id.
-This is implemented as a hash table, where the hash value is calculated
-from the thread id, to prepare for a large number of threads. The hash table
-is protected by a mutex. If you need modify the program and put new data to
-the thread local storage, just add it to struct thr_local_struct in the
-header file. */
-
-/** Mutex protecting thr_local_hash */
-static mutex_t		thr_local_mutex;
-
-/** The hash table. The module is not yet initialized when it is NULL. */
-static hash_table_t*	thr_local_hash	= NULL;
-
-/** Thread local data */
-typedef struct thr_local_struct thr_local_t;
-
-#ifdef UNIV_PFS_MUTEX
-/* Key to register the mutex with performance schema */
-UNIV_INTERN mysql_pfs_key_t	thr_local_mutex_key;
-#endif /* UNIV_PFS_MUTEX */
-
-/** @brief Thread local data.
-The private data for each thread should be put to
-the structure below and the accessor functions written
-for the field. */
-struct thr_local_struct{
-	os_thread_id_t	id;	/*!< id of the thread which owns this struct */
-	os_thread_t	handle;	/*!< operating system handle to the thread */
-	ulint		slot_no;/*!< the index of the slot in the thread table
-				for this thread */
-	ibool		in_ibuf;/*!< TRUE if the thread is doing an ibuf
-				operation */
-	hash_node_t	hash;	/*!< hash chain node */
-	ulint		magic_n;/*!< magic number (THR_LOCAL_MAGIC_N) */
-};
-
-/** The value of thr_local_struct::magic_n */
-#define THR_LOCAL_MAGIC_N	1231234
-
-#ifdef UNIV_DEBUG
-/*******************************************************************//**
-Validates thread local data.
-@return	TRUE if valid */
-static
-ibool
-thr_local_validate(
-/*===============*/
-	const thr_local_t*	local)	/*!< in: data to validate */
-{
-	ut_ad(local->magic_n == THR_LOCAL_MAGIC_N);
-	ut_ad(local->slot_no == ULINT_UNDEFINED
-	      || local->slot_no < OS_THREAD_MAX_N);
-	ut_ad(local->in_ibuf == FALSE || local->in_ibuf == TRUE);
-	return(TRUE);
-}
-#endif /* UNIV_DEBUG */
-
-/*******************************************************************//**
-Returns the local storage struct for a thread.
-@return	local storage */
-static
-thr_local_t*
-thr_local_get(
-/*==========*/
-	os_thread_id_t	id)	/*!< in: thread id of the thread */
-{
-	thr_local_t*	local;
-
-try_again:
-	ut_ad(thr_local_hash);
-	ut_ad(mutex_own(&thr_local_mutex));
-
-	/* Look for the local struct in the hash table */
-
-	local = NULL;
-
-	HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
-		    thr_local_t*, local, ut_ad(thr_local_validate(local)),
-		    os_thread_eq(local->id, id));
-	if (local == NULL) {
-		mutex_exit(&thr_local_mutex);
-
-		thr_local_create();
-
-		mutex_enter(&thr_local_mutex);
-
-		goto try_again;
-	}
-
-	ut_ad(thr_local_validate(local));
-
-	return(local);
-}
-
-/*******************************************************************//**
-Gets the slot number in the thread table of a thread.
-@return	slot number */
-UNIV_INTERN
-ulint
-thr_local_get_slot_no(
-/*==================*/
-	os_thread_id_t	id)	/*!< in: thread id of the thread */
-{
-	ulint		slot_no;
-	thr_local_t*	local;
-
-	mutex_enter(&thr_local_mutex);
-
-	local = thr_local_get(id);
-
-	slot_no = local->slot_no;
-
-	mutex_exit(&thr_local_mutex);
-
-	return(slot_no);
-}
-
-/*******************************************************************//**
-Sets the slot number in the thread table of a thread. */
-UNIV_INTERN
-void
-thr_local_set_slot_no(
-/*==================*/
-	os_thread_id_t	id,	/*!< in: thread id of the thread */
-	ulint		slot_no)/*!< in: slot number */
-{
-	thr_local_t*	local;
-
-	mutex_enter(&thr_local_mutex);
-
-	local = thr_local_get(id);
-
-	local->slot_no = slot_no;
-
-	mutex_exit(&thr_local_mutex);
-}
-
-/*******************************************************************//**
-Returns pointer to the 'in_ibuf' field within the current thread local
-storage.
-@return	pointer to the in_ibuf field */
-UNIV_INTERN
-ibool*
-thr_local_get_in_ibuf_field(void)
-/*=============================*/
-{
-	thr_local_t*	local;
-
-	mutex_enter(&thr_local_mutex);
-
-	local = thr_local_get(os_thread_get_curr_id());
-
-	mutex_exit(&thr_local_mutex);
-
-	return(&(local->in_ibuf));
-}
-
-/*******************************************************************//**
-Creates a local storage struct for the calling new thread. */
-UNIV_INTERN
-void
-thr_local_create(void)
-/*==================*/
-{
-	thr_local_t*	local;
-
-	if (thr_local_hash == NULL) {
-		thr_local_init();
-	}
-
-	local = mem_alloc(sizeof(thr_local_t));
-
-	local->id = os_thread_get_curr_id();
-	local->handle = os_thread_get_curr();
-	local->magic_n = THR_LOCAL_MAGIC_N;
-	local->slot_no = ULINT_UNDEFINED;
-	local->in_ibuf = FALSE;
-
-	mutex_enter(&thr_local_mutex);
-
-	HASH_INSERT(thr_local_t, hash, thr_local_hash,
-		    os_thread_pf(os_thread_get_curr_id()),
-		    local);
-
-	mutex_exit(&thr_local_mutex);
-}
-
-/*******************************************************************//**
-Frees the local storage struct for the specified thread. */
-UNIV_INTERN
-void
-thr_local_free(
-/*===========*/
-	os_thread_id_t	id)	/*!< in: thread id */
-{
-	thr_local_t*	local;
-
-	mutex_enter(&thr_local_mutex);
-
-	/* Look for the local struct in the hash table */
-
-	HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
-		    thr_local_t*, local, ut_ad(thr_local_validate(local)),
-		    os_thread_eq(local->id, id));
-	if (local == NULL) {
-		mutex_exit(&thr_local_mutex);
-
-		return;
-	}
-
-	HASH_DELETE(thr_local_t, hash, thr_local_hash,
-		    os_thread_pf(id), local);
-
-	mutex_exit(&thr_local_mutex);
-
-	ut_a(local->magic_n == THR_LOCAL_MAGIC_N);
-	ut_ad(thr_local_validate(local));
-
-	mem_free(local);
-}
-
-/****************************************************************//**
-Initializes the thread local storage module. */
-UNIV_INTERN
-void
-thr_local_init(void)
-/*================*/
-{
-
-	ut_a(thr_local_hash == NULL);
-
-	thr_local_hash = hash_create(OS_THREAD_MAX_N + 100);
-
-	mutex_create(thr_local_mutex_key,
-		     &thr_local_mutex, SYNC_THR_LOCAL);
-}
-
-/********************************************************************
-Close the thread local storage module. */
-UNIV_INTERN
-void
-thr_local_close(void)
-/*=================*/
-{
-	ulint		i;
-
-	ut_a(thr_local_hash != NULL);
-
-	/* Free the hash elements. We don't remove them from the table
-	because we are going to destroy the table anyway. */
-	for (i = 0; i < hash_get_n_cells(thr_local_hash); i++) {
-		thr_local_t*	local;
-
-		local = HASH_GET_FIRST(thr_local_hash, i);
-
-		while (local) {
-			thr_local_t*	prev_local = local;
-
-			local = HASH_GET_NEXT(hash, prev_local);
-			ut_a(prev_local->magic_n == THR_LOCAL_MAGIC_N);
-			ut_ad(thr_local_validate(prev_local));
-			mem_free(prev_local);
-		}
-	}
-
-	hash_table_free(thr_local_hash);
-	thr_local_hash = NULL;
-}

=== modified file 'storage/innobase/trx/trx0i_s.c'
--- a/storage/innobase/trx/trx0i_s.c	2011-01-07 03:50:49 +0000
+++ b/storage/innobase/trx/trx0i_s.c	2011-03-28 09:05:02 +0000
@@ -518,7 +518,7 @@ fill_trx_row(
 		query[stmt_len] = '\0';
 
 		row->trx_query = ha_storage_put_memlim(
-			cache->storage, stmt, stmt_len + 1,
+			cache->storage, query, stmt_len + 1,
 			MAX_ALLOWED_FOR_STORAGE(cache));
 
 		row->trx_query_cs = innobase_get_charset(trx->mysql_thd);

=== modified file 'storage/innobase/trx/trx0trx.c'
--- a/storage/innobase/trx/trx0trx.c	2011-02-22 05:04:08 +0000
+++ b/storage/innobase/trx/trx0trx.c	2011-03-24 12:00:14 +0000
@@ -38,7 +38,6 @@ Created 3/26/1996 Heikki Tuuri
 #include "usr0sess.h"
 #include "read0read.h"
 #include "srv0srv.h"
-#include "thr0loc.h"
 #include "btr0sea.h"
 #include "os0proc.h"
 #include "trx0xa.h"

=== modified file 'storage/innobase/ut/ut0dbg.c'
--- a/storage/innobase/ut/ut0dbg.c	2011-01-06 07:19:02 +0000
+++ b/storage/innobase/ut/ut0dbg.c	2011-02-25 08:33:13 +0000
@@ -25,6 +25,7 @@ Created 1/30/1994 Heikki Tuuri
 
 #include "univ.i"
 #include "ut0dbg.h"
+#include "ha_prototypes.h"
 
 #if defined(__GNUC__) && (__GNUC__ > 2)
 #else
@@ -55,12 +56,13 @@ ut_dbg_assertion_failed(
 	ut_print_timestamp(stderr);
 #ifdef UNIV_HOTBACKUP
 	fprintf(stderr, "  InnoDB: Assertion failure in file %s line %lu\n",
-		file, line);
+		innobase_basename(file), line);
 #else /* UNIV_HOTBACKUP */
 	fprintf(stderr,
 		"  InnoDB: Assertion failure in thread %lu"
 		" in file %s line %lu\n",
-		os_thread_pf(os_thread_get_curr_id()), file, line);
+		os_thread_pf(os_thread_get_curr_id()),
+		innobase_basename(file), line);
 #endif /* UNIV_HOTBACKUP */
 	if (expr) {
 		fprintf(stderr,
@@ -93,7 +95,8 @@ ut_dbg_stop_thread(
 {
 #ifndef UNIV_HOTBACKUP
 	fprintf(stderr, "InnoDB: Thread %lu stopped in file %s line %lu\n",
-		os_thread_pf(os_thread_get_curr_id()), file, line);
+		os_thread_pf(os_thread_get_curr_id()),
+		innobase_basename(file), line);
 	os_thread_sleep(1000000000);
 #endif /* !UNIV_HOTBACKUP */
 }

No bundle (reason: revision is a merge).
Thread
bzr commit into mysql-5.5-mtr branch (bjorn.munch:3192) Bjorn Munch5 Apr